From 1f0aa23bff695ab8224eb725a9ef12858c786dcd Mon Sep 17 00:00:00 2001 From: Florian Date: Thu, 9 Oct 2025 21:43:47 +0200 Subject: [PATCH 001/347] Add variable playback speed feature for voice messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add playback speed control for voice messages with support for 0.5×, 1×, 1.5×, and 2× playback speeds. The speed button is displayed above the timestamp and cycles through the available speeds when tapped. --- .../components/event/TimelineItemVoiceView.kt | 71 ++++++++++++++++--- .../libraries/mediaplayer/api/MediaPlayer.kt | 6 ++ .../mediaplayer/impl/DefaultMediaPlayer.kt | 4 ++ .../mediaplayer/impl/SimplePlayer.kt | 5 ++ .../mediaplayer/impl/FakeSimplePlayer.kt | 2 + .../mediaplayer/test/FakeMediaPlayer.kt | 4 ++ .../impl/gallery/ui/VoiceItemView.kt | 66 +++++++++++++++-- .../voiceplayer/api/VoiceMessageEvents.kt | 1 + .../voiceplayer/api/VoiceMessageState.kt | 1 + .../api/VoiceMessageStateProvider.kt | 2 + .../voiceplayer/impl/VoiceMessagePlayer.kt | 11 +++ .../voiceplayer/impl/VoiceMessagePresenter.kt | 11 +++ .../impl/VoiceMessagePresenterTest.kt | 34 +++++++++ 13 files changed, 203 insertions(+), 15 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index 02d08a8f43..e12887eab1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -8,6 +8,8 @@ package io.element.android.features.messages.impl.timeline.components.event import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -16,6 +18,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -109,19 +112,30 @@ fun TimelineItemVoiceView( } } Spacer(Modifier.width(8.dp)) - Text( - text = state.time, - color = ElementTheme.colors.textSecondary, - style = ElementTheme.typography.fontBodySmMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + PlaybackSpeedButton( + speed = state.playbackSpeed, + onClick = { state.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) }, + ) + Text( + text = state.time, + color = ElementTheme.colors.textSecondary, + style = ElementTheme.typography.fontBodySmMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } Spacer(Modifier.width(8.dp)) WaveformPlaybackView( showCursor = state.showCursor, playbackProgress = state.progress, waveform = content.waveform, - modifier = Modifier.height(34.dp), + modifier = Modifier + .weight(1f) + .height(34.dp), seekEnabled = !isTalkbackActive(), onSeek = { state.eventSink(VoiceMessageEvents.Seek(it)) }, ) @@ -172,6 +186,36 @@ private fun RetryButton( } } +@Composable +private fun PlaybackSpeedButton( + speed: Float, + onClick: () -> Unit, +) { + val speedText = when (speed) { + 0.5f -> "0.5×" + 1.0f -> "1×" + 1.5f -> "1.5×" + 2.0f -> "2×" + else -> "${speed}×" + } + androidx.compose.foundation.layout.Box( + modifier = Modifier + .background( + color = ElementTheme.colors.bgCanvasDefault, + shape = RoundedCornerShape(12.dp) + ) + .padding(horizontal = 8.dp, vertical = 4.dp) + .clickable(onClick = onClick), + contentAlignment = Alignment.Center, + ) { + Text( + text = speedText, + color = ElementTheme.colors.iconSecondary, + style = ElementTheme.typography.fontBodyXsMedium, + ) + } +} + @Composable private fun ControlIcon( imageVector: ImageVector, @@ -295,3 +339,14 @@ internal fun ProgressButtonPreview() = ElementPreview { ProgressButton(displayImmediately = false) } } + +@PreviewsDayNight +@Composable +internal fun PlaybackSpeedButtonPreview() = ElementPreview { + Row { + PlaybackSpeedButton(speed = 0.5f, onClick = {}) + PlaybackSpeedButton(speed = 1.0f, onClick = {}) + PlaybackSpeedButton(speed = 1.5f, onClick = {}) + PlaybackSpeedButton(speed = 2.0f, onClick = {}) + } +} diff --git a/libraries/mediaplayer/api/src/main/kotlin/io/element/android/libraries/mediaplayer/api/MediaPlayer.kt b/libraries/mediaplayer/api/src/main/kotlin/io/element/android/libraries/mediaplayer/api/MediaPlayer.kt index 0834323f90..b10dd44b7f 100644 --- a/libraries/mediaplayer/api/src/main/kotlin/io/element/android/libraries/mediaplayer/api/MediaPlayer.kt +++ b/libraries/mediaplayer/api/src/main/kotlin/io/element/android/libraries/mediaplayer/api/MediaPlayer.kt @@ -46,6 +46,12 @@ interface MediaPlayer : AutoCloseable { */ fun seekTo(positionMs: Long) + /** + * Sets the playback speed. + * @param speed The playback speed (e.g., 0.5f for half speed, 1.0f for normal, 2.0f for double speed) + */ + fun setPlaybackSpeed(speed: Float) + /** * Releases any resources associated with this player. */ diff --git a/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/DefaultMediaPlayer.kt b/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/DefaultMediaPlayer.kt index 5aad37779c..0767aea3ef 100644 --- a/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/DefaultMediaPlayer.kt +++ b/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/DefaultMediaPlayer.kt @@ -160,6 +160,10 @@ class DefaultMediaPlayer( } } + override fun setPlaybackSpeed(speed: Float) { + player.setPlaybackSpeed(speed) + } + override fun close() { player.release() } diff --git a/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/SimplePlayer.kt b/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/SimplePlayer.kt index c8e42b8abf..b6aff2570a 100644 --- a/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/SimplePlayer.kt +++ b/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/SimplePlayer.kt @@ -33,6 +33,7 @@ interface SimplePlayer { fun isPlaying(): Boolean fun pause() fun seekTo(positionMs: Long) + fun setPlaybackSpeed(speed: Float) fun release() interface Listener { fun onIsPlayingChanged(isPlaying: Boolean) @@ -87,5 +88,9 @@ class DefaultSimplePlayer( override fun seekTo(positionMs: Long) = p.seekTo(positionMs) + override fun setPlaybackSpeed(speed: Float) { + p.setPlaybackParameters(p.playbackParameters.withSpeed(speed)) + } + override fun release() = p.release() } diff --git a/libraries/mediaplayer/impl/src/test/kotlin/io/element/android/libraries/mediaplayer/impl/FakeSimplePlayer.kt b/libraries/mediaplayer/impl/src/test/kotlin/io/element/android/libraries/mediaplayer/impl/FakeSimplePlayer.kt index 94c880a862..34078ab4e8 100644 --- a/libraries/mediaplayer/impl/src/test/kotlin/io/element/android/libraries/mediaplayer/impl/FakeSimplePlayer.kt +++ b/libraries/mediaplayer/impl/src/test/kotlin/io/element/android/libraries/mediaplayer/impl/FakeSimplePlayer.kt @@ -19,6 +19,7 @@ class FakeSimplePlayer( private val isPlayingLambda: () -> Boolean = { lambdaError() }, private val pauseLambda: () -> Unit = { lambdaError() }, private val seekToLambda: (Long) -> Unit = { lambdaError() }, + private val setPlaybackSpeedLambda: (Float) -> Unit = { lambdaError() }, private val releaseLambda: () -> Unit = { lambdaError() }, ) : SimplePlayer { private val listeners = mutableListOf() @@ -44,6 +45,7 @@ class FakeSimplePlayer( override fun isPlaying() = isPlayingLambda() override fun pause() = pauseLambda() override fun seekTo(positionMs: Long) = seekToLambda(positionMs) + override fun setPlaybackSpeed(speed: Float) = setPlaybackSpeedLambda(speed) override fun release() = releaseLambda() fun simulateIsPlayingChanged(isPlaying: Boolean) { diff --git a/libraries/mediaplayer/test/src/main/kotlin/io/element/android/libraries/mediaplayer/test/FakeMediaPlayer.kt b/libraries/mediaplayer/test/src/main/kotlin/io/element/android/libraries/mediaplayer/test/FakeMediaPlayer.kt index 1e670d4675..0dcd655424 100644 --- a/libraries/mediaplayer/test/src/main/kotlin/io/element/android/libraries/mediaplayer/test/FakeMediaPlayer.kt +++ b/libraries/mediaplayer/test/src/main/kotlin/io/element/android/libraries/mediaplayer/test/FakeMediaPlayer.kt @@ -95,6 +95,10 @@ class FakeMediaPlayer( } } + override fun setPlaybackSpeed(speed: Float) { + // no-op + } + override fun close() { // no-op } diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt index 6d5fdd9612..bd8daa69e1 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt @@ -9,7 +9,9 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -119,13 +121,22 @@ private fun VoiceInfoRow( VoiceMessageState.Button.Disabled -> PlayButton(onClick = {}, enabled = false) } Spacer(Modifier.width(8.dp)) - Text( - text = if (state.progress > 0f) state.time else voice.mediaInfo.duration ?: state.time, - color = ElementTheme.colors.textSecondary, - style = ElementTheme.typography.fontBodyMdMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + PlaybackSpeedButton( + speed = state.playbackSpeed, + onClick = { state.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) }, + ) + Text( + text = if (state.progress > 0f) state.time else voice.mediaInfo.duration ?: state.time, + color = ElementTheme.colors.textSecondary, + style = ElementTheme.typography.fontBodyMdMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } Spacer(modifier = Modifier.width(8.dp)) WaveformPlaybackView( modifier = Modifier @@ -223,6 +234,36 @@ private fun RetryButton( } } +@Composable +private fun PlaybackSpeedButton( + speed: Float, + onClick: () -> Unit, +) { + val speedText = when (speed) { + 0.5f -> "0.5×" + 1.0f -> "1×" + 1.5f -> "1.5×" + 2.0f -> "2×" + else -> "${speed}×" + } + androidx.compose.foundation.layout.Box( + modifier = Modifier + .background( + color = ElementTheme.colors.bgCanvasDefault, + shape = RoundedCornerShape(12.dp) + ) + .padding(horizontal = 8.dp, vertical = 4.dp) + .clickable(onClick = onClick), + contentAlignment = Alignment.Center, + ) { + Text( + text = speedText, + color = ElementTheme.colors.iconSecondary, + style = ElementTheme.typography.fontBodyXsMedium, + ) + } +} + @Composable private fun ControlIcon( imageVector: ImageVector, @@ -283,3 +324,14 @@ internal fun VoiceItemViewPlayPreview( onLongClick = {}, ) } + +@PreviewsDayNight +@Composable +internal fun PlaybackSpeedButtonPreview() = ElementPreview { + Row { + PlaybackSpeedButton(speed = 0.5f, onClick = {}) + PlaybackSpeedButton(speed = 1.0f, onClick = {}) + PlaybackSpeedButton(speed = 1.5f, onClick = {}) + PlaybackSpeedButton(speed = 2.0f, onClick = {}) + } +} diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt index db97331b6f..7e5430a566 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt @@ -10,4 +10,5 @@ package io.element.android.libraries.voiceplayer.api sealed interface VoiceMessageEvents { data object PlayPause : VoiceMessageEvents data class Seek(val percentage: Float) : VoiceMessageEvents + data object ChangePlaybackSpeed : VoiceMessageEvents } diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt index f14bf690cc..522b5cfbe2 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt @@ -12,6 +12,7 @@ data class VoiceMessageState( val progress: Float, val time: String, val showCursor: Boolean, + val playbackSpeed: Float, val eventSink: (event: VoiceMessageEvents) -> Unit, ) { enum class Button { diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt index 0ff510a485..bfc2f144ab 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt @@ -47,10 +47,12 @@ fun aVoiceMessageState( progress: Float = 0f, time: String = "1:00", showCursor: Boolean = false, + playbackSpeed: Float = 1.0f, ) = VoiceMessageState( button = button, progress = progress, time = time, showCursor = showCursor, + playbackSpeed = playbackSpeed, eventSink = {}, ) diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePlayer.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePlayer.kt index 64a479105d..51a1163e36 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePlayer.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePlayer.kt @@ -79,6 +79,13 @@ interface VoiceMessagePlayer { */ fun seekTo(positionMs: Long) + /** + * Set the playback speed. + * + * @param speed The playback speed (e.g., 0.5f for half speed, 1.0f for normal, 2.0f for double speed) + */ + fun setPlaybackSpeed(speed: Float) + data class State( /** * Whether the player is ready to play. @@ -218,6 +225,10 @@ class Factory( } } + override fun setPlaybackSpeed(speed: Float) { + mediaPlayer.setPlaybackSpeed(speed) + } + private val MediaPlayer.State.isMyTrack: Boolean get() = if (eventId == null) false else this.mediaId == eventId.value diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt index c7811f6d17..9637c5e587 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt @@ -37,6 +37,9 @@ class VoiceMessagePresenter( private val duration: Duration, ) : Presenter { private val play = mutableStateOf>(AsyncData.Uninitialized) + private val playbackSpeed = mutableStateOf(1.0f) + + private val availablePlaybackSpeeds = listOf(0.5f, 1.0f, 1.5f, 2.0f) @Composable override fun present(): VoiceMessageState { @@ -111,6 +114,13 @@ class VoiceMessagePresenter( is VoiceMessageEvents.Seek -> { player.seekTo((event.percentage * duration).toLong()) } + is VoiceMessageEvents.ChangePlaybackSpeed -> { + val currentIndex = availablePlaybackSpeeds.indexOf(playbackSpeed.value) + val nextIndex = (currentIndex + 1) % availablePlaybackSpeeds.size + val newSpeed = availablePlaybackSpeeds[nextIndex] + playbackSpeed.value = newSpeed + player.setPlaybackSpeed(newSpeed) + } } } @@ -119,6 +129,7 @@ class VoiceMessagePresenter( progress = progress, time = time, showCursor = showCursor, + playbackSpeed = playbackSpeed.value, eventSink = { eventSink(it) }, ) } diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index 9d16cd6bcc..5f0b34b45e 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -222,6 +222,40 @@ class VoiceMessagePresenterTest { } } } + + @Test + fun `changing playback speed cycles through available speeds`() = runTest { + val presenter = createVoiceMessagePresenter( + duration = 10_000.milliseconds, + ) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(1.0f) + } + + initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(1.5f) + } + + initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(2.0f) + } + + initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(0.5f) + } + + initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(1.0f) + } + } + } } fun TestScope.createVoiceMessagePresenter( From d7bbf8f5669a65e30146854a60730261b69be83b Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 27 Nov 2025 18:08:00 +0100 Subject: [PATCH 002/347] change(room member): make sure we never display name/avatar when a member is banned --- .../element/android/libraries/matrix/api/room/RoomMember.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomMember.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomMember.kt index 5a1f253eaf..0b3d7071c8 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomMember.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomMember.kt @@ -99,6 +99,6 @@ fun RoomMember.getBestName(): String { fun RoomMember.toMatrixUser() = MatrixUser( userId = userId, - displayName = displayName, - avatarUrl = avatarUrl, + displayName = displayName.takeUnless { membership == RoomMembershipState.BAN }, + avatarUrl = avatarUrl.takeUnless { membership == RoomMembershipState.BAN }, ) From e6bbc7059e3d192c22deed4fd1d73d6bc1f2c5ce Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 27 Nov 2025 17:28:21 +0000 Subject: [PATCH 003/347] Update screenshots --- ...s.roomdetails.impl.members_RoomMemberListView_Day_3_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_3_en.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png index 6ac0644c32..dfbbd46e39 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bae192229d384047dcf5fb6744267a9e448d7f0a4f933a4984a0d1c3b9d07da2 -size 30789 +oid sha256:d5ff0c767c13a80f8305096982d1fb92800d3a25fb50115c631fd3916fd7f52c +size 30180 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png index c313f14d52..4f5dba242e 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc20039c1c5d456f318f22e524360d411d4a4980b6a2a9312c0707c0fe865340 -size 29867 +oid sha256:5fa0396ed5afbb31ef60cbc74c3369e3eb306f0b4eb168424165c6246ea7cdca +size 29276 From cfa494bd2cdad819bbb50e4eb2429e98884f8e98 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 28 Nov 2025 14:20:52 +0100 Subject: [PATCH 004/347] space: mark space ff as finished --- .../io/element/android/libraries/featureflag/api/FeatureFlags.kt | 1 + 1 file changed, 1 insertion(+) 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 d809fe34dc..997d4c2684 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 @@ -74,6 +74,7 @@ enum class FeatureFlags( key = "feature.space", title = "Spaces", defaultValue = { true }, + isFinished = true, isFinished = false, ), PrintLogsToLogcat( From 9a081c496fd301614ac235a2a65a11ed52985bcb Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 28 Nov 2025 14:50:55 +0100 Subject: [PATCH 005/347] space: add space settings ff and branch it --- .../android/features/space/impl/root/SpacePresenter.kt | 8 ++++++++ .../android/features/space/impl/root/SpaceState.kt | 1 + .../features/space/impl/root/SpaceStateProvider.kt | 2 ++ .../element/android/features/space/impl/root/SpaceView.kt | 5 +++-- .../android/libraries/featureflag/api/FeatureFlags.kt | 6 ++++++ 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt index ce76aa457f..3d36de0cea 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt @@ -26,6 +26,8 @@ import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.mapState import io.element.android.libraries.di.annotations.SessionCoroutineScope +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.RoomId import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias @@ -53,6 +55,7 @@ class SpacePresenter( private val joinRoom: JoinRoom, private val acceptDeclineInvitePresenter: Presenter, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, + private val featureFlagService: FeatureFlagService, ) : Presenter { private var children by mutableStateOf>(persistentListOf()) @@ -79,6 +82,10 @@ class SpacePresenter( } }.collectAsState() + val isSpaceSettingsEnabled by remember { + featureFlagService.isFeatureEnabledFlow(FeatureFlags.SpaceSettings) + }.collectAsState(false) + val currentSpace by spaceRoomList.currentSpaceFlow.collectAsState() val (joinActions, setJoinActions) = remember { mutableStateOf(emptyMap>()) } @@ -129,6 +136,7 @@ class SpacePresenter( joinActions = joinActions.toImmutableMap(), acceptDeclineInviteState = acceptDeclineInviteState, topicViewerState = topicViewerState, + canAccessSpaceSettings = isSpaceSettingsEnabled, eventSink = ::handleEvent, ) } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceState.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceState.kt index 031721ee26..cceda62806 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceState.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceState.kt @@ -26,6 +26,7 @@ data class SpaceState( val joinActions: ImmutableMap>, val acceptDeclineInviteState: AcceptDeclineInviteState, val topicViewerState: TopicViewerState, + val canAccessSpaceSettings: Boolean, val eventSink: (SpaceEvents) -> Unit ) { fun isJoining(spaceId: RoomId): Boolean = joinActions[spaceId] == AsyncAction.Loading diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt index bfb63c63db..52894ad599 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceStateProvider.kt @@ -53,6 +53,7 @@ fun aSpaceState( hasMoreToLoad: Boolean = true, acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(), topicViewerState: TopicViewerState = TopicViewerState.Hidden, + canAccessSpaceSettings: Boolean = true, eventSink: (SpaceEvents) -> Unit = { }, ) = SpaceState( currentSpace = parentSpace, @@ -63,6 +64,7 @@ fun aSpaceState( joinActions = joinActions.toImmutableMap(), acceptDeclineInviteState = acceptDeclineInviteState, topicViewerState = topicViewerState, + canAccessSpaceSettings = canAccessSpaceSettings, eventSink = eventSink, ) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt index cd1b3de74d..862b9882d2 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt @@ -88,6 +88,7 @@ fun SpaceView( topBar = { SpaceViewTopBar( currentSpace = state.currentSpace, + canAccessSpaceSettings = state.canAccessSpaceSettings, onBackClick = onBackClick, onLeaveSpaceClick = onLeaveSpaceClick, onShareSpace = onShareSpace, @@ -255,6 +256,7 @@ private fun LoadingMoreIndicator( @Composable private fun SpaceViewTopBar( currentSpace: SpaceRoom?, + canAccessSpaceSettings: Boolean, onBackClick: () -> Unit, onLeaveSpaceClick: () -> Unit, onDetailsClick: () -> Unit, @@ -275,8 +277,7 @@ private fun SpaceViewTopBar( avatarData = currentSpace.getAvatarData(AvatarSize.TimelineRoom), modifier = Modifier .clip(roundedCornerShape) - // TODO enable when screen ready for space - .clickable(enabled = false, onClick = onDetailsClick) + .clickable(enabled = canAccessSpaceSettings, onClick = onDetailsClick) ) } }, 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 997d4c2684..2b8eb0f397 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 @@ -75,6 +75,12 @@ enum class FeatureFlags( title = "Spaces", defaultValue = { true }, isFinished = true, + ), + SpaceSettings( + key = "feature.spaceSettings", + title = "Space settings", + description = "Allow managing space settings such details, permissions and privacy.", + defaultValue = { true }, isFinished = false, ), PrintLogsToLogcat( From b78761e89a451d1bc286309bc88ee5fd17b97df7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 28 Nov 2025 15:54:05 +0100 Subject: [PATCH 006/347] space: start branching space settings flow --- features/space/impl/build.gradle.kts | 2 + .../features/space/impl/SpaceFlowNode.kt | 26 ++-- .../impl/settings/SpaceSettingsFlowNode.kt | 116 ++++++++++++++++++ .../space/impl/settings/SpaceSettingsNode.kt | 4 +- 4 files changed, 127 insertions(+), 21 deletions(-) create mode 100644 features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt diff --git a/features/space/impl/build.gradle.kts b/features/space/impl/build.gradle.kts index d212bac36b..4ee6822bc5 100644 --- a/features/space/impl/build.gradle.kts +++ b/features/space/impl/build.gradle.kts @@ -40,6 +40,8 @@ dependencies { implementation(projects.libraries.featureflag.api) implementation(projects.features.invite.api) implementation(projects.libraries.previewutils) + implementation(projects.features.securityandprivacy.api) + implementation(projects.features.rolesandpermissions.api) api(projects.features.space.api) testCommonDependencies(libs, true) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt index 036eab1c22..5fe646aaeb 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt @@ -28,7 +28,7 @@ import io.element.android.features.space.api.SpaceEntryPoint import io.element.android.features.space.impl.di.SpaceFlowGraph import io.element.android.features.space.impl.leave.LeaveSpaceNode import io.element.android.features.space.impl.root.SpaceNode -import io.element.android.features.space.impl.settings.SpaceSettingsNode +import io.element.android.features.space.impl.settings.SpaceSettingsFlowNode import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.callback @@ -115,32 +115,20 @@ class SpaceFlowNode( createNode(buildContext, listOf(callback)) } NavTarget.Settings -> { - val callback = object : SpaceSettingsNode.Callback { - override fun closeSettings() { - backstack.pop() - } - - override fun navigateToSpaceInfo() { - // TODO - } - + val callback = object : SpaceSettingsFlowNode.Callback { override fun navigateToSpaceMembers() { callback.navigateToRoomMemberList() } - override fun navigateToRolesAndPermissions() { - // TODO - } - - override fun navigateToSecurityAndPrivacy() { - // TODO - } - override fun startLeaveSpaceFlow() { backstack.push(NavTarget.Leave) } + + override fun closeSettings() { + backstack.pop() + } } - createNode(buildContext, listOf(callback)) + createNode(buildContext, listOf(callback)) } } } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt new file mode 100644 index 0000000000..b52da111b3 --- /dev/null +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt @@ -0,0 +1,116 @@ +/* + * 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.space.impl.settings + +import android.os.Parcelable +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import com.bumble.appyx.navmodel.backstack.BackStack +import com.bumble.appyx.navmodel.backstack.operation.push +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.features.rolesandpermissions.api.RolesAndPermissionsEntryPoint +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint +import io.element.android.features.space.impl.di.SpaceFlowScope +import io.element.android.libraries.architecture.BackstackView +import io.element.android.libraries.architecture.BaseFlowNode +import io.element.android.libraries.architecture.callback +import io.element.android.libraries.architecture.createNode +import kotlinx.parcelize.Parcelize + +@ContributesNode(SpaceFlowScope::class) +@AssistedInject +class SpaceSettingsFlowNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val securityAndPrivacyEntryPoint: SecurityAndPrivacyEntryPoint, + private val rolesAndPermissionsEntryPoint: RolesAndPermissionsEntryPoint, +) : BaseFlowNode( + backstack = BackStack( + initialElement = NavTarget.Root, + savedStateMap = buildContext.savedStateMap, + ), + buildContext = buildContext, + plugins = plugins, +) { + interface Callback : Plugin { + fun navigateToSpaceMembers() + fun startLeaveSpaceFlow() + fun closeSettings() + } + + sealed interface NavTarget : Parcelable { + @Parcelize + data object Root : NavTarget + + @Parcelize + data object SecurityAndPrivacy : NavTarget + + @Parcelize + data object RolesAndPermissions : NavTarget + } + + private val callback: Callback = callback() + + override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { + return when (navTarget) { + is NavTarget.Root -> { + val callback = object : SpaceSettingsNode.Callback { + override fun closeSettings() { + callback.closeSettings() + } + + override fun navigateToEditDetails() { + // TODO + } + + override fun navigateToSpaceMembers() { + callback.navigateToSpaceMembers() + } + + override fun navigateToRolesAndPermissions() { + backstack.push(NavTarget.RolesAndPermissions) + } + + override fun navigateToSecurityAndPrivacy() { + backstack.push(NavTarget.SecurityAndPrivacy) + } + + override fun startLeaveSpaceFlow() { + callback.startLeaveSpaceFlow() + } + } + createNode( + buildContext = buildContext, + plugins = listOf(callback), + ) + } + is NavTarget.SecurityAndPrivacy -> { + securityAndPrivacyEntryPoint.createNode( + parentNode = this, + buildContext = buildContext, + ) + } + is NavTarget.RolesAndPermissions -> { + rolesAndPermissionsEntryPoint.createNode( + parentNode = this, + buildContext = buildContext, + ) + } + } + } + + @Composable + override fun View(modifier: Modifier) { + BackstackView(modifier) + } +} diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsNode.kt index ae2f4857c0..b1e64fbba1 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsNode.kt @@ -32,7 +32,7 @@ class SpaceSettingsNode( interface Callback : Plugin { fun closeSettings() - fun navigateToSpaceInfo() + fun navigateToEditDetails() fun navigateToSpaceMembers() fun navigateToRolesAndPermissions() fun navigateToSecurityAndPrivacy() @@ -48,7 +48,7 @@ class SpaceSettingsNode( SpaceSettingsView( state = state, modifier = modifier, - onSpaceInfoClick = callback::navigateToSpaceInfo, + onSpaceInfoClick = callback::navigateToEditDetails, onBackClick = callback::closeSettings, onMembersClick = callback::navigateToSpaceMembers, onRolesAndPermissionsClick = callback::navigateToRolesAndPermissions, From eaf66462911ddd8e9f3ca82a1b83bd4299c24080 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 13:54:36 +0000 Subject: [PATCH 007/347] fix(deps): update dependency org.maplibre.gl:android-sdk to v12.2.1 --- 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 1a8ebd36a2..effaf6dbab 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -206,7 +206,7 @@ vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0" telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" } telephoto_flick = { module = "me.saket.telephoto:flick-android", version.ref = "telephoto" } statemachine = "com.freeletics.flowredux:compose:1.2.2" -maplibre = "org.maplibre.gl:android-sdk:12.2.0" +maplibre = "org.maplibre.gl:android-sdk:12.2.1" maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2" maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2" opusencoder = "io.element.android:opusencoder:1.2.0" From 8ece139b635de052e4828c85174ad2b8c1584b8b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 2 Dec 2025 15:34:09 +0100 Subject: [PATCH 008/347] Remove dead code. --- .../components/ExpandableBottomSheetLayout.kt | 24 ------------------- .../ExpandableBottomSheetLayoutState.kt | 9 ------- 2 files changed, 33 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 433c38102d..85307823f6 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 @@ -77,28 +77,9 @@ fun ExpandableBottomSheetLayout( var calculatedMaxBottomContentHeightPx by remember(maxBottomContentHeightPx) { mutableIntStateOf(maxBottomContentHeightPx) } val animatable = remember { Animatable(0f) } - fun calculatePercentage(currentPos: Int, minPos: Int, maxPos: Int): Float { - val currentProgress = currentPos - minPos - if (currentProgress < 0) { - Timber.e("Invalid current progress: $currentProgress, minPos: $minPos, maxPos: $maxPos") - return 0f - } - val total = (maxPos - minPos).toFloat() - if (total <= 0) { - Timber.e("Invalid total space: $total, minPos: $minPos, maxPos: $maxPos") - return 0f - } - return currentProgress / total - } - LaunchedEffect(animatable.value) { if (animatable.isRunning && animatable.value != animatable.targetValue) { currentBottomContentHeightPx = animatable.value.roundToInt() - state.internalDraggingPercentage = calculatePercentage( - currentPos = currentBottomContentHeightPx, - minPos = minBottomContentHeightPx, - maxPos = calculatedMaxBottomContentHeightPx, - ) } } @@ -122,11 +103,6 @@ fun ExpandableBottomSheetLayout( minBottomContentHeightPx -> ExpandableBottomSheetLayoutState.Position.COLLAPSED else -> ExpandableBottomSheetLayoutState.Position.DRAGGING } - state.internalDraggingPercentage = calculatePercentage( - currentPos = newHeight, - minPos = minBottomContentHeightPx, - maxPos = calculatedMaxBottomContentHeightPx, - ) currentBottomContentHeightPx = newHeight }, onDragEnd = { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayoutState.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayoutState.kt index 1b17ec544b..ad6828aed3 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayoutState.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayoutState.kt @@ -32,21 +32,12 @@ fun rememberExpandableBottomSheetLayoutState(): ExpandableBottomSheetLayoutState @Stable class ExpandableBottomSheetLayoutState { internal var internalPosition: Position by mutableStateOf(Position.COLLAPSED) - internal var internalDraggingPercentage: Float by mutableFloatStateOf( - if (internalPosition == Position.EXPANDED) 1f else 0f - ) /** * The current position of the bottom sheet layout. */ val position get() = internalPosition - /** - * The percentage of the bottom sheet layout that is currently being dragged. - * This value ranges from `0f` for [Position.COLLAPSED] to `1f` for [Position.EXPANDED]. - */ - val draggingPercentage = internalDraggingPercentage - /** * The position of the bottom sheet layout. */ From b366446cabca26b3f64a63a099ae937cf3fa90d0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 2 Dec 2025 16:36:30 +0100 Subject: [PATCH 009/347] Let the composer takes at max half of the available height. The value will be different if the soft keyboard is displayed or not. Closes #3851 --- .../features/messages/impl/MessagesView.kt | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) 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 1f62adeb23..14a021a067 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 @@ -29,10 +29,15 @@ import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.material3.MaterialTheme 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.draw.shadow import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role @@ -82,6 +87,7 @@ import io.element.android.libraries.designsystem.components.rememberExpandableBo import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.text.toAnnotatedString +import io.element.android.libraries.designsystem.text.toDp import io.element.android.libraries.designsystem.theme.components.BottomSheetDragHandle import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.Text @@ -129,6 +135,8 @@ fun MessagesView( val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage) + var maxComposerHeightPx by remember { mutableIntStateOf(120) } + // This is needed because the composer is inside an AndroidView that can't be affected by the FocusManager in Compose val localView = LocalView.current @@ -179,7 +187,13 @@ fun MessagesView( modifier = modifier .fillMaxSize() .imePadding() - .systemBarsPadding(), + .systemBarsPadding() + .onSizeChanged { size -> + // Let the composer takes at max half of the available height. + // The value will be different if the soft keyboard is displayed + // or not. + maxComposerHeightPx = (size.height * 0.5f).toInt() + }, content = { Scaffold( contentWindowInsets = WindowInsets.statusBars, @@ -313,7 +327,7 @@ fun MessagesView( } else { RectangleShape }, - maxBottomSheetContentHeight = 360.dp, + maxBottomSheetContentHeight = maxComposerHeightPx.toDp(), ) ActionListView( From a91c78b56f32319e024a2a9c2a71d415bfc30c03 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 1 Dec 2025 16:08:11 +0100 Subject: [PATCH 010/347] fix: rely only on RoomMember Role values instead of using the powerLevel. --- .../leaveroom/impl/LeaveRoomPresenter.kt | 5 +- .../impl/roles/ChangeRolesPresenter.kt | 9 +-- .../impl/root/RolesAndPermissionsPresenter.kt | 38 +++-------- .../impl/root/RolesAndPermissionsState.kt | 4 +- .../impl/root/RolesAndPermissionsView.kt | 8 ++- .../impl/roles/ChangeRolesPresenterTest.kt | 27 ++++---- .../root/RolesAndPermissionPresenterTest.kt | 63 ++++++++++--------- .../libraries/matrix/api/room/RoomInfo.kt | 11 ---- ...bersWithRole.kt => RoomMembersWithRole.kt} | 28 +++++---- .../api/room/powerlevels/RoomPowerLevels.kt | 13 ---- 10 files changed, 84 insertions(+), 122 deletions(-) rename libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/{MatrixRoomMembersWithRole.kt => RoomMembersWithRole.kt} (62%) diff --git a/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenter.kt b/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenter.kt index c371d425c1..6455b45659 100644 --- a/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenter.kt +++ b/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenter.kt @@ -96,10 +96,7 @@ class LeaveRoomPresenter( } else { val hasPrivilegedCreatorRole = roomInfoFlow.value.privilegedCreatorRole if (!hasPrivilegedCreatorRole) return false - - val creators = usersWithRole(RoomMember.Role.Owner(isCreator = true)).first() - val superAdmins = usersWithRole(RoomMember.Role.Owner(isCreator = false)).first() - val owners = creators + superAdmins + val owners = usersWithRole { role -> role is RoomMember.Role.Owner }.first() return owners.size == 1 && owners.first().userId == sessionId } } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt index 88da850fcd..e460870b5a 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt @@ -79,18 +79,13 @@ class ChangeRolesPresenter( val usersWithRole = produceState>(initialValue = persistentListOf()) { // If the role is admin, we need to include the owners as well since they implicitly have admin role val owners = if (role == RoomMember.Role.Admin) { - combine( - room.usersWithRole(RoomMember.Role.Owner(isCreator = true)), - room.usersWithRole(RoomMember.Role.Owner(isCreator = false)), - ) { creators, superAdmins -> - creators + superAdmins - } + room.usersWithRole { role -> role is RoomMember.Role.Owner } } else { emptyFlow() } combine( owners, - room.usersWithRole(role), + room.usersWithRole { it == role }, ) { owners, users -> owners + users }.map { members -> members.map { it.toMatrixUser() } } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt index 2ade971a66..bde20affd8 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt @@ -22,12 +22,10 @@ import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runUpdatingState import io.element.android.libraries.core.coroutine.CoroutineDispatchers -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.room.activeRoomMembers import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange +import io.element.android.libraries.matrix.api.room.powerlevels.userCountWithRole import io.element.android.libraries.matrix.ui.model.roleOf import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.CoroutineScope @@ -43,32 +41,14 @@ class RolesAndPermissionsPresenter( override fun present(): RolesAndPermissionsState { val coroutineScope = rememberCoroutineScope() val roomInfo by room.roomInfoFlow.collectAsState() - val roomMembers by room.membersStateFlow.collectAsState() - // Get the list of active room members (joined or invited), in order to filter members present in the power - // level state Event. - val activeRoomMemberIds by remember { - derivedStateOf { - roomMembers.activeRoomMembers().map { it.userId } - } - } val moderatorCount by remember { - derivedStateOf { - roomInfo.userCountWithRole(activeRoomMemberIds, RoomMember.Role.Moderator) - } - } + room.userCountWithRole { role -> role is RoomMember.Role.Moderator } + }.collectAsState(null) + val adminCount by remember { - derivedStateOf { - val admins = roomInfo.userCountWithRole(activeRoomMemberIds, RoomMember.Role.Admin) - val ownersCount = if (roomInfo.privilegedCreatorRole) { - val superAdmins = roomInfo.userCountWithRole(activeRoomMemberIds, RoomMember.Role.Owner(isCreator = false)) - val creators = roomInfo.userCountWithRole(activeRoomMemberIds, RoomMember.Role.Owner(isCreator = true)) - superAdmins + creators - } else { - 0 - } - admins + ownersCount - } - } + room.userCountWithRole { role -> role is RoomMember.Role.Admin || role is RoomMember.Role.Owner } + }.collectAsState(null) + val canDemoteSelf = remember { derivedStateOf { roomInfo.roleOf(room.sessionId) !is RoomMember.Role.Owner } } val changeOwnRoleAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } val resetPermissionsAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } @@ -122,8 +102,4 @@ class RolesAndPermissionsPresenter( room.resetPowerLevels() } } - - private fun RoomInfo.userCountWithRole(userIds: List, role: RoomMember.Role): Int { - return usersWithRole(role).filter { it in userIds }.size - } } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt index 3fc94f99e9..90785d1b38 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt @@ -12,8 +12,8 @@ import io.element.android.libraries.architecture.AsyncAction data class RolesAndPermissionsState( val roomSupportsOwnerRole: Boolean, - val adminCount: Int, - val moderatorCount: Int, + val adminCount: Int?, + val moderatorCount: Int?, val canDemoteSelf: Boolean, val changeOwnRoleAction: AsyncAction, val resetPermissionsAction: AsyncAction, diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt index 189ad83a5c..c0cb15983c 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt @@ -63,13 +63,17 @@ fun RolesAndPermissionsView( ListItem( headlineContent = { Text(adminsTitle) }, leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Admin())), - trailingContent = ListItemContent.Text("${state.adminCount}"), + trailingContent = state.adminCount?.let { adminCount -> + ListItemContent.Text("$adminCount") + }, onClick = { rolesAndPermissionsNavigator.openAdminList() }, ) ListItem( headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_moderators)) }, leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.ChatProblem())), - trailingContent = ListItemContent.Text("${state.moderatorCount}"), + trailingContent = state.moderatorCount?.let { moderationCount -> + ListItemContent.Text("$moderationCount") + }, onClick = { rolesAndPermissionsNavigator.openModeratorList() }, ) if (state.canDemoteSelf) { diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt index 1da7ddcce4..e1998f94a3 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt @@ -18,7 +18,9 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels +import io.element.android.libraries.matrix.api.room.toMatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.A_USER_ID_3 @@ -26,11 +28,13 @@ import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.anAlice import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues import io.element.android.libraries.previewutils.room.aRoomMemberList import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers +import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableMap @@ -63,7 +67,7 @@ class ChangeRolesPresenterTest { } val presenter = createChangeRolesPresenter(room = room) presenter.test { - skipItems(1) + skipItems(2) assertThat(awaitItem().searchResults).isInstanceOf(SearchBarResultState.Results::class.java) } } @@ -161,13 +165,13 @@ class ChangeRolesPresenterTest { } @Test - fun `present - when modifying admins, creators are displayed too`() = runTest { + fun `present - when modifying admins, creators are displayed too - privilegedCreatorRole is true`() = runTest { val room = FakeJoinedRoom().apply { val creatorUserId = UserId("@creator:matrix.org") val memberList = aRoomMemberList() .plus(aRoomMember(displayName = "CREATOR", role = RoomMember.Role.Owner(isCreator = true), userId = creatorUserId)) .toImmutableList() - givenRoomInfo(aRoomInfo(roomCreators = listOf(creatorUserId))) + givenRoomInfo(aRoomInfo(roomCreators = listOf(creatorUserId), privilegedCreatorRole = true)) givenRoomMembersState(RoomMembersState.Ready(memberList)) } val presenter = createChangeRolesPresenter(room = room) @@ -190,6 +194,7 @@ class ChangeRolesPresenterTest { } val presenter = createChangeRolesPresenter(room = room) presenter.test { + skipItems(1) val initialState = awaitItem() initialState.eventSink(ChangeRolesEvent.ToggleSearchActive) @@ -207,6 +212,7 @@ class ChangeRolesPresenterTest { } val presenter = createChangeRolesPresenter(room = room) presenter.test { + skipItems(1) val initialState = awaitItem() val initialResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results assertThat(initialResults?.members).hasSize(8) @@ -231,7 +237,7 @@ class ChangeRolesPresenterTest { } val presenter = createChangeRolesPresenter(room = room) presenter.test { - skipItems(1) + skipItems(2) val initialResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results assertThat(initialResults?.members).hasSize(8) assertThat(initialResults?.moderators).hasSize(1) @@ -478,17 +484,14 @@ class ChangeRolesPresenterTest { @Test fun `present - Save will just save the changes if the current user is a room creator and the selected users are not`() = runTest { val analyticsService = FakeAnalyticsService() + val alice = anAlice() + val me = aRoomMember(displayName = "CREATOR", role = RoomMember.Role.Owner(isCreator = true), userId = A_SESSION_ID) val room = FakeJoinedRoom( updateUserRoleResult = { Result.success(Unit) }, baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }), ).apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo( - aRoomInfo( - roomCreators = listOf(sessionId), - roomPowerLevels = roomPowerLevelsWithRole(role = RoomMember.Role.Admin, userId = A_USER_ID_2) - ) - ) + val roomMemberList = persistentListOf(alice, me) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) } val presenter = createChangeRolesPresenter( role = RoomMember.Role.Admin, @@ -499,7 +502,7 @@ class ChangeRolesPresenterTest { skipItems(2) val initialState = awaitItem() assertThat(initialState.selectedUsers).hasSize(2) - initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) + initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(alice.toMatrixUser())) awaitItem().also { assertThat(it.selectedUsers).hasSize(1) it.eventSink(ChangeRolesEvent.Save) diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionPresenterTest.kt index 3eaacb9c3b..54bd6b7987 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionPresenterTest.kt @@ -8,16 +8,17 @@ package io.element.android.features.rolesandpermissions.impl.root -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow -import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.RoomModeration import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.matrix.api.room.RoomMember +import io.element.android.libraries.matrix.api.room.RoomMembersState +import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom +import io.element.android.libraries.matrix.test.room.aRoomMemberList import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher @@ -30,12 +31,10 @@ class RolesAndPermissionPresenterTest { @Test fun `present - initial state`() = runTest { val presenter = createRolesAndPermissionsPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { with(awaitItem()) { - assertThat(adminCount).isEqualTo(0) - assertThat(moderatorCount).isEqualTo(0) + assertThat(adminCount).isNull() + assertThat(moderatorCount).isNull() assertThat(changeOwnRoleAction).isEqualTo(AsyncAction.Uninitialized) } } @@ -44,12 +43,9 @@ class RolesAndPermissionPresenterTest { @Test fun `present - ChangeOwnRole presents a confirmation dialog`() = runTest { val presenter = createRolesAndPermissionsPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(RolesAndPermissionsEvents.ChangeOwnRole) - assertThat(awaitItem().changeOwnRoleAction).isEqualTo(AsyncAction.ConfirmingNoParams) } } @@ -60,12 +56,11 @@ class RolesAndPermissionPresenterTest { val presenter = createRolesAndPermissionsPresenter( dispatchers = testCoroutineDispatchers(), room = FakeJoinedRoom( + baseRoom = FakeBaseRoom(updateMembersResult = {}), updateUserRoleResult = { Result.success(Unit) } ), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.Moderator)) @@ -81,12 +76,11 @@ class RolesAndPermissionPresenterTest { @Test fun `present - DemoteSelfTo can handle failures and clean them`() = runTest(StandardTestDispatcher()) { val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom(updateMembersResult = {}), updateUserRoleResult = { Result.failure(Exception("Failed to update role")) } ) val presenter = createRolesAndPermissionsPresenter(room = room, dispatchers = testCoroutineDispatchers()) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.Moderator)) @@ -104,9 +98,7 @@ class RolesAndPermissionPresenterTest { @Test fun `present - CancelPendingAction dismisses confirmation dialog too`() = runTest { val presenter = createRolesAndPermissionsPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(RolesAndPermissionsEvents.ChangeOwnRole) awaitItem().eventSink(RolesAndPermissionsEvents.CancelPendingAction) @@ -121,12 +113,11 @@ class RolesAndPermissionPresenterTest { val presenter = createRolesAndPermissionsPresenter( analyticsService = analyticsService, room = FakeJoinedRoom( + baseRoom = FakeBaseRoom(updateMembersResult = {}), resetPowerLevelsResult = { Result.success(Unit) } ) ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(RolesAndPermissionsEvents.ResetPermissions) // Confirmation @@ -141,9 +132,7 @@ class RolesAndPermissionPresenterTest { @Test fun `present - ResetPermissions confirmation can be cancelled`() = runTest { val presenter = createRolesAndPermissionsPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(RolesAndPermissionsEvents.ResetPermissions) awaitItem().eventSink(RolesAndPermissionsEvents.CancelPendingAction) @@ -152,8 +141,26 @@ class RolesAndPermissionPresenterTest { } } + @Test + fun `present - admins and moderator counts are updated when members changes`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom(updateMembersResult = {}), + ) + val presenter = createRolesAndPermissionsPresenter(room = room) + presenter.test { + val initialState = awaitItem() + assertThat(initialState.adminCount).isNull() + assertThat(initialState.moderatorCount).isNull() + room.givenRoomMembersState(state = RoomMembersState.Ready(aRoomMemberList())) + skipItems(1) + val finalState = awaitItem() + assertThat(finalState.adminCount).isEqualTo(1) + assertThat(finalState.moderatorCount).isEqualTo(1) + } + } + private fun TestScope.createRolesAndPermissionsPresenter( - room: FakeJoinedRoom = FakeJoinedRoom(), + room: FakeJoinedRoom = FakeJoinedRoom(baseRoom = FakeBaseRoom(updateMembersResult = {})), dispatchers: CoroutineDispatchers = testCoroutineDispatchers(), analyticsService: FakeAnalyticsService = FakeAnalyticsService() ): RolesAndPermissionsPresenter { diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomInfo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomInfo.kt index 943745d60e..9a789187ca 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomInfo.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomInfo.kt @@ -79,15 +79,4 @@ data class RoomInfo( ) { val aliases: List get() = listOfNotNull(canonicalAlias) + alternativeAliases - - /** - * Returns the list of users with the given [role] in this room. - */ - fun usersWithRole(role: RoomMember.Role): List { - return if (role is RoomMember.Role.Owner && role.isCreator) { - this.creators - } else { - this.roomPowerLevels?.usersWithRole(role).orEmpty().toList() - } - } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomMembersWithRole.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomMembersWithRole.kt similarity index 62% rename from libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomMembersWithRole.kt rename to libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomMembersWithRole.kt index 39e5dafae9..ff1ec62f0a 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomMembersWithRole.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomMembersWithRole.kt @@ -15,17 +15,16 @@ import io.element.android.libraries.matrix.api.room.activeRoomMembers import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart /** - * Return a flow of the list of active room members who have the given role. + * Return a flow of the list of active room members who match the predicate. */ -fun BaseRoom.usersWithRole(role: RoomMember.Role): Flow> { - // Ensure the room members flow is ready +fun BaseRoom.usersWithRole(predicate: (RoomMember.Role) -> Boolean): Flow> { + // Wait until members are ready to avoid returning empty lists initially val readyMembersFlow = membersStateFlow .onStart { if (membersStateFlow.value is RoomMembersState.Unknown) { @@ -34,12 +33,17 @@ fun BaseRoom.usersWithRole(role: RoomMember.Role): Flow roomInfo.usersWithRole(role) } - .combine(readyMembersFlow) { powerLevels, membersState -> - membersState.activeRoomMembers() - .filter { powerLevels.contains(it.userId) } - .toImmutableList() - } - .distinctUntilChanged() + return readyMembersFlow.map { membersState -> + membersState + .activeRoomMembers() + .filter({ predicate(it.role) }) + .toImmutableList() + }.distinctUntilChanged() +} + +/** + * Return the number of active room members who match the predicate. + */ +fun BaseRoom.userCountWithRole(predicate: (RoomMember.Role) -> Boolean): Flow { + return usersWithRole(predicate).map { it.size } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevels.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevels.kt index 19db749e67..31019878d9 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevels.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevels.kt @@ -35,19 +35,6 @@ data class RoomPowerLevels( return users[userId] ?: 0L } - /** - * Returns the set of [UserId]s that have the given role in the room. - * - * **WARNING**: This method must not be used with a creator role. It'll result in a runtime error. - */ - fun usersWithRole(role: RoomMember.Role): Set { - return if (role is RoomMember.Role.Owner && role.isCreator) { - error("RoomPowerLevels.usersWithRole should not be used with a creator role, use roomInfo.creators instead") - } else { - users.filterValues { RoomMember.Role.forPowerLevel(it) == role }.keys - } - } - /** * Returns the role of the user in the room based on their power level. * If the user is not found, returns null. From ae3056317d27302d547bcac6657c577ef68f83f1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 3 Dec 2025 11:14:20 +0100 Subject: [PATCH 011/347] space: SpaceSettings feature flag should be off by default --- .../element/android/libraries/featureflag/api/FeatureFlags.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2b8eb0f397..9bacb3c0d6 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 @@ -80,7 +80,7 @@ enum class FeatureFlags( key = "feature.spaceSettings", title = "Space settings", description = "Allow managing space settings such details, permissions and privacy.", - defaultValue = { true }, + defaultValue = { false }, isFinished = false, ), PrintLogsToLogcat( From 135dba79bde0375d2f3060aafdad5e8299baf1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 3 Dec 2025 11:27:28 +0100 Subject: [PATCH 012/347] Changelog for version 25.12.0 --- CHANGES.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 01a83c0ccf..47ea7ec332 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,58 @@ +Changes in Element X v25.12.0 +============================= + + + +## What's Changed +### ✨ Features +* Room list: enable latest event sorter. by @bmarty in https://github.com/element-hq/element-x-android/pull/5825 +* Add room list indicators about last message by @bmarty in https://github.com/element-hq/element-x-android/pull/5824 +### 🙌 Improvements +* Change : improve room and space member list by @ganfra in https://github.com/element-hq/element-x-android/pull/5806 +* Change : security and privacy rework by @ganfra in https://github.com/element-hq/element-x-android/pull/5816 +### 🐛 Bugfixes +* Ensure confirmation dialog is displayed when an admin add other admin to a room by @bmarty in https://github.com/element-hq/element-x-android/pull/5786 +* Edit user profile cancel confirmation by @bmarty in https://github.com/element-hq/element-x-android/pull/5788 +* Fix editing owner by @bmarty in https://github.com/element-hq/element-x-android/pull/5807 +* Uris should take precedence in plain text intents by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5785 +* Fix long voice recording by @bmarty in https://github.com/element-hq/element-x-android/pull/5821 +### 🗣 Translations +* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/5792 +* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/5830 +### 🧱 Build +* Use regex to check forbidden terms by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5784 +* Update Gradle Wrapper from 8.14.3 to 9.2.1 by @ElementBot in https://github.com/element-hq/element-x-android/pull/5751 +### Dependency upgrades +* fix(deps): update dependency androidx.sqlite:sqlite-ktx to v2.6.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5769 +* fix(deps): update datastore to v1.2.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5789 +* chore(deps): update peter-evans/create-pull-request action to v7.0.9 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5793 +* fix(deps): update dependency io.nlopez.compose.rules:detekt to v0.4.28 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5795 +* fix(deps): update metro to v0.7.7 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5771 +* chore(deps): update plugin sonarqube to v7.1.0.6387 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5783 +* fix(deps): update dependency io.github.sergio-sastre.composablepreviewscanner:android to v0.7.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5799 +* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.11.24 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5796 +* fix(deps): update dependency io.sentry:sentry-android to v8.27.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5803 +* fix(deps): update dependency io.element.android:emojibase-bindings to v1.5.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5801 +* fix(deps): update roborazzi to v1.52.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5804 +* fix(deps): update dependency org.maplibre.gl:android-sdk to v12.2.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5814 +* chore(deps): update actions/checkout action to v6 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5805 +* fix(deps): update dependency com.google.testparameterinjector:test-parameter-injector to v1.20 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5800 +* fix(deps): update android.gradle.plugin to v8.13.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5260 +* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.11.26 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5818 +* fix(deps): update dependencyanalysis to v3.5.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5819 +* fix(deps): update dependency com.posthog:posthog-android to v3.27.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5834 +* fix(deps): update dependency io.element.android:element-call-embedded to v0.16.3 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5839 +* Upgrade the Rust SDK to `v25.12.2` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5838 +### Others +* misc : use newLatestEvent api from sdk by @ganfra in https://github.com/element-hq/element-x-android/pull/5809 +* Inject RoomMemberListDataSource in the presenter constructor. by @bmarty in https://github.com/element-hq/element-x-android/pull/5822 +* Add more performance checks by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5767 +* Load `JoinedRoom` in home screen, pass it to the room flow by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5817 +* Revert "fix(deps): update dependency com.posthog:posthog-android to v3.27.0" by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5836 + + +**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v25.11.3...v25.12.0 + Changes in Element X v25.11.3 ============================= From ee4ee6f921c3f69f2b2ea4a4063437e682e73729 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 3 Dec 2025 11:28:24 +0100 Subject: [PATCH 013/347] quality: fix SpacePresenterTest --- .../space/impl/root/SpacePresenterTest.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpacePresenterTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpacePresenterTest.kt index 51e3634345..9b6df0d258 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpacePresenterTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpacePresenterTest.kt @@ -19,6 +19,8 @@ import io.element.android.features.invite.api.toInviteData import io.element.android.features.invite.test.InMemorySeenInvitesStore import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias @@ -62,11 +64,22 @@ class SpacePresenterTest { assertThat(state.joinActions).isEmpty() assertThat(state.acceptDeclineInviteState).isEqualTo(anAcceptDeclineInviteState()) assertThat(state.topicViewerState).isEqualTo(TopicViewerState.Hidden) + assertThat(state.canAccessSpaceSettings).isFalse() advanceUntilIdle() paginateResult.assertions().isCalledOnce() } } + @Test + fun `present - canAccessSpaceSettings when space settings ff is enabled`() = runTest { + val presenter = createSpacePresenter(spaceSettingsEnabled = true) + presenter.test { + skipItems(1) + val state = awaitItem() + assertThat(state.canAccessSpaceSettings).isTrue() + } + } + @Test fun `present - load more`() = runTest { val paginateResult = lambdaRecorder> { @@ -328,6 +341,7 @@ class SpacePresenterTest { lambda = { _, _, _ -> Result.success(Unit) }, ), acceptDeclineInvitePresenter: Presenter = Presenter { anAcceptDeclineInviteState() }, + spaceSettingsEnabled: Boolean = false, ): SpacePresenter { return SpacePresenter( client = client, @@ -336,6 +350,11 @@ class SpacePresenterTest { joinRoom = joinRoom, acceptDeclineInvitePresenter = acceptDeclineInvitePresenter, sessionCoroutineScope = backgroundScope, + featureFlagService = FakeFeatureFlagService( + initialState = mapOf( + FeatureFlags.SpaceSettings.key to spaceSettingsEnabled, + ) + ), ) } } From af6099106b52d124943d9fd1089aaf144aa29569 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 14 Nov 2025 10:40:37 +0100 Subject: [PATCH 014/347] change(edit room details): expose isSpace --- .../impl/edit/RoomDetailsEditPresenter.kt | 12 +++++------- .../roomdetails/impl/edit/RoomDetailsEditState.kt | 1 + .../impl/edit/RoomDetailsEditStateProvider.kt | 3 +++ .../roomdetails/impl/edit/RoomDetailsEditView.kt | 6 +++++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt index 542b15a776..930d63031a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt @@ -32,9 +32,6 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.powerlevels.canSendState import io.element.android.libraries.matrix.ui.media.AvatarAction -import io.element.android.libraries.matrix.ui.room.avatarUrl -import io.element.android.libraries.matrix.ui.room.rawName -import io.element.android.libraries.matrix.ui.room.topic import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider import io.element.android.libraries.mediaupload.api.MediaPreProcessor @@ -61,8 +58,8 @@ class RoomDetailsEditPresenter( override fun present(): RoomDetailsEditState { val cameraPermissionState = cameraPermissionPresenter.present() val roomSyncUpdateFlow = room.syncUpdateFlow.collectAsState() - - val roomAvatarUri = room.avatarUrl() + val roomInfo by room.roomInfoFlow.collectAsState() + val roomAvatarUri = roomInfo.avatarUrl var roomAvatarUriEdited by rememberSaveable { mutableStateOf(null) } LaunchedEffect(roomAvatarUri) { // Every time the roomAvatar change (from sync), we can set the new avatar. @@ -70,13 +67,13 @@ class RoomDetailsEditPresenter( roomAvatarUriEdited = roomAvatarUri } - val roomRawNameTrimmed = room.rawName().orEmpty().trim() + val roomRawNameTrimmed = roomInfo.rawName.orEmpty().trim() var roomRawNameEdited by rememberSaveable { mutableStateOf("") } LaunchedEffect(roomRawNameTrimmed) { // Every time the rawName change (from sync), we can set the new name. roomRawNameEdited = roomRawNameTrimmed } - val roomTopicTrimmed = room.topic().orEmpty().trim() + val roomTopicTrimmed = roomInfo.topic.orEmpty().trim() var roomTopicEdited by rememberSaveable { mutableStateOf("") } LaunchedEffect(roomTopicTrimmed) { // Every time the topic change (from sync), we can set the new topic. @@ -192,6 +189,7 @@ class RoomDetailsEditPresenter( saveButtonEnabled = saveButtonEnabled, saveAction = saveAction.value, cameraPermissionState = cameraPermissionState, + isSpace = roomInfo.isSpace, eventSink = ::handleEvent, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt index 3c5e87a2cd..f1d7a8861b 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt @@ -27,5 +27,6 @@ data class RoomDetailsEditState( val saveButtonEnabled: Boolean, val saveAction: AsyncAction, val cameraPermissionState: PermissionsState, + val isSpace: Boolean, val eventSink: (RoomDetailsEditEvents) -> Unit ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt index 33ed4a9e1e..7913620f04 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt @@ -23,6 +23,7 @@ open class RoomDetailsEditStateProvider : PreviewParameterProvider = AsyncAction.Uninitialized, cameraPermissionState: PermissionsState = aPermissionsState(showDialog = false), + isSpace: Boolean = false, eventSink: (RoomDetailsEditEvents) -> Unit = {}, ) = RoomDetailsEditState( roomId = roomId, @@ -56,5 +58,6 @@ fun aRoomDetailsEditState( saveButtonEnabled = saveButtonEnabled, saveAction = saveAction, cameraPermissionState = cameraPermissionState, + isSpace = isSpace, eventSink = eventSink, ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt index b8f7e00069..870f48b60e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt @@ -108,7 +108,11 @@ fun RoomDetailsEditView( displayName = state.roomRawName, avatarUrl = state.roomAvatarUrl, avatarSize = AvatarSize.EditRoomDetails, - avatarType = AvatarType.Room(), + avatarType = if(state.isSpace){ + AvatarType.Space() + }else { + AvatarType.Room() + }, onAvatarClick = ::onAvatarClick, modifier = Modifier.fillMaxWidth(), ) From e5317b069d28185911268732e0a1457e0c2f3033 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 14 Nov 2025 10:41:01 +0100 Subject: [PATCH 015/347] quality: remove useless code on MatrixRoomState --- .../matrix/ui/room/MatrixRoomState.kt | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt index e9a33282c0..03e0e5bea1 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt @@ -111,21 +111,3 @@ fun BaseRoom.isOwnUserAdmin(): Boolean { val role = roomInfo.roleOf(sessionId) return role == RoomMember.Role.Admin || role is RoomMember.Role.Owner } - -@Composable -fun BaseRoom.rawName(): String? { - val roomInfo by roomInfoFlow.collectAsState() - return roomInfo.rawName -} - -@Composable -fun BaseRoom.topic(): String? { - val roomInfo by roomInfoFlow.collectAsState() - return roomInfo.topic -} - -@Composable -fun BaseRoom.avatarUrl(): String? { - val roomInfo by roomInfoFlow.collectAsState() - return roomInfo.avatarUrl -} From 15cb6431c6543b067e871aab380a5876b606fc39 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 14 Nov 2025 16:05:00 +0100 Subject: [PATCH 016/347] design: update EditableAvatarView to match figma --- .../ui/components/EditableAvatarView.kt | 91 +++++++++++-------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt index 889c977552..7e02cf6e07 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt @@ -8,20 +8,25 @@ package io.element.android.libraries.matrix.ui.components -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.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.CompositingStrategy +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.semantics.contentDescription @@ -52,24 +57,42 @@ fun EditableAvatarView( onAvatarClick: () -> Unit, modifier: Modifier = Modifier, ) { - Column( - modifier = modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, + val a11yAvatar = stringResource(CommonStrings.a11y_avatar) + val editIconRadius = 15.dp + val parentHeight = avatarSize.dp + val parentWidth = avatarSize.dp + editIconRadius / 2f + Box( + modifier = modifier + .wrapContentSize() + .size(height = parentHeight, width = parentWidth) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + onClickLabel = stringResource(CommonStrings.a11y_edit_avatar), + onClick = onAvatarClick, + indication = ripple(bounded = false), + ) + .testTag(TestTags.editAvatar) + .clearAndSetSemantics { + contentDescription = a11yAvatar + }, ) { - val a11yAvatar = stringResource(CommonStrings.a11y_avatar) Box( modifier = Modifier - .clickable( - interactionSource = remember { MutableInteractionSource() }, - onClickLabel = stringResource(CommonStrings.a11y_edit_avatar), - onClick = onAvatarClick, - indication = ripple(bounded = false), - ) - .testTag(TestTags.editAvatar) - .clearAndSetSemantics { - contentDescription = a11yAvatar - }, - ) { + .graphicsLayer { + compositingStrategy = CompositingStrategy.Offscreen + } + .drawWithContent { + drawContent() + drawCircle( + color = Color.Black, + center = Offset( + x = parentWidth.toPx() - editIconRadius.toPx(), + y = size.height - editIconRadius.toPx(), + ), + radius = (editIconRadius + 4.dp).toPx(), + blendMode = BlendMode.Clear, + ) + }) { when { avatarUrl == null || avatarUrl.startsWith("mxc://") -> { Avatar( @@ -90,23 +113,17 @@ fun EditableAvatarView( ) } } - - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .clip(CircleShape) - .background(ElementTheme.colors.iconPrimary) - .size(24.dp), - contentAlignment = Alignment.Center, - ) { - Icon( - modifier = Modifier.size(16.dp), - imageVector = CompoundIcons.EditSolid(), - contentDescription = null, - tint = ElementTheme.colors.iconOnSolidPrimary, - ) - } } + Icon( + modifier = Modifier + .align(Alignment.BottomEnd) + .size(editIconRadius * 2) + .border(1.dp, ElementTheme.colors.borderInteractiveSecondary, CircleShape) + .padding(6.dp), + imageVector = CompoundIcons.Edit(), + contentDescription = null, + tint = ElementTheme.colors.iconPrimary, + ) } } @@ -119,9 +136,9 @@ internal fun EditableAvatarViewPreview( ) { EditableAvatarView( matrixId = "id", - displayName = "A room", + displayName = "Room", avatarUrl = uri, - avatarSize = AvatarSize.EditRoomDetails, + avatarSize = AvatarSize.RoomDetailsHeader, avatarType = AvatarType.User, onAvatarClick = {}, ) From 2e7355e78963643e48ab4af147e39de7fdf49aaf Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 3 Dec 2025 14:08:14 +0100 Subject: [PATCH 017/347] change(room details edit): move to his own module --- features/roomdetails/impl/build.gradle.kts | 2 + .../roomdetails/impl/RoomDetailsFlowNode.kt | 5 +- .../impl/DefaultRoomDetailsEntryPointTest.kt | 2 + features/roomdetailsedit/api/build.gradle.kts | 21 +++++++ .../api/RoomDetailsEditEntryPoint.kt | 13 +++++ .../roomdetailsedit/impl/build.gradle.kts | 57 ++++++++++++++++++ .../impl/DefaultRoomDetailsEditEntryPoint.kt | 23 ++++++++ .../impl}/RoomDetailsEditEvents.kt | 2 +- .../impl}/RoomDetailsEditNode.kt | 2 +- .../impl}/RoomDetailsEditPresenter.kt | 5 +- .../impl}/RoomDetailsEditState.kt | 2 +- .../impl}/RoomDetailsEditStateProvider.kt | 2 +- .../impl}/RoomDetailsEditView.kt | 9 ++- .../src/main/res/values-be/translations.xml | 7 +++ .../src/main/res/values-bg/translations.xml | 7 +++ .../src/main/res/values-cs/translations.xml | 7 +++ .../src/main/res/values-cy/translations.xml | 7 +++ .../src/main/res/values-da/translations.xml | 7 +++ .../src/main/res/values-de/translations.xml | 7 +++ .../src/main/res/values-el/translations.xml | 7 +++ .../src/main/res/values-es/translations.xml | 7 +++ .../src/main/res/values-et/translations.xml | 7 +++ .../src/main/res/values-eu/translations.xml | 7 +++ .../src/main/res/values-fa/translations.xml | 7 +++ .../src/main/res/values-fi/translations.xml | 7 +++ .../src/main/res/values-fr/translations.xml | 7 +++ .../src/main/res/values-hu/translations.xml | 7 +++ .../src/main/res/values-in/translations.xml | 7 +++ .../src/main/res/values-it/translations.xml | 7 +++ .../src/main/res/values-ka/translations.xml | 7 +++ .../src/main/res/values-ko/translations.xml | 7 +++ .../src/main/res/values-lt/translations.xml | 7 +++ .../src/main/res/values-nb/translations.xml | 7 +++ .../src/main/res/values-nl/translations.xml | 7 +++ .../src/main/res/values-pl/translations.xml | 7 +++ .../main/res/values-pt-rBR/translations.xml | 7 +++ .../src/main/res/values-pt/translations.xml | 7 +++ .../src/main/res/values-ro/translations.xml | 7 +++ .../src/main/res/values-ru/translations.xml | 7 +++ .../src/main/res/values-sk/translations.xml | 7 +++ .../src/main/res/values-sv/translations.xml | 7 +++ .../src/main/res/values-tr/translations.xml | 7 +++ .../src/main/res/values-uk/translations.xml | 7 +++ .../src/main/res/values-ur/translations.xml | 7 +++ .../src/main/res/values-uz/translations.xml | 7 +++ .../main/res/values-zh-rTW/translations.xml | 7 +++ .../src/main/res/values-zh/translations.xml | 7 +++ .../impl/src/main/res/values/localazy.xml | 7 +++ .../impl}/RoomDetailsEditPresenterTest.kt | 58 ++++++++++++++----- .../impl}/RoomDetailsEditViewTest.kt | 3 +- .../roomdetailsedit/test/build.gradle.kts | 22 +++++++ .../test/FakeRoomDetailsEditEntryPoint.kt | 19 ++++++ .../ui/components/EditableAvatarView.kt | 3 +- tools/localazy/config.json | 9 +++ 54 files changed, 475 insertions(+), 29 deletions(-) create mode 100644 features/roomdetailsedit/api/build.gradle.kts create mode 100644 features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditEntryPoint.kt create mode 100644 features/roomdetailsedit/impl/build.gradle.kts create mode 100644 features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/DefaultRoomDetailsEditEntryPoint.kt rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit => roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl}/RoomDetailsEditEvents.kt (92%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit => roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl}/RoomDetailsEditNode.kt (96%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit => roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl}/RoomDetailsEditPresenter.kt (98%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit => roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl}/RoomDetailsEditState.kt (95%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit => roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl}/RoomDetailsEditStateProvider.kt (97%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit => roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl}/RoomDetailsEditView.kt (96%) create mode 100644 features/roomdetailsedit/impl/src/main/res/values-be/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-bg/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-cs/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-cy/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-da/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-de/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-el/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-es/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-et/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-eu/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-fa/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-fi/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-fr/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-hu/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-in/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-it/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-ka/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-ko/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-lt/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-nb/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-nl/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-pl/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-pt-rBR/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-pt/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-ro/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-ru/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-sk/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-sv/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-tr/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-uk/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-ur/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-uz/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-zh-rTW/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-zh/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values/localazy.xml rename features/{roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/edit => roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl}/RoomDetailsEditPresenterTest.kt (94%) rename features/{roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/edit => roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl}/RoomDetailsEditViewTest.kt (98%) create mode 100644 features/roomdetailsedit/test/build.gradle.kts create mode 100644 features/roomdetailsedit/test/src/main/kotlin/io/element/android/features/roomdetailsedit/test/FakeRoomDetailsEditEntryPoint.kt diff --git a/features/roomdetails/impl/build.gradle.kts b/features/roomdetails/impl/build.gradle.kts index 4ca260be16..f6e2d5387d 100644 --- a/features/roomdetails/impl/build.gradle.kts +++ b/features/roomdetails/impl/build.gradle.kts @@ -59,6 +59,7 @@ dependencies { implementation(projects.features.roommembermoderation.api) implementation(projects.features.rolesandpermissions.api) implementation(projects.features.securityandprivacy.api) + implementation(projects.features.roomdetailsedit.api) implementation(projects.features.invitepeople.api) testCommonDependencies(libs, true) @@ -73,6 +74,7 @@ dependencies { testImplementation(projects.features.call.test) testImplementation(projects.features.rolesandpermissions.test) testImplementation(projects.features.securityandprivacy.test) + implementation(projects.features.roomdetailsedit.test) testImplementation(projects.features.knockrequests.test) testImplementation(projects.features.messages.test) testImplementation(projects.features.poll.test) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index c8ef60513c..9071425a72 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -35,11 +35,11 @@ import io.element.android.features.rolesandpermissions.api.ChangeRoomMemberRoles import io.element.android.features.rolesandpermissions.api.ChangeRoomMemberRolesListType import io.element.android.features.rolesandpermissions.api.RolesAndPermissionsEntryPoint import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint -import io.element.android.features.roomdetails.impl.edit.RoomDetailsEditNode import io.element.android.features.roomdetails.impl.invite.RoomInviteMembersNode import io.element.android.features.roomdetails.impl.members.RoomMemberListNode import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsNode import io.element.android.features.roomdetails.impl.notificationsettings.RoomNotificationSettingsNode +import io.element.android.features.roomdetailsedit.api.RoomDetailsEditEntryPoint import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint import io.element.android.features.userprofile.shared.UserProfileNodeHelper import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint @@ -85,6 +85,7 @@ class RoomDetailsFlowNode( private val changeRoomMemberRolesEntryPoint: ChangeRoomMemberRolesEntryPoint, private val rolesAndPermissionsEntryPoint: RolesAndPermissionsEntryPoint, private val securityAndPrivacyEntryPoint: SecurityAndPrivacyEntryPoint, + private val roomDetailsEditEntryPoint: RoomDetailsEditEntryPoint, ) : BaseFlowNode( backstack = BackStack( initialElement = plugins.filterIsInstance().first().initialElement.toNavTarget(), @@ -256,7 +257,7 @@ class RoomDetailsFlowNode( } NavTarget.RoomDetailsEdit -> { - createNode(buildContext) + roomDetailsEditEntryPoint.createNode(this, buildContext) } NavTarget.InviteMembers -> { diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/DefaultRoomDetailsEntryPointTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/DefaultRoomDetailsEntryPointTest.kt index cd2af112a7..5042f942b6 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/DefaultRoomDetailsEntryPointTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/DefaultRoomDetailsEntryPointTest.kt @@ -20,6 +20,7 @@ import io.element.android.features.messages.test.FakeMessagesEntryPoint import io.element.android.features.poll.test.history.FakePollHistoryEntryPoint import io.element.android.features.reportroom.test.FakeReportRoomEntryPoint import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint +import io.element.android.features.roomdetailsedit.test.FakeRoomDetailsEditEntryPoint import io.element.android.features.securityandprivacy.test.FakeSecurityAndPrivacyEntryPoint import io.element.android.features.verifysession.test.FakeOutgoingVerificationEntryPoint import io.element.android.libraries.matrix.api.core.EventId @@ -63,6 +64,7 @@ class DefaultRoomDetailsEntryPointTest { changeRoomMemberRolesEntryPoint = FakeChangeRoomMemberRolesEntryPoint(), rolesAndPermissionsEntryPoint = FakeRolesAndPermissionsEntryPoint(), securityAndPrivacyEntryPoint = FakeSecurityAndPrivacyEntryPoint(), + roomDetailsEditEntryPoint = FakeRoomDetailsEditEntryPoint(), ) } val callback = object : RoomDetailsEntryPoint.Callback { diff --git a/features/roomdetailsedit/api/build.gradle.kts b/features/roomdetailsedit/api/build.gradle.kts new file mode 100644 index 0000000000..0afaad72a6 --- /dev/null +++ b/features/roomdetailsedit/api/build.gradle.kts @@ -0,0 +1,21 @@ +/* + * 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-library") + id("kotlin-parcelize") +} + +android { + namespace = "io.element.android.features.roomdetailsedit.api" +} + +dependencies { + implementation(projects.libraries.architecture) + implementation(projects.libraries.matrix.api) +} diff --git a/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditEntryPoint.kt b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditEntryPoint.kt new file mode 100644 index 0000000000..1dad365646 --- /dev/null +++ b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditEntryPoint.kt @@ -0,0 +1,13 @@ +/* + * 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.roomdetailsedit.api + +import io.element.android.libraries.architecture.SimpleFeatureEntryPoint + +fun interface RoomDetailsEditEntryPoint : SimpleFeatureEntryPoint diff --git a/features/roomdetailsedit/impl/build.gradle.kts b/features/roomdetailsedit/impl/build.gradle.kts new file mode 100644 index 0000000000..6b1d886abe --- /dev/null +++ b/features/roomdetailsedit/impl/build.gradle.kts @@ -0,0 +1,57 @@ +import extension.setupDependencyInjection +import extension.testCommonDependencies + +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2023, 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +plugins { + id("io.element.android-compose-library") + id("kotlin-parcelize") +} + +android { + namespace = "io.element.android.features.roomdetailsedit.impl" + testOptions { + unitTests { + isIncludeAndroidResources = true + } + } +} + +setupDependencyInjection() + +dependencies { + implementation(projects.libraries.core) + implementation(projects.libraries.architecture) + implementation(projects.libraries.matrix.api) + implementation(projects.libraries.matrixui) + implementation(projects.libraries.designsystem) + implementation(projects.libraries.uiStrings) + implementation(projects.libraries.androidutils) + implementation(projects.libraries.mediapickers.api) + implementation(projects.libraries.mediaupload.api) + implementation(projects.libraries.mediaviewer.api) + implementation(projects.libraries.featureflag.api) + implementation(projects.libraries.permissions.api) + implementation(projects.libraries.preferences.api) + implementation(projects.services.analytics.api) + implementation(projects.libraries.testtags) + api(projects.features.roomdetailsedit.api) + api(projects.services.apperror.api) + implementation(libs.coil.compose) + + testCommonDependencies(libs, true) + testImplementation(projects.libraries.matrix.test) + testImplementation(projects.libraries.mediaupload.test) + testImplementation(projects.libraries.mediapickers.test) + testImplementation(projects.libraries.mediaviewer.test) + testImplementation(projects.libraries.permissions.test) + testImplementation(projects.libraries.preferences.test) + testImplementation(projects.libraries.featureflag.test) + testImplementation(projects.services.analytics.test) +} diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/DefaultRoomDetailsEditEntryPoint.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/DefaultRoomDetailsEditEntryPoint.kt new file mode 100644 index 0000000000..d928a0238c --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/DefaultRoomDetailsEditEntryPoint.kt @@ -0,0 +1,23 @@ +/* + * 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.roomdetailsedit.impl + +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.roomdetailsedit.api.RoomDetailsEditEntryPoint +import io.element.android.libraries.architecture.createNode + +@ContributesBinding(AppScope::class) +class DefaultRoomDetailsEditEntryPoint : RoomDetailsEditEntryPoint { + override fun createNode(parentNode: Node, buildContext: BuildContext): Node { + return parentNode.createNode(buildContext) + } +} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditEvents.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditEvents.kt similarity index 92% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditEvents.kt rename to features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditEvents.kt index 2606d6be83..858d08c2a0 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditEvents.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditEvents.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.edit +package io.element.android.features.roomdetailsedit.impl import io.element.android.libraries.matrix.ui.media.AvatarAction diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditNode.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditNode.kt similarity index 96% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditNode.kt rename to features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditNode.kt index dc2ebe8c27..541a36c91a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditNode.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditNode.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.edit +package io.element.android.features.roomdetailsedit.impl import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt similarity index 98% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt rename to features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt index 930d63031a..89af0aa288 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt @@ -6,8 +6,9 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.edit +package io.element.android.features.roomdetailsedit.impl +import android.Manifest import android.net.Uri import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -51,7 +52,7 @@ class RoomDetailsEditPresenter( permissionsPresenterFactory: PermissionsPresenter.Factory, private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider, ) : Presenter { - private val cameraPermissionPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA) + private val cameraPermissionPresenter = permissionsPresenterFactory.create(Manifest.permission.CAMERA) private var pendingPermissionRequest = false @Composable diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditState.kt similarity index 95% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt rename to features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditState.kt index f1d7a8861b..1017c961b1 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditState.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.edit +package io.element.android.features.roomdetailsedit.impl import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt similarity index 97% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt rename to features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt index 7913620f04..d1f13d252c 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.edit +package io.element.android.features.roomdetailsedit.impl import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.architecture.AsyncAction diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt similarity index 96% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt rename to features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt index 870f48b60e..22795c98d3 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt @@ -8,7 +8,7 @@ @file:OptIn(ExperimentalMaterial3Api::class) -package io.element.android.features.roomdetails.impl.edit +package io.element.android.features.roomdetailsedit.impl import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Column @@ -31,7 +31,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.features.roomdetails.impl.R import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults @@ -108,9 +107,9 @@ fun RoomDetailsEditView( displayName = state.roomRawName, avatarUrl = state.roomAvatarUrl, avatarSize = AvatarSize.EditRoomDetails, - avatarType = if(state.isSpace){ + avatarType = if (state.isSpace) { AvatarType.Space() - }else { + } else { AvatarType.Room() }, onAvatarClick = ::onAvatarClick, @@ -119,7 +118,7 @@ fun RoomDetailsEditView( Spacer(modifier = Modifier.height(60.dp)) TextField( - label = stringResource(id = R.string.screen_room_details_room_name_label), + label = stringResource(id = CommonStrings.common_room_name), value = state.roomRawName, placeholder = stringResource(CommonStrings.common_room_name_placeholder), singleLine = true, diff --git a/features/roomdetailsedit/impl/src/main/res/values-be/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-be/translations.xml new file mode 100644 index 0000000000..26537576b4 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-be/translations.xml @@ -0,0 +1,7 @@ + + + "Рэдагаваць пакой" + "Адбылася невядомая памылка, і інфармацыю нельга было змяніць." + "Немагчыма абнавіць пакой" + "Ідзе абнаўленне пакоя…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-bg/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-bg/translations.xml new file mode 100644 index 0000000000..787110dc79 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-bg/translations.xml @@ -0,0 +1,7 @@ + + + "Редактиране на стаята" + "Възникна неизвестна грешка и информацията не можа да бъде променена." + "Не може да се обнови стаята" + "Обновяване на стаята…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-cs/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-cs/translations.xml new file mode 100644 index 0000000000..b2ea107300 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-cs/translations.xml @@ -0,0 +1,7 @@ + + + "Upravit podrobnosti" + "Došlo k neznámé chybě a informace nebylo možné změnit." + "Nelze aktualizovat místnost" + "Aktualizace místnosti…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-cy/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-cy/translations.xml new file mode 100644 index 0000000000..e13ddf6d91 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-cy/translations.xml @@ -0,0 +1,7 @@ + + + "Ystafell Golygu" + "Roedd gwall anhysbys ac nid oedd modd newid y manylion." + "Methu diweddaru\'r ystafell" + "Wrthi\'n diweddaru ystafell…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-da/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-da/translations.xml new file mode 100644 index 0000000000..489bd9b13b --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-da/translations.xml @@ -0,0 +1,7 @@ + + + "Rediger rum" + "Der opstod en ukendt fejl, og oplysningerne kunne ikke ændres." + "Rummet kunne ikke opdateres" + "Opdaterer rum…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-de/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-de/translations.xml new file mode 100644 index 0000000000..1bc31f9f68 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-de/translations.xml @@ -0,0 +1,7 @@ + + + "Chat bearbeiten" + "Es ist ein unbekannter Fehler aufgetreten und die Informationen konnten nicht geändert werden." + "Chat kann nicht aktualisiert werden" + "Chat wird aktualisiert…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-el/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-el/translations.xml new file mode 100644 index 0000000000..c783ab1d86 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-el/translations.xml @@ -0,0 +1,7 @@ + + + "Επεξεργασία Αίθουσας" + "Υπήρξε ένα άγνωστο σφάλμα και οι πληροφορίες δεν μπορούσαν να αλλάξουν." + "Αδυναμία ενημέρωσης αίθουσας" + "Ενημέρωση αίθουσας…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-es/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-es/translations.xml new file mode 100644 index 0000000000..45e1d81df9 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-es/translations.xml @@ -0,0 +1,7 @@ + + + "Editar sala" + "Se ha producido un error desconocido y no se ha podido cambiar la información." + "No se puede actualizar la sala" + "Actualizando la sala…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-et/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-et/translations.xml new file mode 100644 index 0000000000..4c158d348a --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-et/translations.xml @@ -0,0 +1,7 @@ + + + "Muuda üksikasju" + "Tekkis tundmatu viga ja andmed jäid muutmata." + "Jututoa andmete muutmine ei õnnestu" + "Uuendame jututuba…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-eu/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-eu/translations.xml new file mode 100644 index 0000000000..000b5856bb --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-eu/translations.xml @@ -0,0 +1,7 @@ + + + "Editatu gela" + "Errore ezezaguna gertatu da eta ezin izan da informazioa aldatu." + "Ezin da gela eguneratu" + "Gela eguneratzen…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-fa/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-fa/translations.xml new file mode 100644 index 0000000000..bbbd63d171 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-fa/translations.xml @@ -0,0 +1,7 @@ + + + "ویرایش اتاق" + "خطایی ناشناخته رخ داد و اطّلاعات قابل تغییر نبودند." + "ناتوان در به‌روز رسانی اتاق" + "به‌روز کردن اتاق…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-fi/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-fi/translations.xml new file mode 100644 index 0000000000..eabdcf2ab1 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-fi/translations.xml @@ -0,0 +1,7 @@ + + + "Muokkaa tietoja" + "Tuntematon virhe tapahtui, eikä tietoja voitu muuttaa." + "Huoneen muokkaaminen ei onnistunut" + "Muokataan huonetta…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-fr/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-fr/translations.xml new file mode 100644 index 0000000000..bd0c4b6f02 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-fr/translations.xml @@ -0,0 +1,7 @@ + + + "Modifier les détails" + "Une erreur inconnue s’est produite et les informations n’ont pas pu être modifiées." + "Impossible de mettre à jour le salon" + "Mise à jour du salon…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-hu/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-hu/translations.xml new file mode 100644 index 0000000000..9685a9afbb --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-hu/translations.xml @@ -0,0 +1,7 @@ + + + "Részletek szerkesztése" + "Ismeretlen hiba történt, és az információkat nem lehetett megváltoztatni." + "Nem sikerült frissíteni a szobát" + "Szoba frissítése…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-in/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..14b3d68c74 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,7 @@ + + + "Sunting Ruangan" + "Terjadi kesalahan yang tidak diketahui dan informasinya tidak dapat diubah." + "Tidak dapat memperbarui ruangan" + "Memperbarui ruangan…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-it/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-it/translations.xml new file mode 100644 index 0000000000..7d28c1a3e2 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-it/translations.xml @@ -0,0 +1,7 @@ + + + "Modifica dettagli" + "Si è verificato un errore sconosciuto e non è stato possibile modificare le informazioni." + "Impossibile aggiornare la stanza" + "Aggiornamento della stanza…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-ka/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-ka/translations.xml new file mode 100644 index 0000000000..53ea28028b --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-ka/translations.xml @@ -0,0 +1,7 @@ + + + "ოთახის რედაქტირება" + "უცნობი შეცდომა მოხდა. ინფორმაციის შეცვლა ვერ მოხერხდა." + "ოთახის განახლება შეუძლებელია" + "ოთახის განახლება…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-ko/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-ko/translations.xml new file mode 100644 index 0000000000..ae51384737 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-ko/translations.xml @@ -0,0 +1,7 @@ + + + "방 편집" + "알 수 없는 오류가 발생하여 정보를 변경할 수 없습니다." + "방을 업데이트할 수 없습니다." + "방 업데이트 중…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-lt/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-lt/translations.xml new file mode 100644 index 0000000000..7e28eeb16c --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-lt/translations.xml @@ -0,0 +1,7 @@ + + + "Redaguoti kambarį" + "Įvyko nežinoma klaida ir informacijos pakeisti nepavyko." + "Nepavyko atnaujinti kambario" + "Atnaujinamas kambarys…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-nb/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-nb/translations.xml new file mode 100644 index 0000000000..d5095ae854 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-nb/translations.xml @@ -0,0 +1,7 @@ + + + "Rediger rom" + "Det oppstod en ukjent feil, og informasjonen kunne ikke endres." + "Kan ikke oppdatere rommet" + "Oppdaterer rommet …" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-nl/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-nl/translations.xml new file mode 100644 index 0000000000..af6fae3a90 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-nl/translations.xml @@ -0,0 +1,7 @@ + + + "Kamer bewerken" + "Er is een onbekende fout opgetreden en de informatie kon niet worden gewijzigd." + "Kan kamer niet bijwerken" + "Kamer bijwerken…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-pl/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-pl/translations.xml new file mode 100644 index 0000000000..c676ff46ed --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-pl/translations.xml @@ -0,0 +1,7 @@ + + + "Edytuj pokój" + "Wystąpił nieznany błąd i nie można było zmienić informacji." + "Nie można zaktualizować pokoju" + "Aktualizuję pokój…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-pt-rBR/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-pt-rBR/translations.xml new file mode 100644 index 0000000000..e8e5dfc28d --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-pt-rBR/translations.xml @@ -0,0 +1,7 @@ + + + "Editar detalhes" + "Ocorreu um erro desconhecido e as informações não puderam ser alteradas." + "Não foi possível atualizar a sala" + "Atualizando a sala…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-pt/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-pt/translations.xml new file mode 100644 index 0000000000..25069318a5 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-pt/translations.xml @@ -0,0 +1,7 @@ + + + "Editar sala" + "Ocorreu um erro desconhecido e não foi possível alterar a informação." + "Não foi possível atualizar a sala" + "A atualizar sala…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-ro/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-ro/translations.xml new file mode 100644 index 0000000000..9d9e769196 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-ro/translations.xml @@ -0,0 +1,7 @@ + + + "Editați camera" + "A apărut o eroare la actualizarea detaliilor camerei" + "Nu s-a putut actualiza camera" + "Se actualizează camera…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-ru/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-ru/translations.xml new file mode 100644 index 0000000000..91ce37e6c0 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-ru/translations.xml @@ -0,0 +1,7 @@ + + + "Редактировать комнату" + "Произошла неизвестная ошибка и информацию не удалось изменить." + "Не удалось обновить комнату" + "Обновление комнаты…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-sk/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-sk/translations.xml new file mode 100644 index 0000000000..52e484f1a3 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-sk/translations.xml @@ -0,0 +1,7 @@ + + + "Upraviť podrobnosti" + "Vyskytla sa neznáma chyba a informácie nebolo možné zmeniť." + "Nepodarilo sa aktualizovať miestnosť" + "Aktualizácia miestnosti…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-sv/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-sv/translations.xml new file mode 100644 index 0000000000..176aed6b00 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-sv/translations.xml @@ -0,0 +1,7 @@ + + + "Redigera rummet" + "Ett okänt fel uppstod och informationen kunde inte ändras." + "Kunde inte uppdatera rummet" + "Uppdaterar rummet …" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-tr/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-tr/translations.xml new file mode 100644 index 0000000000..f55c55cfaf --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-tr/translations.xml @@ -0,0 +1,7 @@ + + + "Odayı Düzenle" + "Bilinmeyen bir hata oluştu ve bilgiler değiştirilemedi." + "Oda güncellenemiyor" + "Oda güncelleniyor…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-uk/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-uk/translations.xml new file mode 100644 index 0000000000..21a47cbd59 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-uk/translations.xml @@ -0,0 +1,7 @@ + + + "Редагувати кімнату" + "Сталася невідома помилка, й інформацію не вдалося змінити." + "Не вдалося оновити кімнату" + "Оновлення кімнати…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-ur/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-ur/translations.xml new file mode 100644 index 0000000000..e0fd0e01b5 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-ur/translations.xml @@ -0,0 +1,7 @@ + + + "کمرے میں ترمیم کریں" + "ایک نامعلوم خلل تھا اور معلومات تبدیل نہیں ہوسکی۔" + "کمرے کی تجدید کرنے سے قاصر" + "کمرے کی تجدید کر رہا ہے…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-uz/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-uz/translations.xml new file mode 100644 index 0000000000..e3ab69c86d --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-uz/translations.xml @@ -0,0 +1,7 @@ + + + "Xonani tahrirlash" + "Nomaʼlum xatolik yuz berdi va maʼlumotni oʻzgartirib boʻlmadi." + "Xonani yangilab bo‘lmadi" + "Xona yangilanmoqda…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-zh-rTW/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-zh-rTW/translations.xml new file mode 100644 index 0000000000..44955e96dd --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-zh-rTW/translations.xml @@ -0,0 +1,7 @@ + + + "編輯詳細資訊" + "發生未知錯誤,無法變更資訊。" + "無法更新聊天室" + "正在更新聊天室…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-zh/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-zh/translations.xml new file mode 100644 index 0000000000..6b174fcb2c --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-zh/translations.xml @@ -0,0 +1,7 @@ + + + "编辑聊天室" + "出现未知错误,无法更改信息。" + "无法更新聊天室" + "正在更新聊天室……" + diff --git a/features/roomdetailsedit/impl/src/main/res/values/localazy.xml b/features/roomdetailsedit/impl/src/main/res/values/localazy.xml new file mode 100644 index 0000000000..7a70381a8b --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values/localazy.xml @@ -0,0 +1,7 @@ + + + "Edit details" + "There was an unknown error and the information couldn\'t be changed." + "Unable to update room" + "Updating room…" + diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenterTest.kt b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt similarity index 94% rename from features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenterTest.kt rename to features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt index f66091dd87..d19a07ab04 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenterTest.kt +++ b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt @@ -1,25 +1,28 @@ /* * 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.roomdetails.impl.edit +package io.element.android.features.roomdetailsedit.impl import android.net.Uri import app.cash.turbine.ReceiveTurbine import com.google.common.truth.Truth.assertThat -import io.element.android.features.roomdetails.impl.aJoinedRoom import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.core.mimetype.MimeTypes +import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_ROOM_RAW_NAME +import io.element.android.libraries.matrix.test.A_ROOM_TOPIC +import io.element.android.libraries.matrix.test.room.FakeBaseRoom +import io.element.android.libraries.matrix.test.room.FakeJoinedRoom +import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.mediapickers.test.FakePickerProvider import io.element.android.libraries.mediaupload.api.MediaUploadInfo @@ -124,16 +127,17 @@ class RoomDetailsEditPresenterTest { @Test fun `present - sets canChangeName if user has permission`() = runTest { - val room = aJoinedRoom( - avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_NAME -> Result.success(true) - StateEventType.ROOM_AVATAR -> Result.success(false) - StateEventType.ROOM_TOPIC -> Result.failure(RuntimeException("Oops")) - else -> lambdaError() - } - }, + val room = FakeJoinedRoom( + FakeBaseRoom( + canSendStateResult = { _, stateEventType -> + when (stateEventType) { + StateEventType.ROOM_NAME -> Result.success(true) + StateEventType.ROOM_AVATAR -> Result.success(false) + StateEventType.ROOM_TOPIC -> Result.failure(RuntimeException("Oops")) + else -> lambdaError() + } + }, + ) ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -769,6 +773,34 @@ class RoomDetailsEditPresenterTest { ) } + private fun aJoinedRoom( + avatarUrl: String? = AN_AVATAR_URL, + displayName: String = A_ROOM_NAME, + rawName: String = displayName, + topic: String? = A_ROOM_TOPIC, + setNameResult: (String) -> Result = { Result.success(Unit) }, + setTopicResult: (String) -> Result = { Result.success(Unit) }, + updateAvatarResult: (String, ByteArray) -> Result = { _, _ -> Result.success(Unit) }, + removeAvatarResult: () -> Result = { Result.success(Unit) }, + canSendStateResult: (UserId, StateEventType) -> Result, + ): JoinedRoom { + return FakeJoinedRoom( + baseRoom = FakeBaseRoom( + canSendStateResult = canSendStateResult, + initialRoomInfo = aRoomInfo( + name = displayName, + topic = topic, + avatarUrl = avatarUrl, + rawName = rawName + ) + ), + setNameResult = setNameResult, + setTopicResult = setTopicResult, + updateAvatarResult = updateAvatarResult, + removeAvatarResult = removeAvatarResult, + ) + } + companion object { private const val ANOTHER_AVATAR_URL = "example://camera/foo.jpg" } diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditViewTest.kt b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt similarity index 98% rename from features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditViewTest.kt rename to features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt index c8475cbb89..dcf8a94d66 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditViewTest.kt +++ b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt @@ -1,12 +1,11 @@ /* * 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.roomdetails.impl.edit +package io.element.android.features.roomdetailsedit.impl import androidx.activity.ComponentActivity import androidx.annotation.StringRes diff --git a/features/roomdetailsedit/test/build.gradle.kts b/features/roomdetailsedit/test/build.gradle.kts new file mode 100644 index 0000000000..ff9110eb49 --- /dev/null +++ b/features/roomdetailsedit/test/build.gradle.kts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.features.roomdetetailsedit.test" +} + +dependencies { + implementation(projects.features.roomdetailsedit.api) + implementation(projects.libraries.architecture) + implementation(projects.libraries.matrix.api) + implementation(projects.tests.testutils) +} diff --git a/features/roomdetailsedit/test/src/main/kotlin/io/element/android/features/roomdetailsedit/test/FakeRoomDetailsEditEntryPoint.kt b/features/roomdetailsedit/test/src/main/kotlin/io/element/android/features/roomdetailsedit/test/FakeRoomDetailsEditEntryPoint.kt new file mode 100644 index 0000000000..df890ab2c6 --- /dev/null +++ b/features/roomdetailsedit/test/src/main/kotlin/io/element/android/features/roomdetailsedit/test/FakeRoomDetailsEditEntryPoint.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.features.roomdetailsedit.test + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import io.element.android.features.roomdetailsedit.api.RoomDetailsEditEntryPoint +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeRoomDetailsEditEntryPoint : RoomDetailsEditEntryPoint { + override fun createNode(parentNode: Node, buildContext: BuildContext): Node { + lambdaError() + } +} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt index 7e02cf6e07..7a005402e2 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt @@ -92,7 +92,8 @@ fun EditableAvatarView( radius = (editIconRadius + 4.dp).toPx(), blendMode = BlendMode.Clear, ) - }) { + } + ) { when { avatarUrl == null || avatarUrl.startsWith("mxc://") -> { Avatar( diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 46908438b5..f7463a6396 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -209,6 +209,15 @@ "screen\\.security_and_privacy\\..*" ] }, + { + "name" : ":features:roomdetailsedit:impl", + "includeRegex" : [ + "screen_room_details_edit_room_title", + "screen_room_details_edition_error", + "screen_room_details_edition_error_title", + "screen_room_details_updating_room" + ] + }, { "name" : ":features:space:impl", "includeRegex" : [ From 653f7944758a9a264f8a8565130e1257ac0fb308 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 3 Dec 2025 15:08:43 +0100 Subject: [PATCH 018/347] change(room details edit): adjust the ui --- .../impl/RoomDetailsEditStateProvider.kt | 2 +- .../roomdetailsedit/impl/RoomDetailsEditView.kt | 14 ++++++++------ .../ui-strings/src/main/res/values/localazy.xml | 2 ++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt index d1f13d252c..cecdcfa9d5 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt @@ -23,7 +23,7 @@ open class RoomDetailsEditStateProvider : PreviewParameterProvider "Message removed" "Modern" "Mute" + "Name" "%1$s (%2$s)" "No results" "No room name" @@ -325,6 +326,7 @@ Reason: %1$s." "Something went wrong" "We encountered an issue. Please try again." "Space" + "What is this space about?" "%1$d Space" "%1$d Spaces" From cba07bfd2356d426f67d5398fb3be91c1fa210a5 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 3 Dec 2025 14:26:02 +0000 Subject: [PATCH 019/347] 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 ++-- ...res.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en.png | 3 --- ...res.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en.png | 3 --- ...res.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en.png | 3 --- ...res.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en.png | 3 --- ...res.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en.png | 3 --- ...res.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en.png | 3 --- ...res.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en.png | 3 --- ...res.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en.png | 3 --- ...res.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en.png | 3 --- ...s.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en.png | 3 --- ...s.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en.png | 3 --- ...s.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en.png | 3 --- ...s.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en.png | 3 --- ...s.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en.png | 3 --- ...s.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en.png | 3 --- ...s.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en.png | 3 --- ...s.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en.png | 3 --- ...s.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en.png | 3 --- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png | 3 +++ ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png | 3 +++ ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png | 3 +++ ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png | 3 +++ ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png | 3 +++ ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png | 3 +++ ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png | 3 +++ ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png | 3 +++ ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png | 3 +++ ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png | 3 +++ ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png | 3 +++ ...aries.matrix.ui.components_EditableAvatarView_Day_0_en.png | 4 ++-- ...aries.matrix.ui.components_EditableAvatarView_Day_1_en.png | 4 ++-- ...aries.matrix.ui.components_EditableAvatarView_Day_2_en.png | 4 ++-- ...ies.matrix.ui.components_EditableAvatarView_Night_0_en.png | 4 ++-- ...ies.matrix.ui.components_EditableAvatarView_Night_1_en.png | 4 ++-- ...ies.matrix.ui.components_EditableAvatarView_Night_2_en.png | 4 ++-- 50 files changed, 84 insertions(+), 78 deletions(-) delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png 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 47721b005c..b509b7fff7 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:e036fd006454f8dad5ca62109e047e33ded820b23ba1338e90489cc6af194256 -size 20122 +oid sha256:5896d5e6fd21697d6270aedb4389eee0d57a9796536b847ae657f57e6c2dab3d +size 20974 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 8287d9ec5f..c7aa6f6105 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:23c48ba14e151edf2669cd8a7804517bd4282b0b86e0482ed16c351c8d5da61e -size 68392 +oid sha256:95100c25fb085329f8968a765a4f4359678be67309d5e086ead311c48cfda29f +size 67826 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 1e81e0e58a..d27f554281 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:da49d0867fdaa28fbe7db7dc21c5de09268e7bb3afdb0b2289df372d537c2abb -size 33570 +oid sha256:f2a443d3d6733e4fb9c618c4a689c8fb95195f47d3b08513a955f18251028b2f +size 34203 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 11d25d9f8b..3920f3fe0c 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:cba22353e2689d211508e5b2726d751a31109c490e242708fbdf0bab2b31870c -size 20257 +oid sha256:7f103f89c71cc97a837cf0edc1035c580bfdf2d682857897241a6dec23c91436 +size 21163 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 f4458fc6f8..1a31286fd6 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:8ac052ff95c121119d5dd99d07b41b0f78f83ce59b6644aeb596f45e673f1b03 -size 67341 +oid sha256:9989d429a1ed9f3190a19c0678168de77aca597ed8fda5208e19bbe109ab9ada +size 66391 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 73a68c1db0..4d93498ed8 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:60fe1926cf8d66a8086268f3e4e1b6b1616f860668e1e5f4dc670d5c57ec4d24 -size 31943 +oid sha256:b2166579c462025a6bff38b05da7574502f7200d5f0a4949b31ea4e4fbc25a67 +size 32467 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en.png deleted file mode 100644 index 7023c76361..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:21ef482132a717f7c45bb5775f16344da2a96932d5f6854d73660c599e48d9ca -size 28141 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en.png deleted file mode 100644 index 924470e276..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:36b5337f5edcbcc1b6eafe504ba2a6edd20078e1a22df34c6ff3ddaeade82d55 -size 21966 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en.png deleted file mode 100644 index 7aca6687cf..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:32a649e6c9555bdf4d3a87bc18a51ca226167dd561b868d0b9310ded4a782c0d -size 29622 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en.png deleted file mode 100644 index 84c1911eff..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:47ceaff5ef3c3244faa2ba389a7a84c5c9a6860fd3bf6d84e0728288037edad5 -size 53852 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en.png deleted file mode 100644 index 5070c641c8..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:91f992a8a82e04fef07c5efacf882ac188061b105bea2867edac9fef94c58be7 -size 28099 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en.png deleted file mode 100644 index 1b6336d9f9..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a2289b612f53068f68f5d4bfe5cbaabb29f93564509d27694ddf54617ce3fa9b -size 28192 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en.png deleted file mode 100644 index ed5556b411..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:65c3f2a886d68749d9169945f6ab796bae00dfaaf5a1bc07af395c3d8e3fd8db -size 26561 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en.png deleted file mode 100644 index 517501a24c..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3e653ac4f6a735766b47fe6b9653160c60b79a13836dac84cb1b00d8b3a9ad5e -size 24928 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en.png deleted file mode 100644 index 66acdf7c97..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9e241c5acd53a70d1dee2a7f4542fdbcfab43774d13263a652cd9c0e5e6614a3 -size 31103 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en.png deleted file mode 100644 index 8b532d5719..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6326a107a0e9d5ddf524311b4d650986e26fdce172ed8ee79a587b9c2a7b92a8 -size 27605 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en.png deleted file mode 100644 index 4f06da0bbe..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3edb943c28ebc38755f2167431a75702d21b69ff9188adc76f18bc9085002360 -size 21729 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en.png deleted file mode 100644 index c66713bbc4..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6a4432faa27f3e46f8b2abb91215ba68136daefea50e7cfdec86d77b65773d35 -size 29108 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en.png deleted file mode 100644 index b9e9656e4c..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9ceccd6b99a12d22ea5f8b2e1634c9f0abcd52732a3ad7533a5e4a6263064aab -size 52768 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en.png deleted file mode 100644 index 63c681c5a2..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:21881980c4cd55f521e4bd72b477577c0e2d6887fdc1827fd9d82a9b609a9312 -size 27598 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en.png deleted file mode 100644 index 0cdaf4b630..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:efeec7c32edd8d822c9ccebb5c4765862b1b236b150aa1157f2773b69b8f183b -size 27584 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en.png deleted file mode 100644 index cbf2fbd544..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:616f78d6ddd065169c577a3ecf24accaa793a668786c52ab1eae8e26382cd790 -size 25645 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en.png deleted file mode 100644 index 7f9eeaabad..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8e8b4d9d65eefe2c0343fa5d563d16ba90c1eb2468e2b5f6395f2872bf453db0 -size 23162 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en.png deleted file mode 100644 index f4e874fc48..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:74cb40864ab2e480af32a3929f2f9a3ff74e2c9e40f11fce6384f259c7e7dcc4 -size 29185 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 new file mode 100644 index 0000000000..98fffb180d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c200761849da1ba650f38adfeed65fcc35f4fda94a4b1302447faf55d4196c16 +size 28211 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 new file mode 100644 index 0000000000..146d245888 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:282680791aed814f49e25134742e55270ffa155004d48a4f4645ef160450c529 +size 21933 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 new file mode 100644 index 0000000000..f9fb3f287d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc04e9e69f8111c2837d998f6503e2ea146d91284d1839ac8619d5d9325645d7 +size 29613 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 new file mode 100644 index 0000000000..169e16037f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7579d7b70e81228d997f8390285210a6e6a7c764523a82b59cd68b2e1969656 +size 52193 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 new file mode 100644 index 0000000000..fc9cf97e30 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eaad1ca1ef992a03aae784836139963e5ac8867d5fc70871eb63d273acf05948 +size 49266 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 new file mode 100644 index 0000000000..817b7943b8 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44331b9967290ab96c55cce7a5f8a3531564ad0c074ea6b25adf9299a6ec0239 +size 28165 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 new file mode 100644 index 0000000000..74c01ba304 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d037d7c70b304980c4c0a2c292fdcf800eafff15aee8c3c3adbf180e7e47a557 +size 28293 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 new file mode 100644 index 0000000000..9f58184f04 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f2d14cff976468c7a2408c9e9d0dabcfbed4a0cfb1406f71db459f660305269 +size 24794 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 new file mode 100644 index 0000000000..e3e8f0a8c0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:109a1451e031bcc46e55c2c111a4ce65eb5635a3b66b1ba6a5e6a0980184ec0d +size 26087 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 new file mode 100644 index 0000000000..c9523fb650 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25d60c4025a15e283978fb15abf8417bc896714ebc1faf198a3735978bbbfb18 +size 32392 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 new file mode 100644 index 0000000000..de17d9174f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d797584eca407120de11bdac2792a4501dd414274e5acf786fab74b7df668209 +size 27518 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 new file mode 100644 index 0000000000..df8188c586 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ba88593c26798de646f331f68c48b4675f33090e7533b88f6a31e0c5cfbd081 +size 21538 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 new file mode 100644 index 0000000000..da0a0553d5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16c5f05bb20e9a1f5b3480827fe7c7c4384daa60496da0ee0dc9bcdd77ccdddd +size 29004 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 new file mode 100644 index 0000000000..9cd03d2914 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7616b1926b6b6f1c6aa19d797866a74cb7db487fa72e59b291e715f22d961607 +size 50787 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 new file mode 100644 index 0000000000..ae64071349 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2c9d431942b442b2620268cec8f06166db18b5df732b7a77cd71a11228106c6 +size 48325 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 new file mode 100644 index 0000000000..051a142e26 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd244116c434d143950d0bb7c291d3a4faf4540f34112286b9069c41eb7de576 +size 27509 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 new file mode 100644 index 0000000000..c0fadc78e5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e98e5bdd03bdd7c2da11595416987398ec4af4ba88010a0eab25f11da149ea7 +size 27520 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 new file mode 100644 index 0000000000..da8873613c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b904f634f9668cc207a922979e0b3abc92c586f3986cf3c57630da8aa2eb22fe +size 23835 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 new file mode 100644 index 0000000000..4e8cabc23c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c95f90eba87b390c09894087d4c55dfe8e7797af712315ccbee3f927be4e5d5 +size 24314 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 new file mode 100644 index 0000000000..5f62ef9369 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29cea35b4105715561f34e4c6fe80a57272444b34b01bd9dd1f0adec67ea8878 +size 30270 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png index 682c57cab8..0e5502a30c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31664f09c84f66bca77ae15dc10ab8a9f57a8f4362ce0a1712fe47668950bb04 -size 7149 +oid sha256:a0635fa0f0ca2b150f598279fee291f25203c6313f8d5fe449e4c1629c96637a +size 8528 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png index 98ff128b67..11f2b08dc7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0707b66e4f8766fddbe25137d6a252c467aaf0c823123209b1b4f087cdc7bcd3 -size 9043 +oid sha256:1f8fe5034ae0b5bb611df443e7c1054f3f5e61e608894b14b79aba287eb6fa47 +size 11643 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png index 98ff128b67..11f2b08dc7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0707b66e4f8766fddbe25137d6a252c467aaf0c823123209b1b4f087cdc7bcd3 -size 9043 +oid sha256:1f8fe5034ae0b5bb611df443e7c1054f3f5e61e608894b14b79aba287eb6fa47 +size 11643 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png index 8e4b2ed25f..bb5b9d07ee 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2fe15594310d1b896d669c3996d13331cc582523f907098cc21cd6cc06c581a8 -size 7195 +oid sha256:66242e5546b6f853a2d78493ece0bca7065c036246cd88d83301887b9edc362e +size 8628 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png index bd70020a2f..27f54811e1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c15b2c09da29467add42a143cdfd4f1b9b83e6f6f1a4cfb5fea423ed8b23eddc -size 9080 +oid sha256:9f3d1e3d3d5212df16af61a9ec5a8904fe71bfff4bbfe5086f08e6a2dbc9e58b +size 11823 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png index bd70020a2f..27f54811e1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c15b2c09da29467add42a143cdfd4f1b9b83e6f6f1a4cfb5fea423ed8b23eddc -size 9080 +oid sha256:9f3d1e3d3d5212df16af61a9ec5a8904fe71bfff4bbfe5086f08e6a2dbc9e58b +size 11823 From d89dd958d71f6284292509b9b0e3d9769c4553ac Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 3 Dec 2025 15:42:19 +0100 Subject: [PATCH 020/347] quality: fix test dependency --- features/roomdetails/impl/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/roomdetails/impl/build.gradle.kts b/features/roomdetails/impl/build.gradle.kts index f6e2d5387d..2765a95a1e 100644 --- a/features/roomdetails/impl/build.gradle.kts +++ b/features/roomdetails/impl/build.gradle.kts @@ -74,7 +74,7 @@ dependencies { testImplementation(projects.features.call.test) testImplementation(projects.features.rolesandpermissions.test) testImplementation(projects.features.securityandprivacy.test) - implementation(projects.features.roomdetailsedit.test) + testImplementation(projects.features.roomdetailsedit.test) testImplementation(projects.features.knockrequests.test) testImplementation(projects.features.messages.test) testImplementation(projects.features.poll.test) From b40a98acd5ccc30f18e10e7dcc7d33f92316eacd Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 3 Dec 2025 17:20:56 +0100 Subject: [PATCH 021/347] change : update wording of SpaceSettings ff Co-authored-by: Benoit Marty --- .../element/android/libraries/featureflag/api/FeatureFlags.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9bacb3c0d6..2cbfb50944 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 @@ -79,7 +79,7 @@ enum class FeatureFlags( SpaceSettings( key = "feature.spaceSettings", title = "Space settings", - description = "Allow managing space settings such details, permissions and privacy.", + description = "Allow managing space settings such as details, permissions and privacy.", defaultValue = { false }, isFinished = false, ), From 147c49e99a5fe1dbc00d537eaa987098f6aa9bd8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 3 Dec 2025 17:45:37 +0100 Subject: [PATCH 022/347] quality: remove useless parenthesis Co-authored-by: Benoit Marty --- .../matrix/api/room/powerlevels/RoomMembersWithRole.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomMembersWithRole.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomMembersWithRole.kt index ff1ec62f0a..4981de3b1a 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomMembersWithRole.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomMembersWithRole.kt @@ -36,7 +36,7 @@ fun BaseRoom.usersWithRole(predicate: (RoomMember.Role) -> Boolean): Flow membersState .activeRoomMembers() - .filter({ predicate(it.role) }) + .filter { predicate(it.role) } .toImmutableList() }.distinctUntilChanged() } From 0405ce925443d732b1f69368e5ce8b2a75d072fa Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 17:55:40 +0100 Subject: [PATCH 023/347] Remove unused import. --- .../designsystem/components/ExpandableBottomSheetLayoutState.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayoutState.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayoutState.kt index ad6828aed3..ae9f9e4cf2 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayoutState.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ExpandableBottomSheetLayoutState.kt @@ -11,7 +11,6 @@ package io.element.android.libraries.designsystem.components import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue From eeef1b11ea655ce30d84d595487b120554549f28 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 14:35:52 +0100 Subject: [PATCH 024/347] Iterate on Save change dialog. --- .../features/poll/impl/create/CreatePollView.kt | 5 +++-- .../impl/user/editprofile/EditUserProfileView.kt | 5 +++-- .../impl/permissions/ChangeRoomPermissionsView.kt | 13 +++++-------- .../impl/roles/ChangeRolesView.kt | 5 +++-- .../impl/roles/ChangeRolesViewTest.kt | 10 +++++----- .../roomdetailsedit/impl/RoomDetailsEditView.kt | 3 ++- .../impl/root/SecurityAndPrivacyView.kt | 3 ++- .../components/dialogs/SaveChangesDialog.kt | 15 +++++++++++---- .../push/impl/src/main/res/values/localazy.xml | 1 + .../ui-strings/src/main/res/values/localazy.xml | 1 + 10 files changed, 36 insertions(+), 25 deletions(-) diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt index 53caf33707..3220aa1c5c 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt @@ -66,8 +66,9 @@ fun CreatePollView( BackHandler(onBack = navBack) if (state.showBackConfirmation) { SaveChangesDialog( - onSubmitClick = { state.eventSink(CreatePollEvents.NavBack) }, - onDismiss = { state.eventSink(CreatePollEvents.HideConfirmation) } + onSaveClick = { state.eventSink(CreatePollEvents.Save) }, + onDiscardClick = { state.eventSink(CreatePollEvents.NavBack) }, + onDismiss = { state.eventSink(CreatePollEvents.HideConfirmation) }, ) } if (state.showDeleteConfirmation) { 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 d6f0fcbd2c..4325aa1eb6 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 @@ -147,8 +147,9 @@ fun EditUserProfileView( when (confirming) { is AsyncAction.ConfirmingCancellation -> { SaveChangesDialog( - onSubmitClick = { state.eventSink(EditUserProfileEvents.Exit) }, - onDismiss = { state.eventSink(EditUserProfileEvents.CloseDialog) } + onSaveClick = { state.eventSink(EditUserProfileEvents.Save) }, + onDiscardClick = { state.eventSink(EditUserProfileEvents.Exit) }, + onDismiss = { state.eventSink(EditUserProfileEvents.CloseDialog) }, ) } } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt index 1e88d091c8..a1a19cdcc9 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.features.rolesandpermissions.impl.R import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.button.BackButton -import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog +import io.element.android.libraries.designsystem.components.dialogs.SaveChangesDialog import io.element.android.libraries.designsystem.components.preferences.PreferenceDropdown import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -99,13 +99,10 @@ fun ChangeRoomPermissionsView( async = state.confirmExitAction, onSuccess = { onComplete(false) }, confirmationDialog = { - ConfirmationDialog( - title = stringResource(R.string.screen_room_change_role_unsaved_changes_title), - content = stringResource(R.string.screen_room_change_role_unsaved_changes_description), - submitText = stringResource(CommonStrings.action_save), - cancelText = stringResource(CommonStrings.action_discard), - onSubmitClick = { state.eventSink(ChangeRoomPermissionsEvent.Save) }, - onDismiss = { state.eventSink(ChangeRoomPermissionsEvent.Exit) } + SaveChangesDialog( + onSaveClick = { state.eventSink(ChangeRoomPermissionsEvent.Save) }, + onDiscardClick = { state.eventSink(ChangeRoomPermissionsEvent.Exit) }, + onDismiss = { state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions) }, ) }, onErrorDismiss = {}, diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt index bab24d3f42..20abc70bb7 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt @@ -172,8 +172,9 @@ fun ChangeRolesView( when (confirming) { is AsyncAction.ConfirmingCancellation -> { SaveChangesDialog( - onSubmitClick = { state.eventSink(ChangeRolesEvent.Exit) }, - onDismiss = { state.eventSink(ChangeRolesEvent.CloseDialog) } + onSaveClick = { state.eventSink(ChangeRolesEvent.Save) }, + onDiscardClick = { state.eventSink(ChangeRolesEvent.Exit) }, + onDismiss = { state.eventSink(ChangeRolesEvent.CloseDialog) }, ) } is ConfirmingModifyingOwners -> { diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesViewTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesViewTest.kt index fd45e5408c..39967f9160 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesViewTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesViewTest.kt @@ -119,7 +119,7 @@ class ChangeRolesViewTest { } @Test - fun `exit confirmation dialog - submit exits the screen`() { + fun `exit confirmation dialog - discard exits the screen`() { val eventsRecorder = EventsRecorder() rule.setChangeRolesContent( state = aChangeRolesState( @@ -128,12 +128,12 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_ok) + rule.clickOn(CommonStrings.action_discard) eventsRecorder.assertSingle(ChangeRolesEvent.Exit) } @Test - fun `exit confirmation dialog - cancel removes the dialog`() { + fun `exit confirmation dialog - save emits the save event`() { val eventsRecorder = EventsRecorder() rule.setChangeRolesContent( state = aChangeRolesState( @@ -142,8 +142,8 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_cancel) - eventsRecorder.assertSingle(ChangeRolesEvent.CloseDialog) + rule.clickOn(CommonStrings.action_save) + eventsRecorder.assertSingle(ChangeRolesEvent.Save) } @Test 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 55a6d038dd..04a03fbcfe 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 @@ -159,7 +159,8 @@ fun RoomDetailsEditView( confirmationDialog = { if (state.saveAction == AsyncAction.ConfirmingCancellation) { SaveChangesDialog( - onSubmitClick = { state.eventSink(RoomDetailsEditEvents.OnBackPress) }, + onSaveClick = { state.eventSink(RoomDetailsEditEvents.Save) }, + onDiscardClick = { state.eventSink(RoomDetailsEditEvents.OnBackPress) }, onDismiss = { state.eventSink(RoomDetailsEditEvents.CloseDialog) } ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index ad75580031..019eac665c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -144,7 +144,8 @@ fun SecurityAndPrivacyView( onErrorDismiss = { }, confirmationDialog = { SaveChangesDialog( - onSubmitClick = { state.eventSink(SecurityAndPrivacyEvents.Exit) }, + onSaveClick = { state.eventSink(SecurityAndPrivacyEvents.Save) }, + onDiscardClick = { state.eventSink(SecurityAndPrivacyEvents.Exit) }, onDismiss = { state.eventSink(SecurityAndPrivacyEvents.DismissExitConfirmation) } ) }, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/SaveChangesDialog.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/SaveChangesDialog.kt index b722480bb1..dc30b191a0 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/SaveChangesDialog.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/SaveChangesDialog.kt @@ -17,16 +17,22 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable fun SaveChangesDialog( - onSubmitClick: () -> Unit, + onSaveClick: () -> Unit, + onDiscardClick: () -> Unit, onDismiss: () -> Unit, modifier: Modifier = Modifier, title: String = stringResource(CommonStrings.dialog_unsaved_changes_title), - content: String = stringResource(CommonStrings.dialog_unsaved_changes_description_android), + content: String = stringResource(CommonStrings.dialog_unsaved_changes_description), + submitText: String = stringResource(CommonStrings.action_save), + cancelText: String = stringResource(CommonStrings.action_discard), ) = ConfirmationDialog( modifier = modifier, title = title, content = content, - onSubmitClick = onSubmitClick, + submitText = submitText, + cancelText = cancelText, + onSubmitClick = onSaveClick, + onCancelClick = onDiscardClick, onDismiss = onDismiss, ) @@ -34,7 +40,8 @@ fun SaveChangesDialog( @Composable internal fun SaveChangesDialogPreview() = ElementPreview { SaveChangesDialog( - onSubmitClick = {}, + onSaveClick = {}, + onDiscardClick = {}, onDismiss = {} ) } diff --git a/libraries/push/impl/src/main/res/values/localazy.xml b/libraries/push/impl/src/main/res/values/localazy.xml index 0764851647..935c3e600c 100644 --- a/libraries/push/impl/src/main/res/values/localazy.xml +++ b/libraries/push/impl/src/main/res/values/localazy.xml @@ -38,6 +38,7 @@ "%1$s invited you to join the room" "Me" "%1$s mentioned or replied" + "Invited you to join the space" "You are viewing the notification! Click me!" "Thread in %1$s" "%1$s: %2$s" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 8be01eb439..d422a4c35c 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -392,6 +392,7 @@ Are you sure you want to continue?" "Error" "Success" "Warning" + "You have unsaved changes." "Your changes have not been saved. Are you sure you want to go back?" "Save changes?" "The max file size allowed is: %1$s" From 278231f3d2c513e951b84f03c2b919d4a5165332 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 14:46:58 +0100 Subject: [PATCH 025/347] Remove confirmExitAction and use AsyncAction.ConfirmingCancellation instead. --- .../ChangeRoomPermissionsPresenter.kt | 13 ++++----- .../permissions/ChangeRoomPermissionsState.kt | 3 +-- .../ChangeRoomPermissionsStateProvider.kt | 6 ++--- .../permissions/ChangeRoomPermissionsView.kt | 27 +++++++++---------- .../ChangeRoomPermissionsPresenterTest.kt | 9 +++---- .../ChangeRoomPermissionsViewTest.kt | 22 ++++++++++++--- 6 files changed, 43 insertions(+), 37 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt index b356ca33d2..99f5723bf9 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt @@ -73,8 +73,7 @@ class ChangeRoomPermissionsPresenter( private var initialPermissions by mutableStateOf(null) private var currentPermissions by mutableStateOf(null) - private var saveAction by mutableStateOf>(AsyncAction.Uninitialized) - private var confirmExitAction by mutableStateOf>(AsyncAction.Uninitialized) + private var saveAction by mutableStateOf>(AsyncAction.Uninitialized) @Composable override fun present(): ChangeRoomPermissionsState { @@ -109,15 +108,14 @@ class ChangeRoomPermissionsPresenter( } is ChangeRoomPermissionsEvent.Save -> coroutineScope.save() is ChangeRoomPermissionsEvent.Exit -> { - confirmExitAction = if (!hasChanges || confirmExitAction.isConfirming()) { - AsyncAction.Success(Unit) + saveAction = if (!hasChanges || saveAction == AsyncAction.ConfirmingCancellation) { + AsyncAction.Success(false) } else { - AsyncAction.ConfirmingNoParams + AsyncAction.ConfirmingCancellation } } is ChangeRoomPermissionsEvent.ResetPendingActions -> { saveAction = AsyncAction.Uninitialized - confirmExitAction = AsyncAction.Uninitialized } } } @@ -126,7 +124,6 @@ class ChangeRoomPermissionsPresenter( itemsBySection = itemsBySection, hasChanges = hasChanges, saveAction = saveAction, - confirmExitAction = confirmExitAction, eventSink = ::handleEvent, ) } @@ -147,7 +144,7 @@ class ChangeRoomPermissionsPresenter( .onSuccess { analyticsService.trackPermissionChangeAnalytics(initialPermissions, updatedRoomPowerLevels) initialPermissions = currentPermissions - saveAction = AsyncAction.Success(Unit) + saveAction = AsyncAction.Success(true) } .onFailure { saveAction = AsyncAction.Failure(it) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt index 2dc2c816d6..0dde54db89 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt @@ -23,8 +23,7 @@ data class ChangeRoomPermissionsState( val currentPermissions: RoomPowerLevelsValues?, val itemsBySection: ImmutableMap>, val hasChanges: Boolean, - val saveAction: AsyncAction, - val confirmExitAction: AsyncAction, + val saveAction: AsyncAction, val eventSink: (ChangeRoomPermissionsEvent) -> Unit, ) { fun selectedRoleForType(type: RoomPermissionType): SelectableRole? { diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt index d64c85f8cf..6280e4fd8f 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt @@ -25,7 +25,7 @@ class ChangeRoomPermissionsStateProvider : PreviewParameterProvider> = ChangeRoomPermissionsPresenter.buildItems(false), hasChanges: Boolean = false, - saveAction: AsyncAction = AsyncAction.Uninitialized, - confirmExitAction: AsyncAction = AsyncAction.Uninitialized, + saveAction: AsyncAction = AsyncAction.Uninitialized, eventSink: (ChangeRoomPermissionsEvent) -> Unit = {}, ) = ChangeRoomPermissionsState( currentPermissions = currentPermissions, itemsBySection = itemsBySection.toImmutableMap(), hasChanges = hasChanges, saveAction = saveAction, - confirmExitAction = confirmExitAction, eventSink = eventSink, ) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt index a1a19cdcc9..5ae8203eb4 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.features.rolesandpermissions.impl.R +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.dialogs.SaveChangesDialog @@ -91,21 +92,19 @@ fun ChangeRoomPermissionsView( AsyncActionView( async = state.saveAction, - onSuccess = { onComplete(true) }, - onErrorDismiss = { state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions) } - ) - - AsyncActionView( - async = state.confirmExitAction, - onSuccess = { onComplete(false) }, - confirmationDialog = { - SaveChangesDialog( - onSaveClick = { state.eventSink(ChangeRoomPermissionsEvent.Save) }, - onDiscardClick = { state.eventSink(ChangeRoomPermissionsEvent.Exit) }, - onDismiss = { state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions) }, - ) + onSuccess = { onComplete(it) }, + confirmationDialog = { confirming -> + when (confirming) { + is AsyncAction.ConfirmingCancellation -> { + SaveChangesDialog( + onSaveClick = { state.eventSink(ChangeRoomPermissionsEvent.Save) }, + onDiscardClick = { state.eventSink(ChangeRoomPermissionsEvent.Exit) }, + onDismiss = { state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions) }, + ) + } + } }, - onErrorDismiss = {}, + onErrorDismiss = { state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions) } ) } diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt index 7c328c9bad..d666ec3ccc 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt @@ -39,7 +39,6 @@ class ChangeRoomPermissionsPresenterTest { assertThat(this.itemsBySection).isNotEmpty() assertThat(this.hasChanges).isFalse() assertThat(this.saveAction).isEqualTo(AsyncAction.Uninitialized) - assertThat(this.confirmExitAction).isEqualTo(AsyncAction.Uninitialized) } // Updated state, permissions loaded @@ -162,7 +161,7 @@ class ChangeRoomPermissionsPresenterTest { assertThat(awaitItem().hasChanges).isFalse() awaitItem().run { assertThat(currentPermissions?.roomName).isEqualTo(Moderator.powerLevel) - assertThat(saveAction).isEqualTo(AsyncAction.Success(Unit)) + assertThat(saveAction).isEqualTo(AsyncAction.Success(true)) } assertThat(analyticsService.capturedEvents).containsExactlyElementsIn( listOf( @@ -243,10 +242,10 @@ class ChangeRoomPermissionsPresenterTest { assertThat(awaitItem().hasChanges).isTrue() state.eventSink(ChangeRoomPermissionsEvent.Exit) - assertThat(awaitItem().confirmExitAction).isEqualTo(AsyncAction.ConfirmingNoParams) + assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.ConfirmingCancellation) state.eventSink(ChangeRoomPermissionsEvent.Exit) - assertThat(awaitItem().confirmExitAction).isEqualTo(AsyncAction.Success(Unit)) + assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.Success(false)) } } @@ -260,7 +259,7 @@ class ChangeRoomPermissionsPresenterTest { state.eventSink(ChangeRoomPermissionsEvent.Exit) - assertThat(awaitItem().confirmExitAction).isEqualTo(AsyncAction.Success(Unit)) + assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.Success(false)) } } diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt index 915359cfcf..065fe5992d 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt @@ -76,7 +76,7 @@ class ChangeRoomPermissionsViewTest { rule.setChangeRoomPermissionsRule( state = aChangeRoomPermissionsState( hasChanges = true, - confirmExitAction = AsyncAction.ConfirmingNoParams, + saveAction = AsyncAction.ConfirmingCancellation, eventSink = recorder, ), ) @@ -90,7 +90,7 @@ class ChangeRoomPermissionsViewTest { rule.setChangeRoomPermissionsRule( state = aChangeRoomPermissionsState( hasChanges = true, - confirmExitAction = AsyncAction.ConfirmingNoParams, + saveAction = AsyncAction.ConfirmingCancellation, eventSink = recorder, ), ) @@ -136,9 +136,23 @@ class ChangeRoomPermissionsViewTest { rule.setChangeRoomPermissionsRule( state = aChangeRoomPermissionsState( hasChanges = true, - saveAction = AsyncAction.Success(Unit), + saveAction = AsyncAction.Success(true), ), - onComplete = callback + onComplete = callback, + ) + rule.clickOn(CommonStrings.action_save) + } + } + + @Test + fun `a cancellation exits the screen`() { + ensureCalledOnceWithParam(false) { callback -> + rule.setChangeRoomPermissionsRule( + state = aChangeRoomPermissionsState( + hasChanges = true, + saveAction = AsyncAction.Success(false), + ), + onComplete = callback, ) rule.clickOn(CommonStrings.action_save) } From eec632661f340613991f1108f99457fa359f7f7b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 15:45:33 +0100 Subject: [PATCH 026/347] Remove confirmExitAction and use AsyncAction.ConfirmingCancellation instead. --- .../roomdetails/impl/RoomDetailsFlowNode.kt | 11 +++++++- .../api/SecurityAndPrivacyEntryPoint.kt | 17 +++++++++++-- .../DefaultSecurityAndPrivacyEntryPoint.kt | 8 ++++-- .../impl/SecurityAndPrivacyFlowNode.kt | 5 +++- .../impl/SecurityAndPrivacyNavigator.kt | 7 ++++++ .../impl/root/SecurityAndPrivacyNode.kt | 1 - .../impl/root/SecurityAndPrivacyPresenter.kt | 14 +++++++---- .../impl/root/SecurityAndPrivacyState.kt | 1 - .../root/SecurityAndPrivacyStateProvider.kt | 4 +-- .../impl/root/SecurityAndPrivacyView.kt | 25 ++++++++----------- .../impl/FakeSecurityAndPrivacyNavigator.kt | 5 ++++ .../impl/SecurityAndPrivacyPresenterTest.kt | 12 +++++++-- .../impl/SecurityAndPrivacyViewTest.kt | 17 ++++++------- .../test/FakeSecurityAndPrivacyEntryPoint.kt | 6 ++++- ...nticsNodeInteractionsProviderExtensions.kt | 14 +++++++++-- 15 files changed, 102 insertions(+), 45 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index 9071425a72..9ea060ef6c 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -383,7 +383,16 @@ class RoomDetailsFlowNode( knockRequestsListEntryPoint.createNode(this, buildContext) } NavTarget.SecurityAndPrivacy -> { - securityAndPrivacyEntryPoint.createNode(this, buildContext) + val callback = object : SecurityAndPrivacyEntryPoint.Callback { + override fun onDone() { + backstack.pop() + } + } + securityAndPrivacyEntryPoint.createNode( + parentNode = this, + buildContext = buildContext, + callback = callback, + ) } is NavTarget.VerifyUser -> { val params = OutgoingVerificationEntryPoint.Params( diff --git a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyEntryPoint.kt b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyEntryPoint.kt index 2c7c1cfd41..be2a4dc9e2 100644 --- a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyEntryPoint.kt +++ b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyEntryPoint.kt @@ -8,6 +8,19 @@ package io.element.android.features.securityandprivacy.api -import io.element.android.libraries.architecture.SimpleFeatureEntryPoint +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import io.element.android.libraries.architecture.FeatureEntryPoint -fun interface SecurityAndPrivacyEntryPoint : SimpleFeatureEntryPoint +fun interface SecurityAndPrivacyEntryPoint : FeatureEntryPoint { + interface Callback : Plugin { + fun onDone() + } + + fun createNode( + parentNode: Node, + buildContext: BuildContext, + callback: Callback, + ): Node +} diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/DefaultSecurityAndPrivacyEntryPoint.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/DefaultSecurityAndPrivacyEntryPoint.kt index 2d01ed4a83..d2a40c6836 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/DefaultSecurityAndPrivacyEntryPoint.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/DefaultSecurityAndPrivacyEntryPoint.kt @@ -17,7 +17,11 @@ import io.element.android.libraries.di.RoomScope @ContributesBinding(RoomScope::class) class DefaultSecurityAndPrivacyEntryPoint : SecurityAndPrivacyEntryPoint { - override fun createNode(parentNode: Node, buildContext: BuildContext): Node { - return parentNode.createNode(buildContext) + override fun createNode( + parentNode: Node, + buildContext: BuildContext, + callback: SecurityAndPrivacyEntryPoint.Callback, + ): Node { + return parentNode.createNode(buildContext, listOf(callback)) } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index 5dbc8dbb45..13c5b454a2 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -18,10 +18,12 @@ import com.bumble.appyx.navmodel.backstack.BackStack import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint import io.element.android.features.securityandprivacy.impl.editroomaddress.EditRoomAddressNode import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyNode import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode +import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.RoomScope import kotlinx.parcelize.Parcelize @@ -47,7 +49,8 @@ class SecurityAndPrivacyFlowNode( data object EditRoomAddress : NavTarget } - private val navigator = BackstackSecurityAndPrivacyNavigator(backstack) + private val callback: SecurityAndPrivacyEntryPoint.Callback = callback() + private val navigator = BackstackSecurityAndPrivacyNavigator(callback, backstack) override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { return when (navTarget) { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt index 3b71868bbf..092da87943 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt @@ -12,15 +12,22 @@ import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.operation.pop import com.bumble.appyx.navmodel.backstack.operation.push +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint interface SecurityAndPrivacyNavigator : Plugin { + fun onDone() fun openEditRoomAddress() fun closeEditRoomAddress() } class BackstackSecurityAndPrivacyNavigator( + private val callback: SecurityAndPrivacyEntryPoint.Callback, private val backStack: BackStack ) : SecurityAndPrivacyNavigator { + override fun onDone() { + callback.onDone() + } + override fun openEditRoomAddress() { backStack.push(SecurityAndPrivacyFlowNode.NavTarget.EditRoomAddress) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt index 5e329a06f6..e173117431 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt @@ -40,7 +40,6 @@ class SecurityAndPrivacyNode( val state by stateFlow.collectAsState() SecurityAndPrivacyView( state = state, - onBackClick = this::navigateUp, modifier = modifier ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index 43d8383b76..cdd70259c4 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -64,7 +64,6 @@ class SecurityAndPrivacyPresenter( featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock) }.collectAsState(false) val saveAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } - var confirmExitAction by remember { mutableStateOf>(AsyncAction.Uninitialized) } val homeserverName = remember { matrixClient.userIdServerName() } val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val roomInfo by room.roomInfoFlow.collectAsState() @@ -150,18 +149,24 @@ class SecurityAndPrivacyPresenter( saveAction.value = AsyncAction.Uninitialized } SecurityAndPrivacyEvents.Exit -> { - confirmExitAction = if (savedSettings == editedSettings || confirmExitAction.isConfirming()) { + saveAction.value = if (savedSettings == editedSettings || saveAction.value == AsyncAction.ConfirmingCancellation) { AsyncAction.Success(Unit) } else { - AsyncAction.ConfirmingNoParams + AsyncAction.ConfirmingCancellation } } SecurityAndPrivacyEvents.DismissExitConfirmation -> { - confirmExitAction = AsyncAction.Uninitialized + saveAction.value = AsyncAction.Uninitialized } } } + LaunchedEffect(saveAction.value.isSuccess()) { + if (saveAction.value.isSuccess()) { + navigator.onDone() + } + } + val state = SecurityAndPrivacyState( savedSettings = savedSettings, editedSettings = editedSettings, @@ -171,7 +176,6 @@ class SecurityAndPrivacyPresenter( saveAction = saveAction.value, permissions = permissions, isSpace = roomInfo.isSpace, - confirmExitAction = confirmExitAction, eventSink = ::handleEvent, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index 0671bbf163..61e8ffd17c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -22,7 +22,6 @@ data class SecurityAndPrivacyState( val showEnableEncryptionConfirmation: Boolean, val isKnockEnabled: Boolean, val saveAction: AsyncAction, - val confirmExitAction: AsyncAction, val isSpace: Boolean, private val permissions: SecurityAndPrivacyPermissions, val eventSink: (SecurityAndPrivacyEvents) -> Unit diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index 11e5665c1c..db696b18e8 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -27,7 +27,7 @@ open class SecurityAndPrivacyStateProvider : PreviewParameterProvider = AsyncAction.Uninitialized, - confirmExitAction: AsyncAction = AsyncAction.Uninitialized, permissions: SecurityAndPrivacyPermissions = SecurityAndPrivacyPermissions( canChangeRoomAccess = true, canChangeHistoryVisibility = true, @@ -125,7 +124,6 @@ fun aSecurityAndPrivacyState( homeserverName = homeserverName, showEnableEncryptionConfirmation = showEncryptionConfirmation, saveAction = saveAction, - confirmExitAction = confirmExitAction, isKnockEnabled = isKnockEnabled, permissions = permissions, isSpace = isSpace, diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 019eac665c..d526f381be 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -32,6 +32,7 @@ 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.securityandprivacy.impl.R +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage import io.element.android.libraries.designsystem.components.async.AsyncActionView @@ -56,7 +57,6 @@ import kotlinx.collections.immutable.ImmutableSet @Composable fun SecurityAndPrivacyView( state: SecurityAndPrivacyState, - onBackClick: () -> Unit, modifier: Modifier = Modifier, ) { BackHandler { @@ -130,6 +130,16 @@ fun SecurityAndPrivacyView( async = state.saveAction, onSuccess = { }, onErrorDismiss = { state.eventSink(SecurityAndPrivacyEvents.DismissSaveError) }, + confirmationDialog = { confirming -> + when (confirming) { + is AsyncAction.ConfirmingCancellation -> + SaveChangesDialog( + onSaveClick = { state.eventSink(SecurityAndPrivacyEvents.Save) }, + onDiscardClick = { state.eventSink(SecurityAndPrivacyEvents.Exit) }, + onDismiss = { state.eventSink(SecurityAndPrivacyEvents.DismissExitConfirmation) } + ) + } + }, errorMessage = { stringResource(CommonStrings.error_unknown) }, progressDialog = { AsyncActionViewDefaults.ProgressDialog( @@ -138,18 +148,6 @@ fun SecurityAndPrivacyView( }, onRetry = { state.eventSink(SecurityAndPrivacyEvents.Save) }, ) - AsyncActionView( - async = state.confirmExitAction, - onSuccess = { onBackClick() }, - onErrorDismiss = { }, - confirmationDialog = { - SaveChangesDialog( - onSaveClick = { state.eventSink(SecurityAndPrivacyEvents.Save) }, - onDiscardClick = { state.eventSink(SecurityAndPrivacyEvents.Exit) }, - onDismiss = { state.eventSink(SecurityAndPrivacyEvents.DismissExitConfirmation) } - ) - }, - ) } @OptIn(ExperimentalMaterial3Api::class) @@ -426,6 +424,5 @@ internal fun SecurityAndPrivacyViewDarkPreview(@PreviewParameter(SecurityAndPriv private fun ContentToPreview(state: SecurityAndPrivacyState) { SecurityAndPrivacyView( state = state, - onBackClick = {}, ) } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt index 9ca3cc5288..f90040d3fb 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt @@ -11,9 +11,14 @@ package io.element.android.features.securityandprivacy.impl import io.element.android.tests.testutils.lambda.lambdaError class FakeSecurityAndPrivacyNavigator( + private val onDoneLambda: () -> Unit = { lambdaError() }, private val openEditRoomAddressLambda: () -> Unit = { lambdaError() }, private val closeEditRoomAddressLambda: () -> Unit = { lambdaError() }, ) : SecurityAndPrivacyNavigator { + override fun onDone() { + onDoneLambda() + } + override fun openEditRoomAddress() { openEditRoomAddressLambda() } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index bdae5274f0..203447c911 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -203,7 +203,7 @@ class SecurityAndPrivacyPresenterTest { @Test fun `present - edit room address`() = runTest { val openEditRoomAddressLambda = lambdaRecorder { } - val navigator = FakeSecurityAndPrivacyNavigator(openEditRoomAddressLambda) + val navigator = FakeSecurityAndPrivacyNavigator(openEditRoomAddressLambda = openEditRoomAddressLambda) val presenter = createSecurityAndPrivacyPresenter(navigator = navigator) presenter.test { skipItems(1) @@ -231,7 +231,14 @@ class SecurityAndPrivacyPresenterTest { updateRoomVisibilityResult = updateRoomVisibilityLambda, updateRoomHistoryVisibilityResult = updateRoomHistoryVisibilityLambda, ) - val presenter = createSecurityAndPrivacyPresenter(room = room) + val onDoneLambda = lambdaRecorder { } + val navigator = FakeSecurityAndPrivacyNavigator( + onDoneLambda = onDoneLambda, + ) + val presenter = createSecurityAndPrivacyPresenter( + room = room, + navigator = navigator, + ) presenter.test { skipItems(2) with(awaitItem()) { @@ -276,6 +283,7 @@ class SecurityAndPrivacyPresenterTest { assert(updateJoinRuleLambda).isCalledOnce() assert(updateRoomVisibilityLambda).isCalledOnce() assert(updateRoomHistoryVisibilityLambda).isCalledOnce() + onDoneLambda.assertions().isCalledOnce() } } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt index 78b840d823..d1096c19af 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt @@ -24,7 +24,6 @@ import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPriv import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData 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.pressBack @@ -50,27 +49,27 @@ class SecurityAndPrivacyViewTest { } @Test - fun `confirm cancellation emits the expected event`() { + fun `discard cancellation emits the expected event`() { val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( - confirmExitAction = AsyncAction.ConfirmingCancellation, + saveAction = AsyncAction.ConfirmingCancellation, eventSink = recorder, ) rule.setSecurityAndPrivacyView(state) - rule.clickOn(CommonStrings.action_ok) + rule.clickOn(CommonStrings.action_discard) recorder.assertSingle(SecurityAndPrivacyEvents.Exit) } @Test - fun `dismiss cancellation confirmation emits the expected event`() { + fun `save cancellation confirmation emits the expected event`() { val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( - confirmExitAction = AsyncAction.ConfirmingCancellation, + saveAction = AsyncAction.ConfirmingCancellation, eventSink = recorder, ) rule.setSecurityAndPrivacyView(state) - rule.clickOn(CommonStrings.action_cancel) - recorder.assertSingle(SecurityAndPrivacyEvents.DismissExitConfirmation) + rule.clickOn(CommonStrings.action_save, inDialog = true) + recorder.assertSingle(SecurityAndPrivacyEvents.Save) } @Test @@ -185,12 +184,10 @@ private fun AndroidComposeTestRule.setSecur state: SecurityAndPrivacyState = aSecurityAndPrivacyState( eventSink = EventsRecorder(expectEvents = false), ), - onBackClick: () -> Unit = EnsureNeverCalled(), ) { setContent { SecurityAndPrivacyView( state = state, - onBackClick = onBackClick, ) } } diff --git a/features/securityandprivacy/test/src/main/kotlin/io/element/android/features/securityandprivacy/test/FakeSecurityAndPrivacyEntryPoint.kt b/features/securityandprivacy/test/src/main/kotlin/io/element/android/features/securityandprivacy/test/FakeSecurityAndPrivacyEntryPoint.kt index f316b2fe96..a66fe55bff 100644 --- a/features/securityandprivacy/test/src/main/kotlin/io/element/android/features/securityandprivacy/test/FakeSecurityAndPrivacyEntryPoint.kt +++ b/features/securityandprivacy/test/src/main/kotlin/io/element/android/features/securityandprivacy/test/FakeSecurityAndPrivacyEntryPoint.kt @@ -13,7 +13,11 @@ import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntr import io.element.android.tests.testutils.lambda.lambdaError class FakeSecurityAndPrivacyEntryPoint : SecurityAndPrivacyEntryPoint { - override fun createNode(parentNode: Node, buildContext: BuildContext): Node { + override fun createNode( + parentNode: Node, + buildContext: BuildContext, + callback: SecurityAndPrivacyEntryPoint.Callback, + ): Node { lambdaError() } } diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/SemanticsNodeInteractionsProviderExtensions.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/SemanticsNodeInteractionsProviderExtensions.kt index f81b03b10b..982320aed7 100644 --- a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/SemanticsNodeInteractionsProviderExtensions.kt +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/SemanticsNodeInteractionsProviderExtensions.kt @@ -10,11 +10,14 @@ package io.element.android.tests.testutils import androidx.activity.ComponentActivity import androidx.annotation.StringRes +import androidx.compose.ui.test.SemanticsMatcher import androidx.compose.ui.test.SemanticsNodeInteractionsProvider +import androidx.compose.ui.test.hasAnyAncestor import androidx.compose.ui.test.hasClickAction import androidx.compose.ui.test.hasContentDescription import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.hasText +import androidx.compose.ui.test.isDialog import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.onFirst import androidx.compose.ui.test.onNodeWithText @@ -22,9 +25,16 @@ import androidx.compose.ui.test.performClick import io.element.android.libraries.ui.strings.CommonStrings import org.junit.rules.TestRule -fun AndroidComposeTestRule.clickOn(@StringRes res: Int) { +val trueMatcher = SemanticsMatcher("true matcher") { true } + +fun AndroidComposeTestRule.clickOn( + @StringRes res: Int, + inDialog: Boolean = false, +) { val text = activity.getString(res) - onNode(hasText(text) and hasClickAction()) + onNode( + hasText(text) and hasClickAction() and if (inDialog) hasAnyAncestor(isDialog()) else trueMatcher + ) .performClick() } From a2c92db3605ea31940b114f24467c1485b49d3a9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 16:12:26 +0100 Subject: [PATCH 027/347] Improve test. --- .../impl/permissions/ChangeRoomPermissionsViewTest.kt | 3 +-- .../SemanticsNodeInteractionsProviderExtensions.kt | 11 ----------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt index 065fe5992d..6b637efbed 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt @@ -18,7 +18,6 @@ import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalledWithParam import io.element.android.tests.testutils.EventsRecorder import io.element.android.tests.testutils.clickOn -import io.element.android.tests.testutils.clickOnFirst import io.element.android.tests.testutils.ensureCalledOnceWithParam import io.element.android.tests.testutils.pressBack import io.element.android.tests.testutils.pressBackKey @@ -94,7 +93,7 @@ class ChangeRoomPermissionsViewTest { eventSink = recorder, ), ) - rule.clickOnFirst(CommonStrings.action_save) + rule.clickOn(CommonStrings.action_save, inDialog = true) recorder.assertSingle(ChangeRoomPermissionsEvent.Save) } diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/SemanticsNodeInteractionsProviderExtensions.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/SemanticsNodeInteractionsProviderExtensions.kt index 982320aed7..6502882d7d 100644 --- a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/SemanticsNodeInteractionsProviderExtensions.kt +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/SemanticsNodeInteractionsProviderExtensions.kt @@ -19,7 +19,6 @@ import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.hasText import androidx.compose.ui.test.isDialog import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.compose.ui.test.onFirst import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import io.element.android.libraries.ui.strings.CommonStrings @@ -38,16 +37,6 @@ fun AndroidComposeTestRule.clickOn( .performClick() } -fun AndroidComposeTestRule.clickOnFirst(@StringRes res: Int) { - val text = activity.getString(res) - onAllNodes(hasText(text) and hasClickAction()).onFirst().performClick() -} - -fun AndroidComposeTestRule.clickOnLast(@StringRes res: Int) { - val text = activity.getString(res) - onAllNodes(hasText(text) and hasClickAction()).onFirst().performClick() -} - /** * Press the back button in the app bar. */ From f9b06902577cc3ae1dfa7e0d508510e5680a0ad7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 16:13:12 +0100 Subject: [PATCH 028/347] SecurityAndPrivacyEvents -> SecurityAndPrivacyEvent --- ...cyEvents.kt => SecurityAndPrivacyEvent.kt} | 24 +++++----- .../impl/root/SecurityAndPrivacyPresenter.kt | 24 +++++----- .../impl/root/SecurityAndPrivacyState.kt | 2 +- .../root/SecurityAndPrivacyStateProvider.kt | 2 +- .../impl/root/SecurityAndPrivacyView.kt | 30 ++++++------ .../impl/SecurityAndPrivacyPresenterTest.kt | 48 +++++++++---------- .../impl/SecurityAndPrivacyViewTest.kt | 44 ++++++++--------- 7 files changed, 87 insertions(+), 87 deletions(-) rename features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/{SecurityAndPrivacyEvents.kt => SecurityAndPrivacyEvent.kt} (55%) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt similarity index 55% rename from features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt index b1d739c45b..39abedab8c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt @@ -8,16 +8,16 @@ package io.element.android.features.securityandprivacy.impl.root -sealed interface SecurityAndPrivacyEvents { - data object EditRoomAddress : SecurityAndPrivacyEvents - data object Save : SecurityAndPrivacyEvents - data object Exit : SecurityAndPrivacyEvents - data object DismissExitConfirmation : SecurityAndPrivacyEvents - data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvents - data object ToggleEncryptionState : SecurityAndPrivacyEvents - data object CancelEnableEncryption : SecurityAndPrivacyEvents - data object ConfirmEnableEncryption : SecurityAndPrivacyEvents - data class ChangeHistoryVisibility(val historyVisibility: SecurityAndPrivacyHistoryVisibility) : SecurityAndPrivacyEvents - data object ToggleRoomVisibility : SecurityAndPrivacyEvents - data object DismissSaveError : SecurityAndPrivacyEvents +sealed interface SecurityAndPrivacyEvent { + data object EditRoomAddress : SecurityAndPrivacyEvent + data object Save : SecurityAndPrivacyEvent + data object Exit : SecurityAndPrivacyEvent + data object DismissExitConfirmation : SecurityAndPrivacyEvent + data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvent + data object ToggleEncryptionState : SecurityAndPrivacyEvent + data object CancelEnableEncryption : SecurityAndPrivacyEvent + data object ConfirmEnableEncryption : SecurityAndPrivacyEvent + data class ChangeHistoryVisibility(val historyVisibility: SecurityAndPrivacyHistoryVisibility) : SecurityAndPrivacyEvent + data object ToggleRoomVisibility : SecurityAndPrivacyEvent + data object DismissSaveError : SecurityAndPrivacyEvent } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index cdd70259c4..b77ad0e7d6 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -108,9 +108,9 @@ class SecurityAndPrivacyPresenter( var showEnableEncryptionConfirmation by remember(savedSettings.isEncrypted) { mutableStateOf(false) } val permissions by room.securityAndPrivacyPermissionsAsState(syncUpdateFlow.value) - fun handleEvent(event: SecurityAndPrivacyEvents) { + fun handleEvent(event: SecurityAndPrivacyEvent) { when (event) { - SecurityAndPrivacyEvents.Save -> { + SecurityAndPrivacyEvent.Save -> { coroutineScope.save( saveAction = saveAction, isVisibleInRoomDirectory = savedIsVisibleInRoomDirectory, @@ -118,44 +118,44 @@ class SecurityAndPrivacyPresenter( editedSettings = editedSettings ) } - is SecurityAndPrivacyEvents.ChangeRoomAccess -> { + is SecurityAndPrivacyEvent.ChangeRoomAccess -> { editedRoomAccess = event.roomAccess } - is SecurityAndPrivacyEvents.ToggleEncryptionState -> { + is SecurityAndPrivacyEvent.ToggleEncryptionState -> { if (editedIsEncrypted) { editedIsEncrypted = false } else { showEnableEncryptionConfirmation = true } } - is SecurityAndPrivacyEvents.ChangeHistoryVisibility -> { + is SecurityAndPrivacyEvent.ChangeHistoryVisibility -> { editedHistoryVisibility = event.historyVisibility } - SecurityAndPrivacyEvents.ToggleRoomVisibility -> { + SecurityAndPrivacyEvent.ToggleRoomVisibility -> { editedVisibleInRoomDirectory = when (val edited = editedVisibleInRoomDirectory) { is AsyncData.Success -> AsyncData.Success(!edited.data) else -> edited } } - SecurityAndPrivacyEvents.EditRoomAddress -> navigator.openEditRoomAddress() - SecurityAndPrivacyEvents.CancelEnableEncryption -> { + SecurityAndPrivacyEvent.EditRoomAddress -> navigator.openEditRoomAddress() + SecurityAndPrivacyEvent.CancelEnableEncryption -> { showEnableEncryptionConfirmation = false } - SecurityAndPrivacyEvents.ConfirmEnableEncryption -> { + SecurityAndPrivacyEvent.ConfirmEnableEncryption -> { showEnableEncryptionConfirmation = false editedIsEncrypted = true } - SecurityAndPrivacyEvents.DismissSaveError -> { + SecurityAndPrivacyEvent.DismissSaveError -> { saveAction.value = AsyncAction.Uninitialized } - SecurityAndPrivacyEvents.Exit -> { + SecurityAndPrivacyEvent.Exit -> { saveAction.value = if (savedSettings == editedSettings || saveAction.value == AsyncAction.ConfirmingCancellation) { AsyncAction.Success(Unit) } else { AsyncAction.ConfirmingCancellation } } - SecurityAndPrivacyEvents.DismissExitConfirmation -> { + SecurityAndPrivacyEvent.DismissExitConfirmation -> { saveAction.value = AsyncAction.Uninitialized } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index 61e8ffd17c..2c6bd59e12 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -24,7 +24,7 @@ data class SecurityAndPrivacyState( val saveAction: AsyncAction, val isSpace: Boolean, private val permissions: SecurityAndPrivacyPermissions, - val eventSink: (SecurityAndPrivacyEvents) -> Unit + val eventSink: (SecurityAndPrivacyEvent) -> Unit ) { val canBeSaved = savedSettings != editedSettings diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index db696b18e8..b5347a753f 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -117,7 +117,7 @@ fun aSecurityAndPrivacyState( ), isKnockEnabled: Boolean = true, isSpace: Boolean = false, - eventSink: (SecurityAndPrivacyEvents) -> Unit = {} + eventSink: (SecurityAndPrivacyEvent) -> Unit = {} ) = SecurityAndPrivacyState( editedSettings = editedSettings, savedSettings = savedSettings, diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index d526f381be..add719153a 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -60,7 +60,7 @@ fun SecurityAndPrivacyView( modifier: Modifier = Modifier, ) { BackHandler { - state.eventSink(SecurityAndPrivacyEvents.Exit) + state.eventSink(SecurityAndPrivacyEvent.Exit) } Scaffold( modifier = modifier, @@ -68,10 +68,10 @@ fun SecurityAndPrivacyView( SecurityAndPrivacyToolbar( isSaveActionEnabled = state.canBeSaved, onBackClick = { - state.eventSink(SecurityAndPrivacyEvents.Exit) + state.eventSink(SecurityAndPrivacyEvent.Exit) }, onSaveClick = { - state.eventSink(SecurityAndPrivacyEvents.Save) + state.eventSink(SecurityAndPrivacyEvent.Save) }, ) } @@ -90,7 +90,7 @@ fun SecurityAndPrivacyView( edited = state.editedSettings.roomAccess, saved = state.savedSettings.roomAccess, isKnockEnabled = state.isKnockEnabled, - onSelectOption = { state.eventSink(SecurityAndPrivacyEvents.ChangeRoomAccess(it)) }, + onSelectOption = { state.eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(it)) }, ) } if (state.showRoomVisibilitySections) { @@ -98,10 +98,10 @@ fun SecurityAndPrivacyView( RoomAddressSection( roomAddress = state.editedSettings.address, homeserverName = state.homeserverName, - onRoomAddressClick = { state.eventSink(SecurityAndPrivacyEvents.EditRoomAddress) }, + onRoomAddressClick = { state.eventSink(SecurityAndPrivacyEvent.EditRoomAddress) }, isVisibleInRoomDirectory = state.editedSettings.isVisibleInRoomDirectory, onVisibilityChange = { - state.eventSink(SecurityAndPrivacyEvents.ToggleRoomVisibility) + state.eventSink(SecurityAndPrivacyEvent.ToggleRoomVisibility) }, ) } @@ -110,10 +110,10 @@ fun SecurityAndPrivacyView( isRoomEncrypted = state.editedSettings.isEncrypted, // encryption can't be disabled once enabled canToggleEncryption = !state.savedSettings.isEncrypted, - onToggleEncryption = { state.eventSink(SecurityAndPrivacyEvents.ToggleEncryptionState) }, + onToggleEncryption = { state.eventSink(SecurityAndPrivacyEvent.ToggleEncryptionState) }, showConfirmation = state.showEnableEncryptionConfirmation, - onDismissConfirmation = { state.eventSink(SecurityAndPrivacyEvents.CancelEnableEncryption) }, - onConfirmEncryption = { state.eventSink(SecurityAndPrivacyEvents.ConfirmEnableEncryption) }, + onDismissConfirmation = { state.eventSink(SecurityAndPrivacyEvent.CancelEnableEncryption) }, + onConfirmEncryption = { state.eventSink(SecurityAndPrivacyEvent.ConfirmEnableEncryption) }, ) } if (state.showHistoryVisibilitySection) { @@ -121,7 +121,7 @@ fun SecurityAndPrivacyView( editedOption = state.editedSettings.historyVisibility, savedOptions = state.savedSettings.historyVisibility, availableOptions = state.availableHistoryVisibilities, - onSelectOption = { state.eventSink(SecurityAndPrivacyEvents.ChangeHistoryVisibility(it)) }, + onSelectOption = { state.eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(it)) }, ) } } @@ -129,14 +129,14 @@ fun SecurityAndPrivacyView( AsyncActionView( async = state.saveAction, onSuccess = { }, - onErrorDismiss = { state.eventSink(SecurityAndPrivacyEvents.DismissSaveError) }, + onErrorDismiss = { state.eventSink(SecurityAndPrivacyEvent.DismissSaveError) }, confirmationDialog = { confirming -> when (confirming) { is AsyncAction.ConfirmingCancellation -> SaveChangesDialog( - onSaveClick = { state.eventSink(SecurityAndPrivacyEvents.Save) }, - onDiscardClick = { state.eventSink(SecurityAndPrivacyEvents.Exit) }, - onDismiss = { state.eventSink(SecurityAndPrivacyEvents.DismissExitConfirmation) } + onSaveClick = { state.eventSink(SecurityAndPrivacyEvent.Save) }, + onDiscardClick = { state.eventSink(SecurityAndPrivacyEvent.Exit) }, + onDismiss = { state.eventSink(SecurityAndPrivacyEvent.DismissExitConfirmation) } ) } }, @@ -146,7 +146,7 @@ fun SecurityAndPrivacyView( progressText = stringResource(CommonStrings.common_saving), ) }, - onRetry = { state.eventSink(SecurityAndPrivacyEvents.Save) }, + onRetry = { state.eventSink(SecurityAndPrivacyEvent.Save) }, ) } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index 203447c911..7d88706996 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -9,7 +9,7 @@ package io.element.android.features.securityandprivacy.impl import com.google.common.truth.Truth.assertThat -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyEvents +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyEvent import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyHistoryVisibility import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyPresenter import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyRoomAccess @@ -96,13 +96,13 @@ class SecurityAndPrivacyPresenterTest { with(awaitItem()) { assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) assertThat(showRoomVisibilitySections).isFalse() - eventSink(SecurityAndPrivacyEvents.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) + eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) } with(awaitItem()) { assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.Anyone) assertThat(showRoomVisibilitySections).isTrue() assertThat(canBeSaved).isTrue() - eventSink(SecurityAndPrivacyEvents.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.InviteOnly)) + eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.InviteOnly)) } with(awaitItem()) { assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) @@ -119,12 +119,12 @@ class SecurityAndPrivacyPresenterTest { skipItems(1) with(awaitItem()) { assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.SinceSelection) - eventSink(SecurityAndPrivacyEvents.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.SinceInvite)) + eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.SinceInvite)) } with(awaitItem()) { assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.SinceInvite) assertThat(canBeSaved).isTrue() - eventSink(SecurityAndPrivacyEvents.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.SinceSelection)) + eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.SinceSelection)) } with(awaitItem()) { assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.SinceSelection) @@ -140,26 +140,26 @@ class SecurityAndPrivacyPresenterTest { skipItems(1) with(awaitItem()) { assertThat(editedSettings.isEncrypted).isFalse() - eventSink(SecurityAndPrivacyEvents.ToggleEncryptionState) + eventSink(SecurityAndPrivacyEvent.ToggleEncryptionState) } with(awaitItem()) { assertThat(showEnableEncryptionConfirmation).isTrue() - eventSink(SecurityAndPrivacyEvents.CancelEnableEncryption) + eventSink(SecurityAndPrivacyEvent.CancelEnableEncryption) } with(awaitItem()) { assertThat(showEnableEncryptionConfirmation).isFalse() - eventSink(SecurityAndPrivacyEvents.ToggleEncryptionState) + eventSink(SecurityAndPrivacyEvent.ToggleEncryptionState) } with(awaitItem()) { assertThat(showEnableEncryptionConfirmation).isTrue() - eventSink(SecurityAndPrivacyEvents.ConfirmEnableEncryption) + eventSink(SecurityAndPrivacyEvent.ConfirmEnableEncryption) } skipItems(1) with(awaitItem()) { assertThat(editedSettings.isEncrypted).isTrue() assertThat(showEnableEncryptionConfirmation).isFalse() assertThat(canBeSaved).isTrue() - eventSink(SecurityAndPrivacyEvents.ToggleEncryptionState) + eventSink(SecurityAndPrivacyEvent.ToggleEncryptionState) } skipItems(1) with(awaitItem()) { @@ -186,12 +186,12 @@ class SecurityAndPrivacyPresenterTest { } with(awaitItem()) { assertThat(editedSettings.isVisibleInRoomDirectory).isEqualTo(AsyncData.Success(false)) - eventSink(SecurityAndPrivacyEvents.ToggleRoomVisibility) + eventSink(SecurityAndPrivacyEvent.ToggleRoomVisibility) } with(awaitItem()) { assertThat(editedSettings.isVisibleInRoomDirectory).isEqualTo(AsyncData.Success(true)) assertThat(canBeSaved).isTrue() - eventSink(SecurityAndPrivacyEvents.ToggleRoomVisibility) + eventSink(SecurityAndPrivacyEvent.ToggleRoomVisibility) } with(awaitItem()) { assertThat(editedSettings.isVisibleInRoomDirectory).isEqualTo(AsyncData.Success(false)) @@ -208,7 +208,7 @@ class SecurityAndPrivacyPresenterTest { presenter.test { skipItems(1) with(awaitItem()) { - eventSink(SecurityAndPrivacyEvents.EditRoomAddress) + eventSink(SecurityAndPrivacyEvent.EditRoomAddress) } assert(openEditRoomAddressLambda).isCalledOnce() } @@ -243,23 +243,23 @@ class SecurityAndPrivacyPresenterTest { skipItems(2) with(awaitItem()) { assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) - eventSink(SecurityAndPrivacyEvents.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) + eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) } with(awaitItem()) { - eventSink(SecurityAndPrivacyEvents.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Anyone)) + eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Anyone)) } with(awaitItem()) { assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Anyone) - eventSink(SecurityAndPrivacyEvents.ConfirmEnableEncryption) + eventSink(SecurityAndPrivacyEvent.ConfirmEnableEncryption) } skipItems(1) with(awaitItem()) { assertThat(editedSettings.isEncrypted).isTrue() - eventSink(SecurityAndPrivacyEvents.ToggleRoomVisibility) + eventSink(SecurityAndPrivacyEvent.ToggleRoomVisibility) } with(awaitItem()) { assertThat(editedSettings.isVisibleInRoomDirectory).isEqualTo(AsyncData.Success(true)) - eventSink(SecurityAndPrivacyEvents.Save) + eventSink(SecurityAndPrivacyEvent.Save) } with(awaitItem()) { assertThat(saveAction).isEqualTo(AsyncAction.Loading) @@ -311,23 +311,23 @@ class SecurityAndPrivacyPresenterTest { skipItems(2) with(awaitItem()) { assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) - eventSink(SecurityAndPrivacyEvents.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) + eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) } with(awaitItem()) { - eventSink(SecurityAndPrivacyEvents.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Anyone)) + eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Anyone)) } with(awaitItem()) { assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Anyone) - eventSink(SecurityAndPrivacyEvents.ConfirmEnableEncryption) + eventSink(SecurityAndPrivacyEvent.ConfirmEnableEncryption) } skipItems(1) with(awaitItem()) { assertThat(editedSettings.isEncrypted).isTrue() - eventSink(SecurityAndPrivacyEvents.ToggleRoomVisibility) + eventSink(SecurityAndPrivacyEvent.ToggleRoomVisibility) } with(awaitItem()) { assertThat(editedSettings.isVisibleInRoomDirectory).isEqualTo(AsyncData.Success(true)) - eventSink(SecurityAndPrivacyEvents.Save) + eventSink(SecurityAndPrivacyEvent.Save) } with(awaitItem()) { assertThat(saveAction).isEqualTo(AsyncAction.Loading) @@ -352,7 +352,7 @@ class SecurityAndPrivacyPresenterTest { assert(updateRoomVisibilityLambda).isCalledOnce() assert(updateRoomHistoryVisibilityLambda).isCalledOnce() // Clear error - state.eventSink(SecurityAndPrivacyEvents.DismissSaveError) + state.eventSink(SecurityAndPrivacyEvent.DismissSaveError) with(awaitItem()) { assertThat(saveAction).isEqualTo(AsyncAction.Uninitialized) } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt index d1096c19af..6b429c04ea 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt @@ -14,7 +14,7 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.test.ext.junit.runners.AndroidJUnit4 -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyEvents +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyEvent import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyHistoryVisibility import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyRoomAccess import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyState @@ -39,53 +39,53 @@ class SecurityAndPrivacyViewTest { @Test fun `click on back invokes emits the expected event`() { - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( eventSink = recorder, ) rule.setSecurityAndPrivacyView(state) rule.pressBack() - recorder.assertSingle(SecurityAndPrivacyEvents.Exit) + recorder.assertSingle(SecurityAndPrivacyEvent.Exit) } @Test fun `discard cancellation emits the expected event`() { - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( saveAction = AsyncAction.ConfirmingCancellation, eventSink = recorder, ) rule.setSecurityAndPrivacyView(state) rule.clickOn(CommonStrings.action_discard) - recorder.assertSingle(SecurityAndPrivacyEvents.Exit) + recorder.assertSingle(SecurityAndPrivacyEvent.Exit) } @Test fun `save cancellation confirmation emits the expected event`() { - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( saveAction = AsyncAction.ConfirmingCancellation, eventSink = recorder, ) rule.setSecurityAndPrivacyView(state) rule.clickOn(CommonStrings.action_save, inDialog = true) - recorder.assertSingle(SecurityAndPrivacyEvents.Save) + recorder.assertSingle(SecurityAndPrivacyEvent.Save) } @Test fun `click on room access item emits the expected event`() { - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( eventSink = recorder, ) rule.setSecurityAndPrivacyView(state) rule.clickOn(R.string.screen_security_and_privacy_room_access_invite_only_option_title) - recorder.assertSingle(SecurityAndPrivacyEvents.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.InviteOnly)) + recorder.assertSingle(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.InviteOnly)) } @Test fun `click on disabled save doesn't emit event`() { - val recorder = EventsRecorder(expectEvents = false) + val recorder = EventsRecorder(expectEvents = false) val state = aSecurityAndPrivacyState(eventSink = recorder) rule.setSecurityAndPrivacyView(state) rule.clickOn(CommonStrings.action_save) @@ -94,7 +94,7 @@ class SecurityAndPrivacyViewTest { @Test fun `click on enabled save emits the expected event`() { - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( eventSink = recorder, editedSettings = aSecurityAndPrivacySettings( @@ -103,14 +103,14 @@ class SecurityAndPrivacyViewTest { ) rule.setSecurityAndPrivacyView(state) rule.clickOn(CommonStrings.action_save) - recorder.assertSingle(SecurityAndPrivacyEvents.Save) + recorder.assertSingle(SecurityAndPrivacyEvent.Save) } @Test @Config(qualifiers = "h640dp") fun `click on room address item emits the expected event`() { val address = "@alias:matrix.org" - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( eventSink = recorder, editedSettings = aSecurityAndPrivacySettings( @@ -120,13 +120,13 @@ class SecurityAndPrivacyViewTest { ) rule.setSecurityAndPrivacyView(state) rule.onNodeWithText(address).performClick() - recorder.assertSingle(SecurityAndPrivacyEvents.EditRoomAddress) + recorder.assertSingle(SecurityAndPrivacyEvent.EditRoomAddress) } @Test @Config(qualifiers = "h1024dp") fun `click on room visibility item emits the expected event`() { - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( eventSink = recorder, editedSettings = aSecurityAndPrivacySettings( @@ -136,13 +136,13 @@ class SecurityAndPrivacyViewTest { ) rule.setSecurityAndPrivacyView(state) rule.clickOn(R.string.screen_security_and_privacy_room_directory_visibility_toggle_title) - recorder.assertSingle(SecurityAndPrivacyEvents.ToggleRoomVisibility) + recorder.assertSingle(SecurityAndPrivacyEvent.ToggleRoomVisibility) } @Test @Config(qualifiers = "h640dp") fun `click on history visibility item emits the expected event`() { - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( eventSink = recorder, editedSettings = aSecurityAndPrivacySettings( @@ -151,32 +151,32 @@ class SecurityAndPrivacyViewTest { ) rule.setSecurityAndPrivacyView(state) rule.clickOn(R.string.screen_security_and_privacy_room_history_since_selecting_option_title) - recorder.assertSingle(SecurityAndPrivacyEvents.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.SinceSelection)) + recorder.assertSingle(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.SinceSelection)) } @Test @Config(qualifiers = "h640dp") fun `click on encryption item emits the expected event`() { - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( eventSink = recorder, savedSettings = aSecurityAndPrivacySettings(isEncrypted = false), ) rule.setSecurityAndPrivacyView(state) rule.clickOn(R.string.screen_security_and_privacy_encryption_toggle_title) - recorder.assertSingle(SecurityAndPrivacyEvents.ToggleEncryptionState) + recorder.assertSingle(SecurityAndPrivacyEvent.ToggleEncryptionState) } @Test fun `click on encryption confirm emits the expected event`() { - val recorder = EventsRecorder() + val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( eventSink = recorder, showEncryptionConfirmation = true, ) rule.setSecurityAndPrivacyView(state) rule.clickOn(R.string.screen_security_and_privacy_enable_encryption_alert_confirm_button_title) - recorder.assertSingle(SecurityAndPrivacyEvents.ConfirmEnableEncryption) + recorder.assertSingle(SecurityAndPrivacyEvent.ConfirmEnableEncryption) } } From f913b5963e51a226de2668053f026170df326e52 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 17:03:51 +0100 Subject: [PATCH 029/347] Fix test --- .../impl/user/editprofile/EditUserProfileViewTest.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt index f4c7144350..6ee2604293 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt @@ -45,7 +45,7 @@ class EditUserProfileViewTest { } @Test - fun `clicking on cancel exit emits the expected event`() { + fun `clicking on save from the exit confirmation dialog emits the expected event`() { val eventsRecorder = EventsRecorder() rule.setEditUserProfileView( aEditUserProfileState( @@ -53,12 +53,12 @@ class EditUserProfileViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_cancel) - eventsRecorder.assertSingle(EditUserProfileEvents.CloseDialog) + rule.clickOn(CommonStrings.action_save, inDialog = true) + eventsRecorder.assertSingle(EditUserProfileEvents.Save) } @Test - fun `clicking on OK exit emits the expected event`() { + fun `clicking on discard exit emits the expected event`() { val eventsRecorder = EventsRecorder() rule.setEditUserProfileView( aEditUserProfileState( @@ -66,7 +66,7 @@ class EditUserProfileViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_ok) + rule.clickOn(CommonStrings.action_discard) eventsRecorder.assertSingle(EditUserProfileEvents.Exit) } From 2f52d7c68318e186c04a8fcdd8b53e8e59ed3c03 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 17:04:53 +0100 Subject: [PATCH 030/347] EditUserProfileEvents -> EditUserProfileEvent --- ...ofileEvents.kt => EditUserProfileEvent.kt} | 12 +-- .../editprofile/EditUserProfilePresenter.kt | 12 +-- .../user/editprofile/EditUserProfileState.kt | 2 +- .../EditUserProfileStateProvider.kt | 2 +- .../user/editprofile/EditUserProfileView.kt | 16 ++-- .../EditUserProfilePresenterTest.kt | 78 +++++++++---------- .../editprofile/EditUserProfileViewTest.kt | 20 ++--- 7 files changed, 71 insertions(+), 71 deletions(-) rename features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/{EditUserProfileEvents.kt => EditUserProfileEvent.kt} (70%) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvents.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvent.kt similarity index 70% rename from features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvents.kt rename to features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvent.kt index f7f2ffceb4..d88eb75963 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvents.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvent.kt @@ -10,10 +10,10 @@ package io.element.android.features.preferences.impl.user.editprofile import io.element.android.libraries.matrix.ui.media.AvatarAction -sealed interface EditUserProfileEvents { - data class HandleAvatarAction(val action: AvatarAction) : EditUserProfileEvents - data class UpdateDisplayName(val name: String) : EditUserProfileEvents - data object Exit : EditUserProfileEvents - data object Save : EditUserProfileEvents - data object CloseDialog : EditUserProfileEvents +sealed interface EditUserProfileEvent { + data class HandleAvatarAction(val action: AvatarAction) : EditUserProfileEvent + data class UpdateDisplayName(val name: String) : EditUserProfileEvent + data object Exit : EditUserProfileEvent + data object Save : EditUserProfileEvent + data object CloseDialog : EditUserProfileEvent } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt index 59607139d7..0bdbb1031f 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt @@ -112,15 +112,15 @@ class EditUserProfilePresenter( !userDisplayName.isNullOrBlank() && hasProfileChanged } - fun handleEvent(event: EditUserProfileEvents) { + fun handleEvent(event: EditUserProfileEvent) { when (event) { - is EditUserProfileEvents.Save -> localCoroutineScope.saveChanges( + is EditUserProfileEvent.Save -> localCoroutineScope.saveChanges( name = userDisplayName, avatarUri = userAvatarUri?.toUri(), currentUser = matrixUser, action = saveAction, ) - is EditUserProfileEvents.HandleAvatarAction -> { + is EditUserProfileEvent.HandleAvatarAction -> { when (event.action) { AvatarAction.ChoosePhoto -> galleryImagePicker.launch() AvatarAction.TakePhoto -> if (cameraPermissionState.permissionGranted) { @@ -135,8 +135,8 @@ class EditUserProfilePresenter( } } } - is EditUserProfileEvents.UpdateDisplayName -> userDisplayName = event.name - EditUserProfileEvents.Exit -> { + is EditUserProfileEvent.UpdateDisplayName -> userDisplayName = event.name + EditUserProfileEvent.Exit -> { when (saveAction.value) { is AsyncAction.Confirming -> { // Close the dialog right now @@ -157,7 +157,7 @@ class EditUserProfilePresenter( } } } - EditUserProfileEvents.CloseDialog -> saveAction.value = AsyncAction.Uninitialized + EditUserProfileEvent.CloseDialog -> saveAction.value = AsyncAction.Uninitialized } } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt index 9becf6ce12..a638ed8378 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt @@ -22,5 +22,5 @@ data class EditUserProfileState( val saveButtonEnabled: Boolean, val saveAction: AsyncAction, val cameraPermissionState: PermissionsState, - val eventSink: (EditUserProfileEvents) -> Unit + val eventSink: (EditUserProfileEvent) -> Unit ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt index 56b734a342..ca9571aea5 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt @@ -33,7 +33,7 @@ fun aEditUserProfileState( saveButtonEnabled: Boolean = true, saveAction: AsyncAction = AsyncAction.Uninitialized, cameraPermissionState: PermissionsState = aPermissionsState(showDialog = false), - eventSink: (EditUserProfileEvents) -> Unit = {}, + eventSink: (EditUserProfileEvent) -> Unit = {}, ) = EditUserProfileState( userId = userId, displayName = displayName, 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 4325aa1eb6..5b42440101 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 @@ -68,7 +68,7 @@ fun EditUserProfileView( fun onBackClick() { focusManager.clearFocus() - state.eventSink(EditUserProfileEvents.Exit) + state.eventSink(EditUserProfileEvent.Exit) } BackHandler( @@ -87,7 +87,7 @@ fun EditUserProfileView( enabled = state.saveButtonEnabled, onClick = { focusManager.clearFocus() - state.eventSink(EditUserProfileEvents.Save) + state.eventSink(EditUserProfileEvent.Save) }, ) } @@ -125,7 +125,7 @@ fun EditUserProfileView( value = state.displayName, placeholder = stringResource(CommonStrings.common_room_name_placeholder), singleLine = true, - onValueChange = { state.eventSink(EditUserProfileEvents.UpdateDisplayName(it)) }, + onValueChange = { state.eventSink(EditUserProfileEvent.UpdateDisplayName(it)) }, ) } @@ -133,7 +133,7 @@ fun EditUserProfileView( actions = state.avatarActions, isVisible = isAvatarActionsSheetVisible.value, onDismiss = { isAvatarActionsSheetVisible.value = false }, - onSelectAction = { state.eventSink(EditUserProfileEvents.HandleAvatarAction(it)) } + onSelectAction = { state.eventSink(EditUserProfileEvent.HandleAvatarAction(it)) } ) AsyncActionView( @@ -147,9 +147,9 @@ fun EditUserProfileView( when (confirming) { is AsyncAction.ConfirmingCancellation -> { SaveChangesDialog( - onSaveClick = { state.eventSink(EditUserProfileEvents.Save) }, - onDiscardClick = { state.eventSink(EditUserProfileEvents.Exit) }, - onDismiss = { state.eventSink(EditUserProfileEvents.CloseDialog) }, + onSaveClick = { state.eventSink(EditUserProfileEvent.Save) }, + onDiscardClick = { state.eventSink(EditUserProfileEvent.Exit) }, + onDismiss = { state.eventSink(EditUserProfileEvent.CloseDialog) }, ) } } @@ -157,7 +157,7 @@ fun EditUserProfileView( onSuccess = { onEditProfileSuccess() }, errorTitle = { stringResource(R.string.screen_edit_profile_error_title) }, errorMessage = { stringResource(R.string.screen_edit_profile_error) }, - onErrorDismiss = { state.eventSink(EditUserProfileEvents.CloseDialog) }, + onErrorDismiss = { state.eventSink(EditUserProfileEvent.CloseDialog) }, ) } PermissionsView( diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt index 3432bac29f..d69101cbba 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt @@ -124,7 +124,7 @@ class EditUserProfilePresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvents.Exit) + initialState.eventSink(EditUserProfileEvent.Exit) closeLambda.assertions().isCalledOnce() } } @@ -139,21 +139,21 @@ class EditUserProfilePresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("New name")) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("New name")) val withUpdatedName = awaitItem() - withUpdatedName.eventSink(EditUserProfileEvents.Exit) + withUpdatedName.eventSink(EditUserProfileEvent.Exit) val withConfirmation = awaitItem() assertThat(withConfirmation.saveAction).isEqualTo(AsyncAction.ConfirmingCancellation) // Cancel - withConfirmation.eventSink(EditUserProfileEvents.CloseDialog) + withConfirmation.eventSink(EditUserProfileEvent.CloseDialog) val afterCancel = awaitItem() assertThat(afterCancel.saveAction).isEqualTo(AsyncAction.Uninitialized) // Try again and confirm - afterCancel.eventSink(EditUserProfileEvents.Exit) + afterCancel.eventSink(EditUserProfileEvent.Exit) val withConfirmation2 = awaitItem() assertThat(withConfirmation2.saveAction).isEqualTo(AsyncAction.ConfirmingCancellation) closeLambda.assertions().isNeverCalled() - withConfirmation2.eventSink(EditUserProfileEvents.Exit) + withConfirmation2.eventSink(EditUserProfileEvent.Exit) // Dialog is closed val finalState = awaitItem() assertThat(finalState.saveAction).isEqualTo(AsyncAction.Uninitialized) @@ -174,17 +174,17 @@ class EditUserProfilePresenterTest { val initialState = awaitItem() assertThat(initialState.displayName).isEqualTo("Name") assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL) - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name II")) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("Name II")) awaitItem().apply { assertThat(displayName).isEqualTo("Name II") assertThat(userAvatarUrl).isEqualTo(AN_AVATAR_URL) } - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name III")) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("Name III")) awaitItem().apply { assertThat(displayName).isEqualTo("Name III") assertThat(userAvatarUrl).isEqualTo(AN_AVATAR_URL) } - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.Remove)) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.Remove)) awaitItem().apply { assertThat(displayName).isEqualTo("Name III") assertThat(userAvatarUrl).isNull() @@ -205,7 +205,7 @@ class EditUserProfilePresenterTest { presenter.test { val initialState = awaitItem() assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL) - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) awaitItem().apply { assertThat(userAvatarUrl).isEqualTo(ANOTHER_AVATAR_URL) } @@ -229,7 +229,7 @@ class EditUserProfilePresenterTest { val initialState = awaitItem() assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(initialState.cameraPermissionState.permissionGranted).isFalse() - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.TakePhoto)) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.TakePhoto)) val stateWithAskingPermission = awaitItem() assertThat(stateWithAskingPermission.cameraPermissionState.showDialog).isTrue() fakePermissionsPresenter.setPermissionGranted() @@ -239,7 +239,7 @@ class EditUserProfilePresenterTest { assertThat(stateWithNewAvatar.userAvatarUrl).isEqualTo(ANOTHER_AVATAR_URL) // Do it again, no permission is requested fakePickerProvider.givenResult(userAvatarUri) - stateWithNewAvatar.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.TakePhoto)) + stateWithNewAvatar.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.TakePhoto)) val stateWithNewAvatar2 = awaitItem() assertThat(stateWithNewAvatar2.userAvatarUrl).isEqualTo(AN_AVATAR_URL) deleteCallback.assertions().isCalledExactly(2).withSequence( @@ -264,22 +264,22 @@ class EditUserProfilePresenterTest { val initialState = awaitItem() assertThat(initialState.saveButtonEnabled).isFalse() // Once a change is made, the save button is enabled - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name II")) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("Name II")) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // If it's reverted then the save disables again - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name")) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("Name")) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } // Make a change... - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.Remove)) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.Remove)) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // Revert it... - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } @@ -305,22 +305,22 @@ class EditUserProfilePresenterTest { val initialState = awaitItem() assertThat(initialState.saveButtonEnabled).isFalse() // Once a change is made, the save button is enabled - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name II")) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("Name II")) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // If it's reverted then the save disables again - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("Name")) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("Name")) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } // Make a change... - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // Revert it... - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.Remove)) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.Remove)) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } @@ -344,9 +344,9 @@ class EditUserProfilePresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("New name")) - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.Remove)) - initialState.eventSink(EditUserProfileEvents.Save) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("New name")) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.Remove)) + initialState.eventSink(EditUserProfileEvent.Save) consumeItemsUntilPredicate { matrixClient.setDisplayNameCalled && matrixClient.removeAvatarCalled && !matrixClient.uploadAvatarCalled } assertThat(matrixClient.setDisplayNameCalled).isTrue() assertThat(matrixClient.removeAvatarCalled).isTrue() @@ -365,8 +365,8 @@ class EditUserProfilePresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName(" Name ")) - initialState.eventSink(EditUserProfileEvents.Save) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName(" Name ")) + initialState.eventSink(EditUserProfileEvent.Save) consumeItemsUntilTimeout() assertThat(matrixClient.setDisplayNameCalled).isFalse() assertThat(matrixClient.uploadAvatarCalled).isFalse() @@ -384,8 +384,8 @@ class EditUserProfilePresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("")) - initialState.eventSink(EditUserProfileEvents.Save) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("")) + initialState.eventSink(EditUserProfileEvent.Save) assertThat(matrixClient.setDisplayNameCalled).isFalse() assertThat(matrixClient.uploadAvatarCalled).isFalse() assertThat(matrixClient.removeAvatarCalled).isFalse() @@ -407,8 +407,8 @@ class EditUserProfilePresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) - initialState.eventSink(EditUserProfileEvents.Save) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(EditUserProfileEvent.Save) consumeItemsUntilPredicate { matrixClient.uploadAvatarCalled } assertThat(matrixClient.uploadAvatarCalled).isTrue() } @@ -429,8 +429,8 @@ class EditUserProfilePresenterTest { fakeMediaPreProcessor.givenResult(Result.failure(RuntimeException("Oh no"))) presenter.test { val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) - initialState.eventSink(EditUserProfileEvents.Save) + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(EditUserProfileEvent.Save) skipItems(2) assertThat(matrixClient.uploadAvatarCalled).isFalse() assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) @@ -443,7 +443,7 @@ class EditUserProfilePresenterTest { val matrixClient = FakeMatrixClient().apply { givenSetDisplayNameResult(Result.failure(RuntimeException("!"))) } - saveAndAssertFailure(user, matrixClient, EditUserProfileEvents.UpdateDisplayName("New name")) + saveAndAssertFailure(user, matrixClient, EditUserProfileEvent.UpdateDisplayName("New name")) } @Test @@ -452,7 +452,7 @@ class EditUserProfilePresenterTest { val matrixClient = FakeMatrixClient().apply { givenRemoveAvatarResult(Result.failure(RuntimeException("!"))) } - saveAndAssertFailure(user, matrixClient, EditUserProfileEvents.HandleAvatarAction(AvatarAction.Remove)) + saveAndAssertFailure(user, matrixClient, EditUserProfileEvent.HandleAvatarAction(AvatarAction.Remove)) } @Test @@ -462,7 +462,7 @@ class EditUserProfilePresenterTest { val matrixClient = FakeMatrixClient().apply { givenUploadAvatarResult(Result.failure(RuntimeException("!"))) } - saveAndAssertFailure(user, matrixClient, EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) + saveAndAssertFailure(user, matrixClient, EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) } @Test @@ -475,16 +475,16 @@ class EditUserProfilePresenterTest { val presenter = createEditUserProfilePresenter(matrixUser = user, matrixClient = matrixClient) presenter.test { val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("foo")) - initialState.eventSink(EditUserProfileEvents.Save) + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("foo")) + initialState.eventSink(EditUserProfileEvent.Save) skipItems(2) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) - initialState.eventSink(EditUserProfileEvents.CloseDialog) + initialState.eventSink(EditUserProfileEvent.CloseDialog) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) } } - private suspend fun saveAndAssertFailure(matrixUser: MatrixUser, matrixClient: MatrixClient, event: EditUserProfileEvents) { + private suspend fun saveAndAssertFailure(matrixUser: MatrixUser, matrixClient: MatrixClient, event: EditUserProfileEvent) { val presenter = createEditUserProfilePresenter( matrixUser = matrixUser, matrixClient = matrixClient, @@ -495,7 +495,7 @@ class EditUserProfilePresenterTest { presenter.test { val initialState = awaitItem() initialState.eventSink(event) - initialState.eventSink(EditUserProfileEvents.Save) + initialState.eventSink(EditUserProfileEvent.Save) skipItems(1) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt index 6ee2604293..728e05ee7e 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt @@ -34,19 +34,19 @@ class EditUserProfileViewTest { @Test fun `clicking on back emits the expected event`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setEditUserProfileView( aEditUserProfileState( eventSink = eventsRecorder, ), ) rule.pressBack() - eventsRecorder.assertSingle(EditUserProfileEvents.Exit) + eventsRecorder.assertSingle(EditUserProfileEvent.Exit) } @Test fun `clicking on save from the exit confirmation dialog emits the expected event`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setEditUserProfileView( aEditUserProfileState( saveAction = AsyncAction.ConfirmingCancellation, @@ -54,12 +54,12 @@ class EditUserProfileViewTest { ), ) rule.clickOn(CommonStrings.action_save, inDialog = true) - eventsRecorder.assertSingle(EditUserProfileEvents.Save) + eventsRecorder.assertSingle(EditUserProfileEvent.Save) } @Test fun `clicking on discard exit emits the expected event`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setEditUserProfileView( aEditUserProfileState( saveAction = AsyncAction.ConfirmingCancellation, @@ -67,12 +67,12 @@ class EditUserProfileViewTest { ), ) rule.clickOn(CommonStrings.action_discard) - eventsRecorder.assertSingle(EditUserProfileEvents.Exit) + eventsRecorder.assertSingle(EditUserProfileEvent.Exit) } @Test fun `clicking on save emits the expected event`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setEditUserProfileView( aEditUserProfileState( saveButtonEnabled = true, @@ -81,12 +81,12 @@ class EditUserProfileViewTest { ), ) rule.clickOn(CommonStrings.action_save) - eventsRecorder.assertSingle(EditUserProfileEvents.Save) + eventsRecorder.assertSingle(EditUserProfileEvent.Save) } @Test fun `clicking on avatar opens the bottom sheet dialog`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() val actions = listOf( AvatarAction.TakePhoto, AvatarAction.ChoosePhoto, @@ -110,7 +110,7 @@ class EditUserProfileViewTest { @Test fun `success invokes the expected callback`() { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) ensureCalledOnce { callback -> rule.setEditUserProfileView( aEditUserProfileState( From a10e049a79ff41b082c6a1d04147e77a6fc162c8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 17:29:24 +0100 Subject: [PATCH 031/347] Fix tests --- .../roomdetailsedit/impl/RoomDetailsEditViewTest.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt index dcf8a94d66..4e1801f29a 100644 --- a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt +++ b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt @@ -50,7 +50,7 @@ class RoomDetailsEditViewTest { } @Test - fun `clicking on OK when confirming exit emits the expected Event`() { + fun `clicking on discard when confirming exit emits the expected Event`() { val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( @@ -58,12 +58,12 @@ class RoomDetailsEditViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_ok) + rule.clickOn(CommonStrings.action_discard) eventsRecorder.assertSingle(RoomDetailsEditEvents.OnBackPress) } @Test - fun `clicking on cancel when confirming exit emits the expected Event`() { + fun `clicking on save when confirming exit emits the expected Event`() { val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( @@ -71,8 +71,8 @@ class RoomDetailsEditViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_cancel) - eventsRecorder.assertSingle(RoomDetailsEditEvents.CloseDialog) + rule.clickOn(CommonStrings.action_save, inDialog = true) + eventsRecorder.assertSingle(RoomDetailsEditEvents.Save) } @Test From 4afeb6210c0db4d0db2ba0932b0fd1935544a1cc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 17:31:07 +0100 Subject: [PATCH 032/347] RoomDetailsEditEvents -> RoomDetailsEditEvent --- ...sEditEvents.kt => RoomDetailsEditEvent.kt} | 14 +-- .../impl/RoomDetailsEditPresenter.kt | 14 +-- .../impl/RoomDetailsEditState.kt | 2 +- .../impl/RoomDetailsEditStateProvider.kt | 2 +- .../impl/RoomDetailsEditView.kt | 20 ++-- .../impl/RoomDetailsEditPresenterTest.kt | 100 +++++++++--------- .../impl/RoomDetailsEditViewTest.kt | 48 ++++----- 7 files changed, 100 insertions(+), 100 deletions(-) rename features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/{RoomDetailsEditEvents.kt => RoomDetailsEditEvent.kt} (70%) diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditEvents.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditEvent.kt similarity index 70% rename from features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditEvents.kt rename to features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditEvent.kt index 858d08c2a0..40f123401c 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditEvents.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditEvent.kt @@ -10,11 +10,11 @@ package io.element.android.features.roomdetailsedit.impl import io.element.android.libraries.matrix.ui.media.AvatarAction -sealed interface RoomDetailsEditEvents { - data class HandleAvatarAction(val action: AvatarAction) : RoomDetailsEditEvents - data class UpdateRoomName(val name: String) : RoomDetailsEditEvents - data class UpdateRoomTopic(val topic: String) : RoomDetailsEditEvents - data object OnBackPress : RoomDetailsEditEvents - data object Save : RoomDetailsEditEvents - data object CloseDialog : RoomDetailsEditEvents +sealed interface RoomDetailsEditEvent { + data class HandleAvatarAction(val action: AvatarAction) : RoomDetailsEditEvent + data class UpdateRoomName(val name: String) : RoomDetailsEditEvent + data class UpdateRoomTopic(val topic: String) : RoomDetailsEditEvent + data object OnBackPress : RoomDetailsEditEvent + data object Save : RoomDetailsEditEvent + data object CloseDialog : RoomDetailsEditEvent } diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt index 89af0aa288..4a2dfa3f11 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt @@ -139,9 +139,9 @@ class RoomDetailsEditPresenter( val saveAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val localCoroutineScope = rememberCoroutineScope() - fun handleEvent(event: RoomDetailsEditEvents) { + fun handleEvent(event: RoomDetailsEditEvent) { when (event) { - is RoomDetailsEditEvents.Save -> localCoroutineScope.saveChanges( + is RoomDetailsEditEvent.Save -> localCoroutineScope.saveChanges( currentNameTrimmed = roomRawNameTrimmed, newNameTrimmed = roomRawNameEdited.trim(), currentTopicTrimmed = roomTopicTrimmed, @@ -150,7 +150,7 @@ class RoomDetailsEditPresenter( newAvatarUri = roomAvatarUriEdited?.toUri(), action = saveAction, ) - is RoomDetailsEditEvents.HandleAvatarAction -> { + is RoomDetailsEditEvent.HandleAvatarAction -> { when (event.action) { AvatarAction.ChoosePhoto -> galleryImagePicker.launch() AvatarAction.TakePhoto -> if (cameraPermissionState.permissionGranted) { @@ -166,10 +166,10 @@ class RoomDetailsEditPresenter( } } - is RoomDetailsEditEvents.UpdateRoomName -> roomRawNameEdited = event.name - is RoomDetailsEditEvents.UpdateRoomTopic -> roomTopicEdited = event.topic - RoomDetailsEditEvents.CloseDialog -> saveAction.value = AsyncAction.Uninitialized - RoomDetailsEditEvents.OnBackPress -> if (saveButtonEnabled.not() || saveAction.value == AsyncAction.ConfirmingCancellation) { + is RoomDetailsEditEvent.UpdateRoomName -> roomRawNameEdited = event.name + is RoomDetailsEditEvent.UpdateRoomTopic -> roomTopicEdited = event.topic + RoomDetailsEditEvent.CloseDialog -> saveAction.value = AsyncAction.Uninitialized + RoomDetailsEditEvent.OnBackPress -> if (saveButtonEnabled.not() || saveAction.value == AsyncAction.ConfirmingCancellation) { // No changes to save or already confirming exit without saving saveAction.value = AsyncAction.Success(Unit) } else { diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditState.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditState.kt index 1017c961b1..35f088275f 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditState.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditState.kt @@ -28,5 +28,5 @@ data class RoomDetailsEditState( val saveAction: AsyncAction, val cameraPermissionState: PermissionsState, val isSpace: Boolean, - val eventSink: (RoomDetailsEditEvents) -> Unit + val eventSink: (RoomDetailsEditEvent) -> Unit ) diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt index cecdcfa9d5..a6e2e3798b 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditStateProvider.kt @@ -45,7 +45,7 @@ fun aRoomDetailsEditState( saveAction: AsyncAction = AsyncAction.Uninitialized, cameraPermissionState: PermissionsState = aPermissionsState(showDialog = false), isSpace: Boolean = false, - eventSink: (RoomDetailsEditEvents) -> Unit = {}, + eventSink: (RoomDetailsEditEvent) -> Unit = {}, ) = RoomDetailsEditState( roomId = roomId, roomRawName = roomRawName, 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 04a03fbcfe..268b30cb31 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 @@ -64,7 +64,7 @@ fun RoomDetailsEditView( } BackHandler { - state.eventSink(RoomDetailsEditEvents.OnBackPress) + state.eventSink(RoomDetailsEditEvent.OnBackPress) } Scaffold( modifier = modifier.clearFocusOnTap(focusManager), @@ -74,7 +74,7 @@ fun RoomDetailsEditView( navigationIcon = { BackButton( onClick = { - state.eventSink(RoomDetailsEditEvents.OnBackPress) + state.eventSink(RoomDetailsEditEvent.OnBackPress) } ) }, @@ -84,7 +84,7 @@ fun RoomDetailsEditView( enabled = state.saveButtonEnabled, onClick = { focusManager.clearFocus() - state.eventSink(RoomDetailsEditEvents.Save) + state.eventSink(RoomDetailsEditEvent.Save) }, ) } @@ -121,7 +121,7 @@ fun RoomDetailsEditView( placeholder = stringResource(CommonStrings.common_room_name_placeholder), singleLine = true, readOnly = !state.canChangeName, - onValueChange = { state.eventSink(RoomDetailsEditEvents.UpdateRoomName(it)) }, + onValueChange = { state.eventSink(RoomDetailsEditEvent.UpdateRoomName(it)) }, ) Spacer(modifier = Modifier.height(32.dp)) @@ -136,7 +136,7 @@ fun RoomDetailsEditView( }, maxLines = 10, readOnly = !state.canChangeTopic, - onValueChange = { state.eventSink(RoomDetailsEditEvents.UpdateRoomTopic(it)) }, + onValueChange = { state.eventSink(RoomDetailsEditEvent.UpdateRoomTopic(it)) }, keyboardOptions = KeyboardOptions( capitalization = KeyboardCapitalization.Sentences, ), @@ -147,7 +147,7 @@ fun RoomDetailsEditView( actions = state.avatarActions, isVisible = isAvatarActionsSheetVisible.value, onDismiss = { isAvatarActionsSheetVisible.value = false }, - onSelectAction = { state.eventSink(RoomDetailsEditEvents.HandleAvatarAction(it)) } + onSelectAction = { state.eventSink(RoomDetailsEditEvent.HandleAvatarAction(it)) } ) AsyncActionView( async = state.saveAction, @@ -159,15 +159,15 @@ fun RoomDetailsEditView( confirmationDialog = { if (state.saveAction == AsyncAction.ConfirmingCancellation) { SaveChangesDialog( - onSaveClick = { state.eventSink(RoomDetailsEditEvents.Save) }, - onDiscardClick = { state.eventSink(RoomDetailsEditEvents.OnBackPress) }, - onDismiss = { state.eventSink(RoomDetailsEditEvents.CloseDialog) } + onSaveClick = { state.eventSink(RoomDetailsEditEvent.Save) }, + onDiscardClick = { state.eventSink(RoomDetailsEditEvent.OnBackPress) }, + onDismiss = { state.eventSink(RoomDetailsEditEvent.CloseDialog) } ) } }, onSuccess = { onDone() }, errorMessage = { stringResource(R.string.screen_room_details_edition_error) }, - onErrorDismiss = { state.eventSink(RoomDetailsEditEvents.CloseDialog) } + onErrorDismiss = { state.eventSink(RoomDetailsEditEvent.CloseDialog) } ) PermissionsView( diff --git a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt index d19a07ab04..e438cecf50 100644 --- a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt +++ b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt @@ -241,25 +241,25 @@ class RoomDetailsEditPresenterTest { assertThat(initialState.roomTopic).isEqualTo("My topic") assertThat(initialState.roomRawName).isEqualTo("Name") assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL) - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name II")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name II")) awaitItem().apply { assertThat(roomTopic).isEqualTo("My topic") assertThat(roomRawName).isEqualTo("Name II") assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL) } - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name III")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name III")) awaitItem().apply { assertThat(roomTopic).isEqualTo("My topic") assertThat(roomRawName).isEqualTo("Name III") assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL) } - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("Another topic")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("Another topic")) awaitItem().apply { assertThat(roomTopic).isEqualTo("Another topic") assertThat(roomRawName).isEqualTo("Name III") assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL) } - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove)) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove)) awaitItem().apply { assertThat(roomTopic).isEqualTo("Another topic") assertThat(roomRawName).isEqualTo("Name III") @@ -285,7 +285,7 @@ class RoomDetailsEditPresenterTest { presenter.test { val initialState = awaitFirstItem() assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL) - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) awaitItem().apply { assertThat(roomAvatarUrl).isEqualTo(anotherAvatarUri.toString()) } @@ -312,7 +312,7 @@ class RoomDetailsEditPresenterTest { val initialState = awaitFirstItem() assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(initialState.cameraPermissionState.permissionGranted).isFalse() - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto)) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.TakePhoto)) val stateWithAskingPermission = awaitItem() assertThat(stateWithAskingPermission.cameraPermissionState.showDialog).isTrue() fakePermissionsPresenter.setPermissionGranted() @@ -322,7 +322,7 @@ class RoomDetailsEditPresenterTest { assertThat(stateWithNewAvatar.roomAvatarUrl).isEqualTo(anotherAvatarUri.toString()) // Do it again, no permission is requested fakePickerProvider.givenResult(roomAvatarUri) - stateWithNewAvatar.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto)) + stateWithNewAvatar.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.TakePhoto)) val stateWithNewAvatar2 = awaitItem() assertThat(stateWithNewAvatar2.roomAvatarUrl).isEqualTo(AN_AVATAR_URL) deleteCallback.assertions().isCalledExactly(3).withSequence( @@ -351,32 +351,32 @@ class RoomDetailsEditPresenterTest { val initialState = awaitFirstItem() assertThat(initialState.saveButtonEnabled).isFalse() // Once a change is made, the save button is enabled - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name II")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name II")) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // If it's reverted then the save disables again - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name")) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } // Make a change... - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("Another topic")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("Another topic")) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // Revert it... - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("My topic")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("My topic")) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } // Make a change... - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove)) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove)) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // Revert it... - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } @@ -401,32 +401,32 @@ class RoomDetailsEditPresenterTest { val initialState = awaitFirstItem() assertThat(initialState.saveButtonEnabled).isFalse() // Once a change is made, the save button is enabled - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name II")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name II")) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // If it's reverted then the save disables again - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("fallback")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("fallback")) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } // Make a change... - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("Another topic")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("Another topic")) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // Revert it... - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("")) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } // Make a change... - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() } // Revert it... - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove)) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove)) awaitItem().apply { assertThat(saveButtonEnabled).isFalse() } @@ -454,10 +454,10 @@ class RoomDetailsEditPresenterTest { ) presenter.test { val initialState = awaitFirstItem() - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("New name")) - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("New topic")) - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove)) - initialState.eventSink(RoomDetailsEditEvents.Save) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("New name")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("New topic")) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove)) + initialState.eventSink(RoomDetailsEditEvent.Save) skipItems(5) setNameResult.assertions().isCalledOnce().with(value("New name")) setTopicResult.assertions().isCalledOnce().with(value("New topic")) @@ -480,9 +480,9 @@ class RoomDetailsEditPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName(" Name ")) - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic(" My topic ")) - initialState.eventSink(RoomDetailsEditEvents.Save) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName(" Name ")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic(" My topic ")) + initialState.eventSink(RoomDetailsEditEvent.Save) cancelAndIgnoreRemainingEvents() } } @@ -502,8 +502,8 @@ class RoomDetailsEditPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("")) - initialState.eventSink(RoomDetailsEditEvents.Save) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("")) + initialState.eventSink(RoomDetailsEditEvent.Save) cancelAndIgnoreRemainingEvents() deleteCallback.assertions().isCalledOnce().with(value(null)) } @@ -524,8 +524,8 @@ class RoomDetailsEditPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("")) - initialState.eventSink(RoomDetailsEditEvents.Save) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("")) + initialState.eventSink(RoomDetailsEditEvent.Save) cancelAndIgnoreRemainingEvents() deleteCallback.assertions().isCalledOnce().with(value(null)) } @@ -549,8 +549,8 @@ class RoomDetailsEditPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) - initialState.eventSink(RoomDetailsEditEvents.Save) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(RoomDetailsEditEvent.Save) skipItems(4) updateAvatarResult.assertions().isCalledOnce().with(value(MimeTypes.Jpeg), value(fakeFileContents)) deleteCallback.assertions().isCalledExactly(2).withSequence( @@ -577,8 +577,8 @@ class RoomDetailsEditPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) - initialState.eventSink(RoomDetailsEditEvents.Save) + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(RoomDetailsEditEvent.Save) skipItems(3) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) } @@ -593,7 +593,7 @@ class RoomDetailsEditPresenterTest { setNameResult = { Result.failure(RuntimeException("!")) }, canSendStateResult = { _, _ -> Result.success(true) } ) - saveAndAssertFailure(room, RoomDetailsEditEvents.UpdateRoomName("New name"), deleteCallbackNumberOfInvocation = 1) + saveAndAssertFailure(room, RoomDetailsEditEvent.UpdateRoomName("New name"), deleteCallbackNumberOfInvocation = 1) } @Test @@ -605,7 +605,7 @@ class RoomDetailsEditPresenterTest { setTopicResult = { Result.failure(RuntimeException("!")) }, canSendStateResult = { _, _ -> Result.success(true) } ) - saveAndAssertFailure(room, RoomDetailsEditEvents.UpdateRoomTopic("New topic"), deleteCallbackNumberOfInvocation = 1) + saveAndAssertFailure(room, RoomDetailsEditEvent.UpdateRoomTopic("New topic"), deleteCallbackNumberOfInvocation = 1) } @Test @@ -617,7 +617,7 @@ class RoomDetailsEditPresenterTest { removeAvatarResult = { Result.failure(RuntimeException("!")) }, canSendStateResult = { _, _ -> Result.success(true) } ) - saveAndAssertFailure(room, RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove), deleteCallbackNumberOfInvocation = 2) + saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove), deleteCallbackNumberOfInvocation = 2) } @Test @@ -630,7 +630,7 @@ class RoomDetailsEditPresenterTest { updateAvatarResult = { _, _ -> Result.failure(RuntimeException("!")) }, canSendStateResult = { _, _ -> Result.success(true) } ) - saveAndAssertFailure(room, RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto), deleteCallbackNumberOfInvocation = 2) + saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto), deleteCallbackNumberOfInvocation = 2) } @Test @@ -650,11 +650,11 @@ class RoomDetailsEditPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("foo")) - initialState.eventSink(RoomDetailsEditEvents.Save) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("foo")) + initialState.eventSink(RoomDetailsEditEvent.Save) skipItems(3) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) - initialState.eventSink(RoomDetailsEditEvents.CloseDialog) + initialState.eventSink(RoomDetailsEditEvent.CloseDialog) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) } } @@ -674,14 +674,14 @@ class RoomDetailsEditPresenterTest { val initialState = awaitFirstItem() assertThat(initialState.saveButtonEnabled).isFalse() // Once a change is made, the save button is enabled - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name edited")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name edited")) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() - eventSink(RoomDetailsEditEvents.OnBackPress) + eventSink(RoomDetailsEditEvent.OnBackPress) } awaitItem().apply { assertThat(saveAction).isEqualTo(AsyncAction.ConfirmingCancellation) - eventSink(RoomDetailsEditEvents.CloseDialog) + eventSink(RoomDetailsEditEvent.CloseDialog) } awaitItem().apply { assertThat(saveAction).isEqualTo(AsyncAction.Uninitialized) @@ -702,7 +702,7 @@ class RoomDetailsEditPresenterTest { presenter.test { val initialState = awaitFirstItem() assertThat(initialState.saveButtonEnabled).isFalse() - initialState.eventSink(RoomDetailsEditEvents.OnBackPress) + initialState.eventSink(RoomDetailsEditEvent.OnBackPress) assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.Success(Unit)) } } @@ -721,14 +721,14 @@ class RoomDetailsEditPresenterTest { val initialState = awaitFirstItem() assertThat(initialState.saveButtonEnabled).isFalse() // Once a change is made, the save button is enabled - initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name edited")) + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name edited")) awaitItem().apply { assertThat(saveButtonEnabled).isTrue() - eventSink(RoomDetailsEditEvents.OnBackPress) + eventSink(RoomDetailsEditEvent.OnBackPress) } awaitItem().apply { assertThat(saveAction).isEqualTo(AsyncAction.ConfirmingCancellation) - eventSink(RoomDetailsEditEvents.OnBackPress) + eventSink(RoomDetailsEditEvent.OnBackPress) } awaitItem().apply { assertThat(saveAction).isEqualTo(AsyncAction.Success(Unit)) @@ -738,7 +738,7 @@ class RoomDetailsEditPresenterTest { private suspend fun saveAndAssertFailure( room: JoinedRoom, - event: RoomDetailsEditEvents, + event: RoomDetailsEditEvent, deleteCallbackNumberOfInvocation: Int = 2, ) { val deleteCallback = lambdaRecorder {} @@ -749,7 +749,7 @@ class RoomDetailsEditPresenterTest { presenter.test { val initialState = awaitFirstItem() initialState.eventSink(event) - initialState.eventSink(RoomDetailsEditEvents.Save) + initialState.eventSink(RoomDetailsEditEvent.Save) skipItems(1) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) diff --git a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt index 4e1801f29a..71fb143074 100644 --- a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt +++ b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditViewTest.kt @@ -39,19 +39,19 @@ class RoomDetailsEditViewTest { @Test fun `clicking on back emits the expected Event`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder ), ) rule.pressBack() - eventsRecorder.assertSingle(RoomDetailsEditEvents.OnBackPress) + eventsRecorder.assertSingle(RoomDetailsEditEvent.OnBackPress) } @Test fun `clicking on discard when confirming exit emits the expected Event`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( saveAction = AsyncAction.ConfirmingCancellation, @@ -59,12 +59,12 @@ class RoomDetailsEditViewTest { ), ) rule.clickOn(CommonStrings.action_discard) - eventsRecorder.assertSingle(RoomDetailsEditEvents.OnBackPress) + eventsRecorder.assertSingle(RoomDetailsEditEvent.OnBackPress) } @Test fun `clicking on save when confirming exit emits the expected Event`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( saveAction = AsyncAction.ConfirmingCancellation, @@ -72,12 +72,12 @@ class RoomDetailsEditViewTest { ), ) rule.clickOn(CommonStrings.action_save, inDialog = true) - eventsRecorder.assertSingle(RoomDetailsEditEvents.Save) + eventsRecorder.assertSingle(RoomDetailsEditEvent.Save) } @Test fun `when edition is successful, the expected callback is invoked`() { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) ensureCalledOnce { callback -> rule.setRoomDetailsEditView( aRoomDetailsEditState( @@ -91,7 +91,7 @@ class RoomDetailsEditViewTest { @Test fun `when name is changed, the expected Event is emitted`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder, @@ -99,12 +99,12 @@ class RoomDetailsEditViewTest { ), ) rule.onNodeWithText("Marketing").performTextInput("A") - eventsRecorder.assertSingle(RoomDetailsEditEvents.UpdateRoomName("AMarketing")) + eventsRecorder.assertSingle(RoomDetailsEditEvent.UpdateRoomName("AMarketing")) } @Test fun `when user cannot change name, nothing happen`() { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder, @@ -117,7 +117,7 @@ class RoomDetailsEditViewTest { @Test fun `when topic is changed, the expected Event is emitted`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder, @@ -125,12 +125,12 @@ class RoomDetailsEditViewTest { ), ) rule.onNodeWithText("My Topic").performTextInput("A") - eventsRecorder.assertSingle(RoomDetailsEditEvents.UpdateRoomTopic("AMy Topic")) + eventsRecorder.assertSingle(RoomDetailsEditEvent.UpdateRoomTopic("AMy Topic")) } @Test fun `when user cannot change topic, nothing happen`() { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder, @@ -146,7 +146,7 @@ class RoomDetailsEditViewTest { fun `when avatar is changed with action to take photo, the expected Event is emitted`() { testAvatarChange( stringActionRes = CommonStrings.action_take_photo, - expectedEvent = RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto), + expectedEvent = RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.TakePhoto), ) } @@ -155,7 +155,7 @@ class RoomDetailsEditViewTest { fun `when avatar is changed with action to choose photo, the expected Event is emitted`() { testAvatarChange( stringActionRes = CommonStrings.action_choose_photo, - expectedEvent = RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto), + expectedEvent = RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto), ) } @@ -164,15 +164,15 @@ class RoomDetailsEditViewTest { fun `when avatar is changed with action to remove photo, the expected Event is emitted`() { testAvatarChange( stringActionRes = CommonStrings.action_remove, - expectedEvent = RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove), + expectedEvent = RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove), ) } private fun testAvatarChange( @StringRes stringActionRes: Int, - expectedEvent: RoomDetailsEditEvents.HandleAvatarAction, + expectedEvent: RoomDetailsEditEvent.HandleAvatarAction, ) { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder, @@ -187,7 +187,7 @@ class RoomDetailsEditViewTest { @Test fun `when user cannot change avatar, nothing happen`() { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder, @@ -200,7 +200,7 @@ class RoomDetailsEditViewTest { @Test fun `when save is clicked, the expected Event is emitted`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder, @@ -208,12 +208,12 @@ class RoomDetailsEditViewTest { ), ) rule.clickOn(CommonStrings.action_save) - eventsRecorder.assertSingle(RoomDetailsEditEvents.Save) + eventsRecorder.assertSingle(RoomDetailsEditEvent.Save) } @Test fun `when save is clicked, but nothing need to be saved, nothing happens`() { - val eventsRecorder = EventsRecorder(expectEvents = false) + val eventsRecorder = EventsRecorder(expectEvents = false) rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder, @@ -225,7 +225,7 @@ class RoomDetailsEditViewTest { @Test fun `when error is shown, closing the dialog emit the expected Event`() { - val eventsRecorder = EventsRecorder() + val eventsRecorder = EventsRecorder() rule.setRoomDetailsEditView( aRoomDetailsEditState( eventSink = eventsRecorder, @@ -233,7 +233,7 @@ class RoomDetailsEditViewTest { ), ) rule.clickOn(CommonStrings.action_ok) - eventsRecorder.assertSingle(RoomDetailsEditEvents.CloseDialog) + eventsRecorder.assertSingle(RoomDetailsEditEvent.CloseDialog) } } From 32e2cabae4b51d5da9e4893c2688f965d64c532d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 18:13:18 +0100 Subject: [PATCH 033/347] CreatePollEvents -> CreatePollEvent --- ...CreatePollEvents.kt => CreatePollEvent.kt} | 22 ++--- .../poll/impl/create/CreatePollPresenter.kt | 22 ++--- .../poll/impl/create/CreatePollState.kt | 2 +- .../poll/impl/create/CreatePollView.kt | 26 +++--- .../impl/create/CreatePollPresenterTest.kt | 80 +++++++++---------- 5 files changed, 76 insertions(+), 76 deletions(-) rename features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/{CreatePollEvents.kt => CreatePollEvent.kt} (56%) diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollEvents.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollEvent.kt similarity index 56% rename from features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollEvents.kt rename to features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollEvent.kt index 3d1c162dd3..b98ab899b9 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollEvents.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollEvent.kt @@ -10,15 +10,15 @@ package io.element.android.features.poll.impl.create import io.element.android.libraries.matrix.api.poll.PollKind -sealed interface CreatePollEvents { - data object Save : CreatePollEvents - data class Delete(val confirmed: Boolean) : CreatePollEvents - data class SetQuestion(val question: String) : CreatePollEvents - data class SetAnswer(val index: Int, val text: String) : CreatePollEvents - data object AddAnswer : CreatePollEvents - data class RemoveAnswer(val index: Int) : CreatePollEvents - data class SetPollKind(val pollKind: PollKind) : CreatePollEvents - data object NavBack : CreatePollEvents - data object ConfirmNavBack : CreatePollEvents - data object HideConfirmation : CreatePollEvents +sealed interface CreatePollEvent { + data object Save : CreatePollEvent + data class Delete(val confirmed: Boolean) : CreatePollEvent + data class SetQuestion(val question: String) : CreatePollEvent + data class SetAnswer(val index: Int, val text: String) : CreatePollEvent + data object AddAnswer : CreatePollEvent + data class RemoveAnswer(val index: Int) : CreatePollEvent + data class SetPollKind(val pollKind: PollKind) : CreatePollEvent + data object NavBack : CreatePollEvent + data object ConfirmNavBack : CreatePollEvent + data object HideConfirmation : CreatePollEvent } diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenter.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenter.kt index 3da8c3dc53..6138bab2ae 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenter.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenter.kt @@ -97,9 +97,9 @@ class CreatePollPresenter( val scope = rememberCoroutineScope() - fun handleEvent(event: CreatePollEvents) { + fun handleEvent(event: CreatePollEvent) { when (event) { - is CreatePollEvents.Save -> scope.launch { + is CreatePollEvent.Save -> scope.launch { if (canSave) { repository.savePoll( existingPollId = when (mode) { @@ -123,7 +123,7 @@ class CreatePollPresenter( Timber.d("Cannot create poll") } } - is CreatePollEvents.Delete -> { + is CreatePollEvent.Delete -> { if (mode !is CreatePollMode.EditPoll) { return } @@ -139,25 +139,25 @@ class CreatePollPresenter( navigateUp() } } - is CreatePollEvents.AddAnswer -> { + is CreatePollEvent.AddAnswer -> { poll = poll.withNewAnswer() } - is CreatePollEvents.RemoveAnswer -> { + is CreatePollEvent.RemoveAnswer -> { poll = poll.withAnswerRemoved(event.index) } - is CreatePollEvents.SetAnswer -> { + is CreatePollEvent.SetAnswer -> { poll = poll.withAnswerChanged(event.index, event.text) } - is CreatePollEvents.SetPollKind -> { + is CreatePollEvent.SetPollKind -> { poll = poll.copy(isDisclosed = event.pollKind.isDisclosed) } - is CreatePollEvents.SetQuestion -> { + is CreatePollEvent.SetQuestion -> { poll = poll.copy(question = event.question) } - is CreatePollEvents.NavBack -> { + is CreatePollEvent.NavBack -> { navigateUp() } - CreatePollEvents.ConfirmNavBack -> { + CreatePollEvent.ConfirmNavBack -> { val shouldConfirm = isDirty if (shouldConfirm) { showBackConfirmation = true @@ -165,7 +165,7 @@ class CreatePollPresenter( navigateUp() } } - is CreatePollEvents.HideConfirmation -> { + is CreatePollEvent.HideConfirmation -> { showBackConfirmation = false showDeleteConfirmation = false } diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollState.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollState.kt index 1046f25bd5..80aa7dc4b0 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollState.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollState.kt @@ -20,7 +20,7 @@ data class CreatePollState( val pollKind: PollKind, val showBackConfirmation: Boolean, val showDeleteConfirmation: Boolean, - val eventSink: (CreatePollEvents) -> Unit, + val eventSink: (CreatePollEvent) -> Unit, ) { enum class Mode { New, diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt index 3220aa1c5c..3abf3718af 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/create/CreatePollView.kt @@ -62,21 +62,21 @@ fun CreatePollView( ) { val coroutineScope = rememberCoroutineScope() - val navBack = { state.eventSink(CreatePollEvents.ConfirmNavBack) } + val navBack = { state.eventSink(CreatePollEvent.ConfirmNavBack) } BackHandler(onBack = navBack) if (state.showBackConfirmation) { SaveChangesDialog( - onSaveClick = { state.eventSink(CreatePollEvents.Save) }, - onDiscardClick = { state.eventSink(CreatePollEvents.NavBack) }, - onDismiss = { state.eventSink(CreatePollEvents.HideConfirmation) }, + onSaveClick = { state.eventSink(CreatePollEvent.Save) }, + onDiscardClick = { state.eventSink(CreatePollEvent.NavBack) }, + onDismiss = { state.eventSink(CreatePollEvent.HideConfirmation) }, ) } if (state.showDeleteConfirmation) { ConfirmationDialog( title = stringResource(id = R.string.screen_edit_poll_delete_confirmation_title), content = stringResource(id = R.string.screen_edit_poll_delete_confirmation), - onSubmitClick = { state.eventSink(CreatePollEvents.Delete(confirmed = true)) }, - onDismiss = { state.eventSink(CreatePollEvents.HideConfirmation) } + onSubmitClick = { state.eventSink(CreatePollEvent.Delete(confirmed = true)) }, + onDismiss = { state.eventSink(CreatePollEvent.HideConfirmation) } ) } val questionFocusRequester = remember { FocusRequester() } @@ -91,7 +91,7 @@ fun CreatePollView( mode = state.mode, saveEnabled = state.canSave, onBackClick = navBack, - onSaveClick = { state.eventSink(CreatePollEvents.Save) } + onSaveClick = { state.eventSink(CreatePollEvent.Save) } ) }, ) { paddingValues -> @@ -112,7 +112,7 @@ fun CreatePollView( label = stringResource(id = R.string.screen_create_poll_question_desc), value = state.question, onValueChange = { - state.eventSink(CreatePollEvents.SetQuestion(it)) + state.eventSink(CreatePollEvent.SetQuestion(it)) }, modifier = Modifier .focusRequester(questionFocusRequester) @@ -131,7 +131,7 @@ fun CreatePollView( TextField( value = answer.text, onValueChange = { - state.eventSink(CreatePollEvents.SetAnswer(index, it)) + state.eventSink(CreatePollEvent.SetAnswer(index, it)) }, modifier = Modifier .then(if (isLastItem) Modifier.focusRequester(answerFocusRequester) else Modifier) @@ -145,7 +145,7 @@ fun CreatePollView( imageVector = CompoundIcons.Delete(), contentDescription = stringResource(R.string.screen_create_poll_delete_option_a11y, answer.text), modifier = Modifier.clickable(answer.canDelete) { - state.eventSink(CreatePollEvents.RemoveAnswer(index)) + state.eventSink(CreatePollEvent.RemoveAnswer(index)) }, ) }, @@ -161,7 +161,7 @@ fun CreatePollView( ), style = ListItemStyle.Primary, onClick = { - state.eventSink(CreatePollEvents.AddAnswer) + state.eventSink(CreatePollEvent.AddAnswer) coroutineScope.launch(Dispatchers.Main) { lazyListState.animateScrollToItem(state.answers.size + 1) answerFocusRequester.requestFocus() @@ -181,7 +181,7 @@ fun CreatePollView( ), onClick = { state.eventSink( - CreatePollEvents.SetPollKind( + CreatePollEvent.SetPollKind( if (state.pollKind == PollKind.Disclosed) PollKind.Undisclosed else PollKind.Disclosed ) ) @@ -191,7 +191,7 @@ fun CreatePollView( ListItem( headlineContent = { Text(text = stringResource(id = CommonStrings.action_delete_poll)) }, style = ListItemStyle.Destructive, - onClick = { state.eventSink(CreatePollEvents.Delete(confirmed = false)) }, + onClick = { state.eventSink(CreatePollEvent.Delete(confirmed = false)) }, ) } } diff --git a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt index 1f916eb670..dee0268c1c 100644 --- a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt +++ b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt @@ -104,15 +104,15 @@ class CreatePollPresenterTest { val initial = awaitItem() assertThat(initial.canSave).isFalse() - initial.eventSink(CreatePollEvents.SetQuestion("A question?")) + initial.eventSink(CreatePollEvent.SetQuestion("A question?")) val questionSet = awaitItem() assertThat(questionSet.canSave).isFalse() - questionSet.eventSink(CreatePollEvents.SetAnswer(0, "Answer 1")) + questionSet.eventSink(CreatePollEvent.SetAnswer(0, "Answer 1")) val answer1Set = awaitItem() assertThat(answer1Set.canSave).isFalse() - answer1Set.eventSink(CreatePollEvents.SetAnswer(1, "Answer 2")) + answer1Set.eventSink(CreatePollEvent.SetAnswer(1, "Answer 2")) val answer2Set = awaitItem() assertThat(answer2Set.canSave).isTrue() } @@ -133,11 +133,11 @@ class CreatePollPresenterTest { presenter.present() }.test { val initial = awaitItem() - initial.eventSink(CreatePollEvents.SetQuestion("A question?")) - initial.eventSink(CreatePollEvents.SetAnswer(0, "Answer 1")) - initial.eventSink(CreatePollEvents.SetAnswer(1, "Answer 2")) + initial.eventSink(CreatePollEvent.SetQuestion("A question?")) + initial.eventSink(CreatePollEvent.SetAnswer(0, "Answer 1")) + initial.eventSink(CreatePollEvent.SetAnswer(1, "Answer 2")) skipItems(3) - initial.eventSink(CreatePollEvents.Save) + initial.eventSink(CreatePollEvent.Save) delay(1) // Wait for the coroutine to finish createPollResult.assertions().isCalledOnce() .with( @@ -182,10 +182,10 @@ class CreatePollPresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - awaitDefaultItem().eventSink(CreatePollEvents.SetQuestion("A question?")) - awaitItem().eventSink(CreatePollEvents.SetAnswer(0, "Answer 1")) - awaitItem().eventSink(CreatePollEvents.SetAnswer(1, "Answer 2")) - awaitItem().eventSink(CreatePollEvents.Save) + awaitDefaultItem().eventSink(CreatePollEvent.SetQuestion("A question?")) + awaitItem().eventSink(CreatePollEvent.SetAnswer(0, "Answer 1")) + awaitItem().eventSink(CreatePollEvent.SetAnswer(1, "Answer 2")) + awaitItem().eventSink(CreatePollEvent.Save) delay(1) // Wait for the coroutine to finish createPollResult.assertions().isCalledOnce() assertThat(fakeAnalyticsService.capturedEvents).isEmpty() @@ -210,20 +210,20 @@ class CreatePollPresenterTest { }.test { awaitDefaultItem() awaitPollLoaded().apply { - eventSink(CreatePollEvents.SetQuestion("Changed question")) + eventSink(CreatePollEvent.SetQuestion("Changed question")) } awaitItem().apply { - eventSink(CreatePollEvents.SetAnswer(0, "Changed answer 1")) + eventSink(CreatePollEvent.SetAnswer(0, "Changed answer 1")) } awaitItem().apply { - eventSink(CreatePollEvents.SetAnswer(1, "Changed answer 2")) + eventSink(CreatePollEvent.SetAnswer(1, "Changed answer 2")) } awaitPollLoaded( newQuestion = "Changed question", newAnswer1 = "Changed answer 1", newAnswer2 = "Changed answer 2", ).apply { - eventSink(CreatePollEvents.Save) + eventSink(CreatePollEvent.Save) } advanceUntilIdle() // Wait for the coroutine to finish @@ -275,8 +275,8 @@ class CreatePollPresenterTest { presenter.present() }.test { awaitDefaultItem() - awaitPollLoaded().eventSink(CreatePollEvents.SetAnswer(0, "A")) - awaitPollLoaded(newAnswer1 = "A").eventSink(CreatePollEvents.Save) + awaitPollLoaded().eventSink(CreatePollEvent.SetAnswer(0, "A")) + awaitPollLoaded(newAnswer1 = "A").eventSink(CreatePollEvent.Save) advanceUntilIdle() // Wait for the coroutine to finish editPollLambda.assertions().isCalledOnce() assertThat(fakeAnalyticsService.capturedEvents).isEmpty() @@ -296,12 +296,12 @@ class CreatePollPresenterTest { val initial = awaitItem() assertThat(initial.answers.size).isEqualTo(2) - initial.eventSink(CreatePollEvents.AddAnswer) + initial.eventSink(CreatePollEvent.AddAnswer) val answerAdded = awaitItem() assertThat(answerAdded.answers.size).isEqualTo(3) assertThat(answerAdded.answers[2].text).isEmpty() - initial.eventSink(CreatePollEvents.RemoveAnswer(2)) + initial.eventSink(CreatePollEvent.RemoveAnswer(2)) val answerRemoved = awaitItem() assertThat(answerRemoved.answers.size).isEqualTo(2) } @@ -314,7 +314,7 @@ class CreatePollPresenterTest { presenter.present() }.test { val initial = awaitItem() - initial.eventSink(CreatePollEvents.SetQuestion("A question?")) + initial.eventSink(CreatePollEvent.SetQuestion("A question?")) val questionSet = awaitItem() assertThat(questionSet.question).isEqualTo("A question?") } @@ -327,7 +327,7 @@ class CreatePollPresenterTest { presenter.present() }.test { val initial = awaitItem() - initial.eventSink(CreatePollEvents.SetAnswer(0, "This is answer 1")) + initial.eventSink(CreatePollEvent.SetAnswer(0, "This is answer 1")) val answerSet = awaitItem() assertThat(answerSet.answers.first().text).isEqualTo("This is answer 1") } @@ -340,7 +340,7 @@ class CreatePollPresenterTest { presenter.present() }.test { val initial = awaitItem() - initial.eventSink(CreatePollEvents.SetPollKind(PollKind.Undisclosed)) + initial.eventSink(CreatePollEvent.SetPollKind(PollKind.Undisclosed)) val kindSet = awaitItem() assertThat(kindSet.pollKind).isEqualTo(PollKind.Undisclosed) } @@ -355,10 +355,10 @@ class CreatePollPresenterTest { val initial = awaitItem() assertThat(initial.canAddAnswer).isTrue() repeat(17) { - initial.eventSink(CreatePollEvents.AddAnswer) + initial.eventSink(CreatePollEvent.AddAnswer) assertThat(awaitItem().canAddAnswer).isTrue() } - initial.eventSink(CreatePollEvents.AddAnswer) + initial.eventSink(CreatePollEvent.AddAnswer) assertThat(awaitItem().canAddAnswer).isFalse() } } @@ -371,7 +371,7 @@ class CreatePollPresenterTest { }.test { val initial = awaitItem() assertThat(initial.answers.all { it.canDelete }).isFalse() - initial.eventSink(CreatePollEvents.AddAnswer) + initial.eventSink(CreatePollEvent.AddAnswer) assertThat(awaitItem().answers.all { it.canDelete }).isTrue() } } @@ -383,7 +383,7 @@ class CreatePollPresenterTest { presenter.present() }.test { val initial = awaitItem() - initial.eventSink(CreatePollEvents.SetAnswer(0, "A".repeat(241))) + initial.eventSink(CreatePollEvent.SetAnswer(0, "A".repeat(241))) assertThat(awaitItem().answers.first().text.length).isEqualTo(240) } } @@ -396,7 +396,7 @@ class CreatePollPresenterTest { }.test { val initial = awaitItem() assertThat(navUpInvocationsCount).isEqualTo(0) - initial.eventSink(CreatePollEvents.NavBack) + initial.eventSink(CreatePollEvent.NavBack) assertThat(navUpInvocationsCount).isEqualTo(1) } } @@ -410,7 +410,7 @@ class CreatePollPresenterTest { val initial = awaitItem() assertThat(navUpInvocationsCount).isEqualTo(0) assertThat(initial.showBackConfirmation).isFalse() - initial.eventSink(CreatePollEvents.ConfirmNavBack) + initial.eventSink(CreatePollEvent.ConfirmNavBack) assertThat(navUpInvocationsCount).isEqualTo(1) } } @@ -422,11 +422,11 @@ class CreatePollPresenterTest { presenter.present() }.test { val initial = awaitItem() - initial.eventSink(CreatePollEvents.SetQuestion("Non blank")) + initial.eventSink(CreatePollEvent.SetQuestion("Non blank")) assertThat(awaitItem().showBackConfirmation).isFalse() - initial.eventSink(CreatePollEvents.ConfirmNavBack) + initial.eventSink(CreatePollEvent.ConfirmNavBack) assertThat(awaitItem().showBackConfirmation).isTrue() - initial.eventSink(CreatePollEvents.HideConfirmation) + initial.eventSink(CreatePollEvent.HideConfirmation) assertThat(awaitItem().showBackConfirmation).isFalse() assertThat(navUpInvocationsCount).isEqualTo(0) } @@ -442,7 +442,7 @@ class CreatePollPresenterTest { val loaded = awaitPollLoaded() assertThat(navUpInvocationsCount).isEqualTo(0) assertThat(loaded.showBackConfirmation).isFalse() - loaded.eventSink(CreatePollEvents.ConfirmNavBack) + loaded.eventSink(CreatePollEvent.ConfirmNavBack) assertThat(navUpInvocationsCount).isEqualTo(1) } } @@ -455,11 +455,11 @@ class CreatePollPresenterTest { }.test { awaitDefaultItem() val loaded = awaitPollLoaded() - loaded.eventSink(CreatePollEvents.SetQuestion("CHANGED")) + loaded.eventSink(CreatePollEvent.SetQuestion("CHANGED")) assertThat(awaitItem().showBackConfirmation).isFalse() - loaded.eventSink(CreatePollEvents.ConfirmNavBack) + loaded.eventSink(CreatePollEvent.ConfirmNavBack) assertThat(awaitItem().showBackConfirmation).isTrue() - loaded.eventSink(CreatePollEvents.HideConfirmation) + loaded.eventSink(CreatePollEvent.HideConfirmation) assertThat(awaitItem().showBackConfirmation).isFalse() assertThat(navUpInvocationsCount).isEqualTo(0) } @@ -474,7 +474,7 @@ class CreatePollPresenterTest { presenter.present() }.test { awaitDefaultItem() - awaitPollLoaded().eventSink(CreatePollEvents.Delete(confirmed = false)) + awaitPollLoaded().eventSink(CreatePollEvent.Delete(confirmed = false)) awaitDeleteConfirmation() assert(redactEventLambda).isNeverCalled() } @@ -489,8 +489,8 @@ class CreatePollPresenterTest { presenter.present() }.test { awaitDefaultItem() - awaitPollLoaded().eventSink(CreatePollEvents.Delete(confirmed = false)) - awaitDeleteConfirmation().eventSink(CreatePollEvents.HideConfirmation) + awaitPollLoaded().eventSink(CreatePollEvent.Delete(confirmed = false)) + awaitDeleteConfirmation().eventSink(CreatePollEvent.HideConfirmation) awaitPollLoaded().apply { assertThat(showDeleteConfirmation).isFalse() } @@ -507,8 +507,8 @@ class CreatePollPresenterTest { presenter.present() }.test { awaitDefaultItem() - awaitPollLoaded().eventSink(CreatePollEvents.Delete(confirmed = false)) - awaitDeleteConfirmation().eventSink(CreatePollEvents.Delete(confirmed = true)) + awaitPollLoaded().eventSink(CreatePollEvent.Delete(confirmed = false)) + awaitDeleteConfirmation().eventSink(CreatePollEvent.Delete(confirmed = true)) awaitPollLoaded().apply { assertThat(showDeleteConfirmation).isFalse() } From 627549c67abea96d0959724c8496e6325679e91e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 18:26:25 +0100 Subject: [PATCH 034/347] Fix compilation issue after rebase. --- .../features/space/impl/settings/SpaceSettingsFlowNode.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt index b52da111b3..d299a43791 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt @@ -14,6 +14,7 @@ import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.navmodel.backstack.BackStack +import com.bumble.appyx.navmodel.backstack.operation.pop import com.bumble.appyx.navmodel.backstack.operation.push import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject @@ -95,9 +96,15 @@ class SpaceSettingsFlowNode( ) } is NavTarget.SecurityAndPrivacy -> { + val callback = object : SecurityAndPrivacyEntryPoint.Callback { + override fun onDone() { + backstack.pop() + } + } securityAndPrivacyEntryPoint.createNode( parentNode = this, buildContext = buildContext, + callback = callback, ) } is NavTarget.RolesAndPermissions -> { From 6f7726a472700b97b5afae37f943dcb20d70e482 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 3 Dec 2025 17:45:55 +0000 Subject: [PATCH 035/347] Update screenshots --- .../features.poll.impl.create_CreatePollView_Day_2_en.png | 4 ++-- .../features.poll.impl.create_CreatePollView_Night_2_en.png | 4 ++-- ...ces.impl.user.editprofile_EditUserProfileView_Day_2_en.png | 4 ++-- ...s.impl.user.editprofile_EditUserProfileView_Night_2_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_6_en.png | 4 ++-- ...ures.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png | 4 ++-- ...es.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png | 4 ++-- ...gnsystem.components.dialogs_SaveChangesDialog_Day_0_en.png | 4 ++-- ...system.components.dialogs_SaveChangesDialog_Night_0_en.png | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.poll.impl.create_CreatePollView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.poll.impl.create_CreatePollView_Day_2_en.png index 12e42e376c..d083e1d3e1 100644 --- a/tests/uitests/src/test/snapshots/images/features.poll.impl.create_CreatePollView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.poll.impl.create_CreatePollView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:657d1e0eff5254eb3d36a64212cca38ec129c240cbd61b8cfdeb8399a00a5251 -size 39103 +oid sha256:2d60cf2028add0c159867b252f429ec92575b0ee4e89088046ecfbd3c58997df +size 38027 diff --git a/tests/uitests/src/test/snapshots/images/features.poll.impl.create_CreatePollView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.poll.impl.create_CreatePollView_Night_2_en.png index 5d4488f53a..0788da663d 100644 --- a/tests/uitests/src/test/snapshots/images/features.poll.impl.create_CreatePollView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.poll.impl.create_CreatePollView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3407623ce83d0c3f710ea45d693823d6125b1bc625c34e2922916110d8a2a442 -size 36717 +oid sha256:223002dda410268fbe0c3305ed08749c7fcaabf4d5c3803503525811da2a2841 +size 35821 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 d27f554281..17eb214c80 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:f2a443d3d6733e4fb9c618c4a689c8fb95195f47d3b08513a955f18251028b2f -size 34203 +oid sha256:9b6869e6026df038d739cc14a0a585563d595b1430ba23a985ec57680506ead2 +size 29857 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 4d93498ed8..8ee822b18b 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:b2166579c462025a6bff38b05da7574502f7200d5f0a4949b31ea4e4fbc25a67 -size 32467 +oid sha256:2b3eb9e8908deb84153b19d3735dd2338fac2a7998793915eeec32d7607a0b94 +size 28671 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png index dbf2be2d17..1af85a90ae 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8301124f0464ecd17016d93160899f6a4f3d4bb14ebd8dcd4bc3c3bd77e41996 -size 58980 +oid sha256:6109391197169d423341ba95d8f3de581b6b9663f8a017c0b727bf7d9181b228 +size 56993 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en.png index bdb1f920d1..93d5b14f5f 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be70d554880dec4eb3816360dbdbb6b678f2300afc10c91e741418cfac93cfb4 -size 56852 +oid sha256:71a4998d420d5cad0a799db7f51223393cca34218a1a23520606667ea320331b +size 55323 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 c9523fb650..a1da37b1de 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:25d60c4025a15e283978fb15abf8417bc896714ebc1faf198a3735978bbbfb18 -size 32392 +oid sha256:e3d196d9b4946165718d8a4ad37869d1d81c6134e94e05dcc1b23b71338482cb +size 28941 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 5f62ef9369..1643569702 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:29cea35b4105715561f34e4c6fe80a57272444b34b01bd9dd1f0adec67ea8878 -size 30270 +oid sha256:b9187a1e5fc63707a2c1a9804411e15439469f8562eac2c9766a4e033e214166 +size 27289 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png index e8e5a2019d..f642f7050b 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4b1ce86ad21d9ccd5b170a1628985eadbc5ac92be521ab55e9a1b22eb48c1476 -size 32552 +oid sha256:72be11ed273a790b0ab8e5023c1e21384c020e1b0fc0e3950de8f041c4004e64 +size 33758 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png index 6625789361..5e318df2ca 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da39e0496083394c522d40ed4cc62edc614ddca54ccfb05d5b7c68cfb030960a -size 34559 +oid sha256:c1cbcce698faad80969cd00d2680afd7cd61b6ba649f0b67e8c7fb2fe0dbe746 +size 35884 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en.png index 090d6dce7d..7d4045ec02 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d89a6c9a49b2b0e4fa37e219cec8e0dbe90ed8ca6e71f0ec5e8788076f91526 -size 23679 +oid sha256:9849f4591df3218c78c91e6731a864b72abaa699caa6321c818197faaf6b85af +size 18326 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en.png index 3963c95375..e2700312ba 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e496c8d67a678a7d4c729a3368c145afa080252dd68708b1ba95d98706cd614c -size 22265 +oid sha256:d47c650eae62a550c80aeed85775062304132debf33e5279fddc74c787ad40b3 +size 17211 From 404d8c085af260be953b093216d2610f85d8f413 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 20:44:24 +0000 Subject: [PATCH 036/347] fix(deps): update dependency androidx.exifinterface:exifinterface to v1.4.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 b910cb9b96..b451e6f50e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -90,7 +90,7 @@ androidx_corektx = { module = "androidx.core:core-ktx", version.ref = "core" } androidx_annotationjvm = "androidx.annotation:annotation-jvm:1.9.1" androidx_datastore_preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" } androidx_datastore_datastore = { module = "androidx.datastore:datastore", version.ref = "datastore" } -androidx_exifinterface = "androidx.exifinterface:exifinterface:1.4.1" +androidx_exifinterface = "androidx.exifinterface:exifinterface:1.4.2" androidx_constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" } androidx_constraintlayout_compose = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "constraintlayout_compose" } androidx_camera_lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "camera" } From 96a78d476e98bc4a5cca073ed7d4580962818a4a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 04:25:50 +0000 Subject: [PATCH 037/347] fix(deps): update metro to v0.8.1 --- 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 b451e6f50e..58ab652034 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -52,7 +52,7 @@ haze = "1.6.10" dependencyAnalysis = "3.5.1" # DI -metro = "0.7.7" +metro = "0.8.1" # Auto service autoservice = "1.1.1" From 8b1efd6bc33500ce0fde2d7c4fda3c34c6702321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 4 Dec 2025 09:23:08 +0100 Subject: [PATCH 038/347] Restore `no-unused-imports` behaviour for `ktlintFormat` --- .editorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/.editorconfig b/.editorconfig index d2f28922d9..a41ddcad7f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -35,6 +35,7 @@ ktlint_standard_class-signature = disabled ktlint_standard_when-entry-bracing = disabled ktlint_standard_blank-line-between-when-conditions = disabled ktlint_standard_mixed-condition-operators = disabled +ktlint_standard_no-unused-imports = enabled [*.java] ij_java_align_consecutive_assignments = false From 5007b6e730016cd5632728cad9ead38349b3720b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 4 Dec 2025 09:35:24 +0100 Subject: [PATCH 039/347] run command `./gradlew ktlintFormat` :) --- libraries/mediaupload/api/build.gradle.kts | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/mediaupload/api/build.gradle.kts b/libraries/mediaupload/api/build.gradle.kts index 1f2d844a9a..a9f876c67f 100644 --- a/libraries/mediaupload/api/build.gradle.kts +++ b/libraries/mediaupload/api/build.gradle.kts @@ -1,5 +1,3 @@ -import extension.testCommonDependencies - /* * Copyright (c) 2025 Element Creations Ltd. * Copyright 2023, 2024 New Vector Ltd. From 53ab38d99043bf4ba12e8fcbd01d0fca0ba57c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 21 Nov 2025 10:13:47 +0100 Subject: [PATCH 040/347] Enable Sentry in the SDK: add SDK Sentry DSN value This is provided to the SDK in `PlatformInitializer`. --- .../android/x/initializer/PlatformInitializer.kt | 2 ++ .../matrix/api/tracing/TracingConfiguration.kt | 1 + .../matrix/impl/tracing/RustTracingService.kt | 2 +- plugins/src/main/kotlin/config/BuildTimeConfig.kt | 1 + services/analyticsproviders/sentry/build.gradle.kts | 10 ++++++++++ .../services/analyticsproviders/sentry/SentryConfig.kt | 1 + 6 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt b/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt index 0eea5123b4..757f5af9d3 100644 --- a/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt +++ b/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt @@ -15,6 +15,7 @@ import io.element.android.features.rageshake.api.logs.createWriteToFilesConfigur import io.element.android.libraries.architecture.bindings import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.tracing.TracingConfiguration +import io.element.android.services.analyticsproviders.sentry.SentryConfig import io.element.android.x.di.AppBindings import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking @@ -38,6 +39,7 @@ class PlatformInitializer : Initializer { logLevel = logLevel, extraTargets = listOf(ELEMENT_X_TARGET), traceLogPacks = runBlocking { preferencesStore.getTracingLogPacksFlow().first() }, + sdkSentryDsn = SentryConfig.SDK_DSN.takeIf { it.isNotBlank() }, ) bugReporter.setCurrentTracingLogLevel(logLevel.name) platformService.init(tracingConfiguration) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingConfiguration.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingConfiguration.kt index 45d6e7e46e..569683d3f7 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingConfiguration.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingConfiguration.kt @@ -14,4 +14,5 @@ data class TracingConfiguration( val traceLogPacks: Set, val writesToLogcat: Boolean, val writesToFilesConfiguration: WriteToFilesConfiguration, + val sdkSentryDsn: String?, ) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt index 204fece309..6f235cd0db 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt @@ -60,5 +60,5 @@ fun TracingConfiguration.map(): org.matrix.rustcomponents.sdk.TracingConfigurati extraTargets = extraTargets, traceLogPacks = traceLogPacks.map(), writeToFiles = writesToFilesConfiguration.toTracingFileConfiguration(), - sentryDsn = null, + sentryDsn = sdkSentryDsn, ) diff --git a/plugins/src/main/kotlin/config/BuildTimeConfig.kt b/plugins/src/main/kotlin/config/BuildTimeConfig.kt index f792e899cd..50db4cdf41 100644 --- a/plugins/src/main/kotlin/config/BuildTimeConfig.kt +++ b/plugins/src/main/kotlin/config/BuildTimeConfig.kt @@ -29,6 +29,7 @@ object BuildTimeConfig { val SERVICES_POSTHOG_HOST: String? = null val SERVICES_POSTHOG_APIKEY: String? = null val SERVICES_SENTRY_DSN: String? = null + val SERVICES_SENTRY_SDK_DSN: String? = null val BUG_REPORT_URL: String? = null val BUG_REPORT_APP_NAME: String? = null diff --git a/services/analyticsproviders/sentry/build.gradle.kts b/services/analyticsproviders/sentry/build.gradle.kts index ba46a6f4f9..bbe4015e33 100644 --- a/services/analyticsproviders/sentry/build.gradle.kts +++ b/services/analyticsproviders/sentry/build.gradle.kts @@ -32,6 +32,16 @@ android { } ?: "" ) + buildConfigFieldStr( + name = "SDK_SENTRY_DSN", + value = if (isEnterpriseBuild) { + BuildTimeConfig.SERVICES_SENTRY_SDK_DSN + } else { + System.getenv("ELEMENT_SDK_SENTRY_DSN") + ?: readLocalProperty("services.analyticsproviders.sdk.sentry.dsn") + } + ?: "" + ) } } diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryConfig.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryConfig.kt index 3167d82f77..993823a877 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryConfig.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryConfig.kt @@ -11,6 +11,7 @@ package io.element.android.services.analyticsproviders.sentry object SentryConfig { const val NAME = "Sentry" const val DSN = BuildConfig.SENTRY_DSN + const val SDK_DSN = BuildConfig.SDK_SENTRY_DSN const val ENV_DEBUG = "DEBUG" const val ENV_NIGHTLY = "NIGHTLY" const val ENV_RELEASE = "RELEASE" From ea36caf98166919ac4f1582bdf03fd6595fcc06d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 21 Nov 2025 10:14:05 +0100 Subject: [PATCH 041/347] Update GH action flows to include the SDK DSN value --- .github/workflows/build.yml | 1 + .github/workflows/build_enterprise.yml | 1 + .github/workflows/nightly.yml | 1 + .github/workflows/release.yml | 1 + 4 files changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ef6b3773cd..bbd057c9b0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,6 +46,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} + ELEMENT_SDK_SENTRY_DSN: ${{ secrets.ELEMENT_SDK_SENTRY_DSN }} ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }} ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }} ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }} diff --git a/.github/workflows/build_enterprise.yml b/.github/workflows/build_enterprise.yml index 81e17d6189..66bff7ce51 100644 --- a/.github/workflows/build_enterprise.yml +++ b/.github/workflows/build_enterprise.yml @@ -54,6 +54,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} + ELEMENT_SDK_SENTRY_DSN: ${{ secrets.ELEMENT_SDK_SENTRY_DSN }} ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }} ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }} ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }} diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 71a2d0a595..0ea049b2f0 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -30,6 +30,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} + ELEMENT_SDK_SENTRY_DSN: ${{ secrets.ELEMENT_SDK_SENTRY_DSN }} ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }} ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }} ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 919897deed..79b2d3de6e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,6 +32,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} + ELEMENT_SDK_SENTRY_DSN: ${{ secrets.ELEMENT_SDK_SENTRY_DSN }} ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }} ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }} ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }} From 11f41629c12005999583efd39427060a3ae10c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 21 Nov 2025 17:20:12 +0100 Subject: [PATCH 042/347] Allow bridging Sentry spans to the SDK ones. Add distributed tracing for `Room.timelineWithConfiguration`, so we can inspect the associated Rust trace. --- .../analytics/DefaultAnalyticsSdkFactory.kt | 25 +++++++++ .../impl/analytics/RustAnalyticsSdkSpan.kt | 51 +++++++++++++++++++ .../matrix/impl/room/RustRoomFactory.kt | 23 +++++---- .../analytics/api/AnalyticsSdkSpan.kt | 19 +++++++ .../analytics/api/AnalyticsSdkSpanFactory.kt | 16 ++++++ .../analytics/api/AnalyticsService.kt | 11 ++++ .../analytics/api/NoopAnalyticsSdkSpan.kt | 13 +++++ .../analytics/api/NoopAnalyticsTransaction.kt | 1 + .../analytics/impl/DefaultAnalyticsService.kt | 16 ++++++ .../impl/DefaultAnalyticsServiceTest.kt | 2 + .../analytics/noop/NoopAnalyticsService.kt | 4 ++ .../test/FakeAnalyticsSdkSpanFactory.kt | 18 +++++++ .../analytics/test/FakeAnalyticsService.kt | 4 ++ .../api/AnalyticsTransaction.kt | 1 + .../sentry/SentryAnalyticsTransaction.kt | 1 + 15 files changed, 195 insertions(+), 10 deletions(-) create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultAnalyticsSdkFactory.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/RustAnalyticsSdkSpan.kt create mode 100644 services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpan.kt create mode 100644 services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpanFactory.kt create mode 100644 services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsSdkSpan.kt create mode 100644 services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsSdkSpanFactory.kt diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultAnalyticsSdkFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultAnalyticsSdkFactory.kt new file mode 100644 index 0000000000..b5d42a25e6 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultAnalyticsSdkFactory.kt @@ -0,0 +1,25 @@ +/* + * 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.analytics + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import io.element.android.services.analytics.api.AnalyticsSdkSpan +import io.element.android.services.analytics.api.AnalyticsSdkSpanFactory + +@ContributesBinding(AppScope::class) +class DefaultAnalyticsSdkFactory : AnalyticsSdkSpanFactory { + override fun create(name: String, parentTraceId: String?): AnalyticsSdkSpan { + return RustAnalyticsSdkSpan(name = name, parentTraceId = parentTraceId) + } + + override fun bridge(parentTraceId: String?): AnalyticsSdkSpan { + // A bridge span has no name + return RustAnalyticsSdkSpan(name = null, parentTraceId = parentTraceId) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/RustAnalyticsSdkSpan.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/RustAnalyticsSdkSpan.kt new file mode 100644 index 0000000000..9ed8763ec4 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/RustAnalyticsSdkSpan.kt @@ -0,0 +1,51 @@ +/* + * 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.analytics + +import io.element.android.libraries.core.extensions.runCatchingExceptions +import io.element.android.services.analytics.api.AnalyticsSdkSpan +import kotlinx.coroutines.DelicateCoroutinesApi +import org.matrix.rustcomponents.sdk.LogLevel +import org.matrix.rustcomponents.sdk.Span +import timber.log.Timber + +class RustAnalyticsSdkSpan( + name: String? = null, + private val parentTraceId: String?, +) : AnalyticsSdkSpan { + private val inner = if (name != null) { + Span( + target = "elementx", + name = name, + file = "-", + line = null, + level = LogLevel.WARN, + bridgeTraceId = parentTraceId, + ) + } else { + Span.newBridgeSpan( + target = "elementx", + parentTraceId = parentTraceId, + ) + } + + override fun enter() { + if (Span.current().isNone()) { + inner.enter() + } else { + Timber.w("Not entering span sentry.trace='$parentTraceId' because another span is already active") + } + } + + @OptIn(DelicateCoroutinesApi::class) + override fun exit() { + inner.exit() + runCatchingExceptions { inner.destroy() } + Timber.d("Exited span sentry.trace='$parentTraceId'") + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt index f184356f15..cbc39b1c61 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.impl.room.preview.RoomPreviewInfoMapp import io.element.android.libraries.matrix.impl.roomlist.roomOrNull import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.inBridgeSdkSpan import io.element.android.services.analytics.api.recordTransaction import io.element.android.services.analyticsproviders.api.recordChildTransaction import io.element.android.services.toolbox.api.systemclock.SystemClock @@ -127,17 +128,19 @@ class RustRoomFactory( val timeline = transaction.recordChildTransaction( operation = "sdkRoom.timelineWithConfiguration", description = "Get timeline from the SDK", - ) { - sdkRoom.timelineWithConfiguration( - TimelineConfiguration( - focus = TimelineFocus.Live(hideThreadedEvents = hideThreadedEvents), - filter = eventFilters?.let(TimelineFilter::EventTypeFilter) ?: TimelineFilter.All, - internalIdPrefix = "live", - dateDividerMode = DateDividerMode.DAILY, - trackReadReceipts = TimelineReadReceiptTracking.ALL_EVENTS, - reportUtds = true, + ) { timelineTransaction -> + analyticsService.inBridgeSdkSpan(parentTraceId = timelineTransaction.traceId()) { + sdkRoom.timelineWithConfiguration( + TimelineConfiguration( + focus = TimelineFocus.Live(hideThreadedEvents = hideThreadedEvents), + filter = eventFilters?.let(TimelineFilter::EventTypeFilter) ?: TimelineFilter.All, + internalIdPrefix = "live", + dateDividerMode = DateDividerMode.DAILY, + trackReadReceipts = TimelineReadReceiptTracking.ALL_EVENTS, + reportUtds = true, + ) ) - ) + } } GetRoomResult.Joined( diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpan.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpan.kt new file mode 100644 index 0000000000..92f79da7f9 --- /dev/null +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpan.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.services.analytics.api + +/** + * Represents an analytics span in the Rust SDK. + */ +interface AnalyticsSdkSpan { + /** Enters the span and starts collecting metrics. */ + fun enter() + + /** Exit the span and stop collecting the metrics. A request should be sent shortly after. */ + fun exit() +} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpanFactory.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpanFactory.kt new file mode 100644 index 0000000000..49558f37b0 --- /dev/null +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpanFactory.kt @@ -0,0 +1,16 @@ +/* + * 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.services.analytics.api + +interface AnalyticsSdkSpanFactory { + /** Create an SDK span with the provided [name] and optional [parentTraceId]. */ + fun create(name: String, parentTraceId: String?): AnalyticsSdkSpan + + /** Create a bridge span which will join our tracing spans to the SDK ones while it's active. */ + fun bridge(parentTraceId: String?): AnalyticsSdkSpan +} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt index 08562b01ce..9aeaf293cc 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt @@ -72,6 +72,8 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker { * Removes an ongoing [AnalyticsLongRunningTransaction] so it's no longer shared. */ fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? + + fun enterSdkSpan(name: String?, parentTraceId: String?): AnalyticsSdkSpan } inline fun AnalyticsService.recordTransaction( @@ -110,3 +112,12 @@ fun AnalyticsService.finishLongRunningTransaction( it.finish() } } + +inline fun AnalyticsService.inBridgeSdkSpan(parentTraceId: String?, block: (AnalyticsSdkSpan) -> T): T { + val span = enterSdkSpan(name = null, parentTraceId = parentTraceId) + return try { + block(span) + } finally { + span.exit() + } +} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsSdkSpan.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsSdkSpan.kt new file mode 100644 index 0000000000..d4db9359e2 --- /dev/null +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsSdkSpan.kt @@ -0,0 +1,13 @@ +/* + * 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.services.analytics.api + +object NoopAnalyticsSdkSpan : AnalyticsSdkSpan { + override fun enter() {} + override fun exit() {} +} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt index 2b18f8408c..024a7ac05e 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt @@ -13,5 +13,6 @@ object NoopAnalyticsTransaction : AnalyticsTransaction { override fun startChild(operation: String, description: String?): AnalyticsTransaction = NoopAnalyticsTransaction override fun setData(key: String, value: Any) {} override fun isFinished(): Boolean = true + override fun traceId(): String? = null override fun finish() {} } diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt index f1a5b444de..3dd9abf5d5 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt @@ -20,7 +20,10 @@ import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.sessionstorage.api.observer.SessionListener import io.element.android.libraries.sessionstorage.api.observer.SessionObserver import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsSdkSpan +import io.element.android.services.analytics.api.AnalyticsSdkSpanFactory import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.NoopAnalyticsSdkSpan import io.element.android.services.analytics.api.NoopAnalyticsTransaction import io.element.android.services.analytics.impl.log.analyticsTag import io.element.android.services.analytics.impl.store.AnalyticsStore @@ -43,6 +46,7 @@ class DefaultAnalyticsService( @AppCoroutineScope private val coroutineScope: CoroutineScope, private val sessionObserver: SessionObserver, + private val analyticsSdkSpanFactory: AnalyticsSdkSpanFactory, ) : AnalyticsService, SessionListener { private val pendingLongRunningTransactions = ConcurrentHashMap() @@ -171,4 +175,16 @@ class DefaultAnalyticsService( override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? { return pendingLongRunningTransactions.remove(longRunningTransaction) } + + override fun enterSdkSpan(name: String?, parentTraceId: String?): AnalyticsSdkSpan { + return if (userConsent.get()) { + if (name != null) { + analyticsSdkSpanFactory.create(name, parentTraceId) + } else { + analyticsSdkSpanFactory.bridge(parentTraceId) + }.apply { enter() } + } else { + NoopAnalyticsSdkSpan + } + } } diff --git a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt index 86a0c08d25..d80fb55d3f 100644 --- a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt @@ -21,6 +21,7 @@ import io.element.android.libraries.sessionstorage.api.observer.SessionObserver import io.element.android.libraries.sessionstorage.test.observer.NoOpSessionObserver import io.element.android.services.analytics.impl.store.AnalyticsStore import io.element.android.services.analytics.impl.store.FakeAnalyticsStore +import io.element.android.services.analytics.test.FakeAnalyticsSdkSpanFactory import io.element.android.services.analyticsproviders.api.AnalyticsProvider import io.element.android.services.analyticsproviders.test.FakeAnalyticsProvider import io.element.android.tests.testutils.lambda.lambdaRecorder @@ -278,6 +279,7 @@ class DefaultAnalyticsServiceTest { analyticsStore = analyticsStore, coroutineScope = coroutineScope, sessionObserver = sessionObserver, + analyticsSdkSpanFactory = FakeAnalyticsSdkSpanFactory(), ).also { // Wait for the service to be ready delay(1) diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt index 591651ed6c..004a472de3 100644 --- a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt @@ -16,7 +16,9 @@ import im.vector.app.features.analytics.itf.VectorAnalyticsScreen import im.vector.app.features.analytics.plan.SuperProperties import im.vector.app.features.analytics.plan.UserProperties import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsSdkSpan import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.NoopAnalyticsSdkSpan import io.element.android.services.analytics.api.NoopAnalyticsTransaction import io.element.android.services.analyticsproviders.api.AnalyticsProvider import io.element.android.services.analyticsproviders.api.AnalyticsTransaction @@ -45,4 +47,6 @@ class NoopAnalyticsService : AnalyticsService { ): AnalyticsTransaction = NoopAnalyticsTransaction override fun getLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? = null override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) = NoopAnalyticsTransaction + + override fun enterSdkSpan(name: String?, parentTraceId: String?): AnalyticsSdkSpan = NoopAnalyticsSdkSpan } diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsSdkSpanFactory.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsSdkSpanFactory.kt new file mode 100644 index 0000000000..e01f893d6d --- /dev/null +++ b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsSdkSpanFactory.kt @@ -0,0 +1,18 @@ +/* + * 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.services.analytics.test + +import io.element.android.services.analytics.api.AnalyticsSdkSpan +import io.element.android.services.analytics.api.AnalyticsSdkSpanFactory +import io.element.android.services.analytics.api.NoopAnalyticsSdkSpan + +class FakeAnalyticsSdkSpanFactory : AnalyticsSdkSpanFactory { + override fun create(name: String, parentTraceId: String?): AnalyticsSdkSpan = NoopAnalyticsSdkSpan + + override fun bridge(parentTraceId: String?): AnalyticsSdkSpan = NoopAnalyticsSdkSpan +} diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt index 274d06f6a5..b9b33744e8 100644 --- a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt +++ b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt @@ -13,7 +13,9 @@ import im.vector.app.features.analytics.itf.VectorAnalyticsScreen import im.vector.app.features.analytics.plan.SuperProperties import im.vector.app.features.analytics.plan.UserProperties import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsSdkSpan import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.NoopAnalyticsSdkSpan import io.element.android.services.analytics.api.NoopAnalyticsTransaction import io.element.android.services.analyticsproviders.api.AnalyticsProvider import io.element.android.services.analyticsproviders.api.AnalyticsTransaction @@ -86,4 +88,6 @@ class FakeAnalyticsService( override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? { return longRunningTransactions.remove(longRunningTransaction) } + + override fun enterSdkSpan(name: String?, parentTraceId: String?): AnalyticsSdkSpan = NoopAnalyticsSdkSpan } diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt index 8297055f96..ea63a7f167 100644 --- a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt @@ -11,6 +11,7 @@ interface AnalyticsTransaction { fun startChild(operation: String, description: String? = null): AnalyticsTransaction fun setData(key: String, value: Any) fun isFinished(): Boolean + fun traceId(): String? fun finish() } diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt index 90bbd77e00..75872b7d44 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt @@ -21,6 +21,7 @@ class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTra inner.startChild(operation, description) ) override fun setData(key: String, value: Any) = inner.setData(key, value) + override fun traceId(): String? = inner.toSentryTrace().value override fun isFinished(): Boolean = inner.isFinished override fun finish() { val name = if (inner is ITransaction) inner.name else inner.operation From 9a9f4fd67dd3dda216142ef18a0b1e40b01a5310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 28 Nov 2025 16:07:41 +0100 Subject: [PATCH 043/347] Fix screenshot tests blocking `testDebugUnitTest` task --- tests/uitests/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/uitests/build.gradle.kts b/tests/uitests/build.gradle.kts index 53876b0c8c..466167981c 100644 --- a/tests/uitests/build.gradle.kts +++ b/tests/uitests/build.gradle.kts @@ -20,7 +20,7 @@ android { namespace = "ui" } -tasks.withType(Test::class.java) { +tasks.withType(Test::class) { // Don't fail the test run if there are no tests, this can happen if we run them with screenshot test disabled failOnNoDiscoveredTests = false } From 6dd6ce1ad407d22f70c729f7475dd222df97419d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 28 Nov 2025 16:11:10 +0100 Subject: [PATCH 044/347] Add missing doc --- .../element/android/services/analytics/api/AnalyticsService.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt index 9aeaf293cc..365300d679 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt @@ -73,6 +73,7 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker { */ fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? + /** Enter a span inside the Rust SDK tracing system. If a [parentTraceId] is provided, the SDK trace will be added as a child of that trace. */ fun enterSdkSpan(name: String?, parentTraceId: String?): AnalyticsSdkSpan } From c7a5ce152e80123b8c1fbce7c24b73b7ed42a74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 28 Nov 2025 16:42:36 +0100 Subject: [PATCH 045/347] Fix providing the Sentry SDK DSN in Element Pro when no analytic modules are enabled --- .../io/element/android/x/di/AppBindings.kt | 4 +++ .../x/initializer/PlatformInitializer.kt | 3 +-- .../libraries/di/annotations/SentrySdkDsn.kt | 27 +++++++++++++++++++ .../analytics/noop/di/NoopAnalyticsModule.kt | 22 +++++++++++++++ .../sentry/di/SentryModule.kt | 23 ++++++++++++++++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt create mode 100644 services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt create mode 100644 services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt diff --git a/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt b/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt index 6e157f6ac1..f506e15688 100644 --- a/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt +++ b/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt @@ -17,6 +17,7 @@ import io.element.android.features.lockscreen.api.LockScreenService import io.element.android.features.rageshake.api.reporter.BugReporter import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher +import io.element.android.libraries.di.annotations.SentrySdkDsn import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.matrix.api.platform.InitPlatformService import io.element.android.libraries.matrix.api.tracing.TracingService @@ -48,4 +49,7 @@ interface AppBindings { fun featureFlagService(): FeatureFlagService fun buildMeta(): BuildMeta + + @SentrySdkDsn + fun sentrySdkDsn(): String? } diff --git a/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt b/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt index 757f5af9d3..206024d70b 100644 --- a/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt +++ b/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt @@ -15,7 +15,6 @@ import io.element.android.features.rageshake.api.logs.createWriteToFilesConfigur import io.element.android.libraries.architecture.bindings import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.tracing.TracingConfiguration -import io.element.android.services.analyticsproviders.sentry.SentryConfig import io.element.android.x.di.AppBindings import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking @@ -39,7 +38,7 @@ class PlatformInitializer : Initializer { logLevel = logLevel, extraTargets = listOf(ELEMENT_X_TARGET), traceLogPacks = runBlocking { preferencesStore.getTracingLogPacksFlow().first() }, - sdkSentryDsn = SentryConfig.SDK_DSN.takeIf { it.isNotBlank() }, + sdkSentryDsn = appBindings.sentrySdkDsn()?.takeIf { it.isNotBlank() }, ) bugReporter.setCurrentTracingLogLevel(logLevel.name) platformService.init(tracingConfiguration) diff --git a/libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt b/libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt new file mode 100644 index 0000000000..da3fd2945a --- /dev/null +++ b/libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt @@ -0,0 +1,27 @@ +/* + * 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.di.annotations + +import dev.zacsweers.metro.Qualifier + +/** + * Qualifies the Sentry SDK DSN in the DI graph. + */ +@Retention(AnnotationRetention.RUNTIME) +@MustBeDocumented +@Qualifier +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.FIELD, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.TYPE, +) +annotation class SentrySdkDsn diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt new file mode 100644 index 0000000000..f7d6646b8d --- /dev/null +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt @@ -0,0 +1,22 @@ +/* + * 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.services.analytics.noop.di + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.BindingContainer +import dev.zacsweers.metro.ContributesTo +import dev.zacsweers.metro.Provides +import io.element.android.libraries.di.annotations.SentrySdkDsn + +@BindingContainer +@ContributesTo(AppScope::class) +object NoopAnalyticsModule { + @SentrySdkDsn + @Provides + fun provideSentrySdkDsn(): String? = null +} diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt new file mode 100644 index 0000000000..5ddfce4ce7 --- /dev/null +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt @@ -0,0 +1,23 @@ +/* + * 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.services.analyticsproviders.sentry.di + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.BindingContainer +import dev.zacsweers.metro.ContributesTo +import dev.zacsweers.metro.Provides +import io.element.android.libraries.di.annotations.SentrySdkDsn +import io.element.android.services.analyticsproviders.sentry.SentryConfig + +@BindingContainer +@ContributesTo(AppScope::class) +object SentryModule { + @Provides + @SentrySdkDsn + fun provideSentrySdkDsn(): String? = SentryConfig.SDK_DSN +} From b31267d7c7dbcfa798099f7833f6d33608f6ee41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 4 Dec 2025 10:22:47 +0100 Subject: [PATCH 046/347] Make `SentrySdkDsn` a value class instead of a qualifier --- .../io/element/android/x/di/AppBindings.kt | 3 +-- .../x/initializer/PlatformInitializer.kt | 2 +- .../libraries/di/annotations/SentrySdkDsn.kt | 20 ++----------------- .../analytics/noop/di/NoopAnalyticsModule.kt | 3 +-- .../sentry/di/SentryModule.kt | 3 +-- 5 files changed, 6 insertions(+), 25 deletions(-) diff --git a/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt b/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt index f506e15688..d7bfda93a6 100644 --- a/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt +++ b/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt @@ -50,6 +50,5 @@ interface AppBindings { fun buildMeta(): BuildMeta - @SentrySdkDsn - fun sentrySdkDsn(): String? + fun sentrySdkDsn(): SentrySdkDsn? } diff --git a/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt b/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt index 206024d70b..2a844b1331 100644 --- a/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt +++ b/app/src/main/kotlin/io/element/android/x/initializer/PlatformInitializer.kt @@ -38,7 +38,7 @@ class PlatformInitializer : Initializer { logLevel = logLevel, extraTargets = listOf(ELEMENT_X_TARGET), traceLogPacks = runBlocking { preferencesStore.getTracingLogPacksFlow().first() }, - sdkSentryDsn = appBindings.sentrySdkDsn()?.takeIf { it.isNotBlank() }, + sdkSentryDsn = appBindings.sentrySdkDsn()?.value?.takeIf { it.isNotBlank() }, ) bugReporter.setCurrentTracingLogLevel(logLevel.name) platformService.init(tracingConfiguration) diff --git a/libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt b/libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt index da3fd2945a..19a0eac017 100644 --- a/libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt +++ b/libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt @@ -7,21 +7,5 @@ package io.element.android.libraries.di.annotations -import dev.zacsweers.metro.Qualifier - -/** - * Qualifies the Sentry SDK DSN in the DI graph. - */ -@Retention(AnnotationRetention.RUNTIME) -@MustBeDocumented -@Qualifier -@Target( - AnnotationTarget.CLASS, - AnnotationTarget.FIELD, - AnnotationTarget.FUNCTION, - AnnotationTarget.PROPERTY, - AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.VALUE_PARAMETER, - AnnotationTarget.TYPE, -) -annotation class SentrySdkDsn +@JvmInline +value class SentrySdkDsn(val value: String) diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt index f7d6646b8d..26e4f16b37 100644 --- a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt @@ -16,7 +16,6 @@ import io.element.android.libraries.di.annotations.SentrySdkDsn @BindingContainer @ContributesTo(AppScope::class) object NoopAnalyticsModule { - @SentrySdkDsn @Provides - fun provideSentrySdkDsn(): String? = null + fun provideSentrySdkDsn(): SentrySdkDsn? = null } diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt index 5ddfce4ce7..1887ed829b 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt @@ -18,6 +18,5 @@ import io.element.android.services.analyticsproviders.sentry.SentryConfig @ContributesTo(AppScope::class) object SentryModule { @Provides - @SentrySdkDsn - fun provideSentrySdkDsn(): String? = SentryConfig.SDK_DSN + fun provideSentrySdkDsn(): SentrySdkDsn? = SentrySdkDsn(SentryConfig.SDK_DSN) } From 739f12d603eac427b3c3a98e13ca1d74b875f9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 4 Dec 2025 10:27:04 +0100 Subject: [PATCH 047/347] Replace `AnalyticsSdkSpanFactory` with `AnalyticsSdkManager`. `AnalyticsSdkManager` also enables and disables Sentry logging in the SDK based on analytics user content. --- ...kFactory.kt => RustAnalyticsSdkManager.kt} | 11 +++++-- .../test/analytics/FakeAnalyticsSdkManager.kt | 24 +++++++++++++++ .../analytics/api/AnalyticsSdkManager.kt | 28 ++++++++++++++++++ .../analytics/api/AnalyticsSdkSpanFactory.kt | 16 ---------- .../analytics/impl/DefaultAnalyticsService.kt | 14 ++++----- .../impl/DefaultAnalyticsServiceTest.kt | 29 ++++++++++++++----- .../test/FakeAnalyticsSdkSpanFactory.kt | 18 ------------ 7 files changed, 88 insertions(+), 52 deletions(-) rename libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/{DefaultAnalyticsSdkFactory.kt => RustAnalyticsSdkManager.kt} (66%) create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/analytics/FakeAnalyticsSdkManager.kt create mode 100644 services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkManager.kt delete mode 100644 services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpanFactory.kt delete mode 100644 services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsSdkSpanFactory.kt diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultAnalyticsSdkFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/RustAnalyticsSdkManager.kt similarity index 66% rename from libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultAnalyticsSdkFactory.kt rename to libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/RustAnalyticsSdkManager.kt index b5d42a25e6..a74acab683 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultAnalyticsSdkFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/RustAnalyticsSdkManager.kt @@ -9,12 +9,17 @@ package io.element.android.libraries.matrix.impl.analytics import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding +import io.element.android.services.analytics.api.AnalyticsSdkManager import io.element.android.services.analytics.api.AnalyticsSdkSpan -import io.element.android.services.analytics.api.AnalyticsSdkSpanFactory +import org.matrix.rustcomponents.sdk.enableSentryLogging @ContributesBinding(AppScope::class) -class DefaultAnalyticsSdkFactory : AnalyticsSdkSpanFactory { - override fun create(name: String, parentTraceId: String?): AnalyticsSdkSpan { +class RustAnalyticsSdkManager : AnalyticsSdkManager { + override fun enableSdkAnalytics(enabled: Boolean) { + enableSentryLogging(enabled) + } + + override fun startSpan(name: String, parentTraceId: String?): AnalyticsSdkSpan { return RustAnalyticsSdkSpan(name = name, parentTraceId = parentTraceId) } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/analytics/FakeAnalyticsSdkManager.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/analytics/FakeAnalyticsSdkManager.kt new file mode 100644 index 0000000000..ab4fd48477 --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/analytics/FakeAnalyticsSdkManager.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.test.analytics + +import io.element.android.services.analytics.api.AnalyticsSdkManager +import io.element.android.services.analytics.api.AnalyticsSdkSpan +import io.element.android.services.analytics.api.NoopAnalyticsSdkSpan +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeAnalyticsSdkManager( + private val enableSdkAnalyticsLambda: ((Boolean) -> Unit) = { lambdaError() }, +) : AnalyticsSdkManager { + override fun enableSdkAnalytics(enabled: Boolean) { + enableSdkAnalyticsLambda(enabled) + } + + override fun startSpan(name: String, parentTraceId: String?): AnalyticsSdkSpan = NoopAnalyticsSdkSpan + override fun bridge(parentTraceId: String?): AnalyticsSdkSpan = NoopAnalyticsSdkSpan +} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkManager.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkManager.kt new file mode 100644 index 0000000000..bf5e04509c --- /dev/null +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkManager.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.services.analytics.api + +/** + * Manager to handle SDK analytics (e.g., Sentry). + */ +interface AnalyticsSdkManager { + /** + * Enable or disable SDK analytics. + */ + fun enableSdkAnalytics(enabled: Boolean) + + /** + * Start a new span with the given [name], using [parentTraceId] to optionally attach it to a parent transaction. + */ + fun startSpan(name: String, parentTraceId: String? = null): AnalyticsSdkSpan + + /** + * Create a 'bridge' span optionally linking it to a parent trace via [parentTraceId]. + */ + fun bridge(parentTraceId: String? = null): AnalyticsSdkSpan +} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpanFactory.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpanFactory.kt deleted file mode 100644 index 49558f37b0..0000000000 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsSdkSpanFactory.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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.services.analytics.api - -interface AnalyticsSdkSpanFactory { - /** Create an SDK span with the provided [name] and optional [parentTraceId]. */ - fun create(name: String, parentTraceId: String?): AnalyticsSdkSpan - - /** Create a bridge span which will join our tracing spans to the SDK ones while it's active. */ - fun bridge(parentTraceId: String?): AnalyticsSdkSpan -} diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt index 3dd9abf5d5..df26766506 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt @@ -20,8 +20,8 @@ import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.sessionstorage.api.observer.SessionListener import io.element.android.libraries.sessionstorage.api.observer.SessionObserver import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsSdkManager import io.element.android.services.analytics.api.AnalyticsSdkSpan -import io.element.android.services.analytics.api.AnalyticsSdkSpanFactory import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.NoopAnalyticsSdkSpan import io.element.android.services.analytics.api.NoopAnalyticsTransaction @@ -42,11 +42,9 @@ import java.util.concurrent.atomic.AtomicBoolean class DefaultAnalyticsService( private val analyticsProviders: Set<@JvmSuppressWildcards AnalyticsProvider>, private val analyticsStore: AnalyticsStore, -// private val lateInitUserPropertiesFactory: LateInitUserPropertiesFactory, - @AppCoroutineScope - private val coroutineScope: CoroutineScope, + @AppCoroutineScope private val coroutineScope: CoroutineScope, private val sessionObserver: SessionObserver, - private val analyticsSdkSpanFactory: AnalyticsSdkSpanFactory, + private val analyticsSdkManager: AnalyticsSdkManager, ) : AnalyticsService, SessionListener { private val pendingLongRunningTransactions = ConcurrentHashMap() @@ -72,6 +70,7 @@ class DefaultAnalyticsService( override suspend fun setUserConsent(userConsent: Boolean) { Timber.tag(analyticsTag.value).d("setUserConsent($userConsent)") analyticsStore.setUserConsent(userConsent) + analyticsSdkManager.enableSdkAnalytics(enabled = userConsent) } override suspend fun setDidAskUserConsent() { @@ -88,6 +87,7 @@ class DefaultAnalyticsService( // Delete the store when the last session is deleted if (wasLastSession) { analyticsStore.reset() + analyticsSdkManager.enableSdkAnalytics(false) } } @@ -179,9 +179,9 @@ class DefaultAnalyticsService( override fun enterSdkSpan(name: String?, parentTraceId: String?): AnalyticsSdkSpan { return if (userConsent.get()) { if (name != null) { - analyticsSdkSpanFactory.create(name, parentTraceId) + analyticsSdkManager.startSpan(name, parentTraceId) } else { - analyticsSdkSpanFactory.bridge(parentTraceId) + analyticsSdkManager.bridge(parentTraceId) }.apply { enter() } } else { NoopAnalyticsSdkSpan diff --git a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt index d80fb55d3f..7de3d0ac53 100644 --- a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt @@ -17,11 +17,11 @@ import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.PollEnd import im.vector.app.features.analytics.plan.SuperProperties import im.vector.app.features.analytics.plan.UserProperties +import io.element.android.libraries.matrix.test.analytics.FakeAnalyticsSdkManager import io.element.android.libraries.sessionstorage.api.observer.SessionObserver import io.element.android.libraries.sessionstorage.test.observer.NoOpSessionObserver import io.element.android.services.analytics.impl.store.AnalyticsStore import io.element.android.services.analytics.impl.store.FakeAnalyticsStore -import io.element.android.services.analytics.test.FakeAnalyticsSdkSpanFactory import io.element.android.services.analyticsproviders.api.AnalyticsProvider import io.element.android.services.analyticsproviders.test.FakeAnalyticsProvider import io.element.android.tests.testutils.lambda.lambdaRecorder @@ -33,6 +33,7 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test @@ -127,17 +128,20 @@ class DefaultAnalyticsServiceTest { } @Test - fun `setUserConsent is sent to the store`() = runTest { + fun `setUserConsent is sent to the store and the SDK`() = runTest { + val sdkAnalyticsEnabledLambda = lambdaRecorder {} val store = FakeAnalyticsStore() val sut = createDefaultAnalyticsService( coroutineScope = backgroundScope, analyticsStore = store, + sdkAnalyticsManager = FakeAnalyticsSdkManager(sdkAnalyticsEnabledLambda), ) assertThat(store.userConsentFlow.first()).isFalse() assertThat(sut.userConsentFlow.first()).isFalse() sut.setUserConsent(true) assertThat(store.userConsentFlow.first()).isTrue() assertThat(sut.userConsentFlow.first()).isTrue() + sdkAnalyticsEnabledLambda.assertions().isCalledOnce().with(value(true)) } @Test @@ -170,16 +174,19 @@ class DefaultAnalyticsServiceTest { @Test fun `when the last session is deleted, the store is reset`() = runTest { - val resetLambda = lambdaRecorder { } + val resetLambda = lambdaRecorder {} + val sdkAnalyticsEnabledLambda = lambdaRecorder {} val store = FakeAnalyticsStore( resetLambda = resetLambda, ) val sut = createDefaultAnalyticsService( coroutineScope = backgroundScope, analyticsStore = store, + sdkAnalyticsManager = FakeAnalyticsSdkManager(sdkAnalyticsEnabledLambda), ) sut.onSessionDeleted("userId", true) resetLambda.assertions().isCalledOnce() + sdkAnalyticsEnabledLambda.assertions().isCalledOnce().with(value(false)) } @Test @@ -235,7 +242,6 @@ class DefaultAnalyticsServiceTest { fun `when consent is provided, updateUserProperties is sent to the provider`() = runTest { val updateUserPropertiesLambda = lambdaRecorder { _ -> } val sut = createDefaultAnalyticsService( - coroutineScope = backgroundScope, analyticsProviders = setOf( FakeAnalyticsProvider( initLambda = { }, @@ -252,7 +258,6 @@ class DefaultAnalyticsServiceTest { fun `when super properties are updated, updateSuperProperties is sent to the provider`() = runTest { val updateSuperPropertiesLambda = lambdaRecorder { _ -> } val sut = createDefaultAnalyticsService( - coroutineScope = backgroundScope, analyticsProviders = setOf( FakeAnalyticsProvider( initLambda = { }, @@ -265,8 +270,15 @@ class DefaultAnalyticsServiceTest { updateSuperPropertiesLambda.assertions().isCalledOnce().with(value(aSuperProperty)) } - private suspend fun createDefaultAnalyticsService( - coroutineScope: CoroutineScope, + @Test + fun `startSdkSpan returns a span from the AnalyticsSdkManager`() = runTest { + val sut = createDefaultAnalyticsService() + val span = sut.enterSdkSpan("spanName", "parentTraceId") + assertThat(span).isNotNull() + } + + private suspend fun TestScope.createDefaultAnalyticsService( + coroutineScope: CoroutineScope = backgroundScope, analyticsProviders: Set<@JvmSuppressWildcards AnalyticsProvider> = setOf( FakeAnalyticsProvider( stopLambda = { }, @@ -274,12 +286,13 @@ class DefaultAnalyticsServiceTest { ), analyticsStore: AnalyticsStore = FakeAnalyticsStore(), sessionObserver: SessionObserver = NoOpSessionObserver(), + sdkAnalyticsManager: FakeAnalyticsSdkManager = FakeAnalyticsSdkManager(enableSdkAnalyticsLambda = {}), ) = DefaultAnalyticsService( analyticsProviders = analyticsProviders, analyticsStore = analyticsStore, coroutineScope = coroutineScope, sessionObserver = sessionObserver, - analyticsSdkSpanFactory = FakeAnalyticsSdkSpanFactory(), + analyticsSdkManager = sdkAnalyticsManager, ).also { // Wait for the service to be ready delay(1) diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsSdkSpanFactory.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsSdkSpanFactory.kt deleted file mode 100644 index e01f893d6d..0000000000 --- a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsSdkSpanFactory.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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.services.analytics.test - -import io.element.android.services.analytics.api.AnalyticsSdkSpan -import io.element.android.services.analytics.api.AnalyticsSdkSpanFactory -import io.element.android.services.analytics.api.NoopAnalyticsSdkSpan - -class FakeAnalyticsSdkSpanFactory : AnalyticsSdkSpanFactory { - override fun create(name: String, parentTraceId: String?): AnalyticsSdkSpan = NoopAnalyticsSdkSpan - - override fun bridge(parentTraceId: String?): AnalyticsSdkSpan = NoopAnalyticsSdkSpan -} From a27e31b01b523f6bf839af1a880841b75abc211a Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 4 Dec 2025 12:25:30 +0100 Subject: [PATCH 048/347] change(notification): handle invite notification for spaces --- .../api/notification/NotificationData.kt | 1 + .../impl/notification/NotificationMapper.kt | 1 + .../test/notification/NotificationData.kt | 2 + .../DefaultNotifiableEventResolver.kt | 23 ++++++++--- .../impl/src/main/res/values/localazy.xml | 2 + .../DefaultNotifiableEventResolverTest.kt | 40 +++++++++++++++++++ 6 files changed, 63 insertions(+), 6 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt index 40ec310c34..aff3092549 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt @@ -30,6 +30,7 @@ data class NotificationData( val roomDisplayName: String?, val isDirect: Boolean, val isDm: Boolean, + val isSpace: Boolean, val isEncrypted: Boolean, val isNoisy: Boolean, val timestamp: Long, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt index 8e33117cc7..511c899fdb 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt @@ -53,6 +53,7 @@ class NotificationMapper( roomDisplayName = item.roomInfo.displayName, isDirect = item.roomInfo.isDirect, isDm = isDm, + isSpace = item.roomInfo.isSpace, isEncrypted = item.roomInfo.isEncrypted.orFalse(), isNoisy = item.isNoisy.orFalse(), timestamp = timestamp, diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt index 3eb0758b1b..b6b6cb66e9 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt @@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.test.A_USER_NAME_2 fun aNotificationData( content: NotificationContent = NotificationContent.MessageLike.RoomEncrypted, isDirect: Boolean = false, + isSpace: Boolean = false, hasMention: Boolean = false, threadId: ThreadId? = null, timestamp: Long = A_TIMESTAMP, @@ -40,6 +41,7 @@ fun aNotificationData( roomDisplayName = roomDisplayName, isDirect = isDirect, isDm = false, + isSpace = isSpace, isEncrypted = false, isNoisy = false, timestamp = timestamp, diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt index 3b39815947..763747d7ce 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt @@ -183,7 +183,11 @@ class DefaultNotifiableEventResolver( soundName = null, isRedacted = false, isUpdated = false, - description = descriptionFromRoomMembershipInvite(senderDisambiguatedDisplayName, isDirect), + description = descriptionFromRoomMembershipInvite( + senderDisambiguatedDisplayName = senderDisambiguatedDisplayName, + isDirectRoom = isDirect, + isSpace = isSpace + ), // TODO check if type is needed anymore type = null, // TODO check if title is needed anymore @@ -332,12 +336,19 @@ class DefaultNotifiableEventResolver( private fun descriptionFromRoomMembershipInvite( senderDisambiguatedDisplayName: String, - isDirectRoom: Boolean + isDirectRoom: Boolean, + isSpace: Boolean, ): String { - return if (isDirectRoom) { - stringProvider.getString(R.string.notification_invite_body_with_sender, senderDisambiguatedDisplayName) - } else { - stringProvider.getString(R.string.notification_room_invite_body_with_sender, senderDisambiguatedDisplayName) + return when { + isDirectRoom -> { + stringProvider.getString(R.string.notification_invite_body_with_sender, senderDisambiguatedDisplayName) + } + isSpace -> { + stringProvider.getString(R.string.notification_space_invite_body_with_sender, senderDisambiguatedDisplayName) + } + else -> { + stringProvider.getString(R.string.notification_room_invite_body_with_sender, senderDisambiguatedDisplayName) + } } } diff --git a/libraries/push/impl/src/main/res/values/localazy.xml b/libraries/push/impl/src/main/res/values/localazy.xml index 0764851647..79e50a8e65 100644 --- a/libraries/push/impl/src/main/res/values/localazy.xml +++ b/libraries/push/impl/src/main/res/values/localazy.xml @@ -38,6 +38,8 @@ "%1$s invited you to join the room" "Me" "%1$s mentioned or replied" + "Invited you to join the space" + "%1$s invited you to join the space" "You are viewing the notification! Click me!" "Thread in %1$s" "%1$s: %2$s" 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 d625c7804b..58f97e55cb 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 @@ -38,6 +38,7 @@ import io.element.android.libraries.matrix.test.A_REDACTION_REASON import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.matrix.test.A_SPACE_NAME import io.element.android.libraries.matrix.test.A_TIMESTAMP import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.A_USER_NAME_2 @@ -474,6 +475,45 @@ class DefaultNotifiableEventResolverTest { assertThat(result.getEvent(request)).isEqualTo(Result.success(expectedResult)) } + @Test + fun `resolve invite space`() = runTest { + val sut = createDefaultNotifiableEventResolver( + notificationResult = Result.success( + mapOf( + AN_EVENT_ID to Result.success(aNotificationData( + content = NotificationContent.Invite( + senderId = A_USER_ID_2, + ), + roomDisplayName = A_SPACE_NAME, + isDirect = false, + isSpace = true, + )) + ) + ) + ) + val request = NotificationEventRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, "firebase") + val result = sut.resolveEvents(A_SESSION_ID, listOf(request)) + val expectedResult = ResolvedPushEvent.Event( + InviteNotifiableEvent( + sessionId = A_SESSION_ID, + roomId = A_ROOM_ID, + eventId = AN_EVENT_ID, + editedEventId = null, + canBeReplaced = true, + roomName = A_SPACE_NAME, + noisy = false, + title = null, + description = "Bob invited you to join the space", + type = null, + timestamp = A_TIMESTAMP, + soundName = null, + isRedacted = false, + isUpdated = false, + ) + ) + assertThat(result.getEvent(request)).isEqualTo(Result.success(expectedResult)) + } + @Test fun `resolve invite direct`() = runTest { val sut = createDefaultNotifiableEventResolver( From fe6c1de6f6c5344b6950b088df5053500c9c662c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 13:10:36 +0000 Subject: [PATCH 049/347] chore(deps): update plugin sonarqube to v7.2.0.6526 --- 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 83cfe607f1..9c5126345c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -264,7 +264,7 @@ roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" } sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" } knit = { id = "org.jetbrains.kotlinx.knit", version = "0.5.0" } -sonarqube = "org.sonarqube:7.1.0.6387" +sonarqube = "org.sonarqube:7.2.0.6526" licensee = "app.cash.licensee:1.14.1" compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } gms_google_services = { id = "com.google.gms.google-services", version = "4.4.4" } From effddbb583ffba24df58b0393f371b6de72d1b75 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 14:21:35 +0000 Subject: [PATCH 050/347] fix(deps): update dependency io.nlopez.compose.rules:detekt to v0.5.1 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 19aaf78405..4d657a5c72 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,7 +46,7 @@ allprojects { config.from(files("$rootDir/tools/detekt/detekt.yml")) } dependencies { - detektPlugins("io.nlopez.compose.rules:detekt:0.4.28") + detektPlugins("io.nlopez.compose.rules:detekt:0.5.1") detektPlugins(project(":tests:detekt-rules")) } From 198f3f2a0b7ec34dbcba6e39bc0d611c844c8abb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 15:19:18 +0000 Subject: [PATCH 051/347] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.12.4 --- 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 9c5126345c..71a1a097dc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -177,7 +177,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.2" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.4" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } From e814906ba1bcdc4f0b20a7491ab87ed2aa7513eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 4 Dec 2025 16:55:22 +0100 Subject: [PATCH 052/347] Restore disabled tests with FFI fakes --- .../impl/RustMatrixClientFactoryTest.kt | 2 - .../matrix/impl/RustMatrixClientTest.kt | 2 - .../impl/auth/HomeserverDetailsKtTest.kt | 2 - ...HomeserverLoginCompatibilityCheckerTest.kt | 2 - .../RustMatrixAuthenticationServiceTest.kt | 4 +- .../auth/qrlogin/SdkQrCodeLoginDataTest.kt | 2 - .../RustNotificationServiceTest.kt | 13 ++----- .../RustNotificationSettingsServiceTest.kt | 4 +- .../impl/pushers/RustPushersServiceTest.kt | 2 - .../matrix/impl/room/RoomInfoExtTest.kt | 2 - .../matrix/impl/room/RoomInfoMapperTest.kt | 2 - .../matrix/impl/room/RustBaseRoomTest.kt | 2 - .../impl/room/join/DefaultJoinRoomTest.kt | 2 - .../room/member/RoomMemberListFetcherTest.kt | 2 - .../RustBaseRoomDirectoryListTest.kt | 2 - .../RustBaseRoomDirectoryServiceTest.kt | 4 +- .../impl/roomlist/RoomListFactoryTest.kt | 4 +- .../roomlist/RoomSummaryListProcessorTest.kt | 34 ++++++----------- .../roomlist/RustBaseRoomListServiceTest.kt | 2 - .../spaces/RoomSummaryListProcessorTest.kt | 37 ++++++------------- .../impl/spaces/RustSpaceRoomListTest.kt | 10 ++--- .../MatrixTimelineDiffProcessorTest.kt | 34 ++++++----------- .../matrix/impl/timeline/RustTimelineTest.kt | 2 - .../timeline/TimelineItemsSubscriberTest.kt | 13 ++----- 24 files changed, 49 insertions(+), 136 deletions(-) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt index 471efa30a8..b81ddd713d 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt @@ -23,11 +23,9 @@ import io.element.android.services.toolbox.test.systemclock.FakeSystemClock import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import java.io.File -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class RustMatrixClientFactoryTest { @Test fun test() = runTest { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt index 06bd91eb24..c81d9f1c15 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt @@ -31,13 +31,11 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.UserProfile import java.io.File -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class RustMatrixClientTest { @Test fun `ensure that sessionId and deviceId can be retrieved from the client`() = runTest { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/HomeserverDetailsKtTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/HomeserverDetailsKtTest.kt index 82fa3dfbc7..a5c7b2dbc8 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/HomeserverDetailsKtTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/HomeserverDetailsKtTest.kt @@ -11,10 +11,8 @@ package io.element.android.libraries.matrix.impl.auth import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.auth.MatrixHomeServerDetails import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiHomeserverLoginDetails -import org.junit.Ignore import org.junit.Test -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class HomeserverDetailsKtTest { @Test fun `map should be correct`() { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustHomeserverLoginCompatibilityCheckerTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustHomeserverLoginCompatibilityCheckerTest.kt index c0122b2a7c..50d1f3723b 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustHomeserverLoginCompatibilityCheckerTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustHomeserverLoginCompatibilityCheckerTest.kt @@ -14,10 +14,8 @@ import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClient import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClientBuilder import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiHomeserverLoginDetails import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class RustHomeserverLoginCompatibilityCheckerTest { @Test fun `check - is valid if it supports OIDC login`() = runTest { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt index f620e942a9..f8f792557d 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt @@ -23,13 +23,11 @@ import io.element.android.libraries.sessionstorage.test.InMemorySessionStore import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import java.io.File class RustMatrixAuthenticationServiceTest { - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `setHomeserver is successful`() = runTest { val sut = createRustMatrixAuthenticationService( clientBuilderProvider = FakeClientBuilderProvider( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/qrlogin/SdkQrCodeLoginDataTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/qrlogin/SdkQrCodeLoginDataTest.kt index d4c71f2a83..a0c8f4598f 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/qrlogin/SdkQrCodeLoginDataTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/qrlogin/SdkQrCodeLoginDataTest.kt @@ -11,10 +11,8 @@ package io.element.android.libraries.matrix.impl.auth.qrlogin import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiQrCodeData import io.element.android.libraries.matrix.test.A_HOMESERVER_URL -import org.junit.Ignore import org.junit.Test -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class SdkQrCodeLoginDataTest { @Test fun `getServer reads the value from the Rust side, null case`() { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt index e6fc802ed2..a1dffa7c64 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt @@ -29,15 +29,13 @@ import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.NotificationClient import org.matrix.rustcomponents.sdk.NotificationStatus import org.matrix.rustcomponents.sdk.TimelineEventType class RustNotificationServiceTest { - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun test() = runTest { val notificationClient = FakeFfiNotificationClient( notificationItemResult = mapOf(AN_EVENT_ID.value to aRustBatchNotificationResult()), @@ -58,8 +56,7 @@ class RustNotificationServiceTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `test mapping invalid item only drops that item`() = runTest { val error = IllegalStateException("This event type is not supported") val faultyEvent = object : FakeFfiTimelineEvent() { @@ -86,8 +83,7 @@ class RustNotificationServiceTest { assertThat(successfulResult?.isSuccess).isTrue() } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `test unable to resolve event`() = runTest { val notificationClient = FakeFfiNotificationClient( notificationItemResult = emptyMap(), @@ -99,8 +95,7 @@ class RustNotificationServiceTest { assertThat(exception).isInstanceOf(NotificationResolverException::class.java) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `close should invoke the close method of the service`() = runTest { val closeResult = lambdaRecorder { } val notificationClient = FakeFfiNotificationClient( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsServiceTest.kt index 81d0a3307e..e9a121679b 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsServiceTest.kt @@ -16,13 +16,11 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.NotificationSettings class RustNotificationSettingsServiceTest { - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun test() = runTest { val sut = createRustNotificationSettingsService() val result = sut.getRoomNotificationSettings( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/pushers/RustPushersServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/pushers/RustPushersServiceTest.kt index 1843bf4dd1..61b2965cdd 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/pushers/RustPushersServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/pushers/RustPushersServiceTest.kt @@ -13,10 +13,8 @@ import io.element.android.libraries.matrix.api.pusher.UnsetHttpPusherData import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClient import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class RustPushersServiceTest { @Test fun `setPusher should invoke the client method`() = runTest { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoExtTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoExtTest.kt index dc4eba261b..86a50c3926 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoExtTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoExtTest.kt @@ -14,10 +14,8 @@ import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomHero import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomInfo import io.element.android.libraries.matrix.test.A_USER_ID -import org.junit.Ignore import org.junit.Test -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class RoomInfoExtTest { @Test fun `get non empty element Heroes`() { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoMapperTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoMapperTest.kt index c964f02950..5c1c4a2aa3 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoMapperTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoMapperTest.kt @@ -32,7 +32,6 @@ import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toImmutableList -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.Membership import uniffi.matrix_sdk_base.EncryptionState @@ -40,7 +39,6 @@ import org.matrix.rustcomponents.sdk.JoinRule as RustJoinRule import org.matrix.rustcomponents.sdk.RoomHistoryVisibility as RustRoomHistoryVisibility import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class RoomInfoMapperTest { @Test fun `mapping of RustRoomInfo should map all the fields`() { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt index a98a222c1e..9c8feef2dc 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt @@ -31,11 +31,9 @@ import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.isActive import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import uniffi.matrix_sdk.RoomMemberRole -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class RustBaseRoomTest { @Test fun `RustBaseRoom should cancel the room coroutine scope when it is destroyed`() = runTest { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/join/DefaultJoinRoomTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/join/DefaultJoinRoomTest.kt index e4f0b02e33..52aaa62b97 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/join/DefaultJoinRoomTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/join/DefaultJoinRoomTest.kt @@ -25,10 +25,8 @@ import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class DefaultJoinRoomTest { @Test fun `when using roomId and there is no server names, the classic join room API is used`() = runTest { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/member/RoomMemberListFetcherTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/member/RoomMemberListFetcherTest.kt index 266a4eed7c..c1c436c405 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/member/RoomMemberListFetcherTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/member/RoomMemberListFetcherTest.kt @@ -24,10 +24,8 @@ import io.element.android.libraries.matrix.test.A_USER_ID_3 import io.element.android.libraries.matrix.test.A_USER_ID_4 import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class RoomMemberListFetcherTest { @Test fun `fetchRoomMembers with CACHE source - emits cached members, if any`() = runTest { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryListTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryListTest.kt index cf3260b85c..cf3c746ec0 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryListTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryListTest.kt @@ -19,12 +19,10 @@ import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.RoomDirectorySearch import org.matrix.rustcomponents.sdk.RoomDirectorySearchEntryUpdate -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") @OptIn(ExperimentalCoroutinesApi::class) class RustBaseRoomDirectoryListTest { @Test diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryServiceTest.kt index 04e6a9a3aa..a873298f3e 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryServiceTest.kt @@ -11,12 +11,10 @@ package io.element.android.libraries.matrix.impl.roomdirectory import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClient import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test class RustBaseRoomDirectoryServiceTest { - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun test() = runTest { val client = FakeFfiClient() val sut = RustRoomDirectoryService( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactoryTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactoryTest.kt index ec8053e940..741ed93af8 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactoryTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactoryTest.kt @@ -12,13 +12,11 @@ import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiRoomList import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiRoomListService import io.element.android.services.analytics.test.FakeAnalyticsService import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import kotlin.coroutines.EmptyCoroutineContext class RoomListFactoryTest { - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `createRoomList should work`() = runTest { val sut = RoomListFactory( innerRoomListService = FakeFfiRoomListService(), diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt index eaa62abb65..bdc202d4fc 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt @@ -21,15 +21,13 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate class RoomSummaryListProcessorTest { private val summaries = MutableStateFlow>(emptyList()) - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Append adds new entries at the end of the list`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -41,8 +39,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value.subList(1, 4).all { it.roomId == A_ROOM_ID_2 }).isTrue() } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PushBack adds a new entry at the end of the list`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -52,8 +49,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value.last().roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PushFront inserts a new entry at the start of the list`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -63,8 +59,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value.first().roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Set replaces an entry at some index`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -76,8 +71,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Insert inserts a new entry at the provided index`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -89,8 +83,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Remove removes an entry at some index`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -105,8 +98,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PopBack removes an entry at the end of the list`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -121,8 +113,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PopFront removes an entry at the start of the list`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -137,8 +128,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Clear removes all the entries`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -151,8 +141,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value).isEmpty() } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Truncate removes all entries after the provided length`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -167,8 +156,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Reset removes all entries and add the provided ones`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustBaseRoomListServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustBaseRoomListServiceTest.kt index 9c8c0ddb69..88b57035e8 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustBaseRoomListServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RustBaseRoomListServiceTest.kt @@ -19,12 +19,10 @@ import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicator import org.matrix.rustcomponents.sdk.RoomListService as RustRoomListService -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") @OptIn(ExperimentalCoroutinesApi::class) class RustBaseRoomListServiceTest { @Test diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt index 116b98aaeb..253fd58dff 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt @@ -18,15 +18,13 @@ import io.element.android.libraries.previewutils.room.aSpaceRoom import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.SpaceListUpdate class RoomSummaryListProcessorTest { private val spaceRoomsFlow = MutableStateFlow>(emptyList()) - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Append adds new entries at the end of the list`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -38,8 +36,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value.subList(1, 4).all { it.roomId == A_ROOM_ID_2 }).isTrue() } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PushBack adds a new entry at the end of the list`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -49,8 +46,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value.last().roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PushFront inserts a new entry at the start of the list`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -60,8 +56,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value.first().roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Set replaces an entry at some index`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -73,8 +68,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Insert inserts a new entry at the provided index`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -86,8 +80,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Remove removes an entry at some index`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -102,8 +95,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PopBack removes an entry at the end of the list`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -118,8 +110,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PopFront removes an entry at the start of the list`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -134,8 +125,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Clear removes all the entries`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -148,8 +138,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value).isEmpty() } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Truncate removes all entries after the provided length`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -164,8 +153,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Reset removes all entries and add the provided ones`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -180,8 +168,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_3) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `When there is no replay cache SpaceListUpdateProcessor starts with an empty list`() = runTest { val spaceRoomsSharedFlow = MutableSharedFlow>(replay = 1) val processor = createProcessor( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt index 74cc97d66e..a0f8181c48 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt @@ -23,15 +23,13 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.SpaceListUpdate import uniffi.matrix_sdk_ui.SpaceRoomListPaginationState import org.matrix.rustcomponents.sdk.SpaceRoomList as InnerSpaceRoomList class RustSpaceRoomListTest { - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `paginationStatusFlow emits values`() = runTest { val innerSpaceRoomList = FakeFfiSpaceRoomList( paginationStateResult = { SpaceRoomListPaginationState.Idle(false) } @@ -53,8 +51,7 @@ class RustSpaceRoomListTest { } } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `spaceRoomsFlow emits values`() = runTest { val innerSpaceRoomList = FakeFfiSpaceRoomList( paginationStateResult = { SpaceRoomListPaginationState.Idle(false) } @@ -76,8 +73,7 @@ class RustSpaceRoomListTest { } } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `paginate invokes paginate on the inner class`() = runTest { val paginateResult = lambdaRecorder { } val innerSpaceRoomList = FakeFfiSpaceRoomList( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessorTest.kt index ba7f640514..9b5af1ffb4 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessorTest.kt @@ -21,7 +21,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.TimelineDiff @@ -31,8 +30,7 @@ class MatrixTimelineDiffProcessorTest { private val anEvent = MatrixTimelineItem.Event(A_UNIQUE_ID, anEventTimelineItem()) private val anEvent2 = MatrixTimelineItem.Event(A_UNIQUE_ID_2, anEventTimelineItem()) - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Append adds new entries at the end of the list`() = runTest { timelineItems.value = listOf(anEvent) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -44,8 +42,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PushBack adds a new entry at the end of the list`() = runTest { timelineItems.value = listOf(anEvent) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -57,8 +54,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PushFront inserts a new entry at the start of the list`() = runTest { timelineItems.value = listOf(anEvent) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -70,8 +66,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Set replaces an entry at some index`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -83,8 +78,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Insert inserts a new entry at the provided index`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -97,8 +91,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Remove removes an entry at some index`() = runTest { timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -110,8 +103,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PopBack removes an entry at the end of the list`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -122,8 +114,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `PopFront removes an entry at the start of the list`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -134,8 +125,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Clear removes all the entries`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -143,8 +133,7 @@ class MatrixTimelineDiffProcessorTest { assertThat(timelineItems.value).isEmpty() } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Truncate removes all entries after the provided length`() = runTest { timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -155,8 +144,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `Reset removes all entries and add the provided ones`() = runTest { timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimelineTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimelineTest.kt index 1dde04575e..ab46e8aa5f 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimelineTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimelineTest.kt @@ -30,13 +30,11 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.TimelineDiff import uniffi.matrix_sdk.RoomPaginationStatus import org.matrix.rustcomponents.sdk.Timeline as InnerTimeline -@Ignore("JNA direct mapping has broken unit tests with FFI fakes") class RustTimelineTest { @Test fun `ensure that the timeline emits new loading item when pagination does not bring new events`() = runTest { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriberTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriberTest.kt index 4accf26e68..607f575a2d 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriberTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriberTest.kt @@ -20,7 +20,6 @@ import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Test import org.matrix.rustcomponents.sdk.Timeline import org.matrix.rustcomponents.sdk.TimelineDiff @@ -28,8 +27,7 @@ import uniffi.matrix_sdk_ui.EventItemOrigin @OptIn(ExperimentalCoroutinesApi::class) class TimelineItemsSubscriberTest { - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `when timeline emits an empty list of items, the flow must emits an empty list`() = runTest { val timelineItems: MutableSharedFlow> = MutableSharedFlow(replay = 1, extraBufferCapacity = Int.MAX_VALUE) @@ -52,8 +50,7 @@ class TimelineItemsSubscriberTest { } } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `when timeline emits a non empty list of items, the flow must emits a non empty list`() = runTest { val timelineItems: MutableSharedFlow> = MutableSharedFlow(replay = 1, extraBufferCapacity = Int.MAX_VALUE) @@ -76,8 +73,7 @@ class TimelineItemsSubscriberTest { } } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `when timeline emits an item with SYNC origin`() = runTest { val timelineItems: MutableSharedFlow> = MutableSharedFlow(replay = 1, extraBufferCapacity = Int.MAX_VALUE) @@ -108,8 +104,7 @@ class TimelineItemsSubscriberTest { } } - @Ignore("JNA direct mapping has broken unit tests with FFI fakes") - @Test + @Test fun `multiple subscriptions does not have side effect`() = runTest { val timelineItemsSubscriber = createTimelineItemsSubscriber() timelineItemsSubscriber.subscribeIfNeeded() From 5d88a04ab0f5a194a45aa48014cafbb991e450cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 4 Dec 2025 18:02:59 +0100 Subject: [PATCH 053/347] Add missing abstractions and fakes --- .../matrix/impl/RustMatrixClientFactory.kt | 14 ++++---- .../matrix/impl/storage/SqliteStoreBuilder.kt | 35 +++++++++++++++++++ .../storage/SqliteStoreBuilderProvider.kt | 23 ++++++++++++ .../matrix/impl/FakeFfiSqliteStoreBuilder.kt | 19 ++++++++++ .../impl/RustMatrixClientFactoryTest.kt | 2 ++ .../RustMatrixAuthenticationServiceTest.kt | 2 +- .../impl/fixtures/fakes/FakeFfiClient.kt | 3 ++ .../fixtures/fakes/FakeFfiClientBuilder.kt | 1 + .../matrix/impl/fixtures/fakes/FakeFfiRoom.kt | 6 ++++ .../roomlist/RoomSummaryListProcessorTest.kt | 2 ++ .../impl/storage/FakeSqliteStoreBuilder.kt | 18 ++++++++++ .../storage/FakeSqliteStoreBuilderProvider.kt | 16 +++++++++ 12 files changed, 133 insertions(+), 8 deletions(-) create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilder.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilderProvider.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/FakeFfiSqliteStoreBuilder.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilder.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilderProvider.kt diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index 4e335ae082..58e3485279 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.impl.paths.SessionPaths import io.element.android.libraries.matrix.impl.paths.getSessionPaths import io.element.android.libraries.matrix.impl.proxy.ProxyProvider import io.element.android.libraries.matrix.impl.room.TimelineEventTypeFilterFactory +import io.element.android.libraries.matrix.impl.storage.SqliteStoreBuilderProvider import io.element.android.libraries.matrix.impl.util.anonymizedTokens import io.element.android.libraries.network.useragent.UserAgentProvider import io.element.android.libraries.sessionstorage.api.SessionData @@ -36,7 +37,6 @@ import org.matrix.rustcomponents.sdk.RequestConfig import org.matrix.rustcomponents.sdk.Session import org.matrix.rustcomponents.sdk.SlidingSyncVersion import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder -import org.matrix.rustcomponents.sdk.SqliteStoreBuilder import org.matrix.rustcomponents.sdk.use import timber.log.Timber import uniffi.matrix_sdk_base.MediaRetentionPolicy @@ -62,6 +62,7 @@ class RustMatrixClientFactory( private val featureFlagService: FeatureFlagService, private val timelineEventTypeFilterFactory: TimelineEventTypeFilterFactory, private val clientBuilderProvider: ClientBuilderProvider, + private val sqliteStoreBuilderProvider: SqliteStoreBuilderProvider, ) { private val sessionDelegate = RustClientSessionDelegate(sessionStore, appCoroutineScope, coroutineDispatchers) @@ -126,12 +127,11 @@ class RustMatrixClientFactory( slidingSyncType: ClientBuilderSlidingSync, ): ClientBuilder { return clientBuilderProvider.provide() - .sqliteStore( - SqliteStoreBuilder( - dataPath = sessionPaths.fileDirectory.absolutePath, - cachePath = sessionPaths.cacheDirectory.absolutePath, - ).passphrase(passphrase) - ) + .run { + sqliteStoreBuilderProvider.provide(sessionPaths) + .passphrase(passphrase) + .setupClientBuilder(this) + } .setSessionDelegate(sessionDelegate) .userAgent(userAgentProvider.provide()) .addRootCertificates(userCertificatesProvider.provides()) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilder.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilder.kt new file mode 100644 index 0000000000..7b5d9fb31c --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilder.kt @@ -0,0 +1,35 @@ +/* + * 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.storage + +import io.element.android.libraries.matrix.impl.paths.SessionPaths +import org.matrix.rustcomponents.sdk.ClientBuilder +import org.matrix.rustcomponents.sdk.SqliteStoreBuilder as SdkSqliteStoreBuilder + +interface SqliteStoreBuilder { + fun passphrase(passphrase: String?): SqliteStoreBuilder + fun setupClientBuilder(clientBuilder: ClientBuilder): ClientBuilder +} + +class RustSqliteStoreBuilder( + private val sessionPaths: SessionPaths, +) : SqliteStoreBuilder { + private var inner = SdkSqliteStoreBuilder( + dataPath = sessionPaths.fileDirectory.absolutePath, + cachePath = sessionPaths.cacheDirectory.absolutePath, + ) + + override fun passphrase(passphrase: String?): SqliteStoreBuilder { + inner = inner.passphrase(passphrase) + return this + } + + override fun setupClientBuilder(clientBuilder: ClientBuilder): ClientBuilder { + return clientBuilder.sqliteStore(this.inner) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilderProvider.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilderProvider.kt new file mode 100644 index 0000000000..29a30f3c56 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilderProvider.kt @@ -0,0 +1,23 @@ +/* + * 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.storage + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.matrix.impl.paths.SessionPaths + +interface SqliteStoreBuilderProvider { + fun provide(sessionPaths: SessionPaths): SqliteStoreBuilder +} + +@ContributesBinding(AppScope::class) +class RustSqliteStoreBuilderProvider : SqliteStoreBuilderProvider { + override fun provide(sessionPaths: SessionPaths): SqliteStoreBuilder { + return RustSqliteStoreBuilder(sessionPaths) + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/FakeFfiSqliteStoreBuilder.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/FakeFfiSqliteStoreBuilder.kt new file mode 100644 index 0000000000..8e3240f5be --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/FakeFfiSqliteStoreBuilder.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.matrix.impl + +import org.matrix.rustcomponents.sdk.NoHandle +import org.matrix.rustcomponents.sdk.SqliteStoreBuilder + +class FakeFfiSqliteStoreBuilder : SqliteStoreBuilder(NoHandle) { + override fun cacheSize(cacheSize: UInt?): SqliteStoreBuilder = this + override fun journalSizeLimit(limit: UInt?): SqliteStoreBuilder = this + override fun passphrase(passphrase: String?): SqliteStoreBuilder = this + override fun poolMaxSize(poolMaxSize: UInt?): SqliteStoreBuilder = this + override fun systemIsMemoryConstrained(): SqliteStoreBuilder = this +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt index b81ddd713d..a1b52d430a 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt @@ -14,6 +14,7 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.impl.auth.FakeProxyProvider import io.element.android.libraries.matrix.impl.auth.FakeUserCertificatesProvider import io.element.android.libraries.matrix.impl.room.FakeTimelineEventTypeFilterFactory +import io.element.android.libraries.matrix.impl.storage.FakeSqliteStoreBuilderProvider import io.element.android.libraries.network.useragent.SimpleUserAgentProvider import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.test.InMemorySessionStore @@ -55,4 +56,5 @@ fun TestScope.createRustMatrixClientFactory( featureFlagService = FakeFeatureFlagService(), timelineEventTypeFilterFactory = FakeTimelineEventTypeFilterFactory(), clientBuilderProvider = clientBuilderProvider, + sqliteStoreBuilderProvider = FakeSqliteStoreBuilderProvider(), ) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt index f8f792557d..f4ce7b1fdd 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt @@ -27,7 +27,7 @@ import org.junit.Test import java.io.File class RustMatrixAuthenticationServiceTest { - @Test + @Test fun `setHomeserver is successful`() = runTest { val sut = createRustMatrixAuthenticationService( clientBuilderProvider = FakeClientBuilderProvider( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt index a2227ab63a..3196cd1173 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt @@ -33,6 +33,7 @@ import org.matrix.rustcomponents.sdk.SyncServiceBuilder import org.matrix.rustcomponents.sdk.TaskHandle import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate import org.matrix.rustcomponents.sdk.UserProfile +import uniffi.matrix_sdk_base.MediaRetentionPolicy class FakeFfiClient( private val userId: String = A_USER_ID.value, @@ -88,5 +89,7 @@ class FakeFfiClient( return homeserverLoginDetailsResult() } + override suspend fun setMediaRetentionPolicy(policy: MediaRetentionPolicy) {} + override fun close() = closeResult() } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClientBuilder.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClientBuilder.kt index 3ac1fefd7e..fa10a63e42 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClientBuilder.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClientBuilder.kt @@ -44,5 +44,6 @@ class FakeFfiClientBuilder( override fun enableShareHistoryOnInvite(enableShareHistoryOnInvite: Boolean): ClientBuilder = this override fun threadsEnabled(enabled: Boolean, threadSubscriptions: Boolean): ClientBuilder = this override fun sqliteStore(config: SqliteStoreBuilder): ClientBuilder = this + override fun inMemoryStore(): ClientBuilder = this override suspend fun build() = buildResult() } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoom.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoom.kt index 86625c9737..7b60a9f4c2 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoom.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoom.kt @@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomInfo import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.tests.testutils.lambda.lambdaError import org.matrix.rustcomponents.sdk.EventTimelineItem +import org.matrix.rustcomponents.sdk.LatestEventValue import org.matrix.rustcomponents.sdk.NoHandle import org.matrix.rustcomponents.sdk.Room import org.matrix.rustcomponents.sdk.RoomInfo @@ -25,6 +26,7 @@ class FakeFfiRoom( private val getMembersNoSync: () -> RoomMembersIterator = { lambdaError() }, private val leaveLambda: () -> Unit = { lambdaError() }, private val latestEventLambda: () -> EventTimelineItem? = { lambdaError() }, + private val newLatestEventLambda: () -> LatestEventValue = { lambdaError() }, private val suggestedRoleForUserLambda: (String) -> RoomMemberRole = { lambdaError() }, private val roomInfo: RoomInfo = aRustRoomInfo(id = roomId.value), ) : Room(NoHandle) { @@ -56,6 +58,10 @@ class FakeFfiRoom( return suggestedRoleForUserLambda(userId) } + override suspend fun newLatestEvent(): LatestEventValue { + return newLatestEventLambda() + } + override fun close() { // No-op } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt index bdc202d4fc..36d5b81f42 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test +import org.matrix.rustcomponents.sdk.LatestEventValue import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate class RoomSummaryListProcessorTest { @@ -174,6 +175,7 @@ class RoomSummaryListProcessorTest { private fun aRustRoom(roomId: RoomId = A_ROOM_ID) = FakeFfiRoom( roomId = roomId, latestEventLambda = { null }, + newLatestEventLambda = { LatestEventValue.None } ) private fun TestScope.createProcessor() = RoomSummaryListProcessor( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilder.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilder.kt new file mode 100644 index 0000000000..2f12587f5a --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilder.kt @@ -0,0 +1,18 @@ +/* + * 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.storage + +import org.matrix.rustcomponents.sdk.ClientBuilder + +class FakeSqliteStoreBuilder : SqliteStoreBuilder { + override fun passphrase(passphrase: String?): SqliteStoreBuilder = this + + override fun setupClientBuilder(clientBuilder: ClientBuilder): ClientBuilder { + return clientBuilder + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilderProvider.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilderProvider.kt new file mode 100644 index 0000000000..b196604ca4 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilderProvider.kt @@ -0,0 +1,16 @@ +/* + * 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.storage + +import io.element.android.libraries.matrix.impl.paths.SessionPaths + +class FakeSqliteStoreBuilderProvider : SqliteStoreBuilderProvider { + override fun provide(sessionPaths: SessionPaths): SqliteStoreBuilder { + return FakeSqliteStoreBuilder() + } +} From 0f66fa9ee47469c7b8ba78ef6861eda60e0c0b0b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 18:44:27 +0000 Subject: [PATCH 054/347] fix(deps): update camera to v1.5.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 9c5126345c..50a2804492 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,7 +18,7 @@ constraintlayout_compose = "1.1.1" lifecycle = "2.9.2" activity = "1.11.0" media3 = "1.8.0" -camera = "1.5.1" +camera = "1.5.2" work = "2.11.0" # Compose From 9e997a2fa61acbc4ed9b0ab7610eb13068467edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 4 Dec 2025 16:35:49 +0100 Subject: [PATCH 055/347] Fix: use the right `BuildTimeConfig` field for the SDK DSN We were using `SERVICES_SENTRY_SDK_DSN`, but the enterprise template uses `SERVICES_SENTRY_DSN_RUST` --- plugins/src/main/kotlin/config/BuildTimeConfig.kt | 2 +- services/analyticsproviders/sentry/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/src/main/kotlin/config/BuildTimeConfig.kt b/plugins/src/main/kotlin/config/BuildTimeConfig.kt index 50db4cdf41..8cfa533609 100644 --- a/plugins/src/main/kotlin/config/BuildTimeConfig.kt +++ b/plugins/src/main/kotlin/config/BuildTimeConfig.kt @@ -29,7 +29,7 @@ object BuildTimeConfig { val SERVICES_POSTHOG_HOST: String? = null val SERVICES_POSTHOG_APIKEY: String? = null val SERVICES_SENTRY_DSN: String? = null - val SERVICES_SENTRY_SDK_DSN: String? = null + val SERVICES_SENTRY_DSN_RUST: String? = null val BUG_REPORT_URL: String? = null val BUG_REPORT_APP_NAME: String? = null diff --git a/services/analyticsproviders/sentry/build.gradle.kts b/services/analyticsproviders/sentry/build.gradle.kts index bbe4015e33..780e97a2d5 100644 --- a/services/analyticsproviders/sentry/build.gradle.kts +++ b/services/analyticsproviders/sentry/build.gradle.kts @@ -35,7 +35,7 @@ android { buildConfigFieldStr( name = "SDK_SENTRY_DSN", value = if (isEnterpriseBuild) { - BuildTimeConfig.SERVICES_SENTRY_SDK_DSN + BuildTimeConfig.SERVICES_SENTRY_DSN_RUST } else { System.getenv("ELEMENT_SDK_SENTRY_DSN") ?: readLocalProperty("services.analyticsproviders.sdk.sentry.dsn") From a9afa5905346bb70dbbfa9bb8c379232ae0f5046 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 5 Dec 2025 09:33:21 +0100 Subject: [PATCH 056/347] Update detekt rules after updating compose.rules to version 0.5.1. --- tools/detekt/detekt.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index cc99ecab5a..578e02ee33 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -224,27 +224,12 @@ comments: Compose: CompositionLocalAllowlist: active: true - # You can optionally define a list of CompositionLocals that are allowed here - allowedCompositionLocals: - - LocalCompoundColors - - LocalSnackbarDispatcher - - LocalCameraPositionState - - LocalMediaItemPresenterFactories - - LocalTimelineItemPresenterFactories - - LocalRoomMemberProfilesCache - - LocalMentionSpanUpdater - - LocalAnalyticsService - - LocalBuildMeta - - LocalUiTestMode - - LocalSdkIntVersionProvider CompositionLocalNaming: active: true ContentEmitterReturningValues: active: true # You can optionally add your own composables here # contentEmitters: MyComposable,MyOtherComposable - ModifierComposable: - active: true ModifierMissing: active: true ModifierReused: @@ -267,8 +252,6 @@ Compose: active: true PreviewPublic: active: true - # You can optionally disable that only previews with @PreviewParameter are flagged - previewPublicOnlyIfParams: false RememberMissing: active: true UnstableCollections: From 72b3decf4cb9da4ee18af5146068f8156008d3d6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 5 Dec 2025 09:45:23 +0100 Subject: [PATCH 057/347] Detekt: enable rule `exceptions.SwallowedException` and fix existing issue. --- .../lockscreen/impl/pin/DefaultPinCodeManager.kt | 2 +- .../messages/impl/timeline/debug/EventDebugInfoView.kt | 2 +- .../libraries/androidutils/browser/ChromeCustomTab.kt | 2 +- .../android/libraries/androidutils/hash/Hash.kt | 2 +- .../libraries/androidutils/system/SystemUtils.kt | 10 +++++----- .../io/element/android/libraries/core/hash/Hash.kt | 2 +- .../io/element/android/libraries/core/uri/UrlUtils.kt | 2 +- .../impl/FullScreenIntentPermissionsPresenter.kt | 2 +- .../android/libraries/matrix/api/roomlist/RoomList.kt | 2 +- .../libraries/matrix/impl/room/RoomSyncSubscriber.kt | 2 +- .../matrix/impl/roomlist/RoomListExtensions.kt | 2 +- .../libraries/matrix/impl/widget/RustWidgetDriver.kt | 2 +- .../push/impl/troubleshoot/PushLoopbackTest.kt | 2 +- .../libraries/pushproviders/firebase/FirebaseStore.kt | 2 +- .../io/element/android/tests/testutils/LongTask.kt | 2 +- tools/detekt/detekt.yml | 2 +- 16 files changed, 20 insertions(+), 20 deletions(-) diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/DefaultPinCodeManager.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/DefaultPinCodeManager.kt index 1ebf00dd10..091432044a 100644 --- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/DefaultPinCodeManager.kt +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/DefaultPinCodeManager.kt @@ -71,7 +71,7 @@ class DefaultPinCodeManager( lockScreenStore.onWrongPin() } } - } catch (failure: Throwable) { + } catch (_: Throwable) { false } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/debug/EventDebugInfoView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/debug/EventDebugInfoView.kt index 8a19b88b26..3b0448ddb3 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/debug/EventDebugInfoView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/debug/EventDebugInfoView.kt @@ -112,7 +112,7 @@ fun EventDebugInfoView( private fun prettyJSON(maybeJSON: String): String { return try { JSONObject(maybeJSON).toString(2) - } catch (e: JSONException) { + } catch (_: JSONException) { // Prefer not pretty-printing over crashing if the data is not actually JSON maybeJSON } diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/browser/ChromeCustomTab.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/browser/ChromeCustomTab.kt index 198518466b..6650f70ecb 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/browser/ChromeCustomTab.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/browser/ChromeCustomTab.kt @@ -60,7 +60,7 @@ fun Activity.openUrlInChromeCustomTab( }) } .launchUrl(this, url.toUri()) - } catch (activityNotFoundException: ActivityNotFoundException) { + } catch (_: ActivityNotFoundException) { openUrlInExternalApp(url) } } diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/hash/Hash.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/hash/Hash.kt index 211b60a602..b699054ff0 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/hash/Hash.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/hash/Hash.kt @@ -20,7 +20,7 @@ fun String.hash() = try { digest.digest() .joinToString("") { String.format(Locale.ROOT, "%02X", it) } .lowercase(Locale.ROOT) -} catch (exc: Exception) { +} catch (_: Exception) { // Should not happen, but just in case hashCode().toString() } diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt index 354b68a32b..861aca032d 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt @@ -32,7 +32,7 @@ fun Context.getApplicationLabel(packageName: String): String { return try { val ai = packageManager.getApplicationInfoCompat(packageName, 0) packageManager.getApplicationLabel(ai).toString() - } catch (e: PackageManager.NameNotFoundException) { + } catch (_: PackageManager.NameNotFoundException) { packageName } } @@ -96,7 +96,7 @@ fun Context.startNotificationSettingsIntent( } else { startActivity(intent) } - } catch (activityNotFoundException: ActivityNotFoundException) { + } catch (_: ActivityNotFoundException) { toast(noActivityFoundMessage) } } @@ -112,7 +112,7 @@ fun Context.openAppSettingsPage( data = Uri.fromParts("package", packageName, null) } ) - } catch (activityNotFoundException: ActivityNotFoundException) { + } catch (_: ActivityNotFoundException) { toast(noActivityFoundMessage) } } @@ -126,7 +126,7 @@ fun Context.startInstallFromSourceIntent( .setData("package:$packageName".toUri()) try { activityResultLauncher.launch(intent) - } catch (activityNotFoundException: ActivityNotFoundException) { + } catch (_: ActivityNotFoundException) { toast(noActivityFoundMessage) } } @@ -157,7 +157,7 @@ fun Context.startSharePlainTextIntent( } else { startActivity(intent) } - } catch (activityNotFoundException: ActivityNotFoundException) { + } catch (_: ActivityNotFoundException) { toast(noActivityFoundMessage) } } diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/hash/Hash.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/hash/Hash.kt index 944889bdcb..4a9af95bd1 100644 --- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/hash/Hash.kt +++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/hash/Hash.kt @@ -21,7 +21,7 @@ fun String.md5() = try { digest.digest() .joinToString("") { String.format(locale, "%02X", it) } .lowercase(locale) -} catch (exc: Exception) { +} catch (_: Exception) { // Should not happen, but just in case hashCode().toString() } diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/uri/UrlUtils.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/uri/UrlUtils.kt index a086a6fba5..666ee1d7ab 100644 --- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/uri/UrlUtils.kt +++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/uri/UrlUtils.kt @@ -14,7 +14,7 @@ fun String.isValidUrl(): Boolean { return try { URI(this).toURL() true - } catch (t: Throwable) { + } catch (_: Throwable) { false } } diff --git a/libraries/fullscreenintent/impl/src/main/kotlin/io/element/android/libraries/fullscreenintent/impl/FullScreenIntentPermissionsPresenter.kt b/libraries/fullscreenintent/impl/src/main/kotlin/io/element/android/libraries/fullscreenintent/impl/FullScreenIntentPermissionsPresenter.kt index ed406e75ff..d4a3e75d1a 100644 --- a/libraries/fullscreenintent/impl/src/main/kotlin/io/element/android/libraries/fullscreenintent/impl/FullScreenIntentPermissionsPresenter.kt +++ b/libraries/fullscreenintent/impl/src/main/kotlin/io/element/android/libraries/fullscreenintent/impl/FullScreenIntentPermissionsPresenter.kt @@ -88,7 +88,7 @@ class FullScreenIntentPermissionsPresenter( "package:${buildMeta.applicationId}".toUri() ) externalIntentLauncher.launch(intent) - } catch (e: ActivityNotFoundException) { + } catch (_: ActivityNotFoundException) { val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) .putExtra(Settings.EXTRA_APP_PACKAGE, buildMeta.applicationId) externalIntentLauncher.launch(intent) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomList.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomList.kt index d03a9677e3..a0d092596a 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomList.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomList.kt @@ -65,7 +65,7 @@ suspend fun RoomList.awaitLoaded(timeout: Duration = Duration.INFINITE) { it is RoomList.LoadingState.Loaded } } - } catch (timeoutException: TimeoutCancellationException) { + } catch (_: TimeoutCancellationException) { Timber.d("awaitAllRoomsAreLoaded: no response after $timeout") } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomSyncSubscriber.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomSyncSubscriber.kt index 6a6b45b7a7..724e3f62f0 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomSyncSubscriber.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomSyncSubscriber.kt @@ -34,7 +34,7 @@ class RoomSyncSubscriber( } subscribedRoomIds.add(roomId) } catch (exception: Exception) { - Timber.e("Failed to subscribe to room $roomId") + Timber.e(exception, "Failed to subscribe to room $roomId") } } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt index 84e759040d..ae241e9c02 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt @@ -48,7 +48,7 @@ fun RoomListInterface.loadingStateFlow(): Flow = try { send(result.state) } catch (exception: Exception) { - Timber.d("loadingStateFlow() initialState failed.") + Timber.d(exception, "loadingStateFlow() initialState failed.") } result.stateStream }.catch { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/widget/RustWidgetDriver.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/widget/RustWidgetDriver.kt index 1d1824d240..b908082ab6 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/widget/RustWidgetDriver.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/widget/RustWidgetDriver.kt @@ -62,7 +62,7 @@ class RustWidgetDriver( override suspend fun send(message: String) { try { driverAndHandle.handle.send(message) - } catch (e: IllegalStateException) { + } catch (_: IllegalStateException) { // The handle is closed, ignore } } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushLoopbackTest.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushLoopbackTest.kt index 64b8f98f5b..91ac1ca0ee 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushLoopbackTest.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushLoopbackTest.kt @@ -56,7 +56,7 @@ class PushLoopbackTest( } val testPushResult = try { pushService.testPush(sessionId) - } catch (pusherRejected: PushGatewayFailure.PusherRejected) { + } catch (_: PushGatewayFailure.PusherRejected) { val hasQuickFix = pushService.getCurrentPushProvider(sessionId)?.canRotateToken() == true delegate.updateState( description = stringProvider.getString(R.string.troubleshoot_notifications_test_push_loop_back_failure_1), diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebaseStore.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebaseStore.kt index 2d3f9dce39..1f6a4709cc 100644 --- a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebaseStore.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebaseStore.kt @@ -40,7 +40,7 @@ class SharedPreferencesFirebaseStore( if (k == PREFS_KEY_FCM_TOKEN) { try { flow.value = getFcmToken() - } catch (e: Exception) { + } catch (_: Exception) { flow.value = null } } diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/LongTask.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/LongTask.kt index 5e3367fcc4..bbaa1cf741 100644 --- a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/LongTask.kt +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/LongTask.kt @@ -34,7 +34,7 @@ suspend fun awaitWithLatch(timeout: Duration = 300.milliseconds, block: (Complet withTimeout(timeout) { latch.also(block).await() } - } catch (exception: TimeoutCancellationException) { + } catch (_: TimeoutCancellationException) { latch.complete(Unit) } } diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 578e02ee33..552b46755e 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -150,7 +150,7 @@ exceptions: TooGenericExceptionCaught: active: false SwallowedException: - active: false + active: true ThrowingExceptionsWithoutMessageOrCause: active: true TooGenericExceptionThrown: From 096b8768ea9331850e27ddf28383bacdb6bfb6f9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 5 Dec 2025 09:48:26 +0100 Subject: [PATCH 058/347] Fix warning "Throwable should be first argument" --- .../io/element/android/libraries/matrix/impl/util/Error.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/Error.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/Error.kt index 0a1f45d1d1..70fea1287e 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/Error.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/Error.kt @@ -14,10 +14,10 @@ import timber.log.Timber fun logError(throwable: Throwable) { when (throwable) { is ClientException.Generic -> { - Timber.e("Error ${throwable.msg}", throwable) + Timber.e(throwable, "Error ${throwable.msg}") } else -> { - Timber.e("Error", throwable) + Timber.e(throwable, "Error") } } } From 9b056f8aecb466b3619ede5a0311df7cf98696fb Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Dec 2025 12:53:58 +0100 Subject: [PATCH 059/347] misc(power level) : introduce RoomPermissions --- .../libraries/matrix/api/room/BaseRoom.kt | 6 + .../api/room/powerlevels/RoomPermissions.kt | 142 ++++++++++++++++++ .../matrix/impl/room/RustBaseRoom.kt | 8 + .../room/powerlevels/RustRoomPermissions.kt | 95 ++++++++++++ .../matrix/test/room/FakeBaseRoom.kt | 7 + .../room/powerlevels/FakeRoomPermissions.kt | 58 +++++++ 6 files changed, 316 insertions(+) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RustRoomPermissions.kt create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt index 41e6ce0e62..cde3a5eff7 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt @@ -14,6 +14,7 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.draft.ComposerDraft +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility @@ -99,6 +100,11 @@ interface BaseRoom : Closeable { */ suspend fun userRole(userId: UserId): Result + /** + * Gets the permissions of the room. + */ + suspend fun roomPermissions(): Result + /** * Gets the display name of the user with the provided [userId] in the room. */ diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt new file mode 100644 index 0000000000..cdc735b819 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt @@ -0,0 +1,142 @@ +/* + * 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.powerlevels + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.StateEventType + +/** + * Provides information about the permissions of users in a room. + */ +interface RoomPermissions : AutoCloseable { + fun canOwnUserBan(): Boolean + + /** + * Returns true if the current user is able to invite in the room. + */ + fun canOwnUserInvite(): Boolean + + /** + * Returns true if the current user is able to kick in the room. + */ + fun canOwnUserKick(): Boolean + + /** + * Returns true if the current user is able to pin or unpin events in the + * room. + */ + fun canOwnUserPinUnpin(): Boolean + + /** + * Returns true if the current user user is able to redact messages of + * other users in the room. + */ + fun canOwnUserRedactOther(): Boolean + + /** + * Returns true if the current user is able to redact their own messages in + * the room. + */ + fun canOwnUserRedactOwn(): Boolean + + /** + * Returns true if the current user is able to send a specific message type + * in the room. + */ + fun canOwnUserSendMessage(message: MessageEventType): Boolean + + /** + * Returns true if the current user is able to send a specific state event + * type in the room. + */ + fun canOwnUserSendState(stateEvent: StateEventType): Boolean + + /** + * Returns true if the current user is able to trigger a notification in + * the room. + */ + fun canOwnUserTriggerRoomNotification(): Boolean + + /** + * Returns true if the user with the given userId is able to ban in the + * room. + */ + fun canUserBan(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to invite in the + * room. + */ + fun canUserInvite(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to kick in the + * room. + */ + fun canUserKick(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to pin or unpin + * events in the room. + */ + fun canUserPinUnpin(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to redact + * messages of other users in the room. + */ + fun canUserRedactOther(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to redact + * their own messages in the room. + */ + fun canUserRedactOwn(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to send a + * specific message type in the room. + */ + fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean + + /** + * Returns true if the user with the given userId is able to send a + * specific state event type in the room. + */ + fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean + + /** + * Returns true if the user with the given userId is able to trigger a + * notification in the room. + * + * The call may fail if there is an error in getting the power levels. + */ + fun canUserTriggerRoomNotification(userId: UserId): Boolean +} + +fun RoomPermissions.canEditRoomDetails(): Boolean { + return canOwnUserSendState(StateEventType.ROOM_NAME) || + canOwnUserSendState(StateEventType.ROOM_TOPIC) || + canOwnUserSendState(StateEventType.ROOM_AVATAR) +} + +fun RoomPermissions.canManageKnockRequests(): Boolean { + return canOwnUserInvite() || canOwnUserBan() || canOwnUserKick() +} + +fun RoomPermissions.canEditSecurityAndPrivacy(): Boolean { + return canOwnUserSendState(StateEventType.ROOM_JOIN_RULES) || + canOwnUserSendState(StateEventType.ROOM_HISTORY_VISIBILITY) || + canOwnUserSendState(StateEventType.ROOM_CANONICAL_ALIAS) || + canOwnUserSendState(StateEventType.ROOM_ENCRYPTION) +} + +fun RoomPermissions.canEditRolesAndPermissions(): Boolean { + return canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS) +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt index be7f6240ee..eec9591e32 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.draft.ComposerDraft +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility @@ -33,6 +34,7 @@ import io.element.android.libraries.matrix.impl.room.draft.into import io.element.android.libraries.matrix.impl.room.member.RoomMemberListFetcher import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.powerlevels.RoomPowerLevelsValuesMapper +import io.element.android.libraries.matrix.impl.room.powerlevels.RustRoomPermissions import io.element.android.libraries.matrix.impl.room.tombstone.map import io.element.android.libraries.matrix.impl.roomdirectory.map import io.element.android.libraries.matrix.impl.timeline.toRustReceiptType @@ -178,6 +180,12 @@ class RustBaseRoom( } } + override suspend fun roomPermissions(): Result = withContext(roomDispatcher) { + runCatchingExceptions { + RustRoomPermissions(innerRoom.getPowerLevels()) + } + } + override suspend fun canUserInvite(userId: UserId): Result = withContext(roomDispatcher) { runCatchingExceptions { innerRoom.getPowerLevels().use { it.canUserInvite(userId.value) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RustRoomPermissions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RustRoomPermissions.kt new file mode 100644 index 0000000000..57e20b166f --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RustRoomPermissions.kt @@ -0,0 +1,95 @@ +/* + * 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.powerlevels + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions +import io.element.android.libraries.matrix.impl.room.map +import org.matrix.rustcomponents.sdk.RoomPowerLevels + +class RustRoomPermissions( + private val inner: RoomPowerLevels, +) : RoomPermissions { + override fun canOwnUserBan(): Boolean { + return inner.canOwnUserBan() + } + + override fun canOwnUserInvite(): Boolean { + return inner.canOwnUserInvite() + } + + override fun canOwnUserKick(): Boolean { + return inner.canOwnUserKick() + } + + override fun canOwnUserPinUnpin(): Boolean { + return inner.canOwnUserPinUnpin() + } + + override fun canOwnUserRedactOther(): Boolean { + return inner.canOwnUserRedactOther() + } + + override fun canOwnUserRedactOwn(): Boolean { + return inner.canOwnUserRedactOwn() + } + + override fun canOwnUserSendMessage(message: MessageEventType): Boolean { + return inner.canOwnUserSendMessage(message.map()) + } + + override fun canOwnUserSendState(stateEvent: StateEventType): Boolean { + return inner.canOwnUserSendState(stateEvent.map()) + } + + override fun canOwnUserTriggerRoomNotification(): Boolean { + return inner.canOwnUserTriggerRoomNotification() + } + + override fun canUserBan(userId: UserId): Boolean { + return inner.canUserBan(userId.value) + } + + override fun canUserInvite(userId: UserId): Boolean { + return inner.canUserInvite(userId.value) + } + + override fun canUserKick(userId: UserId): Boolean { + return inner.canUserKick(userId.value) + } + + override fun canUserPinUnpin(userId: UserId): Boolean { + return inner.canUserPinUnpin(userId.value) + } + + override fun canUserRedactOther(userId: UserId): Boolean { + return inner.canUserRedactOther(userId.value) + } + + override fun canUserRedactOwn(userId: UserId): Boolean { + return inner.canUserRedactOwn(userId.value) + } + + override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean { + return inner.canUserSendMessage(userId.value, message.map()) + } + + override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean { + return inner.canUserSendState(userId.value, stateEvent.map()) + } + + override fun canUserTriggerRoomNotification(userId: UserId): Boolean { + return inner.canUserTriggerRoomNotification(userId.value) + } + + override fun close() { + inner.close() + } +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt index 56f880dc11..b05eff77e2 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt @@ -21,12 +21,14 @@ import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.draft.ComposerDraft +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.simulateLongTask import kotlinx.coroutines.CoroutineScope @@ -48,6 +50,7 @@ class FakeBaseRoom( private val userRoleResult: () -> Result = { lambdaError() }, private val getUpdatedMemberResult: (UserId) -> Result = { lambdaError() }, private val joinRoomResult: () -> Result = { lambdaError() }, + private val roomPermissionsResult: () -> Result = { Result.success(FakeRoomPermissions()) }, private val canInviteResult: (UserId) -> Result = { lambdaError() }, private val canKickResult: (UserId) -> Result = { lambdaError() }, private val canBanResult: (UserId) -> Result = { lambdaError() }, @@ -129,6 +132,10 @@ class FakeBaseRoom( return userRoleResult() } + override suspend fun roomPermissions(): Result { + return roomPermissionsResult() + } + override suspend fun getPermalink(): Result { return roomPermalinkResult() } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt new file mode 100644 index 0000000000..04ecb1f60b --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt @@ -0,0 +1,58 @@ +/* + * 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.test.room.powerlevels + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class FakeRoomPermissions( + val ownerCanBan: Boolean = false, + val ownerCanInvite: Boolean = false, + val ownerCanKick: Boolean = false, + val ownerCanPinUnpin: Boolean = false, + val ownerCanRedactOther: Boolean = false, + val ownerCanRedactOwn: Boolean = false, + val ownerCanTriggerRoomNotification: Boolean = false, + val ownerCanSendMessage: (MessageEventType) -> Boolean = { false }, + val ownerCanSendState: (StateEventType) -> Boolean = { false }, + val userCanBan: (UserId) -> Boolean = { false }, + val userCanInvite: (UserId) -> Boolean = { false }, + val userCanKick: (UserId) -> Boolean = { false }, + val userCanPinUnpin: (UserId) -> Boolean = { false }, + val userCanRedactOther: (UserId) -> Boolean = { false }, + val userCanRedactOwn: (UserId) -> Boolean = { false }, + val userCanTriggerRoomNotification: (UserId) -> Boolean = { false }, + val userCanSendMessage: (UserId, MessageEventType) -> Boolean = { _, _ -> false }, + val userCanSendState: (UserId, StateEventType) -> Boolean = { _, _ -> false }, +) : RoomPermissions { + + override fun canOwnUserBan(): Boolean = ownerCanBan + override fun canOwnUserInvite(): Boolean = ownerCanInvite + override fun canOwnUserKick(): Boolean = ownerCanKick + override fun canOwnUserPinUnpin(): Boolean = ownerCanPinUnpin + override fun canOwnUserRedactOther(): Boolean = ownerCanRedactOther + override fun canOwnUserRedactOwn(): Boolean = ownerCanRedactOwn + override fun canOwnUserSendMessage(message: MessageEventType): Boolean = ownerCanSendMessage(message) + override fun canOwnUserSendState(stateEvent: StateEventType): Boolean = ownerCanSendState(stateEvent) + override fun canOwnUserTriggerRoomNotification(): Boolean = ownerCanTriggerRoomNotification + override fun canUserBan(userId: UserId): Boolean = userCanBan(userId) + override fun canUserInvite(userId: UserId): Boolean = userCanInvite(userId) + override fun canUserKick(userId: UserId): Boolean = userCanKick(userId) + override fun canUserPinUnpin(userId: UserId): Boolean = userCanPinUnpin(userId) + override fun canUserRedactOther(userId: UserId): Boolean = userCanRedactOther(userId) + override fun canUserRedactOwn(userId: UserId): Boolean = userCanRedactOwn(userId) + override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean = userCanSendMessage(userId, message) + override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean = userCanSendState(userId, stateEvent) + override fun canUserTriggerRoomNotification(userId: UserId): Boolean = userCanTriggerRoomNotification(userId) + + override fun close() { + // no-op for the fake + } +} From f745f2ca1e1622f90a395f1e52063465929e9f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 4 Dec 2025 11:05:19 +0100 Subject: [PATCH 060/347] Add `SessionRestorationException`, make sure `ClientException` can expose it through the `cause` property --- .../api/auth/SessionRestorationException.kt | 15 +++++++++++++++ .../matrix/api/exception/ClientException.kt | 8 ++++---- .../impl/auth/RustMatrixAuthenticationService.kt | 5 +++-- .../impl/encryption/RecoveryExceptionMapper.kt | 2 +- .../matrix/impl/exception/ClientException.kt | 5 +++-- 5 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/SessionRestorationException.kt diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/SessionRestorationException.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/SessionRestorationException.kt new file mode 100644 index 0000000000..bf6f50cab5 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/SessionRestorationException.kt @@ -0,0 +1,15 @@ +/* + * 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.auth + +import io.element.android.libraries.matrix.api.core.SessionId + +sealed class SessionRestorationException(message: String, cause: Throwable? = null) : Exception(message, cause) { + data class MissingSession(val sessionId: SessionId) : SessionRestorationException("Session with id $sessionId not found") + class InvalidToken : SessionRestorationException("Access token is invalid or expired") +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/exception/ClientException.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/exception/ClientException.kt index 35acec43ca..30f77e7b5e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/exception/ClientException.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/exception/ClientException.kt @@ -8,10 +8,10 @@ package io.element.android.libraries.matrix.api.exception -sealed class ClientException(message: String, val details: String?) : Exception(message) { - class Generic(message: String, details: String?) : ClientException(message, details) - class MatrixApi(val kind: ErrorKind, val code: String, message: String, details: String?) : ClientException(message, details) - class Other(message: String) : ClientException(message, null) +sealed class ClientException(message: String, val details: String?, cause: Throwable? = null) : Exception(message, cause) { + class Generic(message: String, details: String?, cause: Throwable? = null) : ClientException(message, details, cause) + class MatrixApi(val kind: ErrorKind, val code: String, message: String, details: String?, cause: Throwable? = null) : ClientException(message, details, cause) + class Other(message: String, cause: Throwable? = null) : ClientException(message, null, cause) } fun ClientException.isNetworkError(): Boolean { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt index df4333654b..97719bed36 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt @@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.auth.MatrixHomeServerDetails import io.element.android.libraries.matrix.api.auth.OidcDetails import io.element.android.libraries.matrix.api.auth.OidcPrompt +import io.element.android.libraries.matrix.api.auth.SessionRestorationException import io.element.android.libraries.matrix.api.auth.external.ExternalSession import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep @@ -91,10 +92,10 @@ class RustMatrixAuthenticationService( } rustMatrixClientFactory.create(sessionData) } else { - error("Token is not valid") + throw SessionRestorationException.InvalidToken() } } else { - error("No session to restore with id $sessionId") + throw SessionRestorationException.MissingSession(sessionId) } }.mapFailure { failure -> failure.mapClientException() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RecoveryExceptionMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RecoveryExceptionMapper.kt index 76a72cd65b..f5d1a4253b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RecoveryExceptionMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RecoveryExceptionMapper.kt @@ -30,7 +30,7 @@ fun Throwable.mapRecoveryException(): RecoveryException { } } else -> RecoveryException.Client( - ClientException.Other("Unknown error") + ClientException.Other("Unknown error", this) ) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/exception/ClientException.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/exception/ClientException.kt index 668e55e9bf..eefa6d4986 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/exception/ClientException.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/exception/ClientException.kt @@ -15,15 +15,16 @@ fun Throwable.mapClientException(): ClientException { return when (this) { is RustClientException -> { when (this) { - is RustClientException.Generic -> ClientException.Generic(msg, details) + is RustClientException.Generic -> ClientException.Generic(message = msg, details = details, cause = this) is RustClientException.MatrixApi -> ClientException.MatrixApi( kind = kind.map(), code = code, message = msg, details = details, + cause = this, ) } } - else -> ClientException.Other(message ?: "Unknown error") + else -> ClientException.Other(message ?: "Unknown error", this) } } From 754c0781f9e01298866b3590bc47a5018678070d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 4 Dec 2025 11:06:14 +0100 Subject: [PATCH 061/347] Don't re-schedule notification fetches if the cause of the failure is `SessionRestorationException`, since that means it'll most likely fail again --- .../matrix/api/exception/ClientException.kt | 6 +++++- .../DefaultNotifiableEventResolver.kt | 2 +- .../impl/workmanager/FetchNotificationsWorker.kt | 15 +++++++++++---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/exception/ClientException.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/exception/ClientException.kt index 30f77e7b5e..52b1577bf0 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/exception/ClientException.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/exception/ClientException.kt @@ -10,7 +10,11 @@ package io.element.android.libraries.matrix.api.exception sealed class ClientException(message: String, val details: String?, cause: Throwable? = null) : Exception(message, cause) { class Generic(message: String, details: String?, cause: Throwable? = null) : ClientException(message, details, cause) - class MatrixApi(val kind: ErrorKind, val code: String, message: String, details: String?, cause: Throwable? = null) : ClientException(message, details, cause) + class MatrixApi(val kind: ErrorKind, val code: String, message: String, details: String?, cause: Throwable? = null) : ClientException( + message = message, + details = details, + cause = cause + ) class Other(message: String, cause: Throwable? = null) : ClientException(message, null, cause) } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt index 763747d7ce..e3d0f21d03 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt @@ -99,7 +99,7 @@ class DefaultNotifiableEventResolver( ): ResolvePushEventsResult { Timber.d("Queueing notifications: $notificationEventRequests") val client = matrixClientProvider.getOrRestore(sessionId).getOrElse { - return Result.failure(IllegalStateException("Couldn't get or restore client for session $sessionId")) + return Result.failure(it) } val ids = notificationEventRequests.groupBy { it.roomId } .mapValues { (_, requests) -> diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationsWorker.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationsWorker.kt index be8db1a11e..ccc0a02749 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationsWorker.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationsWorker.kt @@ -22,6 +22,7 @@ import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.di.annotations.ApplicationContext +import io.element.android.libraries.matrix.api.auth.SessionRestorationException import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.push.api.push.NotificationEventRequest import io.element.android.libraries.push.api.push.SyncOnNotifiableEvent @@ -63,9 +64,9 @@ class FetchNotificationsWorker( return@withContext Result.retry() } - val failedSyncForSessions = mutableSetOf() + val failedSyncForSessions = mutableMapOf() - val groupedRequests = requests.groupBy { it.sessionId } + val groupedRequests = requests.groupBy { it.sessionId }.toMutableMap() for ((sessionId, notificationRequests) in groupedRequests) { Timber.d("Processing notification requests for session $sessionId") eventResolver.resolveEvents(sessionId, notificationRequests) @@ -75,7 +76,7 @@ class FetchNotificationsWorker( (queue.results as MutableSharedFlow).emit(requests to result) }, onFailure = { - failedSyncForSessions += sessionId + failedSyncForSessions[sessionId] = it Timber.e(it, "Failed to resolve notification events for session $sessionId") } ) @@ -83,7 +84,13 @@ class FetchNotificationsWorker( // If there were failures for whole sessions, we retry all their requests if (failedSyncForSessions.isNotEmpty()) { - for (failedSessionId in failedSyncForSessions) { + @Suppress("LoopWithTooManyJumpStatements") + for ((failedSessionId, exception) in failedSyncForSessions) { + if (exception.cause is SessionRestorationException) { + Timber.e(exception, "Session $failedSessionId could not be restored, not retrying notification fetching") + groupedRequests.remove(failedSessionId) + continue + } val requestsToRetry = groupedRequests[failedSessionId] ?: continue Timber.d("Re-scheduling ${requestsToRetry.size} failed notification requests for session $failedSessionId") workManagerScheduler.submit( From 221e18d1399e48667ce7227f83c71bf295e001ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 4 Dec 2025 12:07:08 +0100 Subject: [PATCH 062/347] Test `DefaultWorkManagerScheduler` --- .../test/InMemorySessionStore.kt | 4 +- libraries/workmanager/impl/build.gradle.kts | 4 + .../impl/DefaultWorkManagerScheduler.kt | 30 ++++- .../workmanager/impl/WorkManagerModule.kt | 29 +++++ .../impl/DefaultWorkManagerSchedulerTest.kt | 120 ++++++++++++++++++ 5 files changed, 180 insertions(+), 7 deletions(-) create mode 100644 libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/WorkManagerModule.kt create mode 100644 libraries/workmanager/impl/src/test/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerSchedulerTest.kt diff --git a/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/InMemorySessionStore.kt b/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/InMemorySessionStore.kt index 6cab993da1..05e58ac623 100644 --- a/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/InMemorySessionStore.kt +++ b/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/InMemorySessionStore.kt @@ -81,8 +81,6 @@ class InMemorySessionStore( } override suspend fun removeSession(sessionId: String) { - val currentList = sessionDataListFlow.value.toMutableList() - currentList.removeAll { it.userId == sessionId } - sessionDataListFlow.value = currentList + sessionDataListFlow.value = sessionDataListFlow.value.filter { it.userId != sessionId } } } diff --git a/libraries/workmanager/impl/build.gradle.kts b/libraries/workmanager/impl/build.gradle.kts index ebf0f906bc..878edb6fe2 100644 --- a/libraries/workmanager/impl/build.gradle.kts +++ b/libraries/workmanager/impl/build.gradle.kts @@ -1,4 +1,5 @@ import extension.setupDependencyInjection +import extension.testCommonDependencies /* * Copyright (c) 2025 Element Creations Ltd. @@ -22,4 +23,7 @@ dependencies { implementation(projects.libraries.core) implementation(projects.libraries.matrix.api) implementation(projects.libraries.di) + + testCommonDependencies(libs, false) + testImplementation(projects.libraries.sessionStorage.test) } diff --git a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt index 6943c1432e..c80735c675 100644 --- a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt +++ b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt @@ -8,23 +8,45 @@ package io.element.android.libraries.workmanager.impl -import android.content.Context import androidx.work.WorkManager import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding -import io.element.android.libraries.di.annotations.ApplicationContext +import io.element.android.libraries.core.coroutine.withPreviousValue +import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.workmanager.api.WorkManagerRequest import io.element.android.libraries.workmanager.api.WorkManagerRequestType import io.element.android.libraries.workmanager.api.WorkManagerScheduler import io.element.android.libraries.workmanager.api.workManagerTag +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach import timber.log.Timber @ContributesBinding(AppScope::class) class DefaultWorkManagerScheduler( - @ApplicationContext private val context: Context, + lazyWorkManager: Lazy, + @AppCoroutineScope private val appCoroutineScope: CoroutineScope, + sessionStore: SessionStore, ) : WorkManagerScheduler { - private val workManager by lazy { WorkManager.getInstance(context) } + private val workManager by lazyWorkManager + + init { + // Observe session removals to cancel associated work automatically + sessionStore.sessionsFlow() + .map { sessions -> sessions.map { SessionId(it.userId) } } + .withPreviousValue() + .map { (prev, new) -> prev.orEmpty() - new.toSet() } + .onEach { removedSessions -> + for (sessionId in removedSessions) { + Timber.d("Session removed for userId: $sessionId, cancelling associated workmanager requests") + cancel(sessionId) + } + } + .launchIn(appCoroutineScope) + } override fun submit(workManagerRequest: WorkManagerRequest) { workManagerRequest.build().fold( diff --git a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/WorkManagerModule.kt b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/WorkManagerModule.kt new file mode 100644 index 0000000000..7df9e7f431 --- /dev/null +++ b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/WorkManagerModule.kt @@ -0,0 +1,29 @@ +/* + * 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.workmanager.impl + +import android.content.Context +import androidx.work.WorkManager +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.BindingContainer +import dev.zacsweers.metro.ContributesTo +import dev.zacsweers.metro.Provides +import dev.zacsweers.metro.SingleIn +import io.element.android.libraries.di.annotations.ApplicationContext + +@BindingContainer +@ContributesTo(AppScope::class) +object WorkManagerModule { + @Provides + @SingleIn(AppScope::class) + fun providesWorkManager( + @ApplicationContext context: Context, + ): WorkManager { + return WorkManager.getInstance(context) + } +} diff --git a/libraries/workmanager/impl/src/test/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerSchedulerTest.kt b/libraries/workmanager/impl/src/test/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerSchedulerTest.kt new file mode 100644 index 0000000000..5ecf0c4a1f --- /dev/null +++ b/libraries/workmanager/impl/src/test/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerSchedulerTest.kt @@ -0,0 +1,120 @@ +/* + * 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.workmanager.impl + +import androidx.work.WorkManager +import androidx.work.WorkRequest +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.sessionstorage.test.InMemorySessionStore +import io.element.android.libraries.sessionstorage.test.aSessionData +import io.element.android.libraries.workmanager.api.WorkManagerRequest +import io.element.android.libraries.workmanager.api.WorkManagerRequestType +import io.element.android.libraries.workmanager.api.workManagerTag +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) +class DefaultWorkManagerSchedulerTest { + @Test + fun `starts observing sessions on init to remove work for logged out sessions`() = runTest { + val sessionId = "@session1:matrix.org" + val sessionStore = InMemorySessionStore(initialList = listOf(aSessionData(sessionId = sessionId))) + + val workManager = spyk() + + DefaultWorkManagerScheduler( + lazyWorkManager = lazy { workManager }, + appCoroutineScope = backgroundScope, + sessionStore = sessionStore, + ) + + // We have a single initial session + assertThat(sessionStore.numberOfSessions()).isEqualTo(1) + + runCurrent() + + // We remove the session + sessionStore.removeSession(sessionId) + + runCurrent() + + // The session is now gone and work associated with the session is cancelled + assertThat(sessionStore.numberOfSessions()).isEqualTo(0) + verify { workManager.cancelAllWorkByTag("notifications-$sessionId") } + } + + @Test + fun `submit builds the request and enqueues it`() = runTest { + val sessionStore = InMemorySessionStore() + val workManager = spyk() + + val scheduler = DefaultWorkManagerScheduler( + lazyWorkManager = lazy { workManager }, + appCoroutineScope = backgroundScope, + sessionStore = sessionStore, + ) + + scheduler.submit(FakeWorkManagerRequest()) + + verify { workManager.enqueue(any>()) } + } + + @Test + fun `submit won't do anything if building the work request fails`() = runTest { + val sessionStore = InMemorySessionStore() + val workManager = spyk() + + val scheduler = DefaultWorkManagerScheduler( + lazyWorkManager = lazy { workManager }, + appCoroutineScope = backgroundScope, + sessionStore = sessionStore, + ) + + scheduler.submit(FakeWorkManagerRequest(result = Result.failure(IllegalStateException("Test error")))) + + verify(exactly = 0) { workManager.enqueue(any>()) } + } + + @Test + fun `cancel will cancel all pending work for a session id`() = runTest { + val sessionStore = InMemorySessionStore() + val workManager = spyk() + + val scheduler = DefaultWorkManagerScheduler( + lazyWorkManager = lazy { workManager }, + appCoroutineScope = backgroundScope, + sessionStore = sessionStore, + ) + + val sessionId = SessionId("@alice:matrix.org") + val tagToRemove = workManagerTag(sessionId, WorkManagerRequestType.NOTIFICATION_SYNC) + val mockSessionA = mockk { + every { tags } returns setOf(tagToRemove) + } + scheduler.submit(FakeWorkManagerRequest(result = Result.success(listOf(mockSessionA)))) + + scheduler.cancel(sessionId) + + verify { workManager.cancelAllWorkByTag(tagToRemove) } + } +} + +private class FakeWorkManagerRequest( + private val result: Result> = Result.success(listOf()), +) : WorkManagerRequest { + override fun build(): Result> { + return result + } +} From 7eae3a16aec9c70690404d18ef079827d7689980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 5 Dec 2025 17:07:54 +0100 Subject: [PATCH 063/347] Use `SessionObserver` instead of `SessionStore` to observe sessions --- .../impl/DefaultWorkManagerScheduler.kt | 28 ++++++------------ .../impl/DefaultWorkManagerSchedulerTest.kt | 29 +++++-------------- 2 files changed, 16 insertions(+), 41 deletions(-) diff --git a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt index c80735c675..345604390b 100644 --- a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt +++ b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt @@ -11,41 +11,31 @@ package io.element.android.libraries.workmanager.impl import androidx.work.WorkManager import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding -import io.element.android.libraries.core.coroutine.withPreviousValue -import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.matrix.api.core.SessionId -import io.element.android.libraries.sessionstorage.api.SessionStore +import io.element.android.libraries.sessionstorage.api.observer.SessionListener +import io.element.android.libraries.sessionstorage.api.observer.SessionObserver import io.element.android.libraries.workmanager.api.WorkManagerRequest import io.element.android.libraries.workmanager.api.WorkManagerRequestType import io.element.android.libraries.workmanager.api.WorkManagerScheduler import io.element.android.libraries.workmanager.api.workManagerTag -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach import timber.log.Timber @ContributesBinding(AppScope::class) class DefaultWorkManagerScheduler( lazyWorkManager: Lazy, - @AppCoroutineScope private val appCoroutineScope: CoroutineScope, - sessionStore: SessionStore, + sessionObserver: SessionObserver, ) : WorkManagerScheduler { private val workManager by lazyWorkManager init { // Observe session removals to cancel associated work automatically - sessionStore.sessionsFlow() - .map { sessions -> sessions.map { SessionId(it.userId) } } - .withPreviousValue() - .map { (prev, new) -> prev.orEmpty() - new.toSet() } - .onEach { removedSessions -> - for (sessionId in removedSessions) { - Timber.d("Session removed for userId: $sessionId, cancelling associated workmanager requests") - cancel(sessionId) - } + sessionObserver.addListener(object : SessionListener { + override suspend fun onSessionDeleted(userId: String, wasLastSession: Boolean) { + val sessionId = SessionId(userId) + Timber.d("Session deleted for userId: $userId, cancelling associated workmanager requests") + cancel(sessionId) } - .launchIn(appCoroutineScope) + }) } override fun submit(workManagerRequest: WorkManagerRequest) { diff --git a/libraries/workmanager/impl/src/test/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerSchedulerTest.kt b/libraries/workmanager/impl/src/test/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerSchedulerTest.kt index 5ecf0c4a1f..b4f964ed12 100644 --- a/libraries/workmanager/impl/src/test/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerSchedulerTest.kt +++ b/libraries/workmanager/impl/src/test/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerSchedulerTest.kt @@ -9,10 +9,8 @@ package io.element.android.libraries.workmanager.impl import androidx.work.WorkManager import androidx.work.WorkRequest -import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.core.SessionId -import io.element.android.libraries.sessionstorage.test.InMemorySessionStore -import io.element.android.libraries.sessionstorage.test.aSessionData +import io.element.android.libraries.sessionstorage.test.observer.FakeSessionObserver import io.element.android.libraries.workmanager.api.WorkManagerRequest import io.element.android.libraries.workmanager.api.WorkManagerRequestType import io.element.android.libraries.workmanager.api.workManagerTag @@ -30,40 +28,31 @@ class DefaultWorkManagerSchedulerTest { @Test fun `starts observing sessions on init to remove work for logged out sessions`() = runTest { val sessionId = "@session1:matrix.org" - val sessionStore = InMemorySessionStore(initialList = listOf(aSessionData(sessionId = sessionId))) + val sessionObserver = FakeSessionObserver() val workManager = spyk() DefaultWorkManagerScheduler( lazyWorkManager = lazy { workManager }, - appCoroutineScope = backgroundScope, - sessionStore = sessionStore, + sessionObserver = sessionObserver, ) - // We have a single initial session - assertThat(sessionStore.numberOfSessions()).isEqualTo(1) - - runCurrent() - // We remove the session - sessionStore.removeSession(sessionId) + sessionObserver.onSessionDeleted(sessionId) runCurrent() // The session is now gone and work associated with the session is cancelled - assertThat(sessionStore.numberOfSessions()).isEqualTo(0) verify { workManager.cancelAllWorkByTag("notifications-$sessionId") } } @Test fun `submit builds the request and enqueues it`() = runTest { - val sessionStore = InMemorySessionStore() val workManager = spyk() val scheduler = DefaultWorkManagerScheduler( lazyWorkManager = lazy { workManager }, - appCoroutineScope = backgroundScope, - sessionStore = sessionStore, + sessionObserver = FakeSessionObserver(), ) scheduler.submit(FakeWorkManagerRequest()) @@ -73,13 +62,11 @@ class DefaultWorkManagerSchedulerTest { @Test fun `submit won't do anything if building the work request fails`() = runTest { - val sessionStore = InMemorySessionStore() val workManager = spyk() val scheduler = DefaultWorkManagerScheduler( lazyWorkManager = lazy { workManager }, - appCoroutineScope = backgroundScope, - sessionStore = sessionStore, + sessionObserver = FakeSessionObserver(), ) scheduler.submit(FakeWorkManagerRequest(result = Result.failure(IllegalStateException("Test error")))) @@ -89,13 +76,11 @@ class DefaultWorkManagerSchedulerTest { @Test fun `cancel will cancel all pending work for a session id`() = runTest { - val sessionStore = InMemorySessionStore() val workManager = spyk() val scheduler = DefaultWorkManagerScheduler( lazyWorkManager = lazy { workManager }, - appCoroutineScope = backgroundScope, - sessionStore = sessionStore, + sessionObserver = FakeSessionObserver(), ) val sessionId = SessionId("@alice:matrix.org") From f15a236c108465ba975d8869ea4032cc4253f302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 5 Dec 2025 17:08:53 +0100 Subject: [PATCH 064/347] Make `DefaultWorkManagerScheduler` a singleton sin it now has an observer that should be a singleton --- .../libraries/workmanager/impl/DefaultWorkManagerScheduler.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt index 345604390b..e5bd67c604 100644 --- a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt +++ b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt @@ -11,6 +11,7 @@ package io.element.android.libraries.workmanager.impl import androidx.work.WorkManager import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.SingleIn import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.sessionstorage.api.observer.SessionListener import io.element.android.libraries.sessionstorage.api.observer.SessionObserver @@ -21,6 +22,7 @@ import io.element.android.libraries.workmanager.api.workManagerTag import timber.log.Timber @ContributesBinding(AppScope::class) +@SingleIn(AppScope::class) class DefaultWorkManagerScheduler( lazyWorkManager: Lazy, sessionObserver: SessionObserver, From f4c8bbd8adbc7863cfa32730c6fb9755a238a104 Mon Sep 17 00:00:00 2001 From: bmarty <3940906+bmarty@users.noreply.github.com> Date: Mon, 8 Dec 2025 00:34:18 +0000 Subject: [PATCH 065/347] Sync Strings from Localazy --- .../src/main/res/values-et/translations.xml | 4 + .../src/main/res/values-sk/translations.xml | 30 +- .../src/main/res/values-et/translations.xml | 5 + .../src/main/res/values-fr/translations.xml | 4 + .../src/main/res/values-sk/translations.xml | 60 +- .../impl/src/main/res/values/localazy.xml | 4 +- .../impl/src/main/res/values/localazy.xml | 2 +- .../src/main/res/values-et/translations.xml | 1 + .../src/main/res/values-fr/translations.xml | 4 + .../src/main/res/values-sk/translations.xml | 28 +- .../impl/src/main/res/values/localazy.xml | 2 + .../src/main/res/values-sk/translations.xml | 1 + .../src/main/res/values-be/translations.xml | 1 + .../src/main/res/values-cs/translations.xml | 1 + .../src/main/res/values-cy/translations.xml | 1 + .../src/main/res/values-da/translations.xml | 1 + .../src/main/res/values-de/translations.xml | 1 + .../src/main/res/values-el/translations.xml | 1 + .../src/main/res/values-es/translations.xml | 1 + .../src/main/res/values-et/translations.xml | 10 + .../src/main/res/values-eu/translations.xml | 1 + .../src/main/res/values-fa/translations.xml | 1 + .../src/main/res/values-fi/translations.xml | 1 + .../src/main/res/values-fr/translations.xml | 8 + .../src/main/res/values-hu/translations.xml | 1 + .../src/main/res/values-in/translations.xml | 1 + .../src/main/res/values-it/translations.xml | 1 + .../src/main/res/values-ka/translations.xml | 1 + .../src/main/res/values-ko/translations.xml | 1 + .../src/main/res/values-nb/translations.xml | 1 + .../src/main/res/values-nl/translations.xml | 1 + .../src/main/res/values-pl/translations.xml | 1 + .../main/res/values-pt-rBR/translations.xml | 1 + .../src/main/res/values-pt/translations.xml | 1 + .../src/main/res/values-ro/translations.xml | 1 + .../src/main/res/values-ru/translations.xml | 1 + .../src/main/res/values-sk/translations.xml | 12 + .../src/main/res/values-sv/translations.xml | 1 + .../src/main/res/values-tr/translations.xml | 1 + .../src/main/res/values-uk/translations.xml | 1 + .../src/main/res/values-ur/translations.xml | 1 + .../src/main/res/values-uz/translations.xml | 1 + .../main/res/values-zh-rTW/translations.xml | 1 + .../src/main/res/values-zh/translations.xml | 1 + .../src/main/res/values/localazy.xml | 4 + ...ll.impl.create_CreatePollView_Day_2_de.png | 4 +- ...itprofile_EditUserProfileView_Day_0_de.png | 4 +- ...itprofile_EditUserProfileView_Day_1_de.png | 4 +- ...itprofile_EditUserProfileView_Day_2_de.png | 3 + ...s.impl.roles_ChangeRolesView_Day_10_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_1_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_2_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_3_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_4_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_6_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_7_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_8_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_9_de.png | 4 +- ..._PendingMemberRowWithLongName_Day_0_de.png | 3 - ...impl.edit_RoomDetailsEditView_Day_0_de.png | 3 - ...impl.edit_RoomDetailsEditView_Day_1_de.png | 3 - ...impl.edit_RoomDetailsEditView_Day_2_de.png | 3 - ...impl.edit_RoomDetailsEditView_Day_3_de.png | 3 - ...impl.edit_RoomDetailsEditView_Day_4_de.png | 3 - ...impl.edit_RoomDetailsEditView_Day_5_de.png | 3 - ...impl.edit_RoomDetailsEditView_Day_6_de.png | 3 - ...impl.edit_RoomDetailsEditView_Day_7_de.png | 3 - ...impl.edit_RoomDetailsEditView_Day_8_de.png | 3 - ...bers_RoomMemberListViewBanned_Day_0_de.png | 3 - ...bers_RoomMemberListViewBanned_Day_1_de.png | 3 - ...bers_RoomMemberListViewBanned_Day_2_de.png | 3 - ...pl.members_RoomMemberListView_Day_0_de.png | 4 +- ...pl.members_RoomMemberListView_Day_1_de.png | 4 +- ...pl.members_RoomMemberListView_Day_2_de.png | 4 +- ...pl.members_RoomMemberListView_Day_3_de.png | 4 +- ...pl.members_RoomMemberListView_Day_4_de.png | 4 +- ...pl.members_RoomMemberListView_Day_5_de.png | 4 +- ...pl.members_RoomMemberListView_Day_6_de.png | 3 + ...pl.members_RoomMemberListView_Day_7_de.png | 3 - ...pl.members_RoomMemberListView_Day_8_de.png | 3 - ...pl.members_RoomMemberListView_Day_9_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_0_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_1_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_2_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_3_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_4_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_5_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_6_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_7_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_8_de.png | 3 - ...rivacy_SecurityAndPrivacyViewDark_9_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_0_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_1_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_2_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_3_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_4_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_5_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_6_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_7_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_8_de.png | 3 - ...ivacy_SecurityAndPrivacyViewLight_9_de.png | 3 - ...edit.impl_RoomDetailsEditView_Day_0_de.png | 3 + ...edit.impl_RoomDetailsEditView_Day_1_de.png | 3 + ...edit.impl_RoomDetailsEditView_Day_2_de.png | 3 + ...edit.impl_RoomDetailsEditView_Day_3_de.png | 3 + ...edit.impl_RoomDetailsEditView_Day_4_de.png | 3 + ...edit.impl_RoomDetailsEditView_Day_5_de.png | 3 + ...edit.impl_RoomDetailsEditView_Day_6_de.png | 3 + ...edit.impl_RoomDetailsEditView_Day_7_de.png | 3 + ...edit.impl_RoomDetailsEditView_Day_8_de.png | 3 + ...edit.impl_RoomDetailsEditView_Day_9_de.png | 3 + ...impl_RoomMemberModerationView_Day_0_de.png | 4 +- ...impl_RoomMemberModerationView_Day_1_de.png | 4 +- ...impl_RoomMemberModerationView_Day_2_de.png | 4 +- ...impl_RoomMemberModerationView_Day_3_de.png | 4 +- ...maddress_EditRoomAddressView_Day_0_de.png} | 0 ...maddress_EditRoomAddressView_Day_1_de.png} | 0 ...maddress_EditRoomAddressView_Day_2_de.png} | 0 ...maddress_EditRoomAddressView_Day_3_de.png} | 0 ...maddress_EditRoomAddressView_Day_4_de.png} | 0 ...l.root_SecurityAndPrivacyViewDark_0_de.png | 3 + ....root_SecurityAndPrivacyViewDark_10_de.png | 3 + ....root_SecurityAndPrivacyViewDark_11_de.png | 3 + ....root_SecurityAndPrivacyViewDark_12_de.png | 3 + ....root_SecurityAndPrivacyViewDark_13_de.png | 3 + ....root_SecurityAndPrivacyViewDark_14_de.png | 3 + ....root_SecurityAndPrivacyViewDark_15_de.png | 3 + ....root_SecurityAndPrivacyViewDark_16_de.png | 3 + ....root_SecurityAndPrivacyViewDark_17_de.png | 3 + ....root_SecurityAndPrivacyViewDark_18_de.png | 3 + ....root_SecurityAndPrivacyViewDark_19_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_1_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_2_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_3_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_4_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_5_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_6_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_7_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_8_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_9_de.png | 3 + ....root_SecurityAndPrivacyViewLight_0_de.png | 3 + ...root_SecurityAndPrivacyViewLight_10_de.png | 3 + ...root_SecurityAndPrivacyViewLight_11_de.png | 3 + ...root_SecurityAndPrivacyViewLight_12_de.png | 3 + ...root_SecurityAndPrivacyViewLight_13_de.png | 3 + ...root_SecurityAndPrivacyViewLight_14_de.png | 3 + ...root_SecurityAndPrivacyViewLight_15_de.png | 3 + ...root_SecurityAndPrivacyViewLight_16_de.png | 3 + ...root_SecurityAndPrivacyViewLight_17_de.png | 3 + ...root_SecurityAndPrivacyViewLight_18_de.png | 3 + ...root_SecurityAndPrivacyViewLight_19_de.png | 3 + ....root_SecurityAndPrivacyViewLight_1_de.png | 3 + ....root_SecurityAndPrivacyViewLight_2_de.png | 3 + ....root_SecurityAndPrivacyViewLight_3_de.png | 3 + ....root_SecurityAndPrivacyViewLight_4_de.png | 3 + ....root_SecurityAndPrivacyViewLight_5_de.png | 3 + ....root_SecurityAndPrivacyViewLight_6_de.png | 3 + ....root_SecurityAndPrivacyViewLight_7_de.png | 3 + ....root_SecurityAndPrivacyViewLight_8_de.png | 3 + ....root_SecurityAndPrivacyViewLight_9_de.png | 3 + ...nts.dialogs_SaveChangesDialog_Day_0_de.png | 4 +- screenshots/html/data.js | 1891 +++++++++-------- ...edit.impl_RoomDetailsEditView_Day_7_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_7_en.png | 4 +- 164 files changed, 1322 insertions(+), 1141 deletions(-) create mode 100644 screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_de.png delete mode 100644 screenshots/de/features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_de.png create mode 100644 screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_6_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_7_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_8_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_9_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_de.png delete mode 100644 screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_de.png create mode 100644 screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_de.png rename screenshots/de/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_de.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_de.png} (100%) rename screenshots/de/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_de.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_de.png} (100%) rename screenshots/de/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_de.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_de.png} (100%) rename screenshots/de/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_de.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_de.png} (100%) rename screenshots/de/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_de.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_de.png} (100%) create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_de.png diff --git a/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml index 7924e7ce7b..582109c717 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml @@ -47,6 +47,10 @@ "Eemalda suhtluskeeld jututoas" "Suhtluskeeluga kasutajad" "Liikmed" + + "%1$d saatis kutse" + "%1$d saatis kutse" + "Ootel" "Peakasutajad" "Moderaatorid" diff --git a/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml index a707b48bc5..ad4832dfd0 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml @@ -1,14 +1,16 @@ - "Iba správcovia" + "Správca" "Zakázať ľudí" "Odstrániť správy" - "Pozvite ľudí a prijmite žiadosti o pripojenie" + "Člen" + "Pozvať ľudí" + "Spravovať členov" "Správy a obsah" - "Správcovia a moderátori" - "Odstrániť ľudí a odmietnuť žiadosti o pripojenie" + "Moderátor" + "Odstrániť ľudí" "Zmeniť obrázok miestnosti" - "Upraviť miestnosť" + "Upraviť podrobnosti" "Zmeniť názov miestnosti" "Zmeniť tému miestnosti" "Odoslať správy" @@ -32,6 +34,13 @@ "Máte neuložené zmeny." "Uložiť zmeny?" "Neexistujú žiadni zablokovaní používatelia." + + "%1$d zakázaný" + "%1$d zakázaní" + "%1$d zakázaných" + + "Skontrolujte preklepy alebo skúste nové vyhľadávanie" + "Žiadne výsledky pre „%1$s“" "%1$d osoba" "%1$d osoby" @@ -44,8 +53,14 @@ "Zrušiť zákaz prístupu do miestnosti" "Zakázaní" "Členovia" - "Iba správcovia" - "Správcovia a moderátori" + + "%1$d pozvaný" + "%1$d pozvaní" + "%1$d pozvaných" + + "Čaká na schválenie" + "Správca" + "Moderátor" "Vlastník" "Členovia miestnosti" "Zrušenie zákazu %1$s" @@ -58,6 +73,7 @@ "Správy a obsah" "Moderátori" "Vlastníci" + "Povolenia" "Obnoviť povolenia" "Po obnovení oprávnení prídete o aktuálne nastavenia." "Obnoviť oprávnenia?" diff --git a/features/roomdetails/impl/src/main/res/values-et/translations.xml b/features/roomdetails/impl/src/main/res/values-et/translations.xml index 7a315de168..570991ff9e 100644 --- a/features/roomdetails/impl/src/main/res/values-et/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-et/translations.xml @@ -84,6 +84,10 @@ "Eemalda suhtluskeeld jututoas" "Suhtluskeeluga kasutajad" "Liikmed" + + "%1$d saatis kutse" + "%1$d saatis kutse" + "Ootel" "Peakasutajad" "Moderaatorid" @@ -133,6 +137,7 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Võta läbiv krüptimine kasutusele" "Kõik võivad jututoaga liituda" "Kõik" + "Halda kogukondi" "Liituda saab vaid kutse olemasolul" "Vaid kutsega" "Ligipääs" diff --git a/features/roomdetails/impl/src/main/res/values-fr/translations.xml b/features/roomdetails/impl/src/main/res/values-fr/translations.xml index 79af58f0e3..75c8592d0e 100644 --- a/features/roomdetails/impl/src/main/res/values-fr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fr/translations.xml @@ -141,9 +141,13 @@ Nous ne recommandons pas d’activer le chiffrement pour les salons que tout le "Activer le chiffrement de bout en bout" "Tout le monde peut rejoindre." "Tout le monde" + "Choisissez les espaces dont les membres peuvent rejoindre ce salon sans invitation. %1$s" + "Gérer les espaces" "Seules les personnes invitées peuvent rejoindre." "Sur invitation uniquement" "Accès" + "Toute personne se trouvant dans un espace autorisé peut joindre le salon." + "Toute personne de l’espace %1$s peut joindre le salon." "Membres de l’espace" "Les Espaces ne sont pas encore supportés" "Vous aurez besoin d’une adresse pour le rendre visible dans l’annuaire public." diff --git a/features/roomdetails/impl/src/main/res/values-sk/translations.xml b/features/roomdetails/impl/src/main/res/values-sk/translations.xml index 477b419788..f61e3341bf 100644 --- a/features/roomdetails/impl/src/main/res/values-sk/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-sk/translations.xml @@ -1,19 +1,21 @@ - "Budete potrebovať adresu miestnosti, aby bola viditeľná v adresári." - "Adresa miestnosti" + "Budete potrebovať adresu, aby sa zobrazovala vo verejnom adresári." + "Upraviť adresu" "Pri aktualizácii nastavenia oznámenia došlo k chybe." "Váš domovský server nepodporuje túto možnosť v šifrovaných miestnostiach, v niektorých miestnostiach nemusíte dostať upozornenie." "Ankety" - "Iba správcovia" + "Správca" "Zakázať ľudí" "Odstrániť správy" - "Pozvite ľudí a prijmite žiadosti o pripojenie" + "Člen" + "Pozvať ľudí" + "Spravovať členov" "Správy a obsah" - "Správcovia a moderátori" - "Odstrániť ľudí a odmietnuť žiadosti o pripojenie" + "Moderátor" + "Odstrániť ľudí" "Zmeniť obrázok miestnosti" - "Upraviť miestnosť" + "Upraviť podrobnosti" "Zmeniť názov miestnosti" "Zmeniť tému miestnosti" "Odoslať správy" @@ -40,7 +42,7 @@ "Zašifrované" "Nešifrované" "Verejná miestnosť" - "Upraviť miestnosť" + "Upraviť podrobnosti" "Vyskytla sa neznáma chyba a informácie nebolo možné zmeniť." "Nepodarilo sa aktualizovať miestnosť" "Správy sú zabezpečené zámkami. Jedine vy a príjemcovia máte jedinečné kľúče na ich odomknutie." @@ -69,6 +71,13 @@ "Téma" "Aktualizácia miestnosti…" "Neexistujú žiadni zablokovaní používatelia." + + "%1$d zakázaný" + "%1$d zakázaní" + "%1$d zakázaných" + + "Skontrolujte preklepy alebo skúste nové vyhľadávanie" + "Žiadne výsledky pre „%1$s“" "%1$d osoba" "%1$d osoby" @@ -81,8 +90,14 @@ "Zrušiť zákaz prístupu do miestnosti" "Zakázaní" "Členovia" - "Iba správcovia" - "Správcovia a moderátori" + + "%1$d pozvaný" + "%1$d pozvaní" + "%1$d pozvaných" + + "Čaká na schválenie" + "Správca" + "Moderátor" "Vlastník" "Členovia miestnosti" "Zrušenie zákazu %1$s" @@ -109,14 +124,15 @@ "Správy a obsah" "Moderátori" "Vlastníci" + "Povolenia" "Obnoviť povolenia" "Po obnovení oprávnení prídete o aktuálne nastavenia." "Obnoviť oprávnenia?" "Roly" "Podrobnosti o miestnosti" "Roly a povolenia" - "Pridať adresu miestnosti" - "Ktokoľvek môže požiadať o pripojenie do miestnosti, ale správca alebo moderátor bude musieť žiadosť prijať." + "Pridať adresu" + "Všetci musia požiadať o prístup." "Požiadať o pripojenie" "Áno, povoliť šifrovanie" "Po aktivácii nie je možné zakázať šifrovanie pre miestnosť. História správ bude viditeľná len pre členov miestnosti, odkedy boli pozvaní alebo keď vstúpili do miestnosti. @@ -126,17 +142,22 @@ To môže brániť správnemu fungovaniu robotov a premostení. Neodporúčame p "Po zapnutí už šifrovanie nie je možné vypnúť." "Šifrovanie" "Povoliť end-to-end šifrovanie" - "Ktokoľvek môže nájsť a pripojiť sa" + "Pripojiť sa môže ktokoľvek." "Ktokoľvek" - "Ľudia sa môžu pripojiť len vtedy, ak sú pozvaní" + "Vyberte, ktorých členovia priestorov sa môžu pripojiť k tejto miestnosti bez pozvánky. %1$s" + "Spravovať priestory" + "Pripojiť sa môžu iba pozvaní ľudia." "Iba na pozvánku" - "Prístup do miestnosti" + "Prístup" + "Ktokoľvek v povolených priestoroch sa môže pripojiť." + "Ktokoľvek v %1$s sa môže pripojiť." "Členovia priestoru" "Priestory momentálne nie sú podporované" - "Budete potrebovať adresu miestnosti, aby bola viditeľná v adresári." - "Adresa miestnosti" + "Budete potrebovať adresu, aby sa zobrazovala vo verejnom adresári." + "Adresa" "Umožniť vyhľadanie tejto miestnosti v adresári verejných miestností %1$s" - "Viditeľné v adresári verejných miestností" + "Umožniť nájdenie vyhľadávaním vo verejnom adresári." + "Viditeľné vo verejnom adresári" "Ktokoľvek" "Kto môže čítať históriu" "Len pre členov, odkedy boli pozvaní" @@ -144,6 +165,7 @@ To môže brániť správnemu fungovaniu robotov a premostení. Neodporúčame p "Adresy miestností predstavujú spôsoby, ako nájsť a získať prístup k miestnostiam. To tiež zaisťuje, že môžete jednoducho zdieľať svoju miestnosť s ostatnými. Môžete sa rozhodnúť zverejniť svoju miestnosť v adresári verejných miestností vášho domovského servera." "Zverejnenie miestnosti" - "Viditeľnosť miestnosti" + "Adresy sú spôsob, ako nájsť a získať prístup do miestností a priestorov. To tiež zabezpečuje, že ich môžete jednoducho zdieľať s ostatnými." + "Viditeľnosť" "Bezpečnosť a súkromie" diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index c582f6f6fb..deb2d62902 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -69,7 +69,7 @@ "Share room" "Room info" "Topic" - "Updating room…" + "Updating details…" "There are no banned users." "%1$d Banned" @@ -129,8 +129,10 @@ "Room details" "Roles & permissions" "Add address" + "Anyone in authorized spaces can join, but everyone else must request access." "Everyone must request access." "Ask to join" + "Anyone in %1$s can join, but everyone else must request access." "Yes, enable encryption" "Once enabled, encryption for a room cannot be disabled, Message history will only be visible for room members since they were invited or since they joined the room. No one besides the room members will be able to read messages. This may prevent bots and bridges to work correctly. diff --git a/features/roomdetailsedit/impl/src/main/res/values/localazy.xml b/features/roomdetailsedit/impl/src/main/res/values/localazy.xml index 7a70381a8b..c20e6f2b47 100644 --- a/features/roomdetailsedit/impl/src/main/res/values/localazy.xml +++ b/features/roomdetailsedit/impl/src/main/res/values/localazy.xml @@ -3,5 +3,5 @@ "Edit details" "There was an unknown error and the information couldn\'t be changed." "Unable to update room" - "Updating room…" + "Updating details…" diff --git a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml index 7e6cdec9c6..c78857389f 100644 --- a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml @@ -15,6 +15,7 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Võta läbiv krüptimine kasutusele" "Kõik võivad jututoaga liituda" "Kõik" + "Halda kogukondi" "Liituda saab vaid kutse olemasolul" "Vaid kutsega" "Ligipääs" diff --git a/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml index 754ef4cd1a..5426d71706 100644 --- a/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml @@ -15,9 +15,13 @@ Nous ne recommandons pas d’activer le chiffrement pour les salons que tout le "Activer le chiffrement de bout en bout" "Tout le monde peut rejoindre." "Tout le monde" + "Choisissez les espaces dont les membres peuvent rejoindre ce salon sans invitation. %1$s" + "Gérer les espaces" "Seules les personnes invitées peuvent rejoindre." "Sur invitation uniquement" "Accès" + "Toute personne se trouvant dans un espace autorisé peut joindre le salon." + "Toute personne de l’espace %1$s peut joindre le salon." "Membres de l’espace" "Les Espaces ne sont pas encore supportés" "Vous aurez besoin d’une adresse pour le rendre visible dans l’annuaire public." diff --git a/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml b/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml index a9e6b1dd1b..ee346dd5d0 100644 --- a/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml @@ -1,9 +1,9 @@ - "Budete potrebovať adresu miestnosti, aby bola viditeľná v adresári." - "Adresa miestnosti" - "Pridať adresu miestnosti" - "Ktokoľvek môže požiadať o pripojenie do miestnosti, ale správca alebo moderátor bude musieť žiadosť prijať." + "Budete potrebovať adresu, aby sa zobrazovala vo verejnom adresári." + "Upraviť adresu" + "Pridať adresu" + "Všetci musia požiadať o prístup." "Požiadať o pripojenie" "Áno, povoliť šifrovanie" "Po aktivácii nie je možné zakázať šifrovanie pre miestnosť. História správ bude viditeľná len pre členov miestnosti, odkedy boli pozvaní alebo keď vstúpili do miestnosti. @@ -13,17 +13,22 @@ To môže brániť správnemu fungovaniu robotov a premostení. Neodporúčame p "Po zapnutí už šifrovanie nie je možné vypnúť." "Šifrovanie" "Povoliť end-to-end šifrovanie" - "Ktokoľvek môže nájsť a pripojiť sa" + "Pripojiť sa môže ktokoľvek." "Ktokoľvek" - "Ľudia sa môžu pripojiť len vtedy, ak sú pozvaní" + "Vyberte, ktorých členovia priestorov sa môžu pripojiť k tejto miestnosti bez pozvánky. %1$s" + "Spravovať priestory" + "Pripojiť sa môžu iba pozvaní ľudia." "Iba na pozvánku" - "Prístup do miestnosti" + "Prístup" + "Ktokoľvek v povolených priestoroch sa môže pripojiť." + "Ktokoľvek v %1$s sa môže pripojiť." "Členovia priestoru" "Priestory momentálne nie sú podporované" - "Budete potrebovať adresu miestnosti, aby bola viditeľná v adresári." - "Adresa miestnosti" + "Budete potrebovať adresu, aby sa zobrazovala vo verejnom adresári." + "Adresa" "Umožniť vyhľadanie tejto miestnosti v adresári verejných miestností %1$s" - "Viditeľné v adresári verejných miestností" + "Umožniť nájdenie vyhľadávaním vo verejnom adresári." + "Viditeľné vo verejnom adresári" "Ktokoľvek" "Kto môže čítať históriu" "Len pre členov, odkedy boli pozvaní" @@ -31,6 +36,7 @@ To môže brániť správnemu fungovaniu robotov a premostení. Neodporúčame p "Adresy miestností predstavujú spôsoby, ako nájsť a získať prístup k miestnostiam. To tiež zaisťuje, že môžete jednoducho zdieľať svoju miestnosť s ostatnými. Môžete sa rozhodnúť zverejniť svoju miestnosť v adresári verejných miestností vášho domovského servera." "Zverejnenie miestnosti" - "Viditeľnosť miestnosti" + "Adresy sú spôsob, ako nájsť a získať prístup do miestností a priestorov. To tiež zabezpečuje, že ich môžete jednoducho zdieľať s ostatnými." + "Viditeľnosť" "Bezpečnosť a súkromie" diff --git a/features/securityandprivacy/impl/src/main/res/values/localazy.xml b/features/securityandprivacy/impl/src/main/res/values/localazy.xml index 859be7670b..f6236edb8b 100644 --- a/features/securityandprivacy/impl/src/main/res/values/localazy.xml +++ b/features/securityandprivacy/impl/src/main/res/values/localazy.xml @@ -3,8 +3,10 @@ "You’ll need an address in order to make it visible in the public directory." "Edit address" "Add address" + "Anyone in authorized spaces can join, but everyone else must request access." "Everyone must request access." "Ask to join" + "Anyone in %1$s can join, but everyone else must request access." "Yes, enable encryption" "Once enabled, encryption for a room cannot be disabled, Message history will only be visible for room members since they were invited or since they joined the room. No one besides the room members will be able to read messages. This may prevent bots and bridges to work correctly. diff --git a/libraries/push/impl/src/main/res/values-sk/translations.xml b/libraries/push/impl/src/main/res/values-sk/translations.xml index a4deefba78..764dbefa70 100644 --- a/libraries/push/impl/src/main/res/values-sk/translations.xml +++ b/libraries/push/impl/src/main/res/values-sk/translations.xml @@ -15,6 +15,7 @@ "%d oznámenia" "%d oznámení" + "Distribútora oznámení UnifiedPush sa nepodarilo zaregistrovať, takže už nebudete dostávať oznámenia. Skontrolujte nastavenia oznámení v aplikácii a stav distribútora push oznámení." "Máte nové správy." "📹 Prichádzajúci hovor" "** Nepodarilo sa odoslať - prosím otvorte miestnosť" diff --git a/libraries/ui-strings/src/main/res/values-be/translations.xml b/libraries/ui-strings/src/main/res/values-be/translations.xml index 247dc9f026..39da09fb9d 100644 --- a/libraries/ui-strings/src/main/res/values-be/translations.xml +++ b/libraries/ui-strings/src/main/res/values-be/translations.xml @@ -272,6 +272,7 @@ "Памылка" "Поспех" "Папярэджанне" + "У вас ёсць незахаваныя змены." "Вашы змены не былі захаваны. Вы ўпэўнены, што хочаце вярнуцца?" "Захаваць змены?" "Ваш хатні сервер неабходна абнавіць для падтрымкі Matrix Authentication Service і стварэння ўліковага запісу." diff --git a/libraries/ui-strings/src/main/res/values-cs/translations.xml b/libraries/ui-strings/src/main/res/values-cs/translations.xml index d4f8550f7a..53429fb1df 100644 --- a/libraries/ui-strings/src/main/res/values-cs/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cs/translations.xml @@ -394,6 +394,7 @@ Opravdu chcete pokračovat?" "Chyba" "Úspěch" "Upozornění" + "Máte neuložené změny." "Vaše změny nebyly uloženy. Opravdu se chcete vrátit?" "Uložit změny?" "Maximální povolená velikost souboru je: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-cy/translations.xml b/libraries/ui-strings/src/main/res/values-cy/translations.xml index 11b46cb85c..bfc00ddffb 100644 --- a/libraries/ui-strings/src/main/res/values-cy/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cy/translations.xml @@ -414,6 +414,7 @@ Ydych chi\'n siŵr eich bod am barhau?" "Gwall" "Llwyddiant" "Rhybudd" + "Mae gennych newidiadau heb eu cadw." "Dyw eich newidiadau heb gael eu cadw. Ydych chi\'n siŵr eich bod am fynd nôl?" "Cadw\'r newidiadau?" "Y maint ffeil mwyaf sy\'n cael ei ganiatáu yw: %1$s" 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 f8491d6f26..6de4dc7ebd 100644 --- a/libraries/ui-strings/src/main/res/values-da/translations.xml +++ b/libraries/ui-strings/src/main/res/values-da/translations.xml @@ -387,6 +387,7 @@ Er du sikker på, at du vil fortsætte?" "Fejl" "Succes" "Advarsel" + "Du har ændringer, der ikke er gemt." "Dine ændringer er ikke blevet gemt. Er du sikker på, at du vil gå tilbage?" "Gem ændringer?" "Den maksimalt tilladte filstørrelse er: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-de/translations.xml b/libraries/ui-strings/src/main/res/values-de/translations.xml index f912fc4fc4..7467a59bd9 100644 --- a/libraries/ui-strings/src/main/res/values-de/translations.xml +++ b/libraries/ui-strings/src/main/res/values-de/translations.xml @@ -387,6 +387,7 @@ Möchtest du wirklich fortfahren?" "Fehler" "Erfolg" "Warnung" + "Du hast nicht gespeicherte Änderungen." "Deine Änderungen wurden nicht gespeichert. Bist du sicher, dass du zurückgehen willst?" "Änderungen speichern?" "Die maximal erlaubte Dateigröße ist: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-el/translations.xml b/libraries/ui-strings/src/main/res/values-el/translations.xml index 5085f404a1..f6bca76182 100644 --- a/libraries/ui-strings/src/main/res/values-el/translations.xml +++ b/libraries/ui-strings/src/main/res/values-el/translations.xml @@ -326,6 +326,7 @@ "Σφάλμα" "Επιτυχία" "Προειδοποίηση" + "Έχεις μη αποθηκευμένες αλλαγές." "Οι αλλαγές σου δεν έχουν αποθηκευτεί. Σίγουρα θες να πας πίσω;" "Αποθήκευση αλλαγών;" "Ο οικιακός διακομιστής σου πρέπει να αναβαθμιστεί για να υποστηρίζει το Matrix Authentication Service και τη δημιουργία λογαριασμού." diff --git a/libraries/ui-strings/src/main/res/values-es/translations.xml b/libraries/ui-strings/src/main/res/values-es/translations.xml index 4428e0b864..4fcc3fd9df 100644 --- a/libraries/ui-strings/src/main/res/values-es/translations.xml +++ b/libraries/ui-strings/src/main/res/values-es/translations.xml @@ -318,6 +318,7 @@ Motivo: %1$s." "Error" "Terminado" "Atención" + "Tienes cambios sin guardar." "Tus cambios no se han guardado. ¿Estás seguro de que quieres volver atrás?" "¿Guardar cambios?" "Tu servidor base debe actualizarse para admitir Matrix Authentication Service y la creación de cuentas." diff --git a/libraries/ui-strings/src/main/res/values-et/translations.xml b/libraries/ui-strings/src/main/res/values-et/translations.xml index 4b8c38be6c..e729286ee5 100644 --- a/libraries/ui-strings/src/main/res/values-et/translations.xml +++ b/libraries/ui-strings/src/main/res/values-et/translations.xml @@ -234,6 +234,7 @@ Põhjus: %1$s." "Hele" "Rida on kopeeritud lõikelauale" "Link on kopeeritud lõikelauale" + "Seo uus seade" "Laadime…" "Laadime veel…" @@ -246,10 +247,12 @@ Põhjus: %1$s." "Sõnum" "Tegevused sõnumiga" + "Sõnumi saatmine ei õnnestunud" "Sõnumi paigutus" "Sõnum on eemaldatud" "Kaasaegne" "Summutatud" + "Nimi" "%1$s (%2$s)" "Otsingul pole tulemusi" "Jututoal puudub nimi" @@ -324,6 +327,7 @@ Põhjus: %1$s." "Midagi läks valesti" "Tekkis viga. Palun proovi uuesti." "Kogukond" + "Mida selles kogukonnas tehakse?" "%1$d kogukond" "%1$d kogukonda" @@ -388,6 +392,7 @@ Kas sa oled kindel, et soovid jätkata?" "Viga" "Õnnestus" "Hoiatus" + "Sul on salvestamata muudatusi" "Sinu tehtud muudatused pole veel salvestatud. Kas sa oled kindel, et soovid minna tagasi?" "Kas salvestame muudatused?" "Suurim lubatud failisuurus on: %1$s" @@ -427,6 +432,11 @@ Kas sa oled kindel, et soovid jätkata?" "Valikud" "Kustuta: %1$s" "Seadistused" + "Lauaarvuti" + "Nutiseade" + "Halda kogukondi" + "(Tundmatu kogukond)" + "Sinu kogukonnad" "Meediafaili valimine ei õnnestunud. Palun proovi uuesti." "Siia lisamiseks vajuta sõnumil ja vali „%1$s“." "Et olulisi sõnumeid oleks lihtsam leida, tõsta nad esile" diff --git a/libraries/ui-strings/src/main/res/values-eu/translations.xml b/libraries/ui-strings/src/main/res/values-eu/translations.xml index 15bfa21fb5..10f914d0fd 100644 --- a/libraries/ui-strings/src/main/res/values-eu/translations.xml +++ b/libraries/ui-strings/src/main/res/values-eu/translations.xml @@ -336,6 +336,7 @@ Ziur jarraitu nahi duzula?" "Errorea" "Arrakasta" "Abisua" + "Gorde gabeko aldaketak dituzu." "Zure aldaketak ez dira gorde. Ziur itzuli nahi duzula?" "Aldaketak gorde?" "Hautatu bideoaren igoera-kalitatea" diff --git a/libraries/ui-strings/src/main/res/values-fa/translations.xml b/libraries/ui-strings/src/main/res/values-fa/translations.xml index 1656bc3b0c..0522010510 100644 --- a/libraries/ui-strings/src/main/res/values-fa/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fa/translations.xml @@ -345,6 +345,7 @@ "خطا" "موفّقیت" "هشدار" + "تغییراتی ذخیره نشده دارید." "تغییراتتان ذخیره نشده‌اند. مطمئنید که می‌خواهید برگردید؟" "ذخیرهٔ تغییرات؟" "حست‌وجوی شکلک‌ها" 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 bc23e78b05..8c725904d7 100644 --- a/libraries/ui-strings/src/main/res/values-fi/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fi/translations.xml @@ -388,6 +388,7 @@ Haluatko varmasti jatkaa?" "Virhe" "Onnistui" "Varoitus" + "Sinulla on tallentamattomia muutoksia" "Muutoksiasi ei ole tallennettu. Haluatko varmasti palata takaisin?" "Tallennetaanko muutokset?" "Suurin sallittu tiedostokoko on: %1$s" 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 11834a4d06..f4b55e8d80 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -246,6 +246,7 @@ Raison : %1$s." "Message" "Actions sur le message" + "Échec de l’envoi du message" "Mode d’affichage des messages" "Message supprimé" "Moderne" @@ -368,6 +369,7 @@ Raison : %1$s." "En attente…" "En attente de la clé de déchiffrement" "Vous" + "Les messages que vous enverrez seront partagés avec les nouveaux membres invités dans ce salon. %1$s" "L’identité de %1$s a été réinitialisée. %2$s" "L’identité de %1$s %2$s a été réinitialisée. %3$s" "(%1$s)" @@ -388,6 +390,7 @@ Raison : %1$s." "Erreur" "Succès" "Attention" + "Vous avez des modifications non-enregistrées." "Vos modifications n’ont pas été enregistrées. Êtes-vous certain de vouloir quitter ?" "Enregistrer les changements ?" "La taille maximale de fichier autorisée est: %1$s" @@ -427,6 +430,11 @@ Raison : %1$s." "Options" "Supprimer %1$s" "Paramètres" + "Espaces où les membres peuvent rejoindre le salon sans invitation." + "Gérer les espaces" + "(Espace inconnu)" + "Autres espaces dont vous n’êtes pas membre" + "Vos espaces" "Échec de la sélection du média, veuillez réessayer." "Cliquez (clic long) sur un message et choisissez « %1$s » pour qu‘il apparaisse ici." "Épinglez les messages importants pour leur donner plus de visibilité" diff --git a/libraries/ui-strings/src/main/res/values-hu/translations.xml b/libraries/ui-strings/src/main/res/values-hu/translations.xml index 4539d065a3..bc235cccd4 100644 --- a/libraries/ui-strings/src/main/res/values-hu/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hu/translations.xml @@ -387,6 +387,7 @@ Biztos, hogy folytatja?" "Hiba" "Sikeres" "Figyelmeztetés" + "Mentetlen módosításai vannak." "A módosítások nem lettek mentve. Biztos, hogy visszalép?" "Menti a módosításokat?" "A legnagyobb megengedett fájlméret: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-in/translations.xml b/libraries/ui-strings/src/main/res/values-in/translations.xml index bd7739d5ba..9735344818 100644 --- a/libraries/ui-strings/src/main/res/values-in/translations.xml +++ b/libraries/ui-strings/src/main/res/values-in/translations.xml @@ -332,6 +332,7 @@ Apakah Anda yakin ingin melanjutkan?" "Eror" "Berhasil" "Peringatan" + "Anda memiliki perubahan yang belum disimpan." "Perubahan Anda belum disimpan. Apakah Anda yakin ingin kembali?" "Simpan perubahan?" "Homeserver Anda perlu ditingkatkan untuk mendukung Matrix Authentication Service dan pembuatan akun." diff --git a/libraries/ui-strings/src/main/res/values-it/translations.xml b/libraries/ui-strings/src/main/res/values-it/translations.xml index 793b115917..1e2765a190 100644 --- a/libraries/ui-strings/src/main/res/values-it/translations.xml +++ b/libraries/ui-strings/src/main/res/values-it/translations.xml @@ -388,6 +388,7 @@ Sei sicuro di voler continuare?" "Errore" "Operazione riuscita" "Attenzione" + "Hai delle modifiche non salvate." "Le modifiche non sono state salvate. Vuoi davvero tornare indietro?" "Salvare le modifiche?" "La dimensione massima consentita per il file è: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-ka/translations.xml b/libraries/ui-strings/src/main/res/values-ka/translations.xml index dd67ca02c2..393b404f31 100644 --- a/libraries/ui-strings/src/main/res/values-ka/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ka/translations.xml @@ -236,6 +236,7 @@ "შეცდომა" "წარმატება" "გაფრთხილება" + "თქვენ გაქვთ შეუნახავი ცვლილებები" "თქვენი ცვლილებები არაა შენახული. დარწმუნებული ხართ დაბრუნებაში?" "შენახვა?" "მუდმივი ბმულის შექმნა ვერ მოხერხდა" diff --git a/libraries/ui-strings/src/main/res/values-ko/translations.xml b/libraries/ui-strings/src/main/res/values-ko/translations.xml index 256e561db5..f00637dbe5 100644 --- a/libraries/ui-strings/src/main/res/values-ko/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ko/translations.xml @@ -364,6 +364,7 @@ "오류" "성공" "경고" + "저장되지 않은 변경 사항이 있습니다." "변경 내용이 저장되지 않았습니다. 정말로 돌아가시겠습니까?" "변경 사항을 저장하시겠습니까?" "허용되는 최대 파일 크기: %1$s diff --git a/libraries/ui-strings/src/main/res/values-nb/translations.xml b/libraries/ui-strings/src/main/res/values-nb/translations.xml index e64a005577..2c62758e39 100644 --- a/libraries/ui-strings/src/main/res/values-nb/translations.xml +++ b/libraries/ui-strings/src/main/res/values-nb/translations.xml @@ -385,6 +385,7 @@ Er du sikker på at du vil fortsette?" "Feil" "Suksess" "Advarsel" + "Du har endringer som ikke er lagret." "Endringene dine er ikke lagret. Er du sikker på at du vil gå tilbake?" "Lagre endringer?" "Maksimal tillatt filstørrelse er: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-nl/translations.xml b/libraries/ui-strings/src/main/res/values-nl/translations.xml index 7c682233a6..cbd2d4d63b 100644 --- a/libraries/ui-strings/src/main/res/values-nl/translations.xml +++ b/libraries/ui-strings/src/main/res/values-nl/translations.xml @@ -300,6 +300,7 @@ Reden: %1$s." "Fout" "Geslaagd" "Waarschuwing" + "Je hebt niet-opgeslagen wijzigingen" "Je wijzigingen zijn niet opgeslagen. Weet je zeker dat je terug wilt gaan?" "Wijzigingen opslaan?" "Je homeserver moet worden geüpgraded om de Matrix Authentication Service en het aanmaken van accounts te ondersteunen." diff --git a/libraries/ui-strings/src/main/res/values-pl/translations.xml b/libraries/ui-strings/src/main/res/values-pl/translations.xml index e4186fd0f2..7b12125a3a 100644 --- a/libraries/ui-strings/src/main/res/values-pl/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pl/translations.xml @@ -395,6 +395,7 @@ Czy na pewno chcesz kontynuować?" "Błąd" "Sukces" "Ostrzeżenie" + "Masz niezapisane zmiany." "Zmiany nie zostały zapisane. Czy na pewno chcesz wrócić?" "Zapisać zmiany?" "Maksymalny dozwolony rozmiar pliku to: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml index 2f9b4a13e8..d7fc53da97 100644 --- a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml @@ -388,6 +388,7 @@ Você tem certeza de que deseja continuar?" "Erro" "Sucesso" "Alerta" + "Você tem alterações não salvas." "Suas alterações não foram salvas. Tem certeza de que você quer voltar?" "Salvar alterações?" "O tamanho máximo permitido de arquivos é: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-pt/translations.xml b/libraries/ui-strings/src/main/res/values-pt/translations.xml index 5e55f3a9de..5fbf7338f4 100644 --- a/libraries/ui-strings/src/main/res/values-pt/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pt/translations.xml @@ -382,6 +382,7 @@ Tens a certeza de que queres continuar?" "Erro" "Sucesso" "Aviso" + "Tens alterações por guardar." "As tuas alterações não foram guardadas. Tens a certeza que queres voltar atrás?" "Guardar alterações?" "O tamanho máximo de ficheiro permitido é: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index 0cf1acf673..16b0e90b89 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -395,6 +395,7 @@ Sunteți sigur că doriți să continuați?" "Eroare" "Succes" "Avertisment" + "Aveți modificări nesalvate." "Modificările dumneavoastră nu au fost salvate. Sunteți sigur că doriți să vă întoarceți?" "Salvați modificările?" "Dimensiunea maximă permisă pentru fișiere este: %1$s" 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 1290cb36c8..d319fcc053 100644 --- a/libraries/ui-strings/src/main/res/values-ru/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ru/translations.xml @@ -396,6 +396,7 @@ "Ошибка" "Успешно" "Предупреждение" + "У вас есть несохраненные изменения." "Изменения не сохранены. Вы действительно хотите вернуться?" "Сохранить изменения?" "Максимально допустимый размер файла: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-sk/translations.xml b/libraries/ui-strings/src/main/res/values-sk/translations.xml index a94c5657cf..694b679f45 100644 --- a/libraries/ui-strings/src/main/res/values-sk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sk/translations.xml @@ -250,6 +250,7 @@ Dôvod: %1$s." "Správa" "Akcie správy" + "Správu sa nepodarilo odoslať" "Štýl správ" "Správa odstránená" "Moderné" @@ -376,6 +377,7 @@ Dôvod: %1$s." "Čaká sa…" "Čaká sa na dešifrovací kľúč" "Vy" + "Správy, ktoré odošlete, budú zdieľané s novými členmi pozvanými do tejto miestnosti. %1$s" "Totožnosť používateľa %1$s sa obnovila.%2$s" "Totožnosť používateľa %1$s %2$s bola obnovená. %3$s" "(%1$s)" @@ -396,6 +398,7 @@ Naozaj chcete pokračovať?" "Chyba" "Úspech" "Upozornenie" + "Máte neuložené zmeny." "Vaše zmeny neboli uložené. Naozaj sa chcete vrátiť?" "Uložiť zmeny?" "Maximálna povolená veľkosť súboru je: %1$s" @@ -435,6 +438,11 @@ Naozaj chcete pokračovať?" "Možnosti" "Odstrániť %1$s" "Nastavenia" + "Priestory, kde sa členovia môžu pripojiť k miestnosti bez pozvania." + "Spravovať priestory" + "(Neznámy priestor)" + "Iné priestory, ktorých nie ste členom" + "Vaše priestory" "Nepodarilo sa vybrať médium, skúste to prosím znova." "Stlačte správu a vyberte možnosť „%1$s“, ktorú chcete zahrnúť sem." "Pripnite dôležité správy, aby sa dali ľahko nájsť" @@ -454,6 +462,10 @@ Naozaj chcete pokračovať?" "Vaša správa nebola odoslaná, pretože %1$s neoveril/a všetky zariadenia." "Jedno alebo viac vašich zariadení nie je overených. Správu môžete odoslať aj tak, alebo môžete zatiaľ zrušiť a skúsiť to znova neskôr po overení všetkých svojich zariadení." "Vaša správa nebola odoslaná, pretože ste neoverili jedno alebo viac svojich zariadení" + "Zmeniť nastavenia" + "Spravovať priestor" + "Spravovať miestnosti" + "Povolenia" "Upraviť správcov alebo vlastníkov" "Nepodarilo sa spracovať médiá na odoslanie, skúste to prosím znova." "Nepodarilo sa získať údaje o používateľovi" diff --git a/libraries/ui-strings/src/main/res/values-sv/translations.xml b/libraries/ui-strings/src/main/res/values-sv/translations.xml index e3cf26193e..9d928a406f 100644 --- a/libraries/ui-strings/src/main/res/values-sv/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sv/translations.xml @@ -369,6 +369,7 @@ Anledning:%1$s." "Fel" "Lyckades" "Varning" + "Du har osparade ändringar." "Dina ändringar har inte sparats. Är du säker på att du vill gå tillbaka?" "Spara ändringar?" "Den maximala tillåtna filstorleken är: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-tr/translations.xml b/libraries/ui-strings/src/main/res/values-tr/translations.xml index c72f5a6139..cabfc68e01 100644 --- a/libraries/ui-strings/src/main/res/values-tr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-tr/translations.xml @@ -307,6 +307,7 @@ Devam etmek istediğinizden emin misiniz?" "Hata" "Başarılı" "Uyarı" + "Kaydedilmemiş değişiklikleriniz var." "Değişiklikleriniz kaydedilmedi. Geri dönmek istediğinden emin misin?" "Değişiklikleri Kaydet?" "Ana sunucunuzun Matrix Authentication Service ve hesap oluşturmayı destekleyecek şekilde güncellenmesi gerekiyor." diff --git a/libraries/ui-strings/src/main/res/values-uk/translations.xml b/libraries/ui-strings/src/main/res/values-uk/translations.xml index a4c171a21b..03b3b6b3f2 100644 --- a/libraries/ui-strings/src/main/res/values-uk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-uk/translations.xml @@ -382,6 +382,7 @@ "Помилка" "Успіх" "Попередження" + "У вас є не збережені зміни." "Внесені зміни не збережено. Ви впевнені, що хочете повернутися?" "Зберегти зміни?" "Максимально дозволений розмір файлу: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-ur/translations.xml b/libraries/ui-strings/src/main/res/values-ur/translations.xml index 5abd2e0894..ef53dc7843 100644 --- a/libraries/ui-strings/src/main/res/values-ur/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ur/translations.xml @@ -265,6 +265,7 @@ "خرابی" "کامیابی" "انتباہ" + "آپکے پاس غیر محفوظ تبدیلیاں ہیں" "آپ کی تبدیلیاں محفوظ نہیں کی گئیں۔ کیا آپ کو یقین ہے کہ آپ واپس جانا چاہتے ہیں؟" "تبدیلیاں محفوظ کریں؟" "‏Matrix Authentication Service اور اکاؤنٹ بنانے میں معاونت کے لیے آپ کے ہوم سرور کو اپ گریڈ کرنے کی ضرورت ہے۔" diff --git a/libraries/ui-strings/src/main/res/values-uz/translations.xml b/libraries/ui-strings/src/main/res/values-uz/translations.xml index 8f23ee0d9e..fb36f3658b 100644 --- a/libraries/ui-strings/src/main/res/values-uz/translations.xml +++ b/libraries/ui-strings/src/main/res/values-uz/translations.xml @@ -376,6 +376,7 @@ Davom etasizmi?" "Xato" "Muvaffaqiyat" "Ogohlantirish" + "Sizda saqlanmagan oʻzgarishlar bor" "Oʻzgarishlar saqlanmadi. Haqiqatan ham orqaga qaytmoqchimisiz?" "O‘zgartirishlarni saqlaysizmi?" "Ruxsat etilgan maksimal fayl hajmi: %1$s" diff --git a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml index 1c88ac71df..6707ca7950 100644 --- a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml @@ -380,6 +380,7 @@ "錯誤" "成功" "警告" + "您有尚未儲存的變更" "變更尚未儲存,您確定要返回嗎?" "是否儲存變更?" "最大允許的檔案大小為:%1$s" diff --git a/libraries/ui-strings/src/main/res/values-zh/translations.xml b/libraries/ui-strings/src/main/res/values-zh/translations.xml index a743a5771b..402029cb2c 100644 --- a/libraries/ui-strings/src/main/res/values-zh/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh/translations.xml @@ -380,6 +380,7 @@ "错误" "成功" "警告" + "您有未保存的更改。" "更改尚未保存,确定要返回吗?" "保存更改?" "允许的最大文件大小为:%1$s" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index d422a4c35c..46a3559f3a 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -234,6 +234,7 @@ Reason: %1$s." "Light" "Line copied to clipboard" "Link copied to clipboard" + "Link new device" "Loading…" "Loading more…" @@ -432,6 +433,9 @@ Are you sure you want to continue?" "Options" "Remove %1$s" "Settings" + "Desktop computer" + "Mobile device" + "What type of device do you want to link?" "Spaces where members can join the room without an invitation." "Manage spaces" "(Unknown space)" diff --git a/screenshots/de/features.poll.impl.create_CreatePollView_Day_2_de.png b/screenshots/de/features.poll.impl.create_CreatePollView_Day_2_de.png index 5f7d39d4b1..41623d158d 100644 --- a/screenshots/de/features.poll.impl.create_CreatePollView_Day_2_de.png +++ b/screenshots/de/features.poll.impl.create_CreatePollView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bda355b4cc26ca3eb609ac11a06b1249c5be56340fbca6b526118c0588e53218 -size 45160 +oid sha256:537fb0eec587e1f9e7b5f4095e9aa09c687f47e2b45025efa7dbc8cb4e030fd3 +size 42366 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 03cd573859..6d1d7aba15 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:371cdd134e7991f65da9fa526b89b1562db79ec91ee12d9aac96b34e43a883f2 -size 22160 +oid sha256:98a2048354e01703cc5a3b63a273682176b45f39dc79432e75c5f2961e71e941 +size 22986 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 d48a261081..e11e0938c6 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:1b67896e65b700af7c989250098de7dabc61ee97db5157c1afebd83640192575 -size 70519 +oid sha256:fbe3d66e2749b8af8e922fb75a723b5885d3909e7fdf94f913d9a73189f6cefa +size 69959 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 new file mode 100644 index 0000000000..8c3409315d --- /dev/null +++ b/screenshots/de/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb4abd8d65e77aecba3d8fa4a4f5e0417b11b8b1b8e438da0b24e14fa5472bdf +size 34714 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png index d17592a23b..5ce611d271 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c69a3dbfca46e010898fa574df4ca20e0ef2c92810b58413125c911bdb1f88ed -size 53040 +oid sha256:5531d2f264a7b6c0f543a4ffb9987d4c7d60caec8f2d0d260a8b1fd1aae8c2a8 +size 52265 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png index 613fc7b48d..96a5fe50e1 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08f1af124411ce01ff24b6b47ccb3e8f02ba17ec6bc6aed98acd62f3dbd32bb7 -size 71876 +oid sha256:d71db8b8e66e0fcd0f82ad7356d3a9794bb4dc980dbfbf1545c00206776ddb90 +size 70427 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png index 749c220c31..1c3d282116 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19845c2e90dd9a5c3bc13f5ba66b38c02ac0ec961d3dac8713d1db465d826f41 -size 65497 +oid sha256:175f2fcd689cd82461350b65db068202972182bda557895c403bbd93d6a73481 +size 64096 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png index 92aa51f8f4..482a1270c5 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68887295c717d5a10e594bcfe4d6c84369bf2d468d7f998b2ccd82d27798d56d -size 65331 +oid sha256:b70911a26479225e26f4fa68e5629043a4e3d3fa7e2ef3c11682ac1fcf52c374 +size 63932 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png index 2617a69130..c7a8938912 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b139e5a7a55132a5bbe260cf300a86f2437feacb62ddf5d4144ed0718545d6c6 -size 59210 +oid sha256:55b998f4f10f8aeb8b72a746b6f9645570b48b5b130f10e4e6d4bc239571b82f +size 57804 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png index d536b91189..c4aeacefe1 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0bc99152df9a9fc1e8ae63bf1d40ded275d178555659981042649555db1c8be -size 65977 +oid sha256:58229d50524a34a5eba484ea7012876c6b90256fa0a293faadd8ebddc935db42 +size 61091 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png index 20109519a7..5938604641 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee106780e3dea8be63a63e22c5c9d44e6402a40729f90fe47a2ca2959395ee07 -size 66214 +oid sha256:5741c7ed5079e1dfeb125ea2a5f3ab429b01966b70fef16ade5d83785f785a7e +size 65477 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png index 6f446ed016..53ddd8d7d1 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2214de9f67c410ea11669fc9846286e6ad8ce6210a60fabcb8da3928a0ab6920 -size 55686 +oid sha256:261e28da918e11842e7d80449de98b861979aa6ee2d32f6f4d4662084a7bfb49 +size 54978 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png index 92aa51f8f4..482a1270c5 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68887295c717d5a10e594bcfe4d6c84369bf2d468d7f998b2ccd82d27798d56d -size 65331 +oid sha256:b70911a26479225e26f4fa68e5629043a4e3d3fa7e2ef3c11682ac1fcf52c374 +size 63932 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_de.png deleted file mode 100644 index fc9c3e2365..0000000000 --- a/screenshots/de/features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:353deccaf44203d369a40c95032787afd5946b12b76c8fecde6a8b8028df7631 -size 15419 diff --git a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_de.png b/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_de.png deleted file mode 100644 index 760a4adfd0..0000000000 --- a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1250b03f29403bac32fac8fa6386e7897336f9812e66fc51ca971665b18c1fad -size 30009 diff --git a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_de.png b/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_de.png deleted file mode 100644 index 592f5e6efd..0000000000 --- a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:305ba31f911770af43df762d462c5c006d781f80f5ccdc63d7adcfd704fae13e -size 24578 diff --git a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_de.png b/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_de.png deleted file mode 100644 index 77c7e2e388..0000000000 --- a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4edb86f9fef95dec9238388e0ddb045fa571ab57a8c0980b40d66cce8bf82e2 -size 31144 diff --git a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_de.png b/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_de.png deleted file mode 100644 index 3fc335c9b9..0000000000 --- a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8c302044f568ac50a50161ffbd05cbb709d2bf198e87fdc75f81343242871676 -size 55607 diff --git a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_de.png b/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_de.png deleted file mode 100644 index e5d2c28620..0000000000 --- a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ddb4b7a2e5b473e8a4b75a65bf884360ed35edd93d7801c7c121d57878523620 -size 30052 diff --git a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_de.png b/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_de.png deleted file mode 100644 index 3f2924b10d..0000000000 --- a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:86115b3d58661c9c59d6ebeb815ac58ab215c25fd5655f98525bbc6f74c641f2 -size 30140 diff --git a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_de.png b/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_de.png deleted file mode 100644 index c66dec9444..0000000000 --- a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:12d0c536795bd5922e4af54e9c7bcab1ae3d6c0f61ecb9a5b68898c26c81aa6b -size 27621 diff --git a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_de.png b/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_de.png deleted file mode 100644 index df697466c4..0000000000 --- a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e12d9f423c460a85a50297e9ddf99a061ee84e04ba36b0765074658807a30390 -size 29743 diff --git a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_de.png b/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_de.png deleted file mode 100644 index 02051a08da..0000000000 --- a/screenshots/de/features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:12f8ce1dbeb1a16ab8351486310fdeabba566db4aad460fc4e1e1f7fdbe63bf7 -size 37209 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_de.png deleted file mode 100644 index e616c17ea9..0000000000 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:66d5bac689bdb05818951e2e6faad9b4e313146bef4cdf99ce500d10b7717cd2 -size 12286 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_de.png deleted file mode 100644 index 9a5c54bfec..0000000000 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0bd483cd461e077f2c1a67eb3a2a6e865da7af0659e6786ca3252d189cd3f4f3 -size 12528 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_de.png deleted file mode 100644 index e616c17ea9..0000000000 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:66d5bac689bdb05818951e2e6faad9b4e313146bef4cdf99ce500d10b7717cd2 -size 12286 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_0_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_0_de.png index da3a20f79f..17a0e0c2a1 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_0_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d667737faee1070520e5dd4e62a1838eb37aa9080a993e33276188ca8ac2bdc9 -size 47880 +oid sha256:344c0d1c9ac8e0b15b396b9bae16136db85a1b81b0cb9f959e2f27a8d6e36c6f +size 13650 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_1_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_1_de.png index ac1a6b63d7..e6c3dab94a 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_1_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:67e7995d4a975a732223a9f248c8c9ac00173b2783fe05ceb2a8d0281f403e6a -size 54190 +oid sha256:a762a5501000d41b1407045482440beb78742a9b671bdd2400d5c23dfb15586f +size 22798 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png index 9a5c54bfec..e916b74f83 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0bd483cd461e077f2c1a67eb3a2a6e865da7af0659e6786ca3252d189cd3f4f3 -size 12528 +oid sha256:817a9c7ab2ef22da1cedd89ba652696ca95fe623baa480f42b86a5e990e58e71 +size 58010 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png index 58d5fd88bb..9cad7e89e3 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d074ac8751c7f125534134d3bb06cc19c6f5ce17da390ddd633f264f9806ee8 -size 13860 +oid sha256:a721a146e8c91aee975941f1c58484de7bf7d28073ec3b31027df72d0a398788 +size 31317 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png index 9a5c54bfec..d551980d61 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0bd483cd461e077f2c1a67eb3a2a6e865da7af0659e6786ca3252d189cd3f4f3 -size 12528 +oid sha256:40be9c1c2afaa5171b96a66adebf9c665324ff1cc323060b0998edad9f788e9c +size 59249 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png index 79a25499ad..4e8c43e825 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f3641f966fcf71259afeedc2c4b32d3e2c581af23c9c4220c9b80152501e77f -size 7949 +oid sha256:8174b00bbcae8f48833c10a474ddb26c2f003c23bb36b43c91b3a3c13485b23e +size 19444 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_6_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_6_de.png new file mode 100644 index 0000000000..27e87d2a1f --- /dev/null +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5989462acb327dea61c68b082349b9bba499bf98968563f8c144a04169e205e6 +size 29897 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_7_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_7_de.png deleted file mode 100644 index 7757f4b08a..0000000000 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_7_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:13c4c05dd4a7e93b9fbcd5c361fdda4c17cb1d5b9918511bf402cf49c0dc27db -size 25164 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_8_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_8_de.png deleted file mode 100644 index 3ba65e7151..0000000000 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_8_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:251848f9afc246fb2ec6f36da893878360e24634efdcb3920aac174768f9ad6e -size 12298 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_9_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_9_de.png deleted file mode 100644 index dbc779e7a6..0000000000 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_9_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7d518add734e55b81cbc35e77d059c2ef1777488f756b5da6cb8504f30c399dd -size 21660 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_de.png deleted file mode 100644 index cd516fe53b..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bce82fc99877bf4baf0f681ebfa1e424a653ee9d5d13d73345a9eb9d8e1a04c8 -size 49084 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_de.png deleted file mode 100644 index da6126ac25..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d26a66215dd6e4c5327603d962c484ecd237c0e39efa2526831548e4ba7d8a3c -size 66264 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_de.png deleted file mode 100644 index d45d21d129..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2146fc5949ddb6ec451c1d375696401c358cb24415351667786ef079516797e5 -size 66390 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_de.png deleted file mode 100644 index ea269fe4c9..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:42cac3e2c1a32c170062e4933e0df0b4df56767b7b1ee9c70c6ba515e5fe9364 -size 66816 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_de.png deleted file mode 100644 index 6a2ec9b414..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e96600ec5b77af84ae80b334700b73a353e19895f97479afacb3ea6667b25c04 -size 66207 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_de.png deleted file mode 100644 index 6a254e1545..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cd52fe9bdae5629cae86e251004bb77cf0a503869839fc78582a8db478fb29fd -size 48853 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_de.png deleted file mode 100644 index 6a254e1545..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cd52fe9bdae5629cae86e251004bb77cf0a503869839fc78582a8db478fb29fd -size 48853 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_de.png deleted file mode 100644 index ea72553cc6..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:400c4e4565f0278ec0ce464d78c05faf5bec81e69b27d0d74962c8b12e99b22d -size 50052 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_de.png deleted file mode 100644 index 032ce0414b..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:aad25334fd43f36325106f39977eec19ffcc0695d752ecc226ef4705c2d073ce -size 42798 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_de.png deleted file mode 100644 index 10ff645a54..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6849deebbd1181d6fa359fd0a88171f53b032d234732d1823ebb2339f094174 -size 65846 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_de.png deleted file mode 100644 index 5c00e6287b..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3e881dee5efc987b70134fc688bb57755f8aab2dfcdee44a2a32caea09e91cee -size 51011 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_de.png deleted file mode 100644 index 6097402d23..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:de4e33e81d42e013e2a1a633d81ad410af38025cd007d0a5502316a3c73cf840 -size 68986 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_de.png deleted file mode 100644 index 0f3b0876cb..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:92413621be8733a417b97b56cb8d518f07eeec4791cba3ff6e3f19ae85719cf0 -size 69200 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_de.png deleted file mode 100644 index f0a81c9655..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:46fd40c5f6ef2a796503398468fed8cb945d20fb016c14d85409726e66a59078 -size 69721 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_de.png deleted file mode 100644 index e57def30b7..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:378bcab0bc462571f1b80489b40cdd03b977b17b8864a684423dfe84f1fd1cf2 -size 68857 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_de.png deleted file mode 100644 index efddf6337d..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2678096406dec316cc4e961102ba38b30de6a3b128fa279db1228225f7cf60fa -size 50974 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_de.png deleted file mode 100644 index efddf6337d..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2678096406dec316cc4e961102ba38b30de6a3b128fa279db1228225f7cf60fa -size 50974 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_de.png deleted file mode 100644 index 9a7c14f9cd..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6193d8ea073e83fe4e32ace278357f1ddf78bb48e0dfda54eb106421c88369e2 -size 52362 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_de.png deleted file mode 100644 index e8df593416..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:30625120454624c48057d57dd2dd17a7e254cdfa2228cbc9776a7dc0be8ec07c -size 44360 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_de.png b/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_de.png deleted file mode 100644 index c6ebfd2112..0000000000 --- a/screenshots/de/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9b26dd32028051acf1fa6d7b2d335a08efd80a0a0fbc0c729a3375b57ef072d8 -size 68465 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_de.png new file mode 100644 index 0000000000..45d287b5ec --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7a8a805ff40cfc6194a414a2d1c1babc5dc2335fb5c96bb72f6f2f412c91346 +size 30052 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_de.png new file mode 100644 index 0000000000..91845d6b8f --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6ccfe1ff08087bd75a8e0017f5d12540cc567423801050dc091005722f3d9b1 +size 24575 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_de.png new file mode 100644 index 0000000000..16fde1067e --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55711397eb8fa3717a3891e56c078cca643520b2d0fefeede118b19db8676341 +size 31204 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_de.png new file mode 100644 index 0000000000..b366ffe07c --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89bcd852bb60044ba429d5c0a884b05d3a28403d985f95bd1582f1f45baca003 +size 54044 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_de.png new file mode 100644 index 0000000000..e8642f7bb8 --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f8fde96567da32ec9a97eecfb1224b5ae23aa0c7608792036f452eebbad466a +size 51217 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_de.png new file mode 100644 index 0000000000..f38d37867b --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e343b3df1a386702c6163393ff05d342abbc9c245ba93129d24e7be5acdaa39 +size 30079 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_de.png new file mode 100644 index 0000000000..60f40910a3 --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ffebfde2aa3d3f3a7e9f7a3dbf8b9e6b8044657815735d2d8c401d2caa8ab51 +size 30225 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_de.png new file mode 100644 index 0000000000..faa2a0b84a --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4253142dd34410c924bfd0499042a05b9ad59afa7073957835a8d4afc6a7d5a6 +size 25470 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_de.png new file mode 100644 index 0000000000..534874b570 --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4fae7c1d5e7bd4f10658bc1777af60ae110278e283a03ca52855e990448f8a4 +size 31022 diff --git a/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_de.png b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_de.png new file mode 100644 index 0000000000..e95bd5c15d --- /dev/null +++ b/screenshots/de/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da72832a3646008468a061de42964b7d98d563d3a2244f63d168c4a2f38247e6 +size 32513 diff --git a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_de.png index 90d52aa97c..a5638d89f3 100644 --- a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_de.png +++ b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:22352da5dc1213be58d28663f6696ca0c0588422576e0e018fae7887edbbd25c -size 18458 +oid sha256:90712ac1929c94927172c10a09ed8c9955e44aa4d87d02020f9bc8781d87f30c +size 18775 diff --git a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_de.png index a3fffe85d9..9c94b62b9c 100644 --- a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_de.png +++ b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e23b88a9cbcbb626dc222660560a9e936b4f0060b6978296d42a7913d19d68bd -size 22298 +oid sha256:e2871173d98a9add3a41617e6033ce4a293e7ee683997a2ffe9e60f4ecc5513b +size 22477 diff --git a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_de.png index 2a137dda7d..207a840978 100644 --- a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_de.png +++ b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4b9761ab02b0421f77a4f9876482817d9be98553ef72291e5d7a4679a09b27c6 -size 27750 +oid sha256:25800bbb0ebf715f7d8977ecd466c545c7b603703e145ba8d87e5572f4bf5421 +size 28052 diff --git a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_de.png index 4ffe9e5c53..348bc07623 100644 --- a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_de.png +++ b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa3fe7ed313bbfdaee18fc9b653008ab7e9bedbe806647b0e8842ed17fc450e3 -size 28168 +oid sha256:3e3c9507e122bf1e90a459ec0a772baaf3811f7f7d41e9e48f20bc2528aee5d1 +size 28467 diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_de.png similarity index 100% rename from screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_de.png rename to screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_de.png diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_de.png similarity index 100% rename from screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_de.png rename to screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_de.png diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_de.png similarity index 100% rename from screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_de.png rename to screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_de.png diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_de.png similarity index 100% rename from screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_de.png rename to screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_de.png diff --git a/screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_de.png similarity index 100% rename from screenshots/de/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_de.png rename to screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_de.png diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png new file mode 100644 index 0000000000..631fd4634e --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76bbbeb0e07b75805decc4a25d815ec1b73f83947b861c71ef697463ff00d9be +size 50558 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_de.png new file mode 100644 index 0000000000..d8e327cec9 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cc7260e1f01727bc96317f278158a36cdb0a6ee544937e1f7b2b2e5aee9b71f +size 51358 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_de.png new file mode 100644 index 0000000000..f584c028e1 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:407a338096b8e758eb4663016fc1448fffc7756b5055c5be015782d4f9d34de7 +size 51832 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_de.png new file mode 100644 index 0000000000..ff8e29ea59 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:044869f6f523e6ab43de53e7ff13a8c1771a929030f60a8191329f385be67835 +size 24752 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_de.png new file mode 100644 index 0000000000..eafb1f2805 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9027ed5e27a1d640ab50b4c544d622c718d3bef6df477bf66b99ee605ccec7c +size 51770 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_de.png new file mode 100644 index 0000000000..f584c028e1 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:407a338096b8e758eb4663016fc1448fffc7756b5055c5be015782d4f9d34de7 +size 51832 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_de.png new file mode 100644 index 0000000000..a7c70bf14d --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e771cd9a182dab3615661aebdeba6069cbf04218f60d709a529693e8ad6005e0 +size 52416 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png new file mode 100644 index 0000000000..ef5cc7a3d4 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:148d51c2ea8929c978065e5db9a531f4611559d230b73ac3fde013992c3d28fb +size 43911 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png new file mode 100644 index 0000000000..71265a00fe --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afe4234500a2f3696e7e794bed9fb62477c3a6f1439d597a7df5cfd1a61fb73f +size 42978 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png new file mode 100644 index 0000000000..56d7e39c4f --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d1963026fb35db84c4413a5c6e225657c95eabeee95b880afd8e7a59de9c28d +size 45475 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png new file mode 100644 index 0000000000..eef53d5522 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49607772cae3cc9f9e6e8436369a9e84392e1fb0892c2f9f4dbe2834f67cbdc8 +size 50557 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_de.png new file mode 100644 index 0000000000..f7ed121780 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cbad28899d0c9f55f4abcd04e5ea3fcd896d7d7e1649ce52eb9b23bbe7b6e91 +size 65600 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_de.png new file mode 100644 index 0000000000..a174686a2d --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f561351b6dbd13b6cd2f55f8df9f31c84453594acf511cdde27855639ba4ea7c +size 65148 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_de.png new file mode 100644 index 0000000000..44e0015abe --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d20dafcb3552d24835bbeec5a288cad29015ceaaee123d64fa32123a51c3cb4 +size 65727 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png new file mode 100644 index 0000000000..97921c3734 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b52d24166c4f30cef7e158016c7d799dab0836750f5193b2997dea90698260da +size 47067 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_de.png new file mode 100644 index 0000000000..9a5f939b49 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92888d4d51a087f628d2c0604d0f02c3a58e2eca5c1e41d1dd01884afb1c1e6a +size 65549 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_de.png new file mode 100644 index 0000000000..3a76a16c3e --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1998f0764fd6706169015fecbe7958f5ea88ccf6718c6fcc31b50259213eda69 +size 65612 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_de.png new file mode 100644 index 0000000000..b307d30172 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dce718324779855609745640fccecda621d121e61186915c626b4f8cd4e8693e +size 62663 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_de.png new file mode 100644 index 0000000000..6432c76e48 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffb5c13b625568456542d7405e9f8f05ebe986de32587c68fbcd7c356cd30cb3 +size 27683 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_de.png new file mode 100644 index 0000000000..5d8f1260f7 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57ba25b77977622a483522f5e360fb9763e4c089a8576d3b51b611a463e81d7c +size 51821 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png new file mode 100644 index 0000000000..c005294209 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0c524cf2a0ebd4afd7cf3517b6a10a8d7aef0f3b5dfd9f83438ac7983e1ca18 +size 52459 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_de.png new file mode 100644 index 0000000000..510202c600 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dc0ed7717de76041c6a5e9c32c3246039a8881ced121276b58b3012bbfb4096 +size 52718 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_de.png new file mode 100644 index 0000000000..fbbf3768e6 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4919373598bd77b7aa9e3aebad6abf4f8ddcf0123894507d76ce63157d347ea7 +size 53335 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_de.png new file mode 100644 index 0000000000..e0478af982 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b4a7e16a3c70933cc7f4ef68636df5d1669789500690f17a5a25f122f9f50b2 +size 25412 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_de.png new file mode 100644 index 0000000000..98d9beba84 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65020e3887540431951a3e99ce31e19dc401b4bbc232b16ded6e59d51f1712c9 +size 53206 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_de.png new file mode 100644 index 0000000000..fbbf3768e6 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4919373598bd77b7aa9e3aebad6abf4f8ddcf0123894507d76ce63157d347ea7 +size 53335 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_de.png new file mode 100644 index 0000000000..579756c731 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73fa1e4a25773720a0e9999b293488017c854576f40cc738fb3b67b59f2b1f05 +size 54167 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png new file mode 100644 index 0000000000..3f12de9672 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:739a7daec14bf01495a99e7e9584e3fdf4a26b1a7135cb0a109d32d275ab4344 +size 45484 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png new file mode 100644 index 0000000000..d83fa83f95 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d80cbcafde684e8c85e36c1106f4cf3d945856c6df6c4455f6d8f1d2b1ffe459 +size 45172 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png new file mode 100644 index 0000000000..5f861eda69 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ed8de485d7c5d33e08ed500600848b29c49d03c8f51de3484781c05963eb34f +size 47813 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png new file mode 100644 index 0000000000..481cc91dee --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:658a968e9ca2d1f55766a45c6c101e136eafefe1c511d22f8368ae42cc5319eb +size 52820 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_de.png new file mode 100644 index 0000000000..d1ce6902de --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90db4ee471ec887f00a9e580ef839a4611216107ec615da90330b7d6be276b77 +size 68316 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_de.png new file mode 100644 index 0000000000..1d2eff636f --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9488bea7d8ea64ac2d2987dcf69b4a51bfb6b81e33b1035195860cc90ae9f291 +size 67707 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_de.png new file mode 100644 index 0000000000..6f1dca9c23 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbf7bda1bff05828fe71045a012b8bcc1f4c047256d8aea6f8f8579e08295dea +size 68546 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png new file mode 100644 index 0000000000..9632558d7b --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e905e5db59825bd332e89d69fc741c4146d0e6f8bdeab428dbc0e6eb27f3341 +size 49369 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_de.png new file mode 100644 index 0000000000..3f1bf5f183 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d32e9542eb673f6e4f0f05ad017615f0c3274683e48f3ec13277e2d98d4db0f +size 68200 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_de.png new file mode 100644 index 0000000000..1b18135ef5 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dd6427f42936ef21702492e5e96a7abaa6873edde04169603ed2124d76f4984 +size 68323 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_de.png new file mode 100644 index 0000000000..e04844391b --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88d3cb4770828935c271cc10fc436c85f0af19bf77a5f58a6abd6fde1af367ec +size 65168 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_de.png new file mode 100644 index 0000000000..1e24950be3 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99ae8ce6973aeacb8d1054722038b9840365b239569f6dbee5c2f234e84c14d3 +size 28626 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_de.png new file mode 100644 index 0000000000..fa87fbe737 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0c6701f9c4faa4495cd92e7414821f39f9adc3d3f755d21302a5c66cab6f5e3 +size 53331 diff --git a/screenshots/de/libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_de.png b/screenshots/de/libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_de.png index b8b796ace4..cd461a5e12 100644 --- a/screenshots/de/libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_de.png +++ b/screenshots/de/libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3632264ac1f406dfdd2d376c033741d2661ebf76b3b8f0ee150e108d6e85740 -size 27940 +oid sha256:0406efd19b2e8c9d83708af8669b8d2e8aaafef335eaef972e363e85589ccc56 +size 22171 diff --git a/screenshots/html/data.js b/screenshots/html/data.js index 758b77c7ee..a757e04ca0 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,80 +1,80 @@ // 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",20420,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20427,], ["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",20420,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20420,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20420,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20420,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20420,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20420,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20420,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20420,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20420,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20420,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20420,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20427,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20427,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20427,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20427,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20427,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20427,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20427,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20427,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20427,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20427,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20427,], ["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",20420,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20420,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20427,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20427,], ["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",20420,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20420,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20427,], ["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",20420,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20420,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20420,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20420,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20420,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20420,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20420,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20420,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20420,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20420,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20420,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20420,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20420,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20420,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20427,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20427,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20427,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20427,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20427,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20427,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20427,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20427,], ["libraries.designsystem.theme.components_AllIcons_Icons_en","",0,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20420,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20420,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20420,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20420,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20420,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20427,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20427,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20427,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20427,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20427,], ["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",20420,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20427,], ["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",20420,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20427,], ["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",20420,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20427,], ["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",20420,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20427,], ["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",20420,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20427,], ["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,], @@ -84,19 +84,19 @@ export const screenshots = [ ["libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_7_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_7_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_8_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_8_en",0,], -["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20420,], -["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20420,], -["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20420,], -["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20420,], -["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20420,], -["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20420,], -["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20420,], -["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20420,], -["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20420,], +["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20427,], +["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20427,], +["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20427,], +["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20427,], +["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20427,], +["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20427,], +["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20427,], +["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20427,], +["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20427,], ["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",20420,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20427,], ["libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en","",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_0_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_1_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_1_en",0,], @@ -123,22 +123,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",20420,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20427,], ["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",20420,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20420,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20420,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20420,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20420,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20420,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20420,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20427,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20427,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20427,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20427,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20427,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20427,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20427,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20420,], -["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20420,], -["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20420,], -["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20420,], -["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20420,], +["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20427,], +["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20427,], +["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20427,], +["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20427,], +["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20427,], ["features.rageshake.impl.bugreport_BugReportViewNight_0_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_1_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_2_en","",0,], @@ -148,133 +148,133 @@ export const screenshots = [ ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20420,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20420,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20427,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20427,], ["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], ["features.call.impl.ui_CallScreenView_Day_0_en","features.call.impl.ui_CallScreenView_Night_0_en",0,], -["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20420,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20420,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20420,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20420,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20420,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20420,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20427,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20427,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20427,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20427,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20427,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20427,], ["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",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20420,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20420,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20420,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20420,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20420,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20420,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20427,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20427,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20427,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20427,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20427,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20427,], ["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",20420,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20420,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20420,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20420,], -["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20420,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20427,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20427,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20427,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20427,], +["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20427,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20420,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20427,], ["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",20420,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20420,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20420,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20420,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20420,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20420,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20420,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20420,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20427,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20427,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20427,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20427,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20427,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20427,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20427,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20427,], ["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",20420,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20420,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20420,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20420,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20420,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20420,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20420,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20420,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20420,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20420,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20427,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20427,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20427,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20427,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20427,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20427,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20427,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20427,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20427,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20427,], ["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","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20420,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20420,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20420,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20420,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20420,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20427,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20427,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20427,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20427,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20427,], ["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",20420,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20420,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20420,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20420,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20420,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20420,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20420,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20420,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20420,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20420,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20420,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20420,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20420,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20420,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20420,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20420,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20420,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20420,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20420,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20420,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20427,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20427,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20427,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20427,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20427,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20427,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20427,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20427,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20427,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20427,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20427,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20427,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20427,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20427,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20427,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20427,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20427,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20427,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20427,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20427,], ["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","",20420,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20420,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20420,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20420,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20420,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20420,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20420,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20427,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20427,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20427,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20427,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20427,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20427,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20427,], ["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",20420,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20420,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20420,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20427,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20427,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20427,], ["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",20420,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20427,], ["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",20420,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20420,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20420,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20420,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20420,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20420,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20420,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20420,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20427,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20427,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20427,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20427,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20427,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20427,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20427,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20427,], ["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,], @@ -289,19 +289,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",20420,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20420,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20420,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20420,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20420,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",0,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",0,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",0,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",0,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",0,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20420,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20420,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",0,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20427,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20427,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20427,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20427,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20427,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20430,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20430,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20430,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20430,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20430,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20427,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20427,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20430,], ["libraries.matrix.ui.components_EditableAvatarView_Day_0_en","libraries.matrix.ui.components_EditableAvatarView_Night_0_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_1_en","libraries.matrix.ui.components_EditableAvatarView_Night_1_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_2_en","libraries.matrix.ui.components_EditableAvatarView_Night_2_en",0,], @@ -312,14 +312,14 @@ export const screenshots = [ ["libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Night_0_en",0,], ["features.messages.impl.timeline.components.customreaction_EmojiItem_Day_0_en","features.messages.impl.timeline.components.customreaction_EmojiItem_Night_0_en",0,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20420,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20420,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20427,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20427,], ["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,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20420,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20420,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20420,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20427,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20427,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20427,], ["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,], @@ -338,43 +338,43 @@ 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",20420,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20420,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20420,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20427,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20427,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20427,], ["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",20420,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20420,], +["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20427,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20427,], ["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",20420,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20420,], -["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20420,], -["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20420,], -["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20420,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20427,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20427,], +["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20427,], +["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20427,], +["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20427,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20420,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20420,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20427,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20427,], ["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",20420,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20420,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20420,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20420,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20420,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20420,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20420,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20420,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20420,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20420,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20420,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20420,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20427,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20427,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20427,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20427,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20427,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20427,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20427,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20427,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20427,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20427,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20427,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20427,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.ruler_HorizontalRuler_Day_0_en","libraries.designsystem.ruler_HorizontalRuler_Night_0_en",0,], ["libraries.designsystem.theme.components_IconButton_Buttons_en","",0,], @@ -387,8 +387,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",20420,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20420,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20427,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20427,], ["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,], @@ -396,109 +396,109 @@ 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",20420,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20427,], ["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",20420,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20427,], ["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",20420,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20427,], ["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20420,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20427,], ["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",20420,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20420,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20420,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20427,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20427,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20427,], ["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",20420,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20420,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20420,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20420,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20427,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20427,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20427,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20427,], ["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",20420,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20420,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20420,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20420,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20420,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20420,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20420,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20420,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20427,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20427,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20427,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20427,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20427,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20427,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20427,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20427,], ["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",20420,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20420,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20420,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20420,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20420,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20420,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20420,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20420,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20420,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20420,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20427,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20427,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20427,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20427,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20427,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20427,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20427,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20427,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20427,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], -["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20420,], -["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20420,], +["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20427,], +["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20427,], ["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",20420,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20420,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20420,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20420,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20420,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20420,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20420,], -["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20420,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20427,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20427,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20427,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20427,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20427,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20427,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20427,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20427,], ["libraries.designsystem.background_LightGradientBackground_Day_0_en","libraries.designsystem.background_LightGradientBackground_Night_0_en",0,], ["libraries.designsystem.theme.components_LinearProgressIndicator_Progress_Indicators_en","",0,], ["features.messages.impl.link_LinkView_Day_0_en","features.messages.impl.link_LinkView_Night_0_en",0,], -["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20420,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20427,], ["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,], @@ -553,38 +553,38 @@ 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",20420,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20420,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20420,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20420,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20427,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20427,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20427,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20427,], ["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",20420,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20420,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20420,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20420,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20420,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20420,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20420,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20420,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20420,], -["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20420,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20420,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20420,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20420,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20420,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20420,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20420,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20420,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20420,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20420,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20420,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20420,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20420,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20420,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20420,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20420,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20427,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20427,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20427,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20427,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20427,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20427,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20427,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20427,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20427,], +["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20427,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20427,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20427,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20427,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20427,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20427,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20427,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20427,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20427,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20427,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20427,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20427,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20427,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20427,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20427,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20427,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20420,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20427,], ["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,], @@ -597,22 +597,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",20420,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20420,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20427,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20427,], ["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",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20420,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20427,], ["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,], @@ -620,14 +620,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","",20420,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20420,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20427,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20427,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20420,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20427,], ["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","",20420,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20427,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -641,7 +641,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",20420,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20427,], ["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,], @@ -650,7 +650,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",20420,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20427,], ["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,], @@ -658,137 +658,137 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessagesReactionButton_Day_1_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_1_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_2_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_2_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_3_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_3_en",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20420,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20420,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20420,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20420,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20420,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20420,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20420,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20420,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20420,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20420,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20420,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20420,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20420,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20420,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20427,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20427,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20427,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20427,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20427,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20427,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20427,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20427,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20427,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20427,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20427,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20427,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20427,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20427,], ["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",20420,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20427,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], -["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20420,], +["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20427,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_MultipleSelectionDialog_Night_0_en",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelectedTrailingContent_Multiple_selection_List_item_-_selection_in_trailing_content_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelected_Multiple_selection_List_item_-_selection_in_supporting_text_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItem_Multiple_selection_List_item_-_no_selection_List_items_en","",0,], ["libraries.designsystem.theme.components_NavigationBar_App_Bars_en","",0,], -["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20420,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20420,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20420,], +["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20427,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20427,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20427,], ["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",20420,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20420,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20420,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20420,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20420,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20420,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20420,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20420,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20427,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20427,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20427,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20427,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20427,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20427,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20427,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20427,], ["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",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20420,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20427,], ["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",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20420,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20427,], ["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",20420,], -["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",20420,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20420,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20420,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20420,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20420,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20427,], +["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",0,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20427,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20427,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20427,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20427,], ["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",20420,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20420,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20427,], ["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",20420,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20420,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20420,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20420,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20420,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20420,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20420,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20420,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20420,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20420,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20420,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20420,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20420,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20427,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20427,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20427,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20427,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20427,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20420,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20420,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20420,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20420,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20420,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20427,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20427,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20427,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20427,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20427,], ["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",20420,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20420,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20420,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20420,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20420,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20420,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20420,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20420,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20420,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20420,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20420,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20427,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20427,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20427,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20427,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20427,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20427,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20427,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20427,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20427,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20427,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20427,], ["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,], @@ -802,205 +802,206 @@ 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","",20420,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20420,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20420,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20420,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20427,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20427,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20427,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20427,], ["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","",20420,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20420,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20427,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20427,], ["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",20420,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20420,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20420,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20420,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20420,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20420,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20420,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20420,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20420,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20420,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20420,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20420,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20420,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20420,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20420,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20420,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20420,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20420,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20420,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20420,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20420,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20420,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20420,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20420,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20420,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20420,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20420,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20427,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20427,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20427,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20427,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20427,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20427,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20427,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20427,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20427,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20427,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20427,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20427,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20427,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20427,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20427,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20427,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20427,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20427,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20427,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20427,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20427,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20427,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20427,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20427,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20427,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20427,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20427,], ["libraries.designsystem.theme.components_RadioButton_Toggles_en","",0,], -["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20420,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20420,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20427,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20427,], ["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",20420,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20420,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20420,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20420,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20420,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20420,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20420,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20427,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20427,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20427,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20427,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20427,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20427,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20427,], ["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",20420,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20420,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20420,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20420,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20420,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20420,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20420,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20420,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20420,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20420,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20420,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20420,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20420,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20420,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20420,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20420,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20420,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20427,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20427,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20427,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20427,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20427,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20427,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20427,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20427,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20427,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20427,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20427,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20427,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20427,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20427,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20427,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20427,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20427,], ["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",20420,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20420,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20420,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20420,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20420,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20420,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20420,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20420,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20420,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20420,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20420,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20420,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20420,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20427,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20427,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20427,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20427,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20427,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20427,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20427,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20427,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20427,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20427,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20427,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20427,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20427,], ["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",20420,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20420,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20420,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20420,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en",20420,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en",20420,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en",20420,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en",20420,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en",20420,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en",20420,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en",20420,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en",20420,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en",20420,], -["features.roomdetails.impl_RoomDetails_0_en","",20420,], -["features.roomdetails.impl_RoomDetails_10_en","",20420,], -["features.roomdetails.impl_RoomDetails_11_en","",20420,], -["features.roomdetails.impl_RoomDetails_12_en","",20420,], -["features.roomdetails.impl_RoomDetails_13_en","",20420,], -["features.roomdetails.impl_RoomDetails_14_en","",20420,], -["features.roomdetails.impl_RoomDetails_15_en","",20420,], -["features.roomdetails.impl_RoomDetails_16_en","",20420,], -["features.roomdetails.impl_RoomDetails_17_en","",20420,], -["features.roomdetails.impl_RoomDetails_18_en","",20420,], -["features.roomdetails.impl_RoomDetails_19_en","",20420,], -["features.roomdetails.impl_RoomDetails_1_en","",20420,], -["features.roomdetails.impl_RoomDetails_2_en","",20420,], -["features.roomdetails.impl_RoomDetails_3_en","",20420,], -["features.roomdetails.impl_RoomDetails_4_en","",20420,], -["features.roomdetails.impl_RoomDetails_5_en","",20420,], -["features.roomdetails.impl_RoomDetails_6_en","",20420,], -["features.roomdetails.impl_RoomDetails_7_en","",20420,], -["features.roomdetails.impl_RoomDetails_8_en","",20420,], -["features.roomdetails.impl_RoomDetails_9_en","",20420,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20420,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20420,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20420,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20420,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20420,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20420,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20420,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20420,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20420,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20427,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20427,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20427,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20427,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20430,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20430,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20430,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20430,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20430,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20430,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20430,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20430,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20430,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20430,], +["features.roomdetails.impl_RoomDetails_0_en","",20427,], +["features.roomdetails.impl_RoomDetails_10_en","",20427,], +["features.roomdetails.impl_RoomDetails_11_en","",20427,], +["features.roomdetails.impl_RoomDetails_12_en","",20427,], +["features.roomdetails.impl_RoomDetails_13_en","",20427,], +["features.roomdetails.impl_RoomDetails_14_en","",20427,], +["features.roomdetails.impl_RoomDetails_15_en","",20427,], +["features.roomdetails.impl_RoomDetails_16_en","",20427,], +["features.roomdetails.impl_RoomDetails_17_en","",20427,], +["features.roomdetails.impl_RoomDetails_18_en","",20427,], +["features.roomdetails.impl_RoomDetails_19_en","",20427,], +["features.roomdetails.impl_RoomDetails_1_en","",20427,], +["features.roomdetails.impl_RoomDetails_2_en","",20427,], +["features.roomdetails.impl_RoomDetails_3_en","",20427,], +["features.roomdetails.impl_RoomDetails_4_en","",20427,], +["features.roomdetails.impl_RoomDetails_5_en","",20427,], +["features.roomdetails.impl_RoomDetails_6_en","",20427,], +["features.roomdetails.impl_RoomDetails_7_en","",20427,], +["features.roomdetails.impl_RoomDetails_8_en","",20427,], +["features.roomdetails.impl_RoomDetails_9_en","",20427,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20427,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20427,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20427,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20427,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20427,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20427,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20427,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20427,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20427,], ["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",20420,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20420,], -["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20420,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20420,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20420,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20420,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20420,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20420,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20420,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20427,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20427,], +["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20427,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20427,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20427,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20427,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20427,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20427,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20427,], ["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",20420,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20420,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20420,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20420,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20420,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20420,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20420,], -["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",0,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20420,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20420,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20420,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20420,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20420,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20420,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20420,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20420,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20420,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20427,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20427,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20427,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20427,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20427,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20427,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20427,], +["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20430,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20427,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20427,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20427,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20427,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20427,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20427,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20427,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20427,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20427,], ["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",20420,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20420,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20420,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20420,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20420,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20420,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20420,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20420,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20420,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20420,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20420,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20420,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20420,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20420,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20427,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20427,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20427,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20427,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20427,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20427,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20427,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20427,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20427,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20427,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20427,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20427,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20427,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20427,], ["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,], @@ -1023,14 +1024,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",20420,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20420,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20420,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20420,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20420,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20420,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20420,], -["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20420,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20427,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20427,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20427,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20427,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20427,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20427,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20427,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20427,], +["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",0,], ["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,], @@ -1038,105 +1041,105 @@ 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",20420,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20420,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20420,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20427,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20427,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20427,], ["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",20420,], -["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20420,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20420,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20420,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20427,], +["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20427,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20427,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20427,], ["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","",20420,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20427,], ["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","",20420,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20420,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20420,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20420,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20420,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20420,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20420,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20420,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20420,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20420,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20420,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20420,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20420,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",0,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",0,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20427,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20427,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20427,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20427,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20427,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20427,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20427,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20427,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20427,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20427,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20427,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20427,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20427,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20430,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20430,], ["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,], @@ -1150,11 +1153,11 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_1_en","libraries.matrix.ui.components_SelectedUser_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedUsersRowList_Day_0_en","libraries.matrix.ui.components_SelectedUsersRowList_Night_0_en",0,], ["libraries.textcomposer.components_SendButton_Day_0_en","libraries.textcomposer.components_SendButton_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20420,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20420,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20420,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20420,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20420,], +["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20427,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20427,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20427,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20427,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20427,], ["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,], @@ -1164,27 +1167,27 @@ export const screenshots = [ ["libraries.matrix.ui.messages.sender_SenderName_Day_6_en","libraries.matrix.ui.messages.sender_SenderName_Night_6_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_7_en","libraries.matrix.ui.messages.sender_SenderName_Night_7_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_8_en","libraries.matrix.ui.messages.sender_SenderName_Night_8_en",0,], -["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20420,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20420,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20420,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20420,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20420,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20420,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20420,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20420,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20427,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20427,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20427,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20427,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20427,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20427,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20427,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20427,], ["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",20420,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20420,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20420,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20420,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20420,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20420,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20420,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20420,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20420,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20420,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20427,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20427,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20427,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20427,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20427,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20427,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20427,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20427,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20427,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20427,], ["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,], @@ -1194,102 +1197,102 @@ 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",20420,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20427,], ["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",20420,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20427,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20420,], -["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20420,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20420,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20427,], +["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20427,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20427,], ["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",20420,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20420,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20420,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20420,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20420,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20420,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20420,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20420,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20420,], -["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20420,], -["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20420,], -["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20420,], -["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20420,], -["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20420,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20420,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20420,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20420,], -["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20420,], -["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20420,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20427,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20427,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20427,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20427,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20427,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20427,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20427,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20427,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20427,], +["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20427,], +["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20427,], +["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20427,], +["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20427,], +["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20427,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20427,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20427,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20427,], +["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20427,], +["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20427,], ["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",20420,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20420,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20420,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20420,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20420,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20420,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20420,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20427,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20427,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20427,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20427,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20427,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20427,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20427,], ["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",20420,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20427,], ["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",20420,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20427,], ["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",20420,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20420,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20420,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20420,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20420,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20420,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20420,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20420,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20420,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20420,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20420,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20420,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20420,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20420,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20420,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20427,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20427,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20427,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20427,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20427,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20427,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20427,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20427,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20427,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20427,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20427,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20427,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20427,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20427,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20427,], ["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",20420,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20420,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20427,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20427,], ["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,], @@ -1301,16 +1304,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",20420,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20420,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20420,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20420,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20420,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20427,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20427,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20427,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20427,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20427,], ["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",20420,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20420,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20427,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20427,], ["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,], @@ -1320,18 +1323,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",20420,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20427,], ["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",20420,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20427,], ["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,], @@ -1339,18 +1342,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",20420,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20427,], ["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",20420,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20420,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20427,], ["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",20420,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20427,], ["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,], @@ -1359,41 +1362,41 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20427,], ["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",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20427,], ["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",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20427,], ["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","",20420,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20427,], ["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",20420,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20420,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20427,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20427,], ["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",20420,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20427,], ["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",20420,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20420,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20420,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20427,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20427,], ["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",20420,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20420,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20427,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20427,], ["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",20420,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20427,], ["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,], @@ -1402,8 +1405,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",20420,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20427,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20427,], ["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,], @@ -1418,8 +1421,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",20420,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20427,], ["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,], @@ -1442,85 +1445,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",20420,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20420,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20427,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20427,], ["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",20420,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20420,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20420,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20420,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20420,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20420,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20420,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20420,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20427,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20427,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20427,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20427,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20427,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20427,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20427,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20427,], ["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",20420,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20427,], ["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",20420,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20427,], ["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",20420,], +["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20427,], ["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",20420,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20420,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20420,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20420,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20420,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20420,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20420,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20420,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20427,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20427,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20427,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20427,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20427,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20427,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20427,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20427,], ["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",20420,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20420,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20420,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20420,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20420,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20420,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20427,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20427,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20427,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20427,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20427,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20427,], ["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","",20420,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20427,], ["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], ["libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en","libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en",0,], -["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20420,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20420,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20420,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20420,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20427,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20427,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20427,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20427,], ["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",20420,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20427,], ["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",20420,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20427,], ["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",20420,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20420,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20420,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20420,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20420,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20420,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20420,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20420,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20420,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20420,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20420,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20420,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20427,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20427,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20427,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20427,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20427,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20427,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20427,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20427,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20427,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20427,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20427,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20427,], ["features.verifysession.impl.ui_VerificationUserProfileContent_Day_0_en","features.verifysession.impl.ui_VerificationUserProfileContent_Night_0_en",0,], ["libraries.designsystem.ruler_VerticalRuler_Day_0_en","libraries.designsystem.ruler_VerticalRuler_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_1_en",0,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20420,], -["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20420,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20427,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20427,], ["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",20420,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20427,], ["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/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png index 9f58184f04..a01340b169 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:3f2d14cff976468c7a2408c9e9d0dabcfbed4a0cfb1406f71db459f660305269 -size 24794 +oid sha256:f4467db8409103caf24b97dab28e5280da60ca420d951d689d353ebaf63841bf +size 24737 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 da8873613c..e7c94c7669 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:b904f634f9668cc207a922979e0b3abc92c586f3986cf3c57630da8aa2eb22fe -size 23835 +oid sha256:fd96a05649a403454636d07168398476b25aae4aaad76cac4e41265478ec4791 +size 23768 From 5d69f289f5a98ed4e6244a1eafe852d70baea00e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 8 Dec 2025 09:54:01 +0100 Subject: [PATCH 066/347] Add a way to configure value of android.packaging.jniLibs.useLegacyPackaging from command line. --- app/build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2464155cb4..322ad47911 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -199,6 +199,10 @@ android { resources.pickFirsts += setOf( "META-INF/versions/9/OSGI-INF/MANIFEST.MF", ) + + jniLibs { + useLegacyPackaging = project.findProperty("useLegacyPackaging")?.toString()?.toBoolean() + } } } From 549054037a558d5e8057ac474bf2ef62790886c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 13:26:21 +0000 Subject: [PATCH 067/347] chore(deps): update peter-evans/create-pull-request action to v7.0.11 --- .github/workflows/sync-localazy.yml | 2 +- .github/workflows/sync-sas-strings.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sync-localazy.yml b/.github/workflows/sync-localazy.yml index 073c075502..c928434b73 100644 --- a/.github/workflows/sync-localazy.yml +++ b/.github/workflows/sync-localazy.yml @@ -36,7 +36,7 @@ jobs: ./tools/localazy/importSupportedLocalesFromLocalazy.py ./tools/test/generateAllScreenshots.py - name: Create Pull Request for Strings - uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 + uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 with: token: ${{ secrets.DANGER_GITHUB_API_TOKEN }} commit-message: Sync Strings from Localazy diff --git a/.github/workflows/sync-sas-strings.yml b/.github/workflows/sync-sas-strings.yml index ca42b8fbe6..b603049a04 100644 --- a/.github/workflows/sync-sas-strings.yml +++ b/.github/workflows/sync-sas-strings.yml @@ -23,7 +23,7 @@ jobs: - name: Run SAS String script run: ./tools/sas/import_sas_strings.py - name: Create Pull Request for SAS Strings - uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 + uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 with: commit-message: Sync SAS Strings title: Sync SAS Strings From 38d17b4ac47e21dc57c126261bf01997d6e1949e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 8 Dec 2025 14:28:29 +0100 Subject: [PATCH 068/347] Trigger CI From f2622e2ee9ea6edb0c676e894a73d70ce85c27dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:50:03 +0100 Subject: [PATCH 069/347] Merge pull request #5853 from element-hq/renovate/io.sentry-sentry-android-8.x fix(deps): update dependency io.sentry:sentry-android to v8.28.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 71a1a097dc..e00585b9ee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -217,7 +217,7 @@ color_picker = "io.mhssn:colorpicker:1.0.0" # Analytics posthog = "com.posthog:posthog-android:3.26.0" -sentry = "io.sentry:sentry-android:8.27.1" +sentry = "io.sentry:sentry-android:8.28.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.29.2" From 374c43794ad93dab45cd2cf68e0aca17e183b506 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:16:36 +0000 Subject: [PATCH 070/347] fix(deps): update dependency io.mockk:mockk to v1.14.7 (#5866) 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 e00585b9ee..c0dd448c17 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -160,7 +160,7 @@ test_corektx = { module = "androidx.test:core-ktx", version.ref = "test_core" } test_arch_core = "androidx.arch.core:core-testing:2.2.0" test_junit = "junit:junit:4.13.2" test_runner = "androidx.test:runner:1.7.0" -test_mockk = "io.mockk:mockk:1.14.6" +test_mockk = "io.mockk:mockk:1.14.7" test_konsist = "com.lemonappdev:konsist:0.17.3" test_turbine = "app.cash.turbine:turbine:1.2.1" test_truth = "com.google.truth:truth:1.4.5" From 2030e79f2e2458a070debaa9f4aed89ac8b9649e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:18:33 +0000 Subject: [PATCH 071/347] Update showkase to v1.0.5 --- 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 c0dd448c17..00c7859895 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -41,7 +41,7 @@ serialization_json = "1.9.0" #other coil = "3.3.0" # Rollback to 1.0.4, 1.0.5 has this issue: https://github.com/airbnb/Showkase/issues/420 -showkase = "1.0.4" +showkase = "1.0.5" appyx = "1.7.1" sqldelight = "2.2.1" wysiwyg = "2.40.0" From eff79d0b8879b1a5977927f024b0f55cc5071dc8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 8 Dec 2025 15:28:38 +0100 Subject: [PATCH 072/347] Add accessibility to the "sending" picto. --- .../android/features/home/impl/components/RoomSummaryRow.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt index da0f47ba05..b722c63622 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt @@ -243,7 +243,7 @@ private fun NameAndTimestampRow( Icon( modifier = Modifier.size(16.dp), imageVector = CompoundIcons.Time(), - contentDescription = null, + contentDescription = stringResource(CommonStrings.common_sending), tint = ElementTheme.colors.iconTertiary, ) } @@ -252,6 +252,7 @@ private fun NameAndTimestampRow( Icon( modifier = Modifier.size(16.dp), imageVector = CompoundIcons.ErrorSolid(), + // The last message contains the error. contentDescription = null, tint = ElementTheme.colors.iconCriticalPrimary, ) From d0ba02dd7ecf92325b111dcce902f2b233ae6e07 Mon Sep 17 00:00:00 2001 From: Skye Elliot Date: Mon, 8 Dec 2025 20:19:15 +0000 Subject: [PATCH 073/347] Add alert to encrypted rooms with visible history (Android). (#5709) * feat: Add visible history alert to encrypted rooms. - Adds a dismissable alert that is displayed whenever the user opens a room with `history_visibility` != `joined`. When cleared, this is recorded in the app's data store. - When opening a room with `history_visibility` = `joined`, this flag is cleared.` Issue: https://github.com/element-hq/element-meta/issues/2875 * chore: Fix linting issues. * feat: Move alert showing logic into state presenter. * chore: Fix linting issues. * tests: Fixup tests. * feat: Use real link. * chore: Update license header. * chore: Add (c) to license headers. * chore: Add `.` to license header. * feat: Lock alert behind history sharing developer setting. * ci: Trigger record screenshots * feat: Create repo key using session ID for multi-account support. * feat: Use session ID hash for constructing data store. * tests: Correct and update tests. * tests: Update snapshots. * feat: Prevent identity alert from displaying with history visibility alert. * feat: Tidy up HistoryVisibleStatePresenter logic, update previews. * chore: Remove unused import. * chore: Update screenshots. * feat: Add translation string. * chore: Remove redundant temporary translation file. --- .../android/appconfig/LearnMoreConfig.kt | 1 + features/messages/impl/build.gradle.kts | 1 + .../messages/impl/MessagesPresenter.kt | 4 + .../features/messages/impl/MessagesState.kt | 2 + .../messages/impl/MessagesStateProvider.kt | 19 +++ .../features/messages/impl/MessagesView.kt | 16 ++- ...HistoryVisibleAcknowledgementRepository.kt | 48 +++++++ .../historyvisible/HistoryVisibleEvent.kt | 12 ++ .../historyvisible/HistoryVisibleState.kt | 13 ++ .../HistoryVisibleStatePresenter.kt | 62 +++++++++ .../HistoryVisibleStateProvider.kt | 25 ++++ .../historyvisible/HistoryVisibleStateView.kt | 81 +++++++++++ .../MessagesViewWithHistoryVisiblePreview.kt | 42 ++++++ .../messages/impl/di/MessagesBindsModule.kt | 5 + .../messages/impl/MessagesPresenterTest.kt | 2 + ...HistoryVisibleAcknowledgementRepository.kt | 42 ++++++ .../HistoryVisibleStatePresenterTest.kt | 127 ++++++++++++++++++ .../tests/konsist/KonsistPreviewTest.kt | 1 + ...sible_HistoryVisibleStateView_Day_0_en.png | 3 + ...sible_HistoryVisibleStateView_Day_1_en.png | 3 + ...ble_HistoryVisibleStateView_Night_0_en.png | 3 + ...ble_HistoryVisibleStateView_Night_1_en.png | 3 + ...essagesViewWithHistoryVisible_Day_0_en.png | 3 + ...essagesViewWithHistoryVisible_Day_1_en.png | 3 + ...sagesViewWithHistoryVisible_Night_0_en.png | 3 + ...sagesViewWithHistoryVisible_Night_1_en.png | 3 + ...s.messages.impl_MessagesView_Day_10_en.png | 3 + ...s.messages.impl_MessagesView_Day_11_en.png | 3 + ...s.messages.impl_MessagesView_Day_12_en.png | 3 + ...messages.impl_MessagesView_Night_10_en.png | 3 + ...messages.impl_MessagesView_Night_11_en.png | 3 + ...messages.impl_MessagesView_Night_12_en.png | 3 + 32 files changed, 541 insertions(+), 4 deletions(-) create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleAcknowledgementRepository.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleEvent.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleState.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateProvider.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateView.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/MessagesViewWithHistoryVisiblePreview.kt create mode 100644 features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/FakeHistoryVisibleAcknowledgementRepository.kt create mode 100644 features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenterTest.kt create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png diff --git a/appconfig/src/main/kotlin/io/element/android/appconfig/LearnMoreConfig.kt b/appconfig/src/main/kotlin/io/element/android/appconfig/LearnMoreConfig.kt index c0c152142e..855586892a 100644 --- a/appconfig/src/main/kotlin/io/element/android/appconfig/LearnMoreConfig.kt +++ b/appconfig/src/main/kotlin/io/element/android/appconfig/LearnMoreConfig.kt @@ -13,4 +13,5 @@ object LearnMoreConfig { const val DEVICE_VERIFICATION_URL: String = "https://element.io/help#encryption-device-verification" const val SECURE_BACKUP_URL: String = "https://element.io/help#encryption5" const val IDENTITY_CHANGE_URL: String = "https://element.io/help#encryption18" + const val HISTORY_VISIBLE_URL: String = "https://element.io/en/help#e2ee-history-sharing" } diff --git a/features/messages/impl/build.gradle.kts b/features/messages/impl/build.gradle.kts index ad6562a83c..eb8aff66ed 100644 --- a/features/messages/impl/build.gradle.kts +++ b/features/messages/impl/build.gradle.kts @@ -68,6 +68,7 @@ dependencies { implementation(libs.jsoup) implementation(libs.androidx.constraintlayout) implementation(libs.androidx.constraintlayout.compose) + implementation(libs.androidx.datastore.preferences) implementation(libs.androidx.media3.exoplayer) implementation(libs.androidx.media3.ui) implementation(libs.sigpwned.emoji4j) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index e912722c6d..a5b3106b3d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -32,6 +32,7 @@ import io.element.android.features.messages.api.timeline.HtmlConverterProvider import io.element.android.features.messages.impl.actionlist.ActionListEvents import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction +import io.element.android.features.messages.impl.crypto.historyvisible.HistoryVisibleState import io.element.android.features.messages.impl.crypto.identity.IdentityChangeState import io.element.android.features.messages.impl.link.LinkState import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvent @@ -107,6 +108,7 @@ class MessagesPresenter( @Assisted private val timelinePresenter: Presenter, private val timelineProtectionPresenter: Presenter, private val identityChangeStatePresenter: Presenter, + private val historyVisibleStatePresenter: Presenter, private val linkPresenter: Presenter, @Assisted private val actionListPresenter: Presenter, private val customReactionPresenter: Presenter, @@ -158,6 +160,7 @@ class MessagesPresenter( val timelineState = timelinePresenter.present() val timelineProtectionState = timelineProtectionPresenter.present() val identityChangeState = identityChangeStatePresenter.present() + val historyVisibleState = historyVisibleStatePresenter.present() val actionListState = actionListPresenter.present() val linkState = linkPresenter.present() val customReactionState = customReactionPresenter.present() @@ -278,6 +281,7 @@ class MessagesPresenter( timelineState = timelineState, timelineProtectionState = timelineProtectionState, identityChangeState = identityChangeState, + historyVisibleState = historyVisibleState, linkState = linkState, actionListState = actionListState, customReactionState = customReactionState, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt index 9faf2f69eb..b9d86a6597 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt @@ -10,6 +10,7 @@ package io.element.android.features.messages.impl import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerState import io.element.android.features.messages.impl.actionlist.ActionListState +import io.element.android.features.messages.impl.crypto.historyvisible.HistoryVisibleState import io.element.android.features.messages.impl.crypto.identity.IdentityChangeState import io.element.android.features.messages.impl.link.LinkState import io.element.android.features.messages.impl.messagecomposer.MessageComposerState @@ -40,6 +41,7 @@ data class MessagesState( val timelineState: TimelineState, val timelineProtectionState: TimelineProtectionState, val identityChangeState: IdentityChangeState, + val historyVisibleState: HistoryVisibleState, val linkState: LinkState, val actionListState: ActionListState, val customReactionState: CustomReactionState, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index 3a077e6cf0..7831265fd0 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -14,7 +14,10 @@ import io.element.android.features.messages.api.timeline.voicemessages.composer. import io.element.android.features.messages.api.timeline.voicemessages.composer.aVoiceMessagePreviewState import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.features.messages.impl.actionlist.anActionListState +import io.element.android.features.messages.impl.crypto.historyvisible.HistoryVisibleState +import io.element.android.features.messages.impl.crypto.historyvisible.aHistoryVisibleState import io.element.android.features.messages.impl.crypto.identity.IdentityChangeState +import io.element.android.features.messages.impl.crypto.identity.aRoomMemberIdentityStateChange import io.element.android.features.messages.impl.crypto.identity.anIdentityChangeState import io.element.android.features.messages.impl.link.LinkState import io.element.android.features.messages.impl.link.aLinkState @@ -48,6 +51,7 @@ import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.textcomposer.model.MessageComposerMode +import io.element.android.libraries.textcomposer.model.aTextEditorStateMarkdown import io.element.android.libraries.textcomposer.model.aTextEditorStateRich import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -83,6 +87,19 @@ open class MessagesStateProvider : PreviewParameterProvider { timelineItems = aTimelineItemList(aTimelineItemTextContent()), ) ), + aMessagesState( + composerState = aMessageComposerState(textEditorState = aTextEditorStateMarkdown()), + identityChangeState = anIdentityChangeState(listOf(aRoomMemberIdentityStateChange())) + ), + aMessagesState( + composerState = aMessageComposerState(textEditorState = aTextEditorStateMarkdown()), + historyVisibleState = aHistoryVisibleState(showAlert = true) + ), + aMessagesState( + composerState = aMessageComposerState(textEditorState = aTextEditorStateMarkdown()), + identityChangeState = anIdentityChangeState(listOf(aRoomMemberIdentityStateChange())), + historyVisibleState = aHistoryVisibleState(showAlert = true) + ) ) } @@ -103,6 +120,7 @@ fun aMessagesState( ), timelineProtectionState: TimelineProtectionState = aTimelineProtectionState(), identityChangeState: IdentityChangeState = anIdentityChangeState(), + historyVisibleState: HistoryVisibleState = aHistoryVisibleState(), linkState: LinkState = aLinkState(), readReceiptBottomSheetState: ReadReceiptBottomSheetState = aReadReceiptBottomSheetState(), actionListState: ActionListState = anActionListState(), @@ -125,6 +143,7 @@ fun aMessagesState( voiceMessageComposerState = voiceMessageComposerState, timelineProtectionState = timelineProtectionState, identityChangeState = identityChangeState, + historyVisibleState = historyVisibleState, linkState = linkState, timelineState = timelineState, readReceiptBottomSheetState = readReceiptBottomSheetState, 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 a37710843d..5479836bb3 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 @@ -53,6 +53,7 @@ import io.element.android.features.messages.api.timeline.voicemessages.composer. import io.element.android.features.messages.impl.actionlist.ActionListEvents import io.element.android.features.messages.impl.actionlist.ActionListView import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction +import io.element.android.features.messages.impl.crypto.historyvisible.HistoryVisibleStateView import io.element.android.features.messages.impl.crypto.identity.IdentityChangeStateView import io.element.android.features.messages.impl.link.LinkEvents import io.element.android.features.messages.impl.link.LinkView @@ -486,10 +487,17 @@ private fun MessagesViewComposerBottomSheetContents( // Do not show the identity change if user is composing a Rich message or is seeing suggestion(s). if (state.composerState.suggestions.isEmpty() && state.composerState.textEditorState is TextEditorState.Markdown) { - IdentityChangeStateView( - state = state.identityChangeState, - onLinkClick = onLinkClick, - ) + if (state.identityChangeState.roomMemberIdentityStateChanges.isNotEmpty()) { + IdentityChangeStateView( + state = state.identityChangeState, + onLinkClick = onLinkClick, + ) + } else { + HistoryVisibleStateView( + state = state.historyVisibleState, + onLinkClick = onLinkClick, + ) + } } val verificationViolation = state.identityChangeState.roomMemberIdentityStateChanges.firstOrNull { it.identityState == IdentityState.VerificationViolation diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleAcknowledgementRepository.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleAcknowledgementRepository.kt new file mode 100644 index 0000000000..1fa992fc3e --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleAcknowledgementRepository.kt @@ -0,0 +1,48 @@ +/* + * 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.crypto.historyvisible + +import androidx.datastore.preferences.core.booleanPreferencesKey +import androidx.datastore.preferences.core.edit +import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.androidutils.hash.hash +import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFactory +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +interface HistoryVisibleAcknowledgementRepository { + fun hasAcknowledged(roomId: RoomId): Flow + suspend fun setAcknowledged(roomId: RoomId, value: Boolean) +} + +@ContributesBinding(SessionScope::class) +class DefaultHistoryVisibleAcknowledgementRepository( + sessionId: SessionId, + preferenceDataStoreFactory: PreferenceDataStoreFactory, +) : HistoryVisibleAcknowledgementRepository { + val store = + sessionId.value.hash().take(16).let { hash -> + preferenceDataStoreFactory.create("elementx_historyvisible_$hash") + } + + override fun hasAcknowledged(roomId: RoomId): Flow { + return store.data.map { prefs -> + val acknowledged = prefs[booleanPreferencesKey(roomId.value)] ?: false + acknowledged + } + } + + override suspend fun setAcknowledged(roomId: RoomId, value: Boolean) { + store.edit { prefs -> + prefs[booleanPreferencesKey(roomId.value)] = value + } + } +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleEvent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleEvent.kt new file mode 100644 index 0000000000..775d9c00d4 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleEvent.kt @@ -0,0 +1,12 @@ +/* + * 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.crypto.historyvisible + +sealed interface HistoryVisibleEvent { + data object Acknowledge : HistoryVisibleEvent +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleState.kt new file mode 100644 index 0000000000..3f980eb086 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleState.kt @@ -0,0 +1,13 @@ +/* + * 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.crypto.historyvisible + +data class HistoryVisibleState( + val showAlert: Boolean, + val eventSink: (HistoryVisibleEvent) -> Unit, +) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt new file mode 100644 index 0000000000..d76e567b3c --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt @@ -0,0 +1,62 @@ +/* + * 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.crypto.historyvisible + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberCoroutineScope +import dev.zacsweers.metro.Inject +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch + +@Inject +class HistoryVisibleStatePresenter( + private val featureFlagService: FeatureFlagService, + private val repository: HistoryVisibleAcknowledgementRepository, + private val room: JoinedRoom, +) : Presenter { + @Composable + override fun present(): HistoryVisibleState { + val isFeatureEnabled by featureFlagService.isFeatureEnabledFlow(FeatureFlags.EnableKeyShareOnInvite).collectAsState(initial = false) + val roomInfo by room.roomInfoFlow.collectAsState() + // Implicitly assume the alert is initially acknowledged to avoid flashes in UI. + val acknowledged by repository.hasAcknowledged(room.roomId).collectAsState(initial = true) + + val coroutineScope = rememberCoroutineScope() + + LaunchedEffect(roomInfo.historyVisibility, acknowledged) { + if (roomInfo.historyVisibility == RoomHistoryVisibility.Joined && acknowledged) { + repository.setAcknowledged(room.roomId, false) + } + } + + fun handleEvent(event: HistoryVisibleEvent) { + when (event) { + is HistoryVisibleEvent.Acknowledge -> coroutineScope.setAcknowledged(room.roomId, true) + } + } + + return HistoryVisibleState( + showAlert = isFeatureEnabled && roomInfo.historyVisibility != RoomHistoryVisibility.Joined && roomInfo.isEncrypted == true && !acknowledged, + eventSink = ::handleEvent, + ) + } + + private fun CoroutineScope.setAcknowledged(roomId: RoomId, value: Boolean) = launch { + repository.setAcknowledged(roomId, value) + } +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateProvider.kt new file mode 100644 index 0000000000..752abdc76b --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateProvider.kt @@ -0,0 +1,25 @@ +/* + * 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.crypto.historyvisible + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +class HistoryVisibleStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aHistoryVisibleState(showAlert = true), + ) +} + +internal fun aHistoryVisibleState( + showAlert: Boolean = false, + eventSink: (HistoryVisibleEvent) -> Unit = {}, +) = HistoryVisibleState( + showAlert, + eventSink = eventSink, +) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateView.kt new file mode 100644 index 0000000000..9c08c9d101 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateView.kt @@ -0,0 +1,81 @@ +/* + * 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.crypto.historyvisible + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.LinkAnnotation +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.tooling.preview.PreviewParameter +import io.element.android.appconfig.LearnMoreConfig +import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.atomic.molecules.ComposerAlertLevel +import io.element.android.libraries.designsystem.atomic.molecules.ComposerAlertMolecule +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +fun HistoryVisibleStateView( + state: HistoryVisibleState, + onLinkClick: (String, Boolean) -> Unit, + modifier: Modifier = Modifier, +) { + if (!state.showAlert) { + return + } + + ComposerAlertMolecule( + modifier = modifier, + avatar = null, + showIcon = true, + level = ComposerAlertLevel.Info, + content = buildAnnotatedString { + val learnMoreStr = stringResource(CommonStrings.action_learn_more) + val fullText = stringResource(CommonStrings.crypto_history_visible, learnMoreStr) + append(fullText) + val learnMoreStartIndex = fullText.lastIndexOf(learnMoreStr) + addStyle( + style = SpanStyle( + textDecoration = TextDecoration.Underline, + fontWeight = FontWeight.Bold, + color = ElementTheme.colors.textPrimary + ), + start = learnMoreStartIndex, + end = learnMoreStartIndex + learnMoreStr.length, + ) + addLink( + url = LinkAnnotation.Url( + url = LearnMoreConfig.HISTORY_VISIBLE_URL, + linkInteractionListener = { + onLinkClick(LearnMoreConfig.HISTORY_VISIBLE_URL, true) + } + ), + start = learnMoreStartIndex, + end = learnMoreStartIndex + learnMoreStr.length, + ) + }, + submitText = stringResource(CommonStrings.action_dismiss), + onSubmitClick = { state.eventSink(HistoryVisibleEvent.Acknowledge) }, + ) +} + +@PreviewsDayNight +@Composable +internal fun HistoryVisibleStateViewPreview( + @PreviewParameter(HistoryVisibleStateProvider::class) state: HistoryVisibleState, +) = ElementPreview { + HistoryVisibleStateView( + state = state, + onLinkClick = { _, _ -> }, + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/MessagesViewWithHistoryVisiblePreview.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/MessagesViewWithHistoryVisiblePreview.kt new file mode 100644 index 0000000000..07cf5170d3 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/MessagesViewWithHistoryVisiblePreview.kt @@ -0,0 +1,42 @@ +/* + * 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.crypto.historyvisible + +import androidx.compose.runtime.Composable +import io.element.android.features.messages.impl.MessagesView +import io.element.android.features.messages.impl.aMessagesState +import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.textcomposer.model.aTextEditorStateMarkdown + +@PreviewsDayNight +@Composable +internal fun MessagesViewWithHistoryVisiblePreview() = ElementPreview { + MessagesView( + state = aMessagesState( + composerState = aMessageComposerState( + textEditorState = aTextEditorStateMarkdown( + initialText = "", + initialFocus = false, + ) + ), + historyVisibleState = aHistoryVisibleState(showAlert = true), + ), + onBackClick = {}, + onRoomDetailsClick = {}, + onEventContentClick = { _, _ -> false }, + onUserDataClick = {}, + onLinkClick = { _, _ -> }, + onSendLocationClick = {}, + onCreatePollClick = {}, + onJoinCallClick = {}, + onViewAllPinnedMessagesClick = {}, + knockRequestsBannerView = {} + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/di/MessagesBindsModule.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/di/MessagesBindsModule.kt index a345e09fa2..a88dbb1b49 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/di/MessagesBindsModule.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/di/MessagesBindsModule.kt @@ -11,6 +11,8 @@ package io.element.android.features.messages.impl.di import dev.zacsweers.metro.BindingContainer import dev.zacsweers.metro.Binds import dev.zacsweers.metro.ContributesTo +import io.element.android.features.messages.impl.crypto.historyvisible.HistoryVisibleState +import io.element.android.features.messages.impl.crypto.historyvisible.HistoryVisibleStatePresenter import io.element.android.features.messages.impl.crypto.identity.IdentityChangeState import io.element.android.features.messages.impl.crypto.identity.IdentityChangeStatePresenter import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailurePresenter @@ -61,4 +63,7 @@ interface MessagesBindsModule { @Binds fun bindIdentityChangeStatePresenter(presenter: IdentityChangeStatePresenter): Presenter + + @Binds + fun bindHistoryVisibleStatePresenter(presenter: HistoryVisibleStatePresenter): Presenter } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index 852e2504b2..de2c8a81c9 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -17,6 +17,7 @@ import io.element.android.features.messages.impl.actionlist.ActionListEvents import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.features.messages.impl.actionlist.anActionListState import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction +import io.element.android.features.messages.impl.crypto.historyvisible.aHistoryVisibleState import io.element.android.features.messages.impl.crypto.identity.anIdentityChangeState import io.element.android.features.messages.impl.fixtures.aMessageEvent import io.element.android.features.messages.impl.link.aLinkState @@ -1355,6 +1356,7 @@ class MessagesPresenterTest { timelinePresenter = { aTimelineState(eventSink = timelineEventSink) }, timelineProtectionPresenter = { aTimelineProtectionState() }, identityChangeStatePresenter = { anIdentityChangeState() }, + historyVisibleStatePresenter = { aHistoryVisibleState() }, linkPresenter = { aLinkState() }, actionListPresenter = { anActionListState(eventSink = actionListEventSink) }, customReactionPresenter = { aCustomReactionState() }, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/FakeHistoryVisibleAcknowledgementRepository.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/FakeHistoryVisibleAcknowledgementRepository.kt new file mode 100644 index 0000000000..faf21720fa --- /dev/null +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/FakeHistoryVisibleAcknowledgementRepository.kt @@ -0,0 +1,42 @@ +/* + * 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.crypto.historyvisible + +import io.element.android.libraries.matrix.api.core.RoomId +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow + +class FakeHistoryVisibleAcknowledgementRepository( + private val acknowledgements: MutableMap> = mutableMapOf() +) : HistoryVisibleAcknowledgementRepository { + override fun hasAcknowledged(roomId: RoomId): Flow { + return acknowledgements.getOrPut(roomId) { + MutableStateFlow(false) + } + } + + override suspend fun setAcknowledged(roomId: RoomId, value: Boolean) { + val flow = acknowledgements.getOrPut(roomId) { + MutableStateFlow(value) + } + flow.emit(value) + } + + companion object { + /** + * Create the repository with a pre-existing entry. + */ + fun withRoom(roomId: RoomId, acknowledged: Boolean = false): FakeHistoryVisibleAcknowledgementRepository { + return FakeHistoryVisibleAcknowledgementRepository( + mutableMapOf( + roomId to MutableStateFlow(acknowledged) + ) + ) + } + } +} diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenterTest.kt new file mode 100644 index 0000000000..b6619851e6 --- /dev/null +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenterTest.kt @@ -0,0 +1,127 @@ +/* + * 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.crypto.historyvisible + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility +import io.element.android.libraries.matrix.test.room.FakeJoinedRoom +import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.awaitLastSequentialItem +import io.element.android.tests.testutils.test +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test + +class HistoryVisibleStatePresenterTest { + @get:Rule + val warmUpRule = WarmUpRule() + + @Test + fun `present - not visible if feature disabled`() = runTest { + val room = FakeJoinedRoom() + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Joined, isEncrypted = true)) + val presenter = createHistoryVisibleStatePresenter(room, enabled = false, acknowledged = false) + presenter.test { + assertThat(awaitLastSequentialItem().showAlert).isFalse() + } + } + + @Test + fun `present - initial with room shared, unencrypted`() = runTest { + val room = FakeJoinedRoom() + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, isEncrypted = false)) + val presenter = createHistoryVisibleStatePresenter(room) + presenter.test { + assertThat(awaitLastSequentialItem().showAlert).isFalse() + } + } + + @Test + fun `present - initial with room joined, encrypted`() = runTest { + val room = FakeJoinedRoom() + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Joined, isEncrypted = false)) + val presenter = createHistoryVisibleStatePresenter(room) + presenter.test { + assertThat(awaitLastSequentialItem().showAlert).isFalse() + } + } + + @Test + fun `present - initial with room shared, encrypted, unacknowledged`() = runTest { + val room = FakeJoinedRoom() + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, isEncrypted = true)) + val presenter = createHistoryVisibleStatePresenter(room, acknowledged = false) + presenter.test { + val initialState = awaitItem() + assertThat(initialState.showAlert).isFalse() + val nextState = awaitItem() + assertThat(nextState.showAlert).isTrue() + } + } + + @Test + fun `present - initial with room shared, encrypted, acknowledged`() = runTest { + val room = FakeJoinedRoom() + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, isEncrypted = true)) + val presenter = createHistoryVisibleStatePresenter(room, acknowledged = true) + presenter.test { + assertThat(awaitLastSequentialItem().showAlert).isFalse() + } + } + + @Test + fun `present - transition from joined + unencrypted, to shared + encrypted`() = runTest { + val room = FakeJoinedRoom() + val featureFlagService = FakeFeatureFlagService(mapOf(FeatureFlags.EnableKeyShareOnInvite.key to true)) + val repository = FakeHistoryVisibleAcknowledgementRepository() + + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Joined, isEncrypted = false)) + + val presenter = HistoryVisibleStatePresenter( + featureFlagService, + repository, + room, + ) + + presenter.test { + // emitted by the feature flag service(?) + assertThat(awaitItem().showAlert).isFalse() + + // emitted state from room info assignment + assertThat(awaitItem().showAlert).isFalse() + + // room is marked as encrypted + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Joined, isEncrypted = true)) + assertThat(awaitItem().showAlert).isFalse() + + // room history visibility is changed to shared + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, isEncrypted = true)) + assertThat(awaitItem().showAlert).isTrue() + + // alert is acknowledged + repository.setAcknowledged(room.roomId, true) + assertThat(awaitItem().showAlert).isFalse() + } + } + + private fun createHistoryVisibleStatePresenter( + room: JoinedRoom = FakeJoinedRoom(), + enabled: Boolean = true, + acknowledged: Boolean = false + ): HistoryVisibleStatePresenter { + return HistoryVisibleStatePresenter( + room = room, + featureFlagService = FakeFeatureFlagService(mapOf("feature.enableKeyShareOnInvite" to enabled)), + repository = FakeHistoryVisibleAcknowledgementRepository.withRoom(room.roomId, acknowledged) + ) + } +} diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt index b4f15d8d96..32f2908cf7 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt @@ -97,6 +97,7 @@ class KonsistPreviewTest { "MessageComposerViewVoicePreview", "MessagesReactionButtonAddPreview", "MessagesReactionButtonExtraPreview", + "MessagesViewWithHistoryVisiblePreview", "MessagesViewWithIdentityChangePreview", "PendingMemberRowWithLongNamePreview", "PinUnlockViewInAppPreview", diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png new file mode 100644 index 0000000000..d19a140456 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96bc0c555188cee4b3f3e3e0f28f944a4225e27b9a1069edf2b10a2993ee3080 +size 26078 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png new file mode 100644 index 0000000000..d19a140456 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96bc0c555188cee4b3f3e3e0f28f944a4225e27b9a1069edf2b10a2993ee3080 +size 26078 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png new file mode 100644 index 0000000000..d21a12dd64 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a103daf8447cb571a0c5010d062a7790aaa0f3dce30f052bf86884708f4881a5 +size 28769 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png new file mode 100644 index 0000000000..d21a12dd64 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a103daf8447cb571a0c5010d062a7790aaa0f3dce30f052bf86884708f4881a5 +size 28769 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png new file mode 100644 index 0000000000..22d05e61fa --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9682cdd7e08e32591fa47f56da5e6ef4cc3a777700931c2c86e9b802a9cf25cb +size 67342 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png new file mode 100644 index 0000000000..22d05e61fa --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9682cdd7e08e32591fa47f56da5e6ef4cc3a777700931c2c86e9b802a9cf25cb +size 67342 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png new file mode 100644 index 0000000000..b2bb8ac3fc --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d20c04c6385e675bd71d93d2d5d832509b1300a27708245755f263392b33bc8a +size 69457 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png new file mode 100644 index 0000000000..b2bb8ac3fc --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d20c04c6385e675bd71d93d2d5d832509b1300a27708245755f263392b33bc8a +size 69457 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png new file mode 100644 index 0000000000..826ba15d61 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0581c343abffc4a71db827cdc5f8b183525daed8b17b80cd6b511cb70ae9a05 +size 66428 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png new file mode 100644 index 0000000000..ca2c69a01b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97065ad20dc15bad0e6be815df8a5bd8b0411d11e7189e50a7abd13438f60f4b +size 69292 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png new file mode 100644 index 0000000000..826ba15d61 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0581c343abffc4a71db827cdc5f8b183525daed8b17b80cd6b511cb70ae9a05 +size 66428 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png new file mode 100644 index 0000000000..57fac247d9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5d618df3faa09281e59897b7f478d12f5a0d907b47f58747607e1de8cbc6e61 +size 68146 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png new file mode 100644 index 0000000000..34738a39fb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f65782549d9ae258584413de54a016705b705f05fd653b48c302b62dc3cd0c71 +size 70718 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png new file mode 100644 index 0000000000..57fac247d9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5d618df3faa09281e59897b7f478d12f5a0d907b47f58747607e1de8cbc6e61 +size 68146 From 8b8f58f018e67f999c599de4d15aa2f1f32e7b08 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 8 Dec 2025 22:23:07 +0100 Subject: [PATCH 074/347] misc(power level) : use new api --- .../api/KnockRequestPermissions.kt | 34 +++++++++ .../banner/KnockRequestsBannerPresenter.kt | 2 +- .../impl/data/KnockRequestPermissions.kt | 33 --------- .../impl/data/KnockRequestsModule.kt | 7 +- .../impl/data/KnockRequestsService.kt | 1 + .../impl/list/KnockRequestsListState.kt | 2 +- .../list/KnockRequestsListStateProvider.kt | 2 +- .../KnockRequestsBannerPresenterTest.kt | 2 +- .../list/KnockRequestsListPresenterTest.kt | 2 +- .../messages/impl/MessagesPresenter.kt | 30 ++------ .../messages/impl/UserEventPermissions.kt | 13 ++++ .../MessageComposerPresenter.kt | 5 +- .../list/PinnedMessagesListPresenter.kt | 69 ++++++++---------- .../impl/timeline/TimelinePresenter.kt | 19 +++-- .../roomcall/impl/RoomCallStatePresenter.kt | 6 +- .../roomdetails/impl/RoomDetailsPresenter.kt | 71 +++++++++---------- .../impl/members/RoomMemberListPresenter.kt | 5 +- .../api/RoomDetailsEditPermissions.kt | 37 ++++++++++ .../impl/RoomDetailsEditPresenter.kt | 21 +++--- .../impl/RoomMemberModerationPresenter.kt | 30 ++++---- .../api/SecurityAndPrivacyPermissions.kt | 24 +++---- .../impl/root/SecurityAndPrivacyPresenter.kt | 8 ++- .../impl/root/UserProfilePresenter.kt | 7 +- .../libraries/matrix/api/room/BaseRoom.kt | 51 ------------- .../api/room/powerlevels/RoomPermissions.kt | 58 ++++++++++----- .../room/powerlevels/RoomPowerLevelsValues.kt | 52 -------------- .../impl/gallery/MediaGalleryPresenter.kt | 14 ++-- .../impl/model/MediaPermissions.kt | 29 ++++++++ .../impl/viewer/MediaViewerPresenter.kt | 12 ++-- 29 files changed, 312 insertions(+), 334 deletions(-) create mode 100644 features/knockrequests/api/src/main/kotlin/io/element/android/features/knockrequests/api/KnockRequestPermissions.kt delete mode 100644 features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestPermissions.kt create mode 100644 features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt create mode 100644 libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/model/MediaPermissions.kt diff --git a/features/knockrequests/api/src/main/kotlin/io/element/android/features/knockrequests/api/KnockRequestPermissions.kt b/features/knockrequests/api/src/main/kotlin/io/element/android/features/knockrequests/api/KnockRequestPermissions.kt new file mode 100644 index 0000000000..82bceb5be0 --- /dev/null +++ b/features/knockrequests/api/src/main/kotlin/io/element/android/features/knockrequests/api/KnockRequestPermissions.kt @@ -0,0 +1,34 @@ +/* + * 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.knockrequests.api + +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class KnockRequestPermissions( + val canAccept: Boolean, + val canDecline: Boolean, + val canBan: Boolean, +) { + val hasAny = canAccept || canDecline || canBan + + companion object { + val DEFAULT = KnockRequestPermissions( + canAccept = false, + canDecline = false, + canBan = false, + ) + } +} + +fun RoomPermissions.knockRequestPermissions(): KnockRequestPermissions { + return KnockRequestPermissions( + canAccept = canOwnUserInvite(), + canDecline = canOwnUserKick(), + canBan = canOwnUserBan(), + ) +} diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt index 641efffaa3..f340d597b1 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt @@ -49,7 +49,7 @@ class KnockRequestsBannerPresenter( val shouldShowBanner by remember { derivedStateOf { - permissions.canHandle && knockRequests.isNotEmpty() + permissions.hasAny && knockRequests.isNotEmpty() } } diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestPermissions.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestPermissions.kt deleted file mode 100644 index 2ca4d4df74..0000000000 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestPermissions.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.knockrequests.impl.data - -import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.powerlevels.canBan -import io.element.android.libraries.matrix.api.room.powerlevels.canInvite -import io.element.android.libraries.matrix.api.room.powerlevels.canKick -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map - -data class KnockRequestPermissions( - val canAccept: Boolean, - val canDecline: Boolean, - val canBan: Boolean, -) { - val canHandle = canAccept || canDecline || canBan -} - -fun JoinedRoom.knockRequestPermissionsFlow(): Flow { - return syncUpdateFlow.map { - val canAccept = canInvite().getOrDefault(false) - val canDecline = canKick().getOrDefault(false) - val canBan = canBan().getOrDefault(false) - KnockRequestPermissions(canAccept, canDecline, canBan) - } -} diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsModule.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsModule.kt index eeba54f87d..b51b78f105 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsModule.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsModule.kt @@ -12,10 +12,13 @@ import dev.zacsweers.metro.BindingContainer import dev.zacsweers.metro.ContributesTo import dev.zacsweers.metro.Provides import dev.zacsweers.metro.SingleIn +import io.element.android.features.knockrequests.api.KnockRequestPermissions +import io.element.android.features.knockrequests.api.knockRequestPermissions import io.element.android.libraries.di.RoomScope import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsFlow @BindingContainer @ContributesTo(RoomScope::class) @@ -25,7 +28,9 @@ object KnockRequestsModule { fun knockRequestsService(room: JoinedRoom, featureFlagService: FeatureFlagService): KnockRequestsService { return KnockRequestsService( knockRequestsFlow = room.knockRequestsFlow, - permissionsFlow = room.knockRequestPermissionsFlow(), + permissionsFlow = room.permissionsFlow(KnockRequestPermissions.DEFAULT) { perms -> + perms.knockRequestPermissions() + }, isKnockFeatureEnabledFlow = featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock), coroutineScope = room.roomCoroutineScope ) diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsService.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsService.kt index 04c2f7b316..98570e6b28 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsService.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsService.kt @@ -8,6 +8,7 @@ package io.element.android.features.knockrequests.impl.data +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.room.knock.KnockRequest diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt index a1bb90cae8..ae770a297d 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt @@ -9,7 +9,7 @@ package io.element.android.features.knockrequests.impl.list import androidx.compose.runtime.Immutable -import io.element.android.features.knockrequests.impl.data.KnockRequestPermissions +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.features.knockrequests.impl.data.KnockRequestPresentable import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStateProvider.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStateProvider.kt index 2c4c92a6b6..85fc0675ad 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStateProvider.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStateProvider.kt @@ -9,7 +9,7 @@ package io.element.android.features.knockrequests.impl.list import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.knockrequests.impl.data.KnockRequestPermissions +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.features.knockrequests.impl.data.KnockRequestPresentable import io.element.android.features.knockrequests.impl.data.aKnockRequestPresentable import io.element.android.libraries.architecture.AsyncAction diff --git a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt index 9eaa51cecb..3161d3e81f 100644 --- a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt +++ b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt @@ -9,7 +9,7 @@ package io.element.android.features.knockrequests.impl.banner import com.google.common.truth.Truth.assertThat -import io.element.android.features.knockrequests.impl.data.KnockRequestPermissions +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.features.knockrequests.impl.data.KnockRequestsService import io.element.android.libraries.matrix.api.room.knock.KnockRequest import io.element.android.libraries.matrix.test.A_USER_ID diff --git a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt index b0d0b68c91..7102b01773 100644 --- a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt +++ b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt @@ -11,7 +11,7 @@ package io.element.android.features.knockrequests.impl.list import com.google.common.truth.Truth.assertThat -import io.element.android.features.knockrequests.impl.data.KnockRequestPermissions +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.features.knockrequests.impl.data.KnockRequestsService import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index e912722c6d..20160ad8c2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -12,12 +12,10 @@ import android.os.Build import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState -import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable @@ -75,14 +73,10 @@ import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.permalink.PermalinkParser import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.isDm -import io.element.android.libraries.matrix.api.room.powerlevels.canPinUnpin -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn -import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.ui.messages.reply.map import io.element.android.libraries.matrix.ui.model.getAvatarData @@ -167,7 +161,9 @@ class MessagesPresenter( val roomCallState = roomCallStatePresenter.present() val roomMemberModerationState = roomMemberModerationPresenter.present() - val userEventPermissions by userEventPermissions(roomInfo) + val userEventPermissions by room.permissionsAsState(UserEventPermissions.DEFAULT) { perms -> + perms.userEventPermissions() + } val roomAvatar by remember { derivedStateOf { roomInfo.avatarData() } @@ -297,24 +293,6 @@ class MessagesPresenter( ) } - @Composable - private fun userEventPermissions(roomInfo: RoomInfo): State { - val key = if (roomInfo.privilegedCreatorRole && roomInfo.creators.contains(room.sessionId)) { - Long.MAX_VALUE - } else { - roomInfo.roomPowerLevels?.hashCode() ?: 0L - } - return produceState(UserEventPermissions.DEFAULT, key1 = key) { - value = UserEventPermissions( - canSendMessage = room.canSendMessage(type = MessageEventType.RoomMessage).getOrElse { true }, - canSendReaction = room.canSendMessage(type = MessageEventType.Reaction).getOrElse { true }, - canRedactOwn = room.canRedactOwn().getOrElse { false }, - canRedactOther = room.canRedactOther().getOrElse { false }, - canPinUnpin = room.canPinUnpin().getOrElse { false }, - ) - } - } - private fun RoomInfo.avatarData(): AvatarData { return AvatarData( id = id.value, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/UserEventPermissions.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/UserEventPermissions.kt index f7d221950b..349c8e58dc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/UserEventPermissions.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/UserEventPermissions.kt @@ -8,6 +8,9 @@ package io.element.android.features.messages.impl +import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + /** * Represents the permissions a user has in a room. * It's dependent of the user's power level in the room. @@ -29,3 +32,13 @@ data class UserEventPermissions( ) } } + +fun RoomPermissions.userEventPermissions(): UserEventPermissions { + return UserEventPermissions( + canRedactOwn = canOwnUserRedactOwn(), + canRedactOther = canOwnUserRedactOther(), + canSendMessage = canOwnUserSendMessage(MessageEventType.RoomMessage), + canSendReaction = canOwnUserSendMessage(MessageEventType.Reaction), + canPinUnpin = canOwnUserPinUnpin() + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 276499d5bb..2d3ab5ac31 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -55,6 +55,7 @@ import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.draft.ComposerDraftType import io.element.android.libraries.matrix.api.room.getDirectRoomMember import io.element.android.libraries.matrix.api.room.isDm +import io.element.android.libraries.matrix.api.room.powerlevels.use import io.element.android.libraries.matrix.api.timeline.TimelineException import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails @@ -396,7 +397,9 @@ class MessageComposerPresenter( val currentUserId = room.sessionId suspend fun canSendRoomMention(): Boolean { - val userCanSendAtRoom = room.canUserTriggerRoomNotification(currentUserId).getOrDefault(false) + val userCanSendAtRoom = room.roomPermissions().use(false){ perms -> + perms.canOwnUserTriggerRoomNotification() + } return !room.isDm() && userCanSendAtRoom } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt index cdc1f85f1d..b2d2caa7f9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt @@ -10,11 +10,10 @@ package io.element.android.features.messages.impl.pinned.list import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue @@ -35,6 +34,7 @@ import io.element.android.features.messages.impl.timeline.factories.TimelineItem import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState import io.element.android.features.messages.impl.typing.TypingNotificationState +import io.element.android.features.messages.impl.userEventPermissions import io.element.android.features.roomcall.api.aStandByCallState import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter @@ -44,11 +44,9 @@ import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.powerlevels.canPinUnpin -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn +import io.element.android.libraries.matrix.api.room.isDm +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomMembers -import io.element.android.libraries.matrix.ui.room.isDmAsState import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analyticsproviders.api.trackers.captureInteraction @@ -97,31 +95,33 @@ class PinnedMessagesListPresenter( @Composable override fun present(): PinnedMessagesListState { htmlConverterProvider.Update() - val isDm by room.isDmAsState() - - val timelineRoomInfo = remember(isDm) { - TimelineRoomInfo( - isDm = isDm, - name = room.info().name, - // We don't need to compute those values - userHasPermissionToSendMessage = false, - userHasPermissionToSendReaction = false, - // We do not care about the call state here. - roomCallState = aStandByCallState(), - // don't compute this value or the pin icon will be shown - pinnedEventIds = persistentListOf(), - typingNotificationState = TypingNotificationState( - renderTypingNotifications = false, - typingMembers = persistentListOf(), - reserveSpace = false, - ), - predecessorRoom = room.predecessorRoom(), - ) + val roomInfo by room.roomInfoFlow.collectAsState() + val timelineRoomInfo by remember { + derivedStateOf { + TimelineRoomInfo( + isDm = roomInfo.isDm, + name = roomInfo.name, + // We don't need to compute those values + userHasPermissionToSendMessage = false, + userHasPermissionToSendReaction = false, + // We do not care about the call state here. + roomCallState = aStandByCallState(), + // don't compute this value or the pin icon will be shown + pinnedEventIds = persistentListOf(), + typingNotificationState = TypingNotificationState( + renderTypingNotifications = false, + typingMembers = persistentListOf(), + reserveSpace = false, + ), + predecessorRoom = room.predecessorRoom(), + ) + } } val timelineProtectionState = timelineProtectionPresenter.present() val linkState = linkPresenter.present() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - val userEventPermissions by userEventPermissions(syncUpdateFlow.value) + val userEventPermissions by room.permissionsAsState(UserEventPermissions.DEFAULT) { perms -> + perms.userEventPermissions() + } val displayThreadSummaries by featureFlagService.isFeatureEnabledFlow(FeatureFlags.Threads).collectAsState(false) @@ -192,19 +192,6 @@ class PinnedMessagesListPresenter( } } - @Composable - private fun userEventPermissions(updateKey: Long): State { - return produceState(UserEventPermissions.DEFAULT, key1 = updateKey) { - value = UserEventPermissions( - canSendMessage = false, - canSendReaction = false, - canRedactOwn = room.canRedactOwn().getOrElse { false }, - canRedactOther = room.canRedactOther().getOrElse { false }, - canPinUnpin = room.canPinUnpin().getOrElse { false }, - ) - } - } - @Composable private fun PinnedMessagesListEffect(onItemsChange: (AsyncData>) -> Unit) { val updatedOnItemsChange by rememberUpdatedState(onItemsChange) 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 e44cac4f27..4815602c8e 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 @@ -24,6 +24,7 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject import io.element.android.features.messages.impl.MessagesNavigator +import io.element.android.features.messages.impl.UserEventPermissions import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureEvents import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureState import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory @@ -32,6 +33,7 @@ import io.element.android.features.messages.impl.timeline.model.NewEventState import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemTypingNotificationModel import io.element.android.features.messages.impl.typing.TypingNotificationState +import io.element.android.features.messages.impl.userEventPermissions import io.element.android.features.messages.impl.voicemessages.timeline.RedactedVoiceMessageManager import io.element.android.features.poll.api.actions.EndPollAction import io.element.android.features.poll.api.actions.SendPollResponseAction @@ -46,14 +48,13 @@ import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.UniqueId import io.element.android.libraries.matrix.api.core.asEventId import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.isDm +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin -import io.element.android.libraries.matrix.ui.room.canSendMessageAsState import io.element.android.libraries.preferences.api.store.SessionPreferencesStore import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.DisplayFirstTimelineItems import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline @@ -128,11 +129,6 @@ class TimelinePresenter( val roomInfo by room.roomInfoFlow.collectAsState() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - - val userHasPermissionToSendMessage by room.canSendMessageAsState(type = MessageEventType.RoomMessage, updateKey = syncUpdateFlow.value) - val userHasPermissionToSendReaction by room.canSendMessageAsState(type = MessageEventType.Reaction, updateKey = syncUpdateFlow.value) - val prevMostRecentItemId = rememberSaveable { mutableStateOf(null) } val newEventState = remember { mutableStateOf(NewEventState.None) } @@ -285,13 +281,16 @@ class TimelinePresenter( val typingNotificationState = typingNotificationPresenter.present() val roomCallState = roomCallStatePresenter.present() + val userEventPermissions by room.permissionsAsState(UserEventPermissions.DEFAULT) { perms -> + perms.userEventPermissions() + } val timelineRoomInfo by remember(typingNotificationState, roomCallState, roomInfo) { derivedStateOf { TimelineRoomInfo( name = roomInfo.name, - isDm = roomInfo.isDm.orFalse(), - userHasPermissionToSendMessage = userHasPermissionToSendMessage, - userHasPermissionToSendReaction = userHasPermissionToSendReaction, + isDm = roomInfo.isDm, + userHasPermissionToSendMessage = userEventPermissions.canSendMessage, + userHasPermissionToSendReaction = userEventPermissions.canSendReaction, roomCallState = roomCallState, pinnedEventIds = roomInfo.pinnedEventIds, typingNotificationState = typingNotificationState, diff --git a/features/roomcall/impl/src/main/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenter.kt b/features/roomcall/impl/src/main/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenter.kt index 5de47f9ff2..b18a2772a3 100644 --- a/features/roomcall/impl/src/main/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenter.kt +++ b/features/roomcall/impl/src/main/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenter.kt @@ -21,7 +21,8 @@ import io.element.android.features.enterprise.api.SessionEnterpriseService import io.element.android.features.roomcall.api.RoomCallState import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.ui.room.canCall +import io.element.android.libraries.matrix.api.room.powerlevels.canCall +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState @Inject class RoomCallStatePresenter( @@ -35,8 +36,7 @@ class RoomCallStatePresenter( value = sessionEnterpriseService.isElementCallAvailable() } val roomInfo by room.roomInfoFlow.collectAsState() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - val canJoinCall by room.canCall(updateKey = syncUpdateFlow.value) + val canJoinCall by room.permissionsAsState(false) { perms -> perms.canCall() } val isUserInTheCall by remember { derivedStateOf { room.sessionId in roomInfo.activeRoomCallParticipants diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index 95c4f1e9e2..83840ad604 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -10,6 +10,7 @@ package io.element.android.features.roomdetails.impl import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue @@ -18,11 +19,14 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import dev.zacsweers.metro.Inject import im.vector.app.features.analytics.plan.Interaction +import io.element.android.features.knockrequests.api.knockRequestPermissions import io.element.android.features.leaveroom.api.LeaveRoomEvent import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.roomcall.api.RoomCallState import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter -import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissionsAsState +import io.element.android.features.roomdetailsedit.api.RoomDetailsEditPermissions +import io.element.android.features.roomdetailsedit.api.roomDetailsEditPermissions +import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions import io.element.android.libraries.androidutils.clipboard.ClipboardHelper import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.CoroutineDispatchers @@ -36,17 +40,13 @@ import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.room.RoomMembersState -import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.room.join.JoinRule -import io.element.android.libraries.matrix.api.room.powerlevels.canInvite -import io.element.android.libraries.matrix.api.room.powerlevels.canSendState +import io.element.android.libraries.matrix.api.room.powerlevels.canEditRolesAndPermissions +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomNotificationSettings -import io.element.android.libraries.matrix.ui.room.canHandleKnockRequestsAsState import io.element.android.libraries.matrix.ui.room.getCurrentRoomMember import io.element.android.libraries.matrix.ui.room.getDirectRoomMember -import io.element.android.libraries.matrix.ui.room.isDmAsState -import io.element.android.libraries.matrix.ui.room.isOwnUserAdmin import io.element.android.libraries.matrix.ui.room.roomMemberIdentityStateChange import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.ui.strings.CommonStrings @@ -77,8 +77,6 @@ class RoomDetailsPresenter( val scope = rememberCoroutineScope() val leaveRoomState = leaveRoomPresenter.present() val roomInfo by room.roomInfoFlow.collectAsState() - val isUserAdmin = room.isOwnUserAdmin() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val roomAvatar by remember { derivedStateOf { roomInfo.avatarUrl } } val roomName by remember { derivedStateOf { roomInfo.name?.trim().orEmpty() } } @@ -93,15 +91,11 @@ class RoomDetailsPresenter( observeNotificationSettings() } + val isDm = roomInfo.isDm val membersState by room.membersStateFlow.collectAsState() - val canInvite by getCanInvite(membersState) - + val permissions by getPermissions() val canonicalAlias by remember { derivedStateOf { roomInfo.canonicalAlias } } val isEncrypted by remember { derivedStateOf { roomInfo.isEncrypted == true } } - val isDm by room.isDmAsState() - val canEditName by getCanSendState(membersState, StateEventType.ROOM_NAME) - val canEditAvatar by getCanSendState(membersState, StateEventType.ROOM_AVATAR) - val canEditTopic by getCanSendState(membersState, StateEventType.ROOM_TOPIC) val dmMember by room.getDirectRoomMember(membersState) val currentMember by room.getCurrentRoomMember(membersState) val roomMemberDetailsPresenter = roomMemberDetailsPresenter(dmMember) @@ -109,16 +103,15 @@ class RoomDetailsPresenter( val roomCallState = roomCallStatePresenter.present() val joinedMemberCount by remember { derivedStateOf { roomInfo.joinedMembersCount } } - val topicState = remember(canEditTopic, roomTopic, roomType) { + val topicState = remember(permissions.editDetailsPermissions.canEditTopic, roomTopic, roomType) { val topic = roomTopic when { !topic.isNullOrBlank() -> RoomTopicState.ExistingTopic(topic) - canEditTopic && roomType is RoomDetailsType.Room -> RoomTopicState.CanAddTopic + permissions.editDetailsPermissions.canEditTopic && roomType is RoomDetailsType.Room -> RoomTopicState.CanAddTopic else -> RoomTopicState.Hidden } } - val canHandleKnockRequests by room.canHandleKnockRequestsAsState(syncUpdateFlow.value) val isKnockRequestsEnabled by remember { featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock) }.collectAsState(false) @@ -126,7 +119,7 @@ class RoomDetailsPresenter( room.knockRequestsFlow.collect { value = it.size } } val canShowKnockRequests by remember { - derivedStateOf { isKnockRequestsEnabled && canHandleKnockRequests && joinRule == JoinRule.Knock } + derivedStateOf { isKnockRequestsEnabled && permissions.canManageKnockRequests && joinRule == JoinRule.Knock } } val isDeveloperModeEnabled by remember { appPreferencesStore.isDeveloperModeEnabledFlow() @@ -162,13 +155,6 @@ class RoomDetailsPresenter( val roomMemberDetailsState = roomMemberDetailsPresenter?.present() - val securityAndPrivacyPermissions = room.securityAndPrivacyPermissionsAsState(syncUpdateFlow.value) - val canShowSecurityAndPrivacy by remember { - derivedStateOf { - roomType is RoomDetailsType.Room && securityAndPrivacyPermissions.value.hasAny - } - } - val hasMemberVerificationViolations by produceState(false) { room.roomMemberIdentityStateChange(waitForEncryption = true) .onEach { identities -> value = identities.any { it.identityState == IdentityState.VerificationViolation } } @@ -185,22 +171,22 @@ class RoomDetailsPresenter( roomTopic = topicState, memberCount = joinedMemberCount, isEncrypted = isEncrypted, - canInvite = canInvite, - canEdit = (canEditAvatar || canEditName || canEditTopic) && roomType == RoomDetailsType.Room, + canInvite = permissions.canInvite, + canEdit = roomType == RoomDetailsType.Room && permissions.editDetailsPermissions.hasAny, roomCallState = roomCallState, roomType = roomType, roomMemberDetailsState = roomMemberDetailsState, leaveRoomState = leaveRoomState, roomNotificationSettings = roomNotificationSettingsState.roomNotificationSettings(), isFavorite = isFavorite, - displayRolesAndPermissionsSettings = !isDm && isUserAdmin, + displayRolesAndPermissionsSettings = !isDm && permissions.canEditRolesAndPermissions, isPublic = joinRule == JoinRule.Public, heroes = roomInfo.heroes.toImmutableList(), pinnedMessagesCount = pinnedMessagesCount, snackbarMessage = snackbarMessage, canShowKnockRequests = canShowKnockRequests, knockRequestsCount = knockRequestsCount, - canShowSecurityAndPrivacy = canShowSecurityAndPrivacy, + canShowSecurityAndPrivacy = !isDm && permissions.canEditSecurityAndPrivacy, hasMemberVerificationViolations = hasMemberVerificationViolations, canReportRoom = canReportRoom, isTombstoned = roomInfo.successorRoom != null, @@ -232,14 +218,25 @@ class RoomDetailsPresenter( } } - @Composable - private fun getCanInvite(membersState: RoomMembersState) = produceState(false, membersState) { - value = room.canInvite().getOrElse { false } - } + private data class Permissions( + val canInvite: Boolean = false, + val editDetailsPermissions: RoomDetailsEditPermissions = RoomDetailsEditPermissions.DEFAULT, + val canManageKnockRequests: Boolean = false, + val canEditRolesAndPermissions: Boolean = false, + val canEditSecurityAndPrivacy: Boolean = false, + ) @Composable - private fun getCanSendState(membersState: RoomMembersState, type: StateEventType) = produceState(false, membersState) { - value = room.canSendState(type).getOrElse { false } + private fun getPermissions(): State { + return room.permissionsAsState(Permissions()) { perms -> + Permissions( + canInvite = perms.canOwnUserInvite(), + editDetailsPermissions = perms.roomDetailsEditPermissions(), + canManageKnockRequests = perms.knockRequestPermissions().hasAny, + canEditRolesAndPermissions = perms.canEditRolesAndPermissions(), + canEditSecurityAndPrivacy = perms.securityAndPrivacyPermissions().hasAny, + ) + } } private fun CoroutineScope.observeNotificationSettings() { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index f1d3f61f7e..6917057a06 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -32,10 +32,10 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.room.toMatrixUser import io.element.android.libraries.matrix.ui.room.PowerLevelRoomMemberComparator -import io.element.android.libraries.matrix.ui.room.canInviteAsState import io.element.android.libraries.matrix.ui.room.roomMemberIdentityStateChange import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.persistentMapOf @@ -58,8 +58,7 @@ class RoomMemberListPresenter( override fun present(): RoomMemberListState { var searchQuery by rememberSaveable { mutableStateOf("") } val membersState by room.membersStateFlow.collectAsState() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - val canInvite by room.canInviteAsState(syncUpdateFlow.value) + val canInvite by room.permissionsAsState(false) { perms -> perms.canOwnUserInvite() } val roomModerationState = roomMembersModerationPresenter.present() val roomMemberIdentityStates by produceState(persistentMapOf()) { diff --git a/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt new file mode 100644 index 0000000000..f95f4466f2 --- /dev/null +++ b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt @@ -0,0 +1,37 @@ +/* + * 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.roomdetailsedit.api + +import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class RoomDetailsEditPermissions( + val canEditName: Boolean, + val canEditTopic: Boolean, + val canEditAvatar: Boolean, +){ + val hasAny = canEditName || + canEditTopic || + canEditAvatar + + companion object { + val DEFAULT = RoomDetailsEditPermissions( + canEditName = false, + canEditTopic = false, + canEditAvatar = false, + ) + } +} + +fun RoomPermissions.roomDetailsEditPermissions(): RoomDetailsEditPermissions { + return RoomDetailsEditPermissions( + canEditName = canOwnUserSendState(StateEventType.ROOM_NAME), + canEditTopic = canOwnUserSendState(StateEventType.ROOM_TOPIC), + canEditAvatar = canOwnUserSendState(StateEventType.ROOM_AVATAR), + ) +} diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt index 4a2dfa3f11..4713ab9255 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt @@ -23,6 +23,8 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.core.net.toUri import dev.zacsweers.metro.Inject +import io.element.android.features.roomdetailsedit.api.RoomDetailsEditPermissions +import io.element.android.features.roomdetailsedit.api.roomDetailsEditPermissions import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter @@ -30,8 +32,7 @@ import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.StateEventType -import io.element.android.libraries.matrix.api.room.powerlevels.canSendState +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider @@ -93,14 +94,8 @@ class RoomDetailsEditPresenter( } } - var canChangeName by remember { mutableStateOf(false) } - var canChangeTopic by remember { mutableStateOf(false) } - var canChangeAvatar by remember { mutableStateOf(false) } - - LaunchedEffect(roomSyncUpdateFlow.value) { - canChangeName = room.canSendState(StateEventType.ROOM_NAME).getOrElse { false } - canChangeTopic = room.canSendState(StateEventType.ROOM_TOPIC).getOrElse { false } - canChangeAvatar = room.canSendState(StateEventType.ROOM_AVATAR).getOrElse { false } + val permissions by room.permissionsAsState(RoomDetailsEditPermissions.DEFAULT){perms -> + perms.roomDetailsEditPermissions() } val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker( @@ -181,11 +176,11 @@ class RoomDetailsEditPresenter( return RoomDetailsEditState( roomId = room.roomId, roomRawName = roomRawNameEdited, - canChangeName = canChangeName, + canChangeName = permissions.canEditName, roomTopic = roomTopicEdited, - canChangeTopic = canChangeTopic, + canChangeTopic = permissions.canEditTopic, roomAvatarUrl = roomAvatarUriEdited, - canChangeAvatar = canChangeAvatar, + canChangeAvatar = permissions.canEditAvatar, avatarActions = avatarActions, saveButtonEnabled = saveButtonEnabled, saveAction = saveAction.value, diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt index 31ff2da2b2..96749ba5ac 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt @@ -30,10 +30,9 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.matrix.ui.room.canBanAsState -import io.element.android.libraries.matrix.ui.room.canKickAsState import io.element.android.libraries.matrix.ui.room.userPowerLevelAsState import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList @@ -56,8 +55,12 @@ class RoomMemberModerationPresenter( override fun present(): RoomMemberModerationState { val coroutineScope = rememberCoroutineScope() val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - val canBan = room.canBanAsState(syncUpdateFlow.value) - val canKick = room.canKickAsState(syncUpdateFlow.value) + val permissions by room.permissionsAsState(Permissions()) { perms -> + Permissions( + canKick = perms.canOwnUserKick(), + canBan = perms.canOwnUserBan(), + ) + } val currentUserMemberPowerLevel = room.userPowerLevelAsState(syncUpdateFlow.value) val kickUserAsyncAction = @@ -80,8 +83,7 @@ class RoomMemberModerationPresenter( } moderationActions.value = computeModerationActions( member = member, - canKick = canKick.value, - canBan = canBan.value, + permissions = permissions, currentUserMemberPowerLevel = currentUserMemberPowerLevel.value, ) } @@ -134,8 +136,8 @@ class RoomMemberModerationPresenter( } return InternalRoomMemberModerationState( - canKick = canKick.value, - canBan = canBan.value, + canKick = permissions.canKick, + canBan = permissions.canBan, selectedUser = selectedUser, actions = moderationActions.value, kickUserAsyncAction = kickUserAsyncAction.value, @@ -147,8 +149,7 @@ class RoomMemberModerationPresenter( private fun computeModerationActions( member: RoomMember?, - canKick: Boolean, - canBan: Boolean, + permissions: Permissions, currentUserMemberPowerLevel: Long, ): ImmutableList { return buildList { @@ -158,11 +159,11 @@ class RoomMemberModerationPresenter( val canModerateThisUser = currentUserMemberPowerLevel > targetMemberPowerLevel // Assume the member is joined when it's unknown val membership = member?.membership ?: RoomMembershipState.JOIN - if (canKick) { + if (permissions.canKick) { val isKickEnabled = canModerateThisUser && membership.isActive() add(ModerationActionState(action = ModerationAction.KickUser, isEnabled = isKickEnabled)) } - if (canBan) { + if (permissions.canBan) { if (membership == RoomMembershipState.BAN) { add(ModerationActionState(action = ModerationAction.UnbanUser, isEnabled = canModerateThisUser)) } else { @@ -208,6 +209,11 @@ class RoomMemberModerationPresenter( ) } + private data class Permissions( + val canKick: Boolean = false, + val canBan: Boolean = false, + ) + private fun CoroutineScope.runActionAndWaitForMembershipChange( action: MutableState>, block: suspend () -> Result diff --git a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt index 82ab30581e..bacd863ca6 100644 --- a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt +++ b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt @@ -8,13 +8,8 @@ package io.element.android.features.securityandprivacy.api -import androidx.compose.runtime.Composable -import androidx.compose.runtime.State -import androidx.compose.runtime.produceState -import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions.Companion.DEFAULT -import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.StateEventType -import io.element.android.libraries.matrix.api.room.powerlevels.canSendState +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions data class SecurityAndPrivacyPermissions( val canChangeRoomAccess: Boolean, @@ -37,14 +32,11 @@ data class SecurityAndPrivacyPermissions( } } -@Composable -fun BaseRoom.securityAndPrivacyPermissionsAsState(updateKey: Long): State { - return produceState(DEFAULT, key1 = updateKey) { - value = SecurityAndPrivacyPermissions( - canChangeRoomAccess = canSendState(type = StateEventType.ROOM_JOIN_RULES).getOrElse { false }, - canChangeHistoryVisibility = canSendState(type = StateEventType.ROOM_HISTORY_VISIBILITY).getOrElse { false }, - canChangeEncryption = canSendState(type = StateEventType.ROOM_ENCRYPTION).getOrElse { false }, - canChangeRoomVisibility = canSendState(type = StateEventType.ROOM_CANONICAL_ALIAS).getOrElse { false }, - ) - } +fun RoomPermissions.securityAndPrivacyPermissions(): SecurityAndPrivacyPermissions { + return SecurityAndPrivacyPermissions( + canChangeRoomAccess = canOwnUserSendState(StateEventType.ROOM_JOIN_RULES), + canChangeHistoryVisibility = canOwnUserSendState(StateEventType.ROOM_HISTORY_VISIBILITY), + canChangeEncryption = canOwnUserSendState(StateEventType.ROOM_ENCRYPTION), + canChangeRoomVisibility = canOwnUserSendState(StateEventType.ROOM_CANONICAL_ALIAS), + ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index b77ad0e7d6..af0f44be38 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -21,7 +21,8 @@ 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.securityandprivacy.api.securityAndPrivacyPermissionsAsState +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions +import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.features.securityandprivacy.impl.editroomaddress.matchesServer import io.element.android.libraries.architecture.AsyncAction @@ -37,6 +38,7 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomInfo 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.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async @@ -106,7 +108,9 @@ class SecurityAndPrivacyPresenter( ) var showEnableEncryptionConfirmation by remember(savedSettings.isEncrypted) { mutableStateOf(false) } - val permissions by room.securityAndPrivacyPermissionsAsState(syncUpdateFlow.value) + val permissions by room.permissionsAsState(SecurityAndPrivacyPermissions.DEFAULT) { perms -> + perms.securityAndPrivacyPermissions() + } fun handleEvent(event: SecurityAndPrivacyEvent) { when (event) { diff --git a/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt b/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt index 9bf31e0b07..8b7eddca54 100644 --- a/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt +++ b/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt @@ -34,6 +34,8 @@ import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.powerlevels.canCall +import io.element.android.libraries.matrix.api.room.powerlevels.use import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.distinctUntilChanged @@ -56,7 +58,7 @@ class UserProfilePresenter( @Composable private fun getDmRoomId(): State { - return produceState(initialValue = null) { + return produceState(initialValue = null) { value = client.findDM(userId).getOrNull() } } @@ -66,7 +68,6 @@ class UserProfilePresenter( val isElementCallAvailable by produceState(initialValue = false, roomId) { value = sessionEnterpriseService.isElementCallAvailable() } - return produceState(initialValue = false, isElementCallAvailable, roomId) { value = when { isElementCallAvailable.not() -> false @@ -75,7 +76,7 @@ class UserProfilePresenter( roomId ?.let { client.getRoom(it) } ?.use { room -> - room.canUserJoinCall(client.sessionId).getOrNull() + room.roomPermissions().use(false){ perms -> perms.canCall()} } .orFalse() } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt index cde3a5eff7..481171ace0 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt @@ -130,57 +130,6 @@ interface BaseRoom : Closeable { */ suspend fun forget(): Result - /** - * Returns `true` if the user with the provided [userId] can invite other users to the room. - */ - suspend fun canUserInvite(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can kick other users from the room. - */ - suspend fun canUserKick(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can ban other users from the room. - */ - suspend fun canUserBan(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can redact their own messages. - */ - suspend fun canUserRedactOwn(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can redact messages from other users. - */ - suspend fun canUserRedactOther(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can send state events. - */ - suspend fun canUserSendState(userId: UserId, type: StateEventType): Result - - /** - * Returns `true` if the user with the provided [userId] can send messages. - */ - suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result - - /** - * Returns `true` if the user with the provided [userId] can trigger an `@room` notification. - */ - suspend fun canUserTriggerRoomNotification(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can pin or unpin messages. - */ - suspend fun canUserPinUnpin(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can join or starts calls. - */ - suspend fun canUserJoinCall(userId: UserId): Result = - canUserSendState(userId, StateEventType.CALL_MEMBER) - /** * Sets the room as favorite or not, based on the [isFavorite] parameter. */ diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt index cdc735b819..735627e10e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt @@ -7,9 +7,18 @@ package io.element.android.libraries.matrix.api.room.powerlevels +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.remember import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.StateEventType +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.map +import timber.log.Timber /** * Provides information about the permissions of users in a room. @@ -120,23 +129,38 @@ interface RoomPermissions : AutoCloseable { fun canUserTriggerRoomNotification(userId: UserId): Boolean } -fun RoomPermissions.canEditRoomDetails(): Boolean { - return canOwnUserSendState(StateEventType.ROOM_NAME) || - canOwnUserSendState(StateEventType.ROOM_TOPIC) || - canOwnUserSendState(StateEventType.ROOM_AVATAR) -} - -fun RoomPermissions.canManageKnockRequests(): Boolean { - return canOwnUserInvite() || canOwnUserBan() || canOwnUserKick() -} - -fun RoomPermissions.canEditSecurityAndPrivacy(): Boolean { - return canOwnUserSendState(StateEventType.ROOM_JOIN_RULES) || - canOwnUserSendState(StateEventType.ROOM_HISTORY_VISIBILITY) || - canOwnUserSendState(StateEventType.ROOM_CANONICAL_ALIAS) || - canOwnUserSendState(StateEventType.ROOM_ENCRYPTION) -} - fun RoomPermissions.canEditRolesAndPermissions(): Boolean { return canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS) } + +fun RoomPermissions.canCall(): Boolean { + return canOwnUserSendState(StateEventType.CALL_MEMBER) +} + +fun Result.use(default: T, block: (RoomPermissions) -> T): T { + return fold( + onSuccess = { perms -> + perms.use(block) + }, + onFailure = { + default + } + ) +} + +fun BaseRoom.permissionsFlow(default: T, block: (RoomPermissions) -> T): Flow { + return roomInfoFlow + .map { info -> info.roomPowerLevels } + .distinctUntilChanged() + .map { + roomPermissions().use(default, block) + } +} + +@Composable +fun BaseRoom.permissionsAsState(default: T, block: (RoomPermissions) -> T): State { + return remember(this, default, block) { + Timber.d("Computing permissionsAsState for room $roomId with default=$default") + permissionsFlow(default, block) + }.collectAsState(default) +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt index d20b6141eb..a7eebbb99c 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt @@ -8,11 +8,6 @@ package io.element.android.libraries.matrix.api.room.powerlevels -import io.element.android.libraries.core.extensions.runCatchingExceptions -import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.MessageEventType -import io.element.android.libraries.matrix.api.room.StateEventType - data class RoomPowerLevelsValues( val ban: Long, val invite: Long, @@ -24,50 +19,3 @@ data class RoomPowerLevelsValues( val roomTopic: Long, val spaceChild: Long, ) - -/** - * Shortcut for calling [BaseRoom.canUserInvite] with our own user. - */ -suspend fun BaseRoom.canInvite(): Result = canUserInvite(sessionId) - -/** - * Shortcut for calling [BaseRoom.canUserKick] with our own user. - */ -suspend fun BaseRoom.canKick(): Result = canUserKick(sessionId) - -/** - * Shortcut for calling [BaseRoom.canUserBan] with our own user. - */ -suspend fun BaseRoom.canBan(): Result = canUserBan(sessionId) - -/** - * Shortcut for calling [BaseRoom.canUserSendState] with our own user. - */ -suspend fun BaseRoom.canSendState(type: StateEventType): Result = canUserSendState(sessionId, type) - -/** - * Shortcut for calling [BaseRoom.canUserSendMessage] with our own user. - */ -suspend fun BaseRoom.canSendMessage(type: MessageEventType): Result = canUserSendMessage(sessionId, type) - -/** - * Shortcut for calling [BaseRoom.canUserRedactOwn] with our own user. - */ -suspend fun BaseRoom.canRedactOwn(): Result = canUserRedactOwn(sessionId) - -/** - * Shortcut for calling [BaseRoom.canRedactOther] with our own user. - */ -suspend fun BaseRoom.canRedactOther(): Result = canUserRedactOther(sessionId) - -/** - * Shortcut for checking if current user can handle knock requests. - */ -suspend fun BaseRoom.canHandleKnockRequests(): Result = runCatchingExceptions { - canInvite().getOrThrow() || canBan().getOrThrow() || canKick().getOrThrow() -} - -/** - * Shortcut for calling [BaseRoom.canUserPinUnpin] with our own user. - */ -suspend fun BaseRoom.canPinUnpin(): Result = canUserPinUnpin(sessionId) diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt index aee9af82b7..e5e493ee63 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt @@ -30,8 +30,7 @@ import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarM import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.mediaviewer.api.local.LocalMedia import io.element.android.libraries.mediaviewer.api.local.LocalMediaFactory import io.element.android.libraries.mediaviewer.impl.datasource.MediaGalleryDataSource @@ -39,8 +38,10 @@ import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetSta import io.element.android.libraries.mediaviewer.impl.local.LocalMediaActions import io.element.android.libraries.mediaviewer.impl.model.GroupedMediaItems import io.element.android.libraries.mediaviewer.impl.model.MediaItem +import io.element.android.libraries.mediaviewer.impl.model.MediaPermissions import io.element.android.libraries.mediaviewer.impl.model.eventId import io.element.android.libraries.mediaviewer.impl.model.mediaInfo +import io.element.android.libraries.mediaviewer.impl.model.mediaPermissions import io.element.android.libraries.mediaviewer.impl.model.mediaSource import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.coroutines.launch @@ -80,6 +81,10 @@ class MediaGalleryPresenter( mediaGalleryDataSource.start() } + val permissions by room.permissionsAsState(MediaPermissions.DEFAULT) { perms -> + perms.mediaPermissions() + } + val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState() localMediaActions.Configure() @@ -119,8 +124,8 @@ class MediaGalleryPresenter( eventId = event.mediaItem.eventId(), canDelete = when (event.mediaItem.mediaInfo().senderId) { null -> false - room.sessionId -> room.canRedactOwn().getOrElse { false } && event.mediaItem.eventId() != null - else -> room.canRedactOther().getOrElse { false } && event.mediaItem.eventId() != null + room.sessionId -> permissions.canRedactOwn && event.mediaItem.eventId() != null + else -> permissions.canRedactOther && event.mediaItem.eventId() != null }, mediaInfo = event.mediaItem.mediaInfo(), thumbnailSource = when (event.mediaItem) { @@ -202,6 +207,7 @@ class MediaGalleryPresenter( CommonStrings.error_unknown } } + } private fun GroupedMediaItems?.find(eventId: EventId?): MediaItem.Event? { diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/model/MediaPermissions.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/model/MediaPermissions.kt new file mode 100644 index 0000000000..4a111965e9 --- /dev/null +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/model/MediaPermissions.kt @@ -0,0 +1,29 @@ +/* + * 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.mediaviewer.impl.model + +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class MediaPermissions( + val canRedactOwn: Boolean, + val canRedactOther: Boolean, +) { + companion object { + val DEFAULT = MediaPermissions( + canRedactOwn = false, + canRedactOther = false, + ) + } +} + +fun RoomPermissions.mediaPermissions(): MediaPermissions { + return MediaPermissions( + canRedactOwn = canOwnUserRedactOwn(), + canRedactOther = canOwnUserRedactOther(), + ) +} diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt index 4709a4ec51..dc0feb70cf 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt @@ -32,8 +32,7 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState 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.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState 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.mediaviewer.api.MediaViewerEntryPoint @@ -41,6 +40,8 @@ import io.element.android.libraries.mediaviewer.api.local.LocalMedia import io.element.android.libraries.mediaviewer.impl.R import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState import io.element.android.libraries.mediaviewer.impl.local.LocalMediaActions +import io.element.android.libraries.mediaviewer.impl.model.MediaPermissions +import io.element.android.libraries.mediaviewer.impl.model.mediaPermissions import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.CoroutineScope @@ -81,6 +82,9 @@ class MediaViewerPresenter( NoMoreItemsBackwardSnackBarDisplayer(currentIndex, data) NoMoreItemsForwardSnackBarDisplayer(currentIndex, data) + val permissions by room.permissionsAsState(MediaPermissions.DEFAULT) { perms -> + perms.mediaPermissions() + } var mediaBottomSheetState by remember { mutableStateOf(MediaBottomSheetState.Hidden) } DisposableEffect(Unit) { @@ -131,8 +135,8 @@ class MediaViewerPresenter( eventId = event.data.eventId, canDelete = when (event.data.mediaInfo.senderId) { null -> false - room.sessionId -> room.canRedactOwn().getOrElse { false } && event.data.eventId != null - else -> room.canRedactOther().getOrElse { false } && event.data.eventId != null + room.sessionId -> permissions.canRedactOwn && event.data.eventId != null + else -> permissions.canRedactOther && event.data.eventId != null }, mediaInfo = event.data.mediaInfo, thumbnailSource = event.data.thumbnailSource, From c87a8e9cffdffbc4f0ac93597662a23b770ab182 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 8 Dec 2025 22:23:17 +0100 Subject: [PATCH 075/347] misc(power level) : remove old api --- .../matrix/impl/room/RustBaseRoom.kt | 54 ------------- .../matrix/ui/room/MatrixRoomState.kt | 79 ------------------- 2 files changed, 133 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt index eec9591e32..141957d1ed 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt @@ -186,60 +186,6 @@ class RustBaseRoom( } } - override suspend fun canUserInvite(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserInvite(userId.value) } - } - } - - override suspend fun canUserKick(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserKick(userId.value) } - } - } - - override suspend fun canUserBan(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserBan(userId.value) } - } - } - - override suspend fun canUserRedactOwn(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserRedactOwn(userId.value) } - } - } - - override suspend fun canUserRedactOther(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserRedactOther(userId.value) } - } - } - - override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserSendState(userId.value, type.map()) } - } - } - - override suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserSendMessage(userId.value, type.map()) } - } - } - - override suspend fun canUserTriggerRoomNotification(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserTriggerRoomNotification(userId.value) } - } - } - - override suspend fun canUserPinUnpin(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserPinUnpin(userId.value) } - } - } - override suspend fun clearEventCacheStorage(): Result = withContext(roomDispatcher) { runCatchingExceptions { innerRoom.clearEventCacheStorage() diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt index 03e0e5bea1..d4e6127b69 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt @@ -14,88 +14,9 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.produceState import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.room.isDm -import io.element.android.libraries.matrix.api.room.powerlevels.canBan -import io.element.android.libraries.matrix.api.room.powerlevels.canHandleKnockRequests -import io.element.android.libraries.matrix.api.room.powerlevels.canInvite -import io.element.android.libraries.matrix.api.room.powerlevels.canKick -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn -import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage import io.element.android.libraries.matrix.ui.model.roleOf -@Composable -fun BaseRoom.canSendMessageAsState(type: MessageEventType, updateKey: Long): State { - return produceState(initialValue = true, key1 = updateKey) { - value = canSendMessage(type).getOrElse { true } - } -} - -@Composable -fun BaseRoom.canInviteAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canInvite().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canRedactOwnAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canRedactOwn().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canRedactOtherAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canRedactOther().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canCall(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canUserJoinCall(sessionId).getOrElse { false } - } -} - -@Composable -fun BaseRoom.canPinUnpin(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canUserPinUnpin(sessionId).getOrElse { false } - } -} - -@Composable -fun BaseRoom.isDmAsState(): State { - return produceState(initialValue = false) { - roomInfoFlow.collect { value = it.isDm } - } -} - -@Composable -fun BaseRoom.canKickAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canKick().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canBanAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canBan().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canHandleKnockRequestsAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canHandleKnockRequests().getOrElse { false } - } -} - @Composable fun BaseRoom.userPowerLevelAsState(updateKey: Long): State { return produceState(initialValue = 0, key1 = updateKey) { From dafc508e060dffdc0c537ee46a8fd01598a3e528 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:07:38 +0000 Subject: [PATCH 076/347] Update metro to v0.8.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 c0dd448c17..2c8f84b01d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -52,7 +52,7 @@ haze = "1.6.10" dependencyAnalysis = "3.5.1" # DI -metro = "0.8.1" +metro = "0.8.2" # Auto service autoservice = "1.1.1" From a6df4af7ed33b17c1e764275075f18d7949b7fc4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Dec 2025 13:07:50 +0000 Subject: [PATCH 077/347] Update dependency net.zetetic:sqlcipher-android to v4.12.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 2c8f84b01d..eb2f1c9af2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -199,7 +199,7 @@ matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } sqldelight-driver-jvm = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sqldelight" } sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqldelight" } -sqlcipher = "net.zetetic:sqlcipher-android:4.11.0" +sqlcipher = "net.zetetic:sqlcipher-android:4.12.0" sqlite = "androidx.sqlite:sqlite-ktx:2.6.2" unifiedpush = "org.unifiedpush.android:connector:3.1.2" vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0" From b32157f99e6b4d1e066da7207e04c962a10b5237 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 9 Dec 2025 20:50:31 +0100 Subject: [PATCH 078/347] misc(power level) : update tests following api change --- .../messages/impl/MessagesPresenterTest.kt | 196 +++++--------- .../MessageComposerPresenterTest.kt | 45 +++- .../list/PinnedMessagesListPresenterTest.kt | 46 ++-- .../impl/timeline/TimelinePresenterTest.kt | 150 +++++------ .../impl/RoomCallStatePresenterTest.kt | 28 +- .../roomdetails/impl/MatrixRoomFixture.kt | 26 +- .../impl/RoomDetailsPresenterTest.kt | 247 ++++++------------ .../members/RoomMemberListPresenterTest.kt | 21 +- .../impl/RoomDetailsEditPresenterTest.kt | 65 ++--- .../impl/RoomMemberModerationPresenterTest.kt | 7 +- .../impl/root/SecurityAndPrivacyPresenter.kt | 1 - .../impl/SecurityAndPrivacyPresenterTest.kt | 39 ++- .../impl/UserProfilePresenterTest.kt | 24 +- .../matrix/test/room/FakeBaseRoom.kt | 54 +--- .../room/powerlevels/FakeRoomPermissions.kt | 74 +++--- 15 files changed, 418 insertions(+), 605 deletions(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index 852e2504b2..28d75d65fd 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -63,6 +63,7 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkParser import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo @@ -85,6 +86,7 @@ import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.test.timeline.aTimelineItemDebugInfo import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails @@ -142,11 +144,7 @@ class MessagesPresenterTest { fun `present - check that the room's unread flag is removed`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), markAsReadResult = { lambdaError() } ), typingNoticeResult = { Result.success(Unit) }, @@ -172,11 +170,7 @@ class MessagesPresenterTest { } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -222,11 +216,7 @@ class MessagesPresenterTest { } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -287,11 +277,7 @@ class MessagesPresenterTest { val event = aMessageEvent() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), eventPermalinkResult = { Result.success("a link") }, ), typingNoticeResult = { Result.success(Unit) }, @@ -513,11 +499,7 @@ class MessagesPresenterTest { val liveTimeline = FakeTimeline() val joinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = liveTimeline, typingNoticeResult = { Result.success(Unit) }, @@ -585,11 +567,7 @@ class MessagesPresenterTest { fun `present - shows prompt to reinvite users in DM`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(isDirect = true, joinedMembersCount = 1, activeMembersCount = 1)) }, @@ -618,11 +596,7 @@ class MessagesPresenterTest { fun `present - doesn't show reinvite prompt in non-direct room`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(isDirect = false, joinedMembersCount = 1, activeMembersCount = 1)) }, @@ -644,11 +618,7 @@ class MessagesPresenterTest { fun `present - doesn't show reinvite prompt if other party is present`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(isDirect = true, joinedMembersCount = 2, activeMembersCount = 2)) }, @@ -671,11 +641,7 @@ class MessagesPresenterTest { val inviteUserResult = lambdaRecorder { _: UserId -> Result.success(Unit) } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, inviteUserResult = inviteUserResult, @@ -706,11 +672,7 @@ class MessagesPresenterTest { val inviteUserResult = lambdaRecorder { _: UserId -> Result.success(Unit) } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, inviteUserResult = inviteUserResult, @@ -743,11 +705,7 @@ class MessagesPresenterTest { fun `present - handle reinviting other user when memberlist is not ready`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -768,11 +726,7 @@ class MessagesPresenterTest { fun `present - handle reinviting other user when inviting fails`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, inviteUserResult = { Result.failure(RuntimeException("Oops!")) }, @@ -806,17 +760,7 @@ class MessagesPresenterTest { fun `present - permission to post`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, - canUserSendMessageResult = { _, messageEventType -> - when (messageEventType) { - MessageEventType.RoomMessage -> Result.success(true) - MessageEventType.Reaction -> Result.success(true) - else -> lambdaError() - } - }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -832,17 +776,9 @@ class MessagesPresenterTest { fun `present - no permission to post`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, - canUserSendMessageResult = { _, messageEventType -> - when (messageEventType) { - MessageEventType.RoomMessage -> Result.success(false) - MessageEventType.Reaction -> Result.success(false) - else -> lambdaError() - } - }, + roomPermissions = roomPermissions( + canSendMessage = false + ), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -858,11 +794,9 @@ class MessagesPresenterTest { fun `present - permission to redact own`() = runTest { val joinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOtherResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canRedactOther = false + ), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -879,11 +813,9 @@ class MessagesPresenterTest { fun `present - permission to redact other`() = runTest { val joinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOtherResult = { Result.success(true) }, - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canRedactOwn = false + ), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -928,11 +860,7 @@ class MessagesPresenterTest { val timeline = FakeTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -972,11 +900,7 @@ class MessagesPresenterTest { val analyticsService = FakeAnalyticsService() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -1073,11 +997,7 @@ class MessagesPresenterTest { } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -1114,11 +1034,7 @@ class MessagesPresenterTest { val successorReason = "This room has been moved to a new location" val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), initialRoomInfo = aRoomInfo( successorRoom = SuccessorRoom( roomId = successorRoomId, @@ -1142,11 +1058,7 @@ class MessagesPresenterTest { fun `present - room without successor room has null successor info in state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), initialRoomInfo = aRoomInfo(successorRoom = null) ), typingNoticeResult = { Result.success(Unit) }, @@ -1164,11 +1076,13 @@ class MessagesPresenterTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( sessionId = A_SESSION_ID, - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canSendState = { true }, + canSendMessage = { true }, + canRedactOther = true, + canRedactOwn = true, + canPinUnpin = true, + ), initialRoomInfo = aRoomInfo(isDirect = true, isEncrypted = true) ).apply { givenRoomMembersState(RoomMembersState.Ready(persistentListOf(aRoomMember(userId = A_SESSION_ID), aRoomMember(userId = A_USER_ID_2)))) @@ -1311,16 +1225,44 @@ class MessagesPresenterTest { } } + private fun roomPermissions( + canStartCall: Boolean = true, + canRedactOther: Boolean = true, + canRedactOwn: Boolean = true, + canSendMessage: Boolean = true, + canSendReaction: Boolean = true, + canPinUnpin: Boolean = true, + ) = FakeRoomPermissions( + canSendState = { type -> + when(type){ + StateEventType.CALL_MEMBER -> canStartCall + else -> lambdaError() + } + }, + canSendMessage = { type -> + when(type){ + MessageEventType.RoomMessage -> canSendMessage + MessageEventType.Reaction -> canSendReaction + else -> lambdaError() + } + }, + canRedactOther = canRedactOther, + canRedactOwn = canRedactOwn, + canPinUnpin = canPinUnpin, + ) + private fun TestScope.createMessagesPresenter( coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(), timeline: Timeline = FakeTimeline(), joinedRoom: FakeJoinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canSendState = { true }, + canSendMessage = { true }, + canRedactOther = true, + canRedactOwn = true, + canPinUnpin = true, + ), ).apply { givenRoomInfo(aRoomInfo(id = roomId, name = "")) }, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt index 4a6e777116..2feafbc9e5 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt @@ -69,6 +69,7 @@ import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails import io.element.android.libraries.mediapickers.api.PickerProvider @@ -991,9 +992,12 @@ class MessageComposerPresenterTest { val invitedUser = aRoomMember(userId = A_USER_ID_3, membership = RoomMembershipState.INVITE) val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN) val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) - var canUserTriggerRoomNotificationResult = true val room = FakeJoinedRoom( - baseRoom = FakeBaseRoom(canUserTriggerRoomNotificationResult = { Result.success(canUserTriggerRoomNotificationResult) }), + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions( + canTriggerRoomNotification = true, + ) + ), typingNoticeResult = { Result.success(Unit) } ).apply { givenRoomMembersState( @@ -1033,10 +1037,38 @@ class MessageComposerPresenterTest { // If the suggestion isn't a mention, no suggestions are returned initialState.eventSink(MessageComposerEvent.SuggestionReceived(Suggestion(0, 0, SuggestionType.Command, ""))) assertThat(awaitItem().suggestions).isEmpty() + } + } - // If user has no permission to send `@room` mentions, `RoomMemberSuggestion.Room` is not returned - canUserTriggerRoomNotificationResult = false + @Test + fun `present - room mention suggestions no permission`() = runTest { + val currentUser = aRoomMember(userId = A_USER_ID, membership = RoomMembershipState.JOIN) + val invitedUser = aRoomMember(userId = A_USER_ID_3, membership = RoomMembershipState.INVITE) + val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN) + val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions( + canTriggerRoomNotification = false, + ) + ), + typingNoticeResult = { Result.success(Unit) } + ).apply { + givenRoomMembersState( + RoomMembersState.Ready( + persistentListOf(currentUser, invitedUser, bob, david), + ) + ) + givenRoomInfo(aRoomInfo(isDirect = false)) + } + val presenter = createPresenter(room) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + // An empty suggestion returns the joined members that are not the current user, but not the room initialState.eventSink(MessageComposerEvent.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, ""))) + skipItems(1) assertThat(awaitItem().suggestions) .containsExactly(ResolvedSuggestion.Member(bob), ResolvedSuggestion.Member(david)) } @@ -1049,7 +1081,9 @@ class MessageComposerPresenterTest { val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN) val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) val room = FakeJoinedRoom( - baseRoom = FakeBaseRoom(canUserTriggerRoomNotificationResult = { Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions(canTriggerRoomNotification = true), + ), typingNoticeResult = { Result.success(Unit) } ).apply { givenRoomMembersState( @@ -1069,7 +1103,6 @@ class MessageComposerPresenterTest { presenter.present() }.test { val initialState = awaitItem() - // An empty suggestion returns the joined members that are not the current user, but not the room initialState.eventSink(MessageComposerEvent.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, ""))) skipItems(1) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt index 8807951d9d..f17681eb4d 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt @@ -22,6 +22,8 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatch 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.MessageEventType +import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo @@ -31,6 +33,7 @@ import io.element.android.libraries.matrix.test.A_UNIQUE_ID import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.sync.FakeSyncService import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.test.timeline.aMessageContent @@ -38,6 +41,7 @@ import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test @@ -55,9 +59,7 @@ class PinnedMessagesListPresenterTest { fun `present - initial state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) } @@ -74,9 +76,7 @@ class PinnedMessagesListPresenterTest { fun `present - timeline failure state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -95,9 +95,7 @@ class PinnedMessagesListPresenterTest { fun `present - empty state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf())) }, @@ -117,9 +115,7 @@ class PinnedMessagesListPresenterTest { val pinnedEventsTimeline = createPinnedMessagesTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -146,9 +142,7 @@ class PinnedMessagesListPresenterTest { val analyticsService = FakeAnalyticsService() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -194,9 +188,7 @@ class PinnedMessagesListPresenterTest { val pinnedEventsTimeline = createPinnedMessagesTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -225,9 +217,7 @@ class PinnedMessagesListPresenterTest { val pinnedEventsTimeline = createPinnedMessagesTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -256,9 +246,7 @@ class PinnedMessagesListPresenterTest { val pinnedEventsTimeline = createPinnedMessagesTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -295,6 +283,16 @@ class PinnedMessagesListPresenterTest { ) } + private fun roomPermissions( + canRedactOther: Boolean = true, + canRedactOwn: Boolean = true, + canPinUnpin: Boolean = true, + ) = FakeRoomPermissions( + canRedactOther = canRedactOther, + canRedactOwn = canRedactOwn, + canPinUnpin = canPinUnpin, + ) + private fun TestScope.createPinnedMessagesListPresenter( navigator: PinnedMessagesListNavigator = FakePinnedMessagesListNavigator(), room: JoinedRoom = FakeJoinedRoom(), diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt index 13c28da6e9..2bbc163626 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt @@ -35,7 +35,9 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UniqueId import io.element.android.libraries.matrix.api.core.asEventId +import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMembersState +import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.ReceiptType @@ -55,6 +57,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.test.timeline.aMessageContent import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem @@ -66,6 +69,7 @@ import io.element.android.tests.testutils.awaitLastSequentialItem import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.lambda.any import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test @@ -97,9 +101,7 @@ class TimelinePresenterTest { @Test fun `present - initial state`() = runTest { val presenter = createTimelinePresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.timelineItems).isEmpty() assertThat(initialState.isLive).isTrue() @@ -118,9 +120,7 @@ class TimelinePresenterTest { this.paginateLambda = paginateLambda } val presenter = createTimelinePresenter(timeline = timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink.invoke(TimelineEvents.LoadMore(Timeline.PaginationDirection.BACKWARDS)) initialState.eventSink.invoke(TimelineEvents.LoadMore(Timeline.PaginationDirection.FORWARDS)) @@ -166,9 +166,6 @@ class TimelinePresenterTest { ) val room = FakeJoinedRoom( liveTimeline = timeline, - baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - ) ) val sessionPreferencesStore = InMemorySessionPreferencesStore(isSendPublicReadReceiptsEnabled = isSendPublicReadReceiptsEnabled) val presenter = createTimelinePresenter( @@ -176,9 +173,7 @@ class TimelinePresenterTest { room = room, sessionPreferencesStore = sessionPreferencesStore, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.OnScrollFinished(0)) runCurrent() @@ -211,9 +206,7 @@ class TimelinePresenterTest { this.sendReadReceiptLambda = sendReadReceiptsLambda } val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) awaitItem().run { eventSink.invoke(TimelineEvents.OnScrollFinished(1)) @@ -252,9 +245,7 @@ class TimelinePresenterTest { timeline = timeline, sessionPreferencesStore = sessionPreferencesStore, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) awaitItem().run { eventSink.invoke(TimelineEvents.OnScrollFinished(0)) @@ -290,9 +281,7 @@ class TimelinePresenterTest { this.sendReadReceiptLambda = sendReadReceiptsLambda } val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) awaitItem().run { eventSink.invoke(TimelineEvents.OnScrollFinished(1)) @@ -320,9 +309,7 @@ class TimelinePresenterTest { this.sendReadReceiptLambda = sendReadReceiptsLambda } val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.OnScrollFinished(1)) @@ -339,9 +326,7 @@ class TimelinePresenterTest { markAsReadResult = { Result.success(Unit) }, ) val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.newEventState).isEqualTo(NewEventState.None) assertThat(initialState.timelineItems.size).isEqualTo(0) @@ -390,9 +375,7 @@ class TimelinePresenterTest { timelineItems = timelineItems, ) val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.newEventState).isEqualTo(NewEventState.None) assertThat(initialState.timelineItems.size).isEqualTo(0) @@ -446,9 +429,7 @@ class TimelinePresenterTest { val presenter = createTimelinePresenter( sendPollResponseAction = sendPollResponseAction, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.SelectPollAnswer(AN_EVENT_ID, "anAnswerId")) } @@ -462,9 +443,7 @@ class TimelinePresenterTest { val presenter = createTimelinePresenter( endPollAction = endPollAction, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.EndPoll(AN_EVENT_ID)) } @@ -481,9 +460,7 @@ class TimelinePresenterTest { val presenter = createTimelinePresenter( messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitFirstItem().eventSink(TimelineEvents.EditPoll(AN_EVENT_ID)) onEditPollClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID)) } @@ -500,9 +477,7 @@ class TimelinePresenterTest { ), redactedVoiceMessageManager = redactedVoiceMessageManager, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { assertThat(redactedVoiceMessageManager.invocations.size).isEqualTo(0) skipItems(2) assertThat(redactedVoiceMessageManager.invocations.size).isEqualTo(1) @@ -528,16 +503,14 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { _ -> Result.success(null) }, ), ) val presenter = createTimelinePresenter( room = room, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) awaitItem().also { state -> @@ -579,15 +552,13 @@ class TimelinePresenterTest { ) ), baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { Result.success(null) }, ), ), timelineItemIndexer = timelineItemIndexer, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() advanceUntilIdle() @@ -619,14 +590,12 @@ class TimelinePresenterTest { ), createTimelineResult = { Result.failure(RuntimeException("An error")) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { _ -> Result.success(null) }, ), ) ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) awaitItem().also { state -> @@ -668,7 +637,7 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { _ -> Result.success(threadId) }, ), ) @@ -679,9 +648,7 @@ class TimelinePresenterTest { timeline = liveTimeline, messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) @@ -729,7 +696,7 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { _ -> Result.success(threadId) }, ), ) @@ -740,9 +707,7 @@ class TimelinePresenterTest { timeline = liveTimeline, messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) @@ -785,7 +750,7 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), // Use a different thread id threadRootIdForEventResult = { _ -> Result.success(A_THREAD_ID_2) }, ), @@ -797,9 +762,7 @@ class TimelinePresenterTest { timeline = liveTimeline, messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) @@ -846,7 +809,7 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), // The event is in the main timeline, not in a thread threadRootIdForEventResult = { _ -> Result.success(null) }, ), @@ -858,9 +821,7 @@ class TimelinePresenterTest { timeline = liveTimeline, messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) @@ -891,9 +852,7 @@ class TimelinePresenterTest { fun `present - show shield hide shield`() = runTest { val presenter = createTimelinePresenter() val shield = aCriticalShield() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.messageShield).isNull() initialState.eventSink(TimelineEvents.ShowShieldDialog(shield)) @@ -929,7 +888,9 @@ class TimelinePresenterTest { ) val room = FakeJoinedRoom( liveTimeline = timeline, - baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + ), ).apply { givenRoomMembersState(RoomMembersState.Unknown) } @@ -937,9 +898,7 @@ class TimelinePresenterTest { val avatarUrl = "https://domain.com/avatar.jpg" val presenter = createTimelinePresenter(timeline, room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = consumeItemsUntilPredicate(30.seconds) { it.timelineItems.isNotEmpty() }.last() val event = initialState.timelineItems.first() as TimelineItem.Event assertThat(event.senderAvatar.url).isNull() @@ -963,15 +922,13 @@ class TimelinePresenterTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), predecessorRoomResult = { predecessorRoom } ), ) val presenter = createTimelinePresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.timelineRoomInfo.predecessorRoom).isNotNull() assertThat(initialState.timelineRoomInfo.predecessorRoom?.roomId).isEqualTo(predecessorRoomId) @@ -982,14 +939,12 @@ class TimelinePresenterTest { fun `present - timeline room info no predecessor`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), predecessorRoomResult = { null } ), ) val presenter = createTimelinePresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.timelineRoomInfo.predecessorRoom).isNull() } @@ -999,7 +954,7 @@ class TimelinePresenterTest { fun `present - timeline event navigate to room`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ), ) val onNavigateToRoomLambda = lambdaRecorder, Unit> { _, _, _ -> } @@ -1025,11 +980,32 @@ class TimelinePresenterTest { return awaitItem() } + private fun roomPermissions( + canRedactOther: Boolean = false, + canRedactOwn: Boolean = true, + canSendMessage: Boolean = true, + canSendReaction: Boolean = true, + canPinUnpin: Boolean = false, + ) = FakeRoomPermissions( + canSendMessage = { type -> + when(type){ + MessageEventType.RoomMessage -> canSendMessage + MessageEventType.Reaction -> canSendReaction + else -> lambdaError() + } + }, + canRedactOther = canRedactOther, + canRedactOwn = canRedactOwn, + canPinUnpin = canPinUnpin, + ) + private fun TestScope.createTimelinePresenter( timeline: Timeline = FakeTimeline(), room: FakeJoinedRoom = FakeJoinedRoom( liveTimeline = timeline, - baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + ), ), redactedVoiceMessageManager: RedactedVoiceMessageManager = FakeRedactedVoiceMessageManager(), messagesNavigator: FakeMessagesNavigator = FakeMessagesNavigator(), diff --git a/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt b/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt index 1aceee227a..bb0dc04c18 100644 --- a/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt +++ b/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt @@ -15,9 +15,12 @@ import io.element.android.features.call.test.FakeCurrentCallService import io.element.android.features.enterprise.test.FakeSessionEnterpriseService import io.element.android.features.roomcall.api.RoomCallState import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.test import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest @@ -28,7 +31,7 @@ class RoomCallStatePresenterTest { fun `present - initial state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(false) }, + roomPermissions = roomPermissions(false), ) ) val presenter = createRoomCallStatePresenter(joinedRoom = room) @@ -47,7 +50,7 @@ class RoomCallStatePresenterTest { fun `present - element call not available`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(false) }, + roomPermissions = roomPermissions(false), ) ) val presenter = createRoomCallStatePresenter( @@ -66,7 +69,7 @@ class RoomCallStatePresenterTest { fun `present - initial state - user can join call`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(true), ) ) val presenter = createRoomCallStatePresenter(joinedRoom = room) @@ -85,7 +88,7 @@ class RoomCallStatePresenterTest { fun `present - call is disabled if user cannot join it even if there is an ongoing call`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(false) }, + roomPermissions = roomPermissions(false), initialRoomInfo = aRoomInfo(hasRoomCall = true), ) ) @@ -106,7 +109,7 @@ class RoomCallStatePresenterTest { fun `present - user has joined the call on another session`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(true), ).apply { givenRoomInfo( aRoomInfo( @@ -133,7 +136,7 @@ class RoomCallStatePresenterTest { fun `present - user has joined the call locally`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(true), ).apply { givenRoomInfo( aRoomInfo( @@ -163,7 +166,7 @@ class RoomCallStatePresenterTest { fun `present - user leaves the call`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(true), ).apply { givenRoomInfo( aRoomInfo( @@ -223,6 +226,17 @@ class RoomCallStatePresenterTest { } } + private fun roomPermissions(canJoinCall: Boolean): FakeRoomPermissions { + return FakeRoomPermissions( + canSendState = { stateEvent -> + when (stateEvent) { + StateEventType.CALL_MEMBER -> canJoinCall + else -> lambdaError() + } + } + ) + } + private fun createRoomCallStatePresenter( joinedRoom: JoinedRoom, currentCallService: CurrentCallService = FakeCurrentCallService(), diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt index 5043aea88c..7056b80f99 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt @@ -15,6 +15,7 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.join.JoinRule +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.A_ROOM_ALIAS import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -25,6 +26,7 @@ import io.element.android.libraries.matrix.test.notificationsettings.FakeNotific import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.tests.testutils.lambda.lambdaError fun aRoom( @@ -35,6 +37,7 @@ fun aRoom( topic: String? = A_ROOM_TOPIC, avatarUrl: String? = AN_AVATAR_URL, canonicalAlias: RoomAlias? = A_ROOM_ALIAS, + roomPermissions: RoomPermissions = FakeRoomPermissions(), isEncrypted: Boolean = true, isPublic: Boolean = true, isDirect: Boolean = false, @@ -42,29 +45,20 @@ fun aRoom( activeMemberCount: Long = 1, joinedMemberCount: Long = 1, invitedMemberCount: Long = 0, - canInviteResult: (UserId) -> Result = { lambdaError() }, - canBanResult: (UserId) -> Result = { lambdaError() }, - canKickResult: (UserId) -> Result = { lambdaError() }, - canSendStateResult: (UserId, StateEventType) -> Result = { _, _ -> lambdaError() }, userDisplayNameResult: (UserId) -> Result = { lambdaError() }, userAvatarUrlResult: () -> Result = { lambdaError() }, - canUserJoinCallResult: (UserId) -> Result = { lambdaError() }, getUpdatedMemberResult: (UserId) -> Result = { lambdaError() }, userRoleResult: () -> Result = { lambdaError() }, setIsFavoriteResult: (Boolean) -> Result = { lambdaError() }, ) = FakeBaseRoom( sessionId = sessionId, roomId = roomId, - canInviteResult = canInviteResult, - canBanResult = canBanResult, - canKickResult = canKickResult, - canSendStateResult = canSendStateResult, userDisplayNameResult = userDisplayNameResult, userAvatarUrlResult = userAvatarUrlResult, - canUserJoinCallResult = canUserJoinCallResult, getUpdatedMemberResult = getUpdatedMemberResult, userRoleResult = userRoleResult, setIsFavoriteResult = setIsFavoriteResult, + roomPermissions = roomPermissions, initialRoomInfo = aRoomInfo( name = displayName, rawName = rawName, @@ -89,6 +83,7 @@ fun aJoinedRoom( topic: String? = A_ROOM_TOPIC, avatarUrl: String? = AN_AVATAR_URL, canonicalAlias: RoomAlias? = A_ROOM_ALIAS, + roomPermissions: RoomPermissions = FakeRoomPermissions(), isEncrypted: Boolean = true, isPublic: Boolean = true, isDirect: Boolean = false, @@ -97,17 +92,12 @@ fun aJoinedRoom( joinedMemberCount: Long = 1, invitedMemberCount: Long = 0, notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(), - canInviteResult: (UserId) -> Result = { lambdaError() }, - canBanResult: (UserId) -> Result = { lambdaError() }, - canKickResult: (UserId) -> Result = { lambdaError() }, - canSendStateResult: (UserId, StateEventType) -> Result = { _, _ -> lambdaError() }, userDisplayNameResult: (UserId) -> Result = { lambdaError() }, userAvatarUrlResult: () -> Result = { lambdaError() }, setNameResult: (String) -> Result = { lambdaError() }, setTopicResult: (String) -> Result = { lambdaError() }, updateAvatarResult: (String, ByteArray) -> Result = { _, _ -> lambdaError() }, removeAvatarResult: () -> Result = { lambdaError() }, - canUserJoinCallResult: (UserId) -> Result = { lambdaError() }, getUpdatedMemberResult: (UserId) -> Result = { lambdaError() }, userRoleResult: () -> Result = { lambdaError() }, kickUserResult: (UserId, String?) -> Result = { _, _ -> lambdaError() }, @@ -132,13 +122,9 @@ fun aJoinedRoom( baseRoom = aRoom( sessionId = sessionId, roomId = roomId, - canInviteResult = canInviteResult, - canBanResult = canBanResult, - canKickResult = canKickResult, - canSendStateResult = canSendStateResult, + roomPermissions = roomPermissions, userDisplayNameResult = userDisplayNameResult, userAvatarUrlResult = userAvatarUrlResult, - canUserJoinCallResult = canUserJoinCallResult, getUpdatedMemberResult = getUpdatedMemberResult, userRoleResult = userRoleResult, setIsFavoriteResult = setIsFavoriteResult, diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt index 9cf46c41c0..fa3ec9bb2e 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt @@ -30,6 +30,7 @@ import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.join.JoinRule +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME @@ -41,6 +42,7 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore import io.element.android.services.analytics.api.AnalyticsService @@ -119,9 +121,7 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state is created from initial room info`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -148,9 +148,7 @@ class RoomDetailsPresenterTest { pinnedEventIds = listOf(AN_EVENT_ID), ) val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(roomInfo) } @@ -170,9 +168,7 @@ class RoomDetailsPresenterTest { fun `present - initial state with no room name`() = runTest { val room = aJoinedRoom( displayName = "", - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -188,9 +184,7 @@ class RoomDetailsPresenterTest { val myRoomMember = aRoomMember(A_SESSION_ID) val otherRoomMember = aRoomMember(A_USER_ID_2) val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getUpdatedMemberResult = { userId -> when (userId) { A_SESSION_ID -> Result.success(myRoomMember) @@ -225,9 +219,9 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can invite others to room`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions( + canInvite = true, + ), ) val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -243,26 +237,9 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can not invite others to room`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(false) }, - canKickResult = { Result.success(false) }, - canBanResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, - ) - val presenter = createRoomDetailsPresenter(room) - presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { - assertThat(awaitItem().canInvite).isFalse() - - cancelAndIgnoreRemainingEvents() - } - } - - @Test - fun `present - initial state when canInvite errors`() = runTest { - val room = aJoinedRoom( - canInviteResult = { Result.failure(RuntimeException("Whoops")) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions( + canInvite = false, + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -275,17 +252,11 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can edit one attribute`() = runTest { val room = aJoinedRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_TOPIC -> Result.success(true) - StateEventType.ROOM_NAME -> Result.success(false) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canBanResult = { Result.success(false) }, - canKickResult = { Result.success(false) }, - canInviteResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canChangeName = true, + canChangeTopic = false, + canChangeAvatar = false, + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -303,18 +274,7 @@ class RoomDetailsPresenterTest { val myRoomMember = aRoomMember(A_SESSION_ID) val otherRoomMember = aRoomMember(A_USER_ID_2) val room = aJoinedRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME, - StateEventType.ROOM_AVATAR -> Result.success(true) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canKickResult = { Result.success(false) }, - canBanResult = { Result.success(false) }, - canInviteResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(), getUpdatedMemberResult = { userId -> when (userId) { A_SESSION_ID -> Result.success(myRoomMember) @@ -354,18 +314,9 @@ class RoomDetailsPresenterTest { val room = aJoinedRoom( isDirect = true, topic = null, - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_AVATAR, - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME -> Result.success(true) - else -> Result.failure(RuntimeException("Whelp")) - } - }, + roomPermissions = roomPermissions(), userDisplayNameResult = { Result.success(A_USER_NAME) }, userAvatarUrlResult = { Result.success(AN_AVATAR_URL) }, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, getUpdatedMemberResult = { userId -> when (userId) { A_SESSION_ID -> Result.success(myRoomMember) @@ -400,24 +351,11 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can edit all attributes`() = runTest { val room = aJoinedRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME, - StateEventType.ROOM_AVATAR -> Result.success(true) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canKickResult = { - Result.success(false) - }, - canBanResult = { - Result.success(false) - }, - canInviteResult = { - Result.success(false) - }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canChangeAvatar = true, + canChangeName = true, + canChangeTopic = true, + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -433,24 +371,11 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can edit no attributes`() = runTest { val room = aJoinedRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME, - StateEventType.ROOM_AVATAR -> Result.success(false) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canBanResult = { - Result.success(false) - }, - canKickResult = { - Result.success(false) - }, - canInviteResult = { - Result.success(false) - }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canChangeAvatar = false, + canChangeName = false, + canChangeTopic = false, + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -465,24 +390,9 @@ class RoomDetailsPresenterTest { fun `present - topic state is hidden when no topic and user has no permission`() = runTest { val room = aJoinedRoom( topic = null, - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_AVATAR, - StateEventType.ROOM_NAME -> Result.success(true) - StateEventType.ROOM_TOPIC -> Result.success(false) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canKickResult = { - Result.success(false) - }, - canBanResult = { - Result.success(false) - }, - canInviteResult = { - Result.success(false) - }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canChangeTopic = false + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -497,24 +407,7 @@ class RoomDetailsPresenterTest { fun `present - topic state is 'can add topic' when no topic and user has permission`() = runTest { val room = aJoinedRoom( topic = null, - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_AVATAR, - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME -> Result.success(true) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canKickResult = { - Result.success(false) - }, - canBanResult = { - Result.success(false) - }, - canInviteResult = { - Result.success(false) - }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(topic = null)) } @@ -534,9 +427,7 @@ class RoomDetailsPresenterTest { fun `present - leave room event is passed on to leave room presenter`() = runTest { val leaveRoomEventRecorder = EventsRecorder() val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter( room = room, @@ -555,9 +446,7 @@ class RoomDetailsPresenterTest { val notificationSettingsService = FakeNotificationSettingsService() val room = aJoinedRoom( notificationSettingsService = notificationSettingsService, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter( room = room, @@ -584,9 +473,7 @@ class RoomDetailsPresenterTest { FakeNotificationSettingsService(initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY) val room = aJoinedRoom( notificationSettingsService = notificationSettingsService, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter( room = room, @@ -612,9 +499,7 @@ class RoomDetailsPresenterTest { ) val room = aJoinedRoom( notificationSettingsService = notificationSettingsService, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter( room = room, @@ -637,9 +522,7 @@ class RoomDetailsPresenterTest { val setIsFavoriteResult = lambdaRecorder> { _ -> Result.success(Unit) } val room = aJoinedRoom( setIsFavoriteResult = setIsFavoriteResult, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val analyticsService = FakeAnalyticsService() val presenter = @@ -665,9 +548,7 @@ class RoomDetailsPresenterTest { @Test fun `present - changes in room info updates the is favorite flag`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter(room = room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -686,9 +567,7 @@ class RoomDetailsPresenterTest { @Test fun `present - show knock requests`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), joinRule = JoinRule.Knock, ) val featureFlagService = FakeFeatureFlagService( @@ -712,9 +591,7 @@ class RoomDetailsPresenterTest { @Test fun `present - show security and privacy`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val featureFlagService = FakeFeatureFlagService() val presenter = createRoomDetailsPresenter(room = room, featureFlagService = featureFlagService) @@ -729,9 +606,7 @@ class RoomDetailsPresenterTest { @Test fun `present - show debug info`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val inMemoryAppPreferencesStore = InMemoryAppPreferencesStore( isDeveloperModeEnabled = true, @@ -744,4 +619,42 @@ class RoomDetailsPresenterTest { } } } + + private fun roomPermissions( + canInvite: Boolean = true, + canKick: Boolean = true, + canBan: Boolean = true, + canRedactOther: Boolean = true, + canRedactOwn: Boolean = true, + canChangeRoomAccess: Boolean = true, + canChangeHistoryVisibility: Boolean = true, + canChangeEncryption: Boolean = true, + canChangeRoomVisibility: Boolean = true, + canChangeName: Boolean = true, + canChangeTopic: Boolean = true, + canChangeAvatar: Boolean = true, + canChangePowerLevels: Boolean = true, + ) : RoomPermissions{ + return FakeRoomPermissions( + canInvite = canInvite, + canKick = canKick, + canBan = canBan, + canRedactOther = canRedactOther, + canRedactOwn = canRedactOwn, + canSendState = { eventType -> + when (eventType) { + StateEventType.ROOM_JOIN_RULES -> canChangeRoomAccess + StateEventType.ROOM_HISTORY_VISIBILITY -> canChangeHistoryVisibility + StateEventType.ROOM_ENCRYPTION -> canChangeEncryption + StateEventType.ROOM_CANONICAL_ALIAS -> canChangeRoomVisibility + StateEventType.ROOM_AVATAR -> canChangeAvatar + StateEventType.ROOM_NAME -> canChangeName + StateEventType.ROOM_TOPIC -> canChangeTopic + StateEventType.ROOM_POWER_LEVELS -> canChangePowerLevels + else -> lambdaError() + } + } + ) + } + } diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt index 8d3d0e35e3..82ca8b249d 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt @@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers @@ -171,7 +172,7 @@ class RoomMemberListPresenterTest { fun `present - asynchronously sets canInvite when user does not have correct power level`() = runTest { val presenter = createPresenter( joinedRoom = createFakeJoinedRoom( - canInviteResult = { Result.success(false) }, + canInvite = false, ) ) presenter.test { @@ -180,18 +181,6 @@ class RoomMemberListPresenterTest { } } - @Test - fun `present - asynchronously sets canInvite when power level check fails`() = runTest { - val presenter = createPresenter( - joinedRoom = createFakeJoinedRoom( - canInviteResult = { Result.failure(RuntimeException("Eek")) }, - ) - ) - presenter.test { - val loadedState = awaitItem() - assertThat(loadedState.canInvite).isFalse() - } - } @Test fun `present - RoomMemberSelected will open the moderation options`() = runTest { @@ -207,12 +196,14 @@ class RoomMemberListPresenterTest { private fun createFakeJoinedRoom( updateMembersResult: () -> Unit = { }, - canInviteResult: (UserId) -> Result = { Result.success(true) }, + canInvite: Boolean = true, ): FakeJoinedRoom { return FakeJoinedRoom( baseRoom = FakeBaseRoom( updateMembersResult = updateMembersResult, - canInviteResult = canInviteResult, + roomPermissions = FakeRoomPermissions( + canInvite = canInvite, + ), ).apply { // Needed to avoid discarding the loaded members as a partial and invalid result givenRoomInfo(aRoomInfo(joinedMembersCount = 2)) diff --git a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt index e438cecf50..9c7f840af2 100644 --- a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt +++ b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt @@ -13,7 +13,6 @@ import com.google.common.truth.Truth.assertThat import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.core.mimetype.MimeTypes -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -23,6 +22,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_TOPIC import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.mediapickers.test.FakePickerProvider import io.element.android.libraries.mediaupload.api.MediaUploadInfo @@ -102,7 +102,6 @@ class RoomDetailsEditPresenterTest { avatarUrl = AN_AVATAR_URL, displayName = A_ROOM_NAME, rawName = A_ROOM_RAW_NAME, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -127,17 +126,15 @@ class RoomDetailsEditPresenterTest { @Test fun `present - sets canChangeName if user has permission`() = runTest { - val room = FakeJoinedRoom( - FakeBaseRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_NAME -> Result.success(true) - StateEventType.ROOM_AVATAR -> Result.success(false) - StateEventType.ROOM_TOPIC -> Result.failure(RuntimeException("Oops")) - else -> lambdaError() - } - }, - ) + val room = aJoinedRoom( + canSendState = { stateEventType -> + when (stateEventType) { + StateEventType.ROOM_NAME -> true + StateEventType.ROOM_AVATAR -> false + StateEventType.ROOM_TOPIC -> false + else -> lambdaError() + } + } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -163,11 +160,11 @@ class RoomDetailsEditPresenterTest { fun `present - sets canChangeAvatar if user has permission`() = runTest { val room = aJoinedRoom( avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, stateEventType -> + canSendState = { stateEventType -> when (stateEventType) { - StateEventType.ROOM_NAME -> Result.success(false) - StateEventType.ROOM_AVATAR -> Result.success(true) - StateEventType.ROOM_TOPIC -> Result.failure(RuntimeException("Oops")) + StateEventType.ROOM_NAME -> false + StateEventType.ROOM_AVATAR -> true + StateEventType.ROOM_TOPIC -> false else -> lambdaError() } } @@ -195,11 +192,11 @@ class RoomDetailsEditPresenterTest { fun `present - sets canChangeTopic if user has permission`() = runTest { val room = aJoinedRoom( avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, stateEventType -> + canSendState = { stateEventType -> when (stateEventType) { - StateEventType.ROOM_NAME -> Result.success(false) - StateEventType.ROOM_AVATAR -> Result.failure(RuntimeException("Oops")) - StateEventType.ROOM_TOPIC -> Result.success(true) + StateEventType.ROOM_NAME -> false + StateEventType.ROOM_AVATAR -> false + StateEventType.ROOM_TOPIC -> true else -> lambdaError() } } @@ -229,7 +226,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -274,7 +270,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(anotherAvatarUri) val deleteCallback = lambdaRecorder {} @@ -298,7 +293,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(anotherAvatarUri) val fakePermissionsPresenter = FakePermissionsPresenter() @@ -339,7 +333,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(roomAvatarUri) val deleteCallback = lambdaRecorder {} @@ -389,7 +382,6 @@ class RoomDetailsEditPresenterTest { topic = null, displayName = "fallback", avatarUrl = null, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(roomAvatarUri) val deleteCallback = lambdaRecorder {} @@ -445,7 +437,6 @@ class RoomDetailsEditPresenterTest { setNameResult = setNameResult, setTopicResult = setTopicResult, removeAvatarResult = removeAvatarResult, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -471,7 +462,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -493,7 +483,6 @@ class RoomDetailsEditPresenterTest { topic = null, displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -515,7 +504,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -539,7 +527,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, updateAvatarResult = updateAvatarResult, - canSendStateResult = { _, _ -> Result.success(true) } ) givenPickerReturnsFile() val deleteCallback = lambdaRecorder {} @@ -566,7 +553,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(anotherAvatarUri) fakeMediaPreProcessor.givenResult(Result.failure(RuntimeException("Oh no"))) @@ -591,7 +577,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, setNameResult = { Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) saveAndAssertFailure(room, RoomDetailsEditEvent.UpdateRoomName("New name"), deleteCallbackNumberOfInvocation = 1) } @@ -603,7 +588,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, setTopicResult = { Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) saveAndAssertFailure(room, RoomDetailsEditEvent.UpdateRoomTopic("New topic"), deleteCallbackNumberOfInvocation = 1) } @@ -615,7 +599,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, removeAvatarResult = { Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove), deleteCallbackNumberOfInvocation = 2) } @@ -628,7 +611,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, updateAvatarResult = { _, _ -> Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto), deleteCallbackNumberOfInvocation = 2) } @@ -641,7 +623,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, setTopicResult = { Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -663,7 +644,6 @@ class RoomDetailsEditPresenterTest { fun `present - leave without saving - cancel`() = runTest { val room = aJoinedRoom( displayName = "Name", - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -693,7 +673,6 @@ class RoomDetailsEditPresenterTest { fun `present - leave no changes, no confirmation`() = runTest { val room = aJoinedRoom( displayName = "Name", - canSendStateResult = { _, _ -> Result.success(true) } ) val presenter = createRoomDetailsEditPresenter( room = room, @@ -711,7 +690,7 @@ class RoomDetailsEditPresenterTest { fun `present - leave without saving - confirm`() = runTest { val room = aJoinedRoom( displayName = "Name", - canSendStateResult = { _, _ -> Result.success(true) } + canSendState = { _ -> true } ) val presenter = createRoomDetailsEditPresenter( room = room, @@ -782,11 +761,13 @@ class RoomDetailsEditPresenterTest { setTopicResult: (String) -> Result = { Result.success(Unit) }, updateAvatarResult: (String, ByteArray) -> Result = { _, _ -> Result.success(Unit) }, removeAvatarResult: () -> Result = { Result.success(Unit) }, - canSendStateResult: (UserId, StateEventType) -> Result, + canSendState: (StateEventType) -> Boolean = { true }, ): JoinedRoom { return FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = canSendStateResult, + roomPermissions = FakeRoomPermissions( + canSendState = canSendState, + ), initialRoomInfo = aRoomInfo( name = displayName, topic = topic, diff --git a/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt b/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt index 2b3f71e770..4ce50a2488 100644 --- a/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt +++ b/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule @@ -355,8 +356,10 @@ class RoomMemberModerationPresenterTest { banUserResult = { _, _ -> banUserResult }, unBanUserResult = { _, _ -> unBanUserResult }, baseRoom = FakeBaseRoom( - canBanResult = { _ -> Result.success(canBan) }, - canKickResult = { _ -> Result.success(canKick) }, + roomPermissions = FakeRoomPermissions( + canBan = canBan, + canKick = canKick + ), userRoleResult = { Result.success(myUserRole) }, updateMembersResult = { Result.success(Unit) } ), diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index af0f44be38..81bfe22697 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -67,7 +67,6 @@ class SecurityAndPrivacyPresenter( }.collectAsState(false) val saveAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } val homeserverName = remember { matrixClient.userIdServerName() } - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val roomInfo by room.roomInfoFlow.collectAsState() val savedIsVisibleInRoomDirectory = remember { mutableStateOf>(AsyncData.Uninitialized) } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index 7d88706996..a4542b02a1 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -18,15 +18,19 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.libraries.matrix.api.room.StateEventType 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.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import io.element.android.libraries.matrix.test.A_ROOM_ALIAS import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.test import kotlinx.coroutines.test.runTest @@ -66,7 +70,7 @@ class SecurityAndPrivacyPresenterTest { fun `present - room info change updates saved and edited settings`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), initialRoomInfo = aRoomInfo( joinRule = JoinRule.Public, historyVisibility = RoomHistoryVisibility.WorldReadable, @@ -173,7 +177,7 @@ class SecurityAndPrivacyPresenterTest { fun `present - room visibility loading and change`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared) ) @@ -222,7 +226,7 @@ class SecurityAndPrivacyPresenterTest { val updateRoomHistoryVisibilityLambda = lambdaRecorder> { Result.success(Unit) } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, initialRoomInfo = aRoomInfo(joinRule = JoinRule.Invite, historyVisibility = RoomHistoryVisibility.Shared) ), @@ -272,8 +276,8 @@ class SecurityAndPrivacyPresenterTest { isEncrypted = true, ) ) - // Saved settings are updated 3 times to match the edited settings - skipItems(3) + // Saved settings are updated 2 times to match the edited settings + skipItems(2) with(awaitItem()) { assertThat(saveAction).isEqualTo(AsyncAction.Success(Unit)) assertThat(savedSettings).isEqualTo(editedSettings) @@ -297,7 +301,7 @@ class SecurityAndPrivacyPresenterTest { val updateRoomHistoryVisibilityLambda = lambdaRecorder> { Result.success(Unit) } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, joinRule = JoinRule.Private) ), @@ -340,7 +344,7 @@ class SecurityAndPrivacyPresenterTest { ) ) // Saved settings are updated 2 times to match the edited settings - skipItems(3) + skipItems(2) val state = awaitItem() with(state) { assertThat(saveAction).isInstanceOf(AsyncAction.Failure::class.java) @@ -374,11 +378,30 @@ class SecurityAndPrivacyPresenterTest { } } + private fun roomPermissions( + canChangeRoomAccess: Boolean = true, + canChangeHistoryVisibility: Boolean = true, + canChangeEncryption: Boolean = true, + canChangeRoomVisibility: Boolean = true, + ): RoomPermissions { + return FakeRoomPermissions( + canSendState = { eventType -> + when (eventType) { + StateEventType.ROOM_JOIN_RULES -> canChangeRoomAccess + StateEventType.ROOM_HISTORY_VISIBILITY -> canChangeHistoryVisibility + StateEventType.ROOM_ENCRYPTION -> canChangeEncryption + StateEventType.ROOM_CANONICAL_ALIAS -> canChangeRoomVisibility + else -> lambdaError() + } + } + ) + } + private fun createSecurityAndPrivacyPresenter( serverName: String = "matrix.org", room: FakeJoinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, joinRule = JoinRule.Private) ), diff --git a/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt b/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt index aa984f0066..b10cf3e48d 100644 --- a/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt +++ b/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt @@ -28,6 +28,7 @@ import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.encryption.identity.IdentityState +import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -36,9 +37,11 @@ import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.room.FakeBaseRoom +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.lambda.any +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test @@ -89,15 +92,7 @@ class UserProfilePresenterTest { @Test fun `present - canCall is false when canUserJoinCall returns false`() { testCanCall( - canUserJoinCallResult = Result.success(false), - expectedResult = false, - ) - } - - @Test - fun `present - canCall is false when canUserJoinCall fails`() { - testCanCall( - canUserJoinCallResult = Result.failure(AN_EXCEPTION), + canUserJoinCall = false, expectedResult = false, ) } @@ -128,7 +123,7 @@ class UserProfilePresenterTest { private fun testCanCall( isElementCallAvailable: Boolean = true, - canUserJoinCallResult: Result = Result.success(true), + canUserJoinCall: Boolean = true, dmRoom: RoomId? = A_ROOM_ID, canFindRoom: Boolean = true, expectedResult: Boolean, @@ -136,7 +131,14 @@ class UserProfilePresenterTest { checkThatRoomIsDestroyed: Boolean = false, ) = runTest { val room = FakeBaseRoom( - canUserJoinCallResult = { canUserJoinCallResult }, + roomPermissions = FakeRoomPermissions( + canSendState = { type -> + when (type) { + StateEventType.CALL_MEMBER -> canUserJoinCall + else -> lambdaError() + } + } + ), ) val client = createFakeMatrixClient().apply { if (canFindRoom) { diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt index b05eff77e2..02b38703ca 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt @@ -42,6 +42,7 @@ class FakeBaseRoom( override val sessionId: SessionId = A_SESSION_ID, override val roomId: RoomId = A_ROOM_ID, initialRoomInfo: RoomInfo = aRoomInfo(), + private val roomPermissions: RoomPermissions = FakeRoomPermissions(), override val roomCoroutineScope: CoroutineScope = TestScope(), private var roomPermalinkResult: () -> Result = { lambdaError() }, private var eventPermalinkResult: (EventId) -> Result = { lambdaError() }, @@ -50,17 +51,6 @@ class FakeBaseRoom( private val userRoleResult: () -> Result = { lambdaError() }, private val getUpdatedMemberResult: (UserId) -> Result = { lambdaError() }, private val joinRoomResult: () -> Result = { lambdaError() }, - private val roomPermissionsResult: () -> Result = { Result.success(FakeRoomPermissions()) }, - private val canInviteResult: (UserId) -> Result = { lambdaError() }, - private val canKickResult: (UserId) -> Result = { lambdaError() }, - private val canBanResult: (UserId) -> Result = { lambdaError() }, - private val canRedactOwnResult: (UserId) -> Result = { lambdaError() }, - private val canRedactOtherResult: (UserId) -> Result = { lambdaError() }, - private val canSendStateResult: (UserId, StateEventType) -> Result = { _, _ -> lambdaError() }, - private val canUserSendMessageResult: (UserId, MessageEventType) -> Result = { _, _ -> lambdaError() }, - private val canUserTriggerRoomNotificationResult: (UserId) -> Result = { lambdaError() }, - private val canUserJoinCallResult: (UserId) -> Result = { lambdaError() }, - private val canUserPinUnpinResult: (UserId) -> Result = { lambdaError() }, private val setIsFavoriteResult: (Boolean) -> Result = { lambdaError() }, private val markAsReadResult: (ReceiptType) -> Result = { Result.success(Unit) }, private val powerLevelsResult: () -> Result = { lambdaError() }, @@ -133,7 +123,7 @@ class FakeBaseRoom( } override suspend fun roomPermissions(): Result { - return roomPermissionsResult() + return Result.success(roomPermissions) } override suspend fun getPermalink(): Result { @@ -160,46 +150,6 @@ class FakeBaseRoom( return forgetResult() } - override suspend fun canUserBan(userId: UserId): Result { - return canBanResult(userId) - } - - override suspend fun canUserKick(userId: UserId): Result { - return canKickResult(userId) - } - - override suspend fun canUserInvite(userId: UserId): Result { - return canInviteResult(userId) - } - - override suspend fun canUserRedactOwn(userId: UserId): Result { - return canRedactOwnResult(userId) - } - - override suspend fun canUserRedactOther(userId: UserId): Result { - return canRedactOtherResult(userId) - } - - override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result { - return canSendStateResult(userId, type) - } - - override suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result { - return canUserSendMessageResult(userId, type) - } - - override suspend fun canUserTriggerRoomNotification(userId: UserId): Result { - return canUserTriggerRoomNotificationResult(userId) - } - - override suspend fun canUserJoinCall(userId: UserId): Result { - return canUserJoinCallResult(userId) - } - - override suspend fun canUserPinUnpin(userId: UserId): Result { - return canUserPinUnpinResult(userId) - } - override suspend fun setIsFavorite(isFavorite: Boolean): Result { return setIsFavoriteResult(isFavorite) } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt index 04ecb1f60b..7820d9193c 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt @@ -13,46 +13,48 @@ import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions data class FakeRoomPermissions( - val ownerCanBan: Boolean = false, - val ownerCanInvite: Boolean = false, - val ownerCanKick: Boolean = false, - val ownerCanPinUnpin: Boolean = false, - val ownerCanRedactOther: Boolean = false, - val ownerCanRedactOwn: Boolean = false, - val ownerCanTriggerRoomNotification: Boolean = false, - val ownerCanSendMessage: (MessageEventType) -> Boolean = { false }, - val ownerCanSendState: (StateEventType) -> Boolean = { false }, - val userCanBan: (UserId) -> Boolean = { false }, - val userCanInvite: (UserId) -> Boolean = { false }, - val userCanKick: (UserId) -> Boolean = { false }, - val userCanPinUnpin: (UserId) -> Boolean = { false }, - val userCanRedactOther: (UserId) -> Boolean = { false }, - val userCanRedactOwn: (UserId) -> Boolean = { false }, - val userCanTriggerRoomNotification: (UserId) -> Boolean = { false }, - val userCanSendMessage: (UserId, MessageEventType) -> Boolean = { _, _ -> false }, - val userCanSendState: (UserId, StateEventType) -> Boolean = { _, _ -> false }, + private val canBan: Boolean = false, + private val canInvite: Boolean = false, + private val canKick: Boolean = false, + private val canPinUnpin: Boolean = false, + private val canRedactOther: Boolean = false, + private val canRedactOwn: Boolean = false, + private val canTriggerRoomNotification: Boolean = false, + private val canSendMessage: (MessageEventType) -> Boolean = { false }, + private val canSendState: (StateEventType) -> Boolean = { false }, + private val canUserBan: (UserId) -> Boolean = { false }, + private val canUserInvite: (UserId) -> Boolean = { false }, + private val canUserKick: (UserId) -> Boolean = { false }, + private val canUserPinUnpin: (UserId) -> Boolean = { false }, + private val canUserRedactOther: (UserId) -> Boolean = { false }, + private val canUserRedactOwn: (UserId) -> Boolean = { false }, + private val canUserTriggerRoomNotification: (UserId) -> Boolean = { false }, + private val canUserSendMessage: (UserId, MessageEventType) -> Boolean = { _, _ -> false }, + private val canUserSendState: (UserId, StateEventType) -> Boolean = { _, _ -> false }, ) : RoomPermissions { - override fun canOwnUserBan(): Boolean = ownerCanBan - override fun canOwnUserInvite(): Boolean = ownerCanInvite - override fun canOwnUserKick(): Boolean = ownerCanKick - override fun canOwnUserPinUnpin(): Boolean = ownerCanPinUnpin - override fun canOwnUserRedactOther(): Boolean = ownerCanRedactOther - override fun canOwnUserRedactOwn(): Boolean = ownerCanRedactOwn - override fun canOwnUserSendMessage(message: MessageEventType): Boolean = ownerCanSendMessage(message) - override fun canOwnUserSendState(stateEvent: StateEventType): Boolean = ownerCanSendState(stateEvent) - override fun canOwnUserTriggerRoomNotification(): Boolean = ownerCanTriggerRoomNotification - override fun canUserBan(userId: UserId): Boolean = userCanBan(userId) - override fun canUserInvite(userId: UserId): Boolean = userCanInvite(userId) - override fun canUserKick(userId: UserId): Boolean = userCanKick(userId) - override fun canUserPinUnpin(userId: UserId): Boolean = userCanPinUnpin(userId) - override fun canUserRedactOther(userId: UserId): Boolean = userCanRedactOther(userId) - override fun canUserRedactOwn(userId: UserId): Boolean = userCanRedactOwn(userId) - override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean = userCanSendMessage(userId, message) - override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean = userCanSendState(userId, stateEvent) - override fun canUserTriggerRoomNotification(userId: UserId): Boolean = userCanTriggerRoomNotification(userId) + override fun canOwnUserBan(): Boolean = canBan + override fun canOwnUserInvite(): Boolean = canInvite + override fun canOwnUserKick(): Boolean = canKick + override fun canOwnUserPinUnpin(): Boolean = canPinUnpin + override fun canOwnUserRedactOther(): Boolean = canRedactOther + override fun canOwnUserRedactOwn(): Boolean = canRedactOwn + override fun canOwnUserSendMessage(message: MessageEventType): Boolean = canSendMessage(message) + override fun canOwnUserSendState(stateEvent: StateEventType): Boolean = canSendState(stateEvent) + + override fun canOwnUserTriggerRoomNotification(): Boolean = canTriggerRoomNotification + override fun canUserBan(userId: UserId): Boolean = canUserBan(userId) + override fun canUserInvite(userId: UserId): Boolean = canUserInvite(userId) + override fun canUserKick(userId: UserId): Boolean = canUserKick(userId) + override fun canUserPinUnpin(userId: UserId): Boolean = canUserPinUnpin(userId) + override fun canUserRedactOther(userId: UserId): Boolean = canUserRedactOther(userId) + override fun canUserRedactOwn(userId: UserId): Boolean = canUserRedactOwn(userId) + override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean = canUserSendMessage(userId, message) + override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean = canUserSendState(userId, stateEvent) + override fun canUserTriggerRoomNotification(userId: UserId): Boolean = canUserTriggerRoomNotification(userId) override fun close() { // no-op for the fake } } + From 618171be0541a840d2028a9f1ca817e285dccac1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Dec 2025 19:49:57 +0000 Subject: [PATCH 079/347] chore(deps): update codecov/codecov-action action to v5.5.2 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4965530b5a..b412eb4a49 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -83,7 +83,7 @@ jobs: # https://github.com/codecov/codecov-action - name: ☂️ Upload coverage reports to codecov - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} From e668c503516d49a4abd0b106fe500c8a742f2cf5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 07:11:40 +0000 Subject: [PATCH 080/347] fix(deps): update dependency org.maplibre.gl:android-sdk to v12.2.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 a0b410b713..86a8bb5fe0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -206,7 +206,7 @@ vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0" telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" } telephoto_flick = { module = "me.saket.telephoto:flick-android", version.ref = "telephoto" } statemachine = "com.freeletics.flowredux:compose:1.2.2" -maplibre = "org.maplibre.gl:android-sdk:12.2.1" +maplibre = "org.maplibre.gl:android-sdk:12.2.2" maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2" maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2" opusencoder = "io.element.android:opusencoder:1.2.0" From b34f2cddeff7b13139c00871fd0e6ed6b3d523ba Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 10 Dec 2025 10:32:37 +0100 Subject: [PATCH 081/347] Fix issue where the wrong system was opened when dealing with other permissions than Manifest.permission.POST_NOTIFICATIONS --- .../permissions/impl/DefaultPermissionsPresenter.kt | 2 +- .../permissions/impl/action/AndroidPermissionActions.kt | 9 +++++++-- .../permissions/impl/action/PermissionActions.kt | 2 +- .../NotificationTroubleshootCheckPermissionTest.kt | 2 +- .../permissions/impl/action/FakePermissionActions.kt | 6 +++--- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt index 76e288013b..99f42a2a0c 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt @@ -113,7 +113,7 @@ class DefaultPermissionsPresenter( } } PermissionsEvents.OpenSystemSettingAndCloseDialog -> { - permissionActions.openSettings() + permissionActions.openSettings(permission) showDialog.value = false } } diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/AndroidPermissionActions.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/AndroidPermissionActions.kt index 59ebfc6deb..1be8428890 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/AndroidPermissionActions.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/AndroidPermissionActions.kt @@ -8,9 +8,11 @@ package io.element.android.libraries.permissions.impl.action +import android.Manifest import android.content.Context import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.androidutils.system.openAppSettingsPage import io.element.android.libraries.androidutils.system.startNotificationSettingsIntent import io.element.android.libraries.di.annotations.ApplicationContext @@ -18,7 +20,10 @@ import io.element.android.libraries.di.annotations.ApplicationContext class AndroidPermissionActions( @ApplicationContext private val context: Context ) : PermissionActions { - override fun openSettings() { - context.startNotificationSettingsIntent() + override fun openSettings(permission: String) { + when (permission) { + Manifest.permission.POST_NOTIFICATIONS -> context.startNotificationSettingsIntent() + else -> context.openAppSettingsPage() + } } } diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/PermissionActions.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/PermissionActions.kt index 5c496bf4c7..2b1249b823 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/PermissionActions.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/PermissionActions.kt @@ -9,5 +9,5 @@ package io.element.android.libraries.permissions.impl.action interface PermissionActions { - fun openSettings() + fun openSettings(permission: String) } diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTest.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTest.kt index f5ff79e910..eff20fabec 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTest.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTest.kt @@ -61,6 +61,6 @@ class NotificationTroubleshootCheckPermissionTest( navigator: NotificationTroubleshootNavigator, ) { // Do not bother about asking the permission inline, just lead the user to the settings - permissionActions.openSettings() + permissionActions.openSettings(Manifest.permission.POST_NOTIFICATIONS) } } diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt index 4299672d8d..fb84109a48 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt @@ -9,13 +9,13 @@ package io.element.android.libraries.permissions.impl.action class FakePermissionActions( - val openSettingsAction: () -> Unit = {} + val openSettingsAction: (String) -> Unit = {} ) : PermissionActions { var openSettingsCalled = false private set - override fun openSettings() { - openSettingsAction() + override fun openSettings(permission: String) { + openSettingsAction(permission) openSettingsCalled = true } } From 0309b9d4cb7079b8873f302442925d216a8ec58b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 10 Dec 2025 10:36:15 +0100 Subject: [PATCH 082/347] Improve test. --- .../impl/DefaultPermissionsPresenterTest.kt | 11 ++++++++--- .../permissions/impl/action/FakePermissionActions.kt | 10 ++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt index 069a632807..6036652748 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt @@ -20,6 +20,8 @@ import io.element.android.libraries.permissions.api.PermissionsEvents import io.element.android.libraries.permissions.impl.action.FakePermissionActions import io.element.android.libraries.permissions.test.InMemoryPermissionsStore import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test @@ -107,7 +109,10 @@ class DefaultPermissionsPresenterTest { FakeComposablePermissionStateProvider( permissionState ) - val permissionActions = FakePermissionActions() + val openSettingsAction = lambdaRecorder { } + val permissionActions = FakePermissionActions( + openSettingsAction = openSettingsAction, + ) val presenter = DefaultPermissionsPresenter( A_PERMISSION, permissionsStore, @@ -122,10 +127,10 @@ class DefaultPermissionsPresenterTest { initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) val withDialogState = awaitItem() assertThat(withDialogState.showDialog).isTrue() - assertThat(permissionActions.openSettingsCalled).isFalse() + openSettingsAction.assertions().isNeverCalled() withDialogState.eventSink.invoke(PermissionsEvents.OpenSystemSettingAndCloseDialog) assertThat(awaitItem().showDialog).isFalse() - assertThat(permissionActions.openSettingsCalled).isTrue() + openSettingsAction.assertions().isCalledOnce().with(value(A_PERMISSION)) } } diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt index fb84109a48..df66dee377 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt @@ -8,14 +8,12 @@ package io.element.android.libraries.permissions.impl.action -class FakePermissionActions( - val openSettingsAction: (String) -> Unit = {} -) : PermissionActions { - var openSettingsCalled = false - private set +import io.element.android.tests.testutils.lambda.lambdaError +class FakePermissionActions( + val openSettingsAction: (String) -> Unit = { lambdaError() } +) : PermissionActions { override fun openSettings(permission: String) { openSettingsAction(permission) - openSettingsCalled = true } } From 87b85409fc44a9ab474b7dd75e9cba2d5cee9f55 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 10 Dec 2025 10:49:16 +0100 Subject: [PATCH 083/347] Test cleanup --- .../impl/DefaultPermissionsPresenterTest.kt | 203 +++++++----------- 1 file changed, 83 insertions(+), 120 deletions(-) diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt index 6036652748..e15a8a5a77 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt @@ -10,23 +10,23 @@ package io.element.android.libraries.permissions.impl -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow -import app.cash.turbine.test import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionStatus import com.google.common.truth.Truth.assertThat import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsStore import io.element.android.libraries.permissions.impl.action.FakePermissionActions +import io.element.android.libraries.permissions.impl.action.PermissionActions import io.element.android.libraries.permissions.test.InMemoryPermissionsStore 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.test.runTest import org.junit.Rule import org.junit.Test -const val A_PERMISSION = "A_PERMISSION" +private const val A_PERMISSION = "A_PERMISSION" class DefaultPermissionsPresenterTest { @get:Rule @@ -34,24 +34,8 @@ class DefaultPermissionsPresenterTest { @Test fun `present - initial state`() = runTest { - val permissionsStore = InMemoryPermissionsStore() - val permissionState = FakePermissionState( - A_PERMISSION, - PermissionStatus.Granted - ) - val permissionStateProvider = - FakeComposablePermissionStateProvider( - permissionState - ) - val presenter = DefaultPermissionsPresenter( - A_PERMISSION, - permissionsStore, - permissionStateProvider, - FakePermissionActions(), - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + val presenter = createPresenter() + presenter.test { val initialState = awaitItem() assertThat(initialState.permission).isEqualTo(A_PERMISSION) assertThat(initialState.permissionGranted).isTrue() @@ -68,23 +52,16 @@ class DefaultPermissionsPresenterTest { permissionDenied = true, permissionAsked = true ) - val permissionState = FakePermissionState( - A_PERMISSION, - PermissionStatus.Denied(shouldShowRationale = false) + val permissionStateProvider = FakeComposablePermissionStateProvider( + permissionState = aFakePermissionState( + initialStatus = PermissionStatus.Denied(shouldShowRationale = false) + ), ) - val permissionStateProvider = - FakeComposablePermissionStateProvider( - permissionState - ) - val presenter = DefaultPermissionsPresenter( - A_PERMISSION, - permissionsStore, - permissionStateProvider, - FakePermissionActions(), + val presenter = createPresenter( + permissionsStore = permissionsStore, + permissionStateProvider = permissionStateProvider, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitItem() initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) @@ -101,27 +78,21 @@ class DefaultPermissionsPresenterTest { permissionDenied = true, permissionAsked = true ) - val permissionState = FakePermissionState( - A_PERMISSION, - PermissionStatus.Denied(shouldShowRationale = false) + val permissionStateProvider = FakeComposablePermissionStateProvider( + permissionState = aFakePermissionState( + initialStatus = PermissionStatus.Denied(shouldShowRationale = false), + ), ) - val permissionStateProvider = - FakeComposablePermissionStateProvider( - permissionState - ) val openSettingsAction = lambdaRecorder { } val permissionActions = FakePermissionActions( openSettingsAction = openSettingsAction, ) - val presenter = DefaultPermissionsPresenter( - A_PERMISSION, - permissionsStore, - permissionStateProvider, - permissionActions, + val presenter = createPresenter( + permissionsStore = permissionsStore, + permissionStateProvider = permissionStateProvider, + permissionActions = permissionActions, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitItem() initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) @@ -136,24 +107,16 @@ class DefaultPermissionsPresenterTest { @Test fun `present - user does not grant permission`() = runTest { - val permissionsStore = InMemoryPermissionsStore() - val permissionState = FakePermissionState( - A_PERMISSION, - PermissionStatus.Denied(shouldShowRationale = false) + val permissionState = aFakePermissionState( + initialStatus = PermissionStatus.Denied(shouldShowRationale = false) ) - val permissionStateProvider = - FakeComposablePermissionStateProvider( - permissionState - ) - val presenter = DefaultPermissionsPresenter( - A_PERMISSION, - permissionsStore, - permissionStateProvider, - FakePermissionActions(), + val permissionStateProvider = FakeComposablePermissionStateProvider( + permissionState = permissionState, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + val presenter = createPresenter( + permissionStateProvider = permissionStateProvider, + ) + presenter.test { val initialState = awaitItem() assertThat(initialState.showDialog).isFalse() initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) @@ -171,24 +134,16 @@ class DefaultPermissionsPresenterTest { @Test fun `present - user does not grant permission second time`() = runTest { - val permissionsStore = InMemoryPermissionsStore() - val permissionState = FakePermissionState( - A_PERMISSION, - PermissionStatus.Denied(shouldShowRationale = true) + val permissionState = aFakePermissionState( + initialStatus = PermissionStatus.Denied(shouldShowRationale = true) ) - val permissionStateProvider = - FakeComposablePermissionStateProvider( - permissionState - ) - val presenter = DefaultPermissionsPresenter( - A_PERMISSION, - permissionsStore, - permissionStateProvider, - FakePermissionActions(), + val permissionStateProvider = FakeComposablePermissionStateProvider( + permissionState = permissionState, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + val presenter = createPresenter( + permissionStateProvider = permissionStateProvider, + ) + presenter.test { val initialState = awaitItem() assertThat(initialState.showDialog).isFalse() initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) @@ -206,28 +161,21 @@ class DefaultPermissionsPresenterTest { @Test fun `present - user does not grant permission third time`() = runTest { - val permissionsStore = - InMemoryPermissionsStore( - permissionDenied = true, - permissionAsked = true - ) - val permissionState = FakePermissionState( - A_PERMISSION, - PermissionStatus.Denied(shouldShowRationale = false) + val permissionsStore = InMemoryPermissionsStore( + permissionDenied = true, + permissionAsked = true, ) - val permissionStateProvider = - FakeComposablePermissionStateProvider( - permissionState - ) - val presenter = DefaultPermissionsPresenter( - A_PERMISSION, - permissionsStore, - permissionStateProvider, - FakePermissionActions(), + val permissionState = aFakePermissionState( + initialStatus = PermissionStatus.Denied(shouldShowRationale = false), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + val permissionStateProvider = FakeComposablePermissionStateProvider( + permissionState = permissionState, + ) + val presenter = createPresenter( + permissionsStore = permissionsStore, + permissionStateProvider = permissionStateProvider, + ) + presenter.test { skipItems(1) val initialState = awaitItem() initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) @@ -241,24 +189,16 @@ class DefaultPermissionsPresenterTest { @Test fun `present - user grants permission`() = runTest { - val permissionsStore = InMemoryPermissionsStore() - val permissionState = FakePermissionState( - A_PERMISSION, - PermissionStatus.Denied(shouldShowRationale = false) + val permissionState = aFakePermissionState( + initialStatus = PermissionStatus.Denied(shouldShowRationale = false) ) - val permissionStateProvider = - FakeComposablePermissionStateProvider( - permissionState - ) - val presenter = DefaultPermissionsPresenter( - A_PERMISSION, - permissionsStore, - permissionStateProvider, - FakePermissionActions(), + val permissionStateProvider = FakeComposablePermissionStateProvider( + permissionState = permissionState, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + val presenter = createPresenter( + permissionStateProvider = permissionStateProvider, + ) + presenter.test { val initialState = awaitItem() assertThat(initialState.showDialog).isFalse() initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) @@ -274,3 +214,26 @@ class DefaultPermissionsPresenterTest { } } } + +private fun createPresenter( + permission: String = A_PERMISSION, + permissionsStore: PermissionsStore = InMemoryPermissionsStore(), + permissionStateProvider: ComposablePermissionStateProvider = FakeComposablePermissionStateProvider( + permissionState = aFakePermissionState(), + ), + permissionActions: PermissionActions = FakePermissionActions(), +) = DefaultPermissionsPresenter( + permission = permission, + permissionsStore = permissionsStore, + composablePermissionStateProvider = permissionStateProvider, + permissionActions = permissionActions, +) + +private fun aFakePermissionState( + permission: String = A_PERMISSION, + initialStatus: PermissionStatus = PermissionStatus.Granted, +) = FakePermissionState( + permission = permission, + initialStatus = initialStatus, +) + From d65cbd46a9ea7aac4ccda4b748527d4c16b7d92c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 10 Dec 2025 10:50:10 +0100 Subject: [PATCH 084/347] PermissionsEvents -> PermissionsEvent --- .../configureroom/ConfigureRoomPresenter.kt | 4 ++-- .../NotificationsOptInPresenter.kt | 4 ++-- .../qrcode/intro/QrCodeIntroPresenter.kt | 4 ++-- .../MessageComposerPresenter.kt | 6 +++--- .../DefaultVoiceMessageComposerPresenter.kt | 8 ++++---- .../editprofile/EditUserProfilePresenter.kt | 4 ++-- .../impl/RoomDetailsEditPresenter.kt | 4 ++-- ...ermissionsEvents.kt => PermissionsEvent.kt} | 8 ++++---- .../permissions/api/PermissionsState.kt | 2 +- .../permissions/api/PermissionsView.kt | 4 ++-- .../impl/DefaultPermissionsPresenter.kt | 10 +++++----- .../impl/DefaultPermissionsPresenterTest.kt | 18 +++++++++--------- .../test/FakePermissionsPresenter.kt | 10 +++++----- 13 files changed, 43 insertions(+), 43 deletions(-) rename libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/{PermissionsEvents.kt => PermissionsEvent.kt} (71%) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index c5d68e127f..dbec30c0c5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -40,7 +40,7 @@ import io.element.android.libraries.matrix.ui.room.address.RoomAddressValidityEf import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider import io.element.android.libraries.mediaupload.api.MediaPreProcessor -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.toImmutableList @@ -132,7 +132,7 @@ class ConfigureRoomPresenter( cameraPhotoPicker.launch() } else { pendingPermissionRequest = true - cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions) + cameraPermissionState.eventSink(PermissionsEvent.RequestPermissions) } AvatarAction.Remove -> dataStore.setAvatarUri(uri = null) } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt index 344d83c38f..deb7fc59b9 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInPresenter.kt @@ -19,7 +19,7 @@ import dev.zacsweers.metro.AssistedInject import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.permissions.api.PermissionStateProvider -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.permissions.noop.NoopPermissionsPresenter import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider @@ -58,7 +58,7 @@ class NotificationsOptInPresenter( if (notificationsPermissionsState.permissionGranted) { callback.onNotificationsOptInFinished() } else { - notificationsPermissionsState.eventSink(PermissionsEvents.RequestPermissions) + notificationsPermissionsState.eventSink(PermissionsEvent.RequestPermissions) } } NotificationsOptInEvents.NotNowClicked -> { diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenter.kt index 4da6448027..13888fe23f 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenter.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/intro/QrCodeIntroPresenter.kt @@ -18,7 +18,7 @@ import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsPresenter @Inject @@ -46,7 +46,7 @@ class QrCodeIntroPresenter( canContinue = true } else { pendingPermissionRequest = true - cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions) + cameraPermissionState.eventSink(PermissionsEvent.RequestPermissions) } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 276499d5bb..b193e97fa3 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -63,7 +63,7 @@ import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider import io.element.android.libraries.mediaupload.api.MediaSenderFactory import io.element.android.libraries.mediaviewer.api.local.LocalMediaFactory -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.preferences.api.store.SessionPreferencesStore import io.element.android.libraries.push.api.notifications.conversations.NotificationConversationService @@ -284,7 +284,7 @@ class MessageComposerPresenter( cameraPhotoPicker.launch() } else { pendingEvent = event - cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions) + cameraPermissionState.eventSink(PermissionsEvent.RequestPermissions) } } MessageComposerEvent.PickAttachmentSource.VideoFromCamera -> localCoroutineScope.launch { @@ -293,7 +293,7 @@ class MessageComposerPresenter( cameraVideoPicker.launch() } else { pendingEvent = event - cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions) + cameraPermissionState.eventSink(PermissionsEvent.RequestPermissions) } } MessageComposerEvent.PickAttachmentSource.Location -> { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt index 051ded02ae..56b0e402d2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt @@ -33,7 +33,7 @@ import io.element.android.libraries.di.RoomScope import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.mediaupload.api.MediaSenderFactory -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.textcomposer.model.VoiceMessagePlayerEvent import io.element.android.libraries.textcomposer.model.VoiceMessageRecorderEvent @@ -111,7 +111,7 @@ class DefaultVoiceMessageComposerPresenter( } else -> { Timber.i("Voice message permission needed") - permissionState.eventSink(PermissionsEvents.RequestPermissions) + permissionState.eventSink(PermissionsEvent.RequestPermissions) } } } @@ -176,10 +176,10 @@ class DefaultVoiceMessageComposerPresenter( localCoroutineScope.deleteRecording() } VoiceMessageComposerEvent.DismissPermissionsRationale -> { - permissionState.eventSink(PermissionsEvents.CloseDialog) + permissionState.eventSink(PermissionsEvent.CloseDialog) } VoiceMessageComposerEvent.AcceptPermissionRationale -> { - permissionState.eventSink(PermissionsEvents.OpenSystemSettingAndCloseDialog) + permissionState.eventSink(PermissionsEvent.OpenSystemSettingAndCloseDialog) } is VoiceMessageComposerEvent.LifecycleEvent -> handleLifecycleEvent(event.event) VoiceMessageComposerEvent.DismissSendFailureDialog -> { diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt index 0bdbb1031f..bddae2fffb 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt @@ -35,7 +35,7 @@ import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider import io.element.android.libraries.mediaupload.api.MediaPreProcessor -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsPresenter import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope @@ -127,7 +127,7 @@ class EditUserProfilePresenter( cameraPhotoPicker.launch() } else { pendingPermissionRequest = true - cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions) + cameraPermissionState.eventSink(PermissionsEvent.RequestPermissions) } AvatarAction.Remove -> { temporaryUriDeleter.delete(userAvatarUri?.toUri()) diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt index 4a2dfa3f11..5e685ff81f 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt @@ -36,7 +36,7 @@ import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider import io.element.android.libraries.mediaupload.api.MediaPreProcessor -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsPresenter import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope @@ -157,7 +157,7 @@ class RoomDetailsEditPresenter( cameraPhotoPicker.launch() } else { pendingPermissionRequest = true - cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions) + cameraPermissionState.eventSink(PermissionsEvent.RequestPermissions) } AvatarAction.Remove -> { temporaryUriDeleter.delete(roomAvatarUriEdited?.toUri()) diff --git a/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsEvents.kt b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsEvent.kt similarity index 71% rename from libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsEvents.kt rename to libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsEvent.kt index 2d3cb0099f..fd01e12134 100644 --- a/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsEvents.kt +++ b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsEvent.kt @@ -8,8 +8,8 @@ package io.element.android.libraries.permissions.api -sealed interface PermissionsEvents { - data object RequestPermissions : PermissionsEvents - data object CloseDialog : PermissionsEvents - data object OpenSystemSettingAndCloseDialog : PermissionsEvents +sealed interface PermissionsEvent { + data object RequestPermissions : PermissionsEvent + data object CloseDialog : PermissionsEvent + data object OpenSystemSettingAndCloseDialog : PermissionsEvent } diff --git a/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsState.kt b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsState.kt index 28c34e6dee..3cbdfea50d 100644 --- a/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsState.kt +++ b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsState.kt @@ -17,5 +17,5 @@ data class PermissionsState( val permissionAlreadyAsked: Boolean, // If true, there is no need to ask again, the system dialog will not be displayed val permissionAlreadyDenied: Boolean, - val eventSink: (PermissionsEvents) -> Unit + val eventSink: (PermissionsEvent) -> Unit ) diff --git a/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt index ef686149ee..af0f3dd5e8 100644 --- a/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt +++ b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt @@ -35,9 +35,9 @@ fun PermissionsView( content = content ?: state.permission.toDialogContent(), submitText = stringResource(id = CommonStrings.action_open_settings), onSubmitClick = { - state.eventSink.invoke(PermissionsEvents.OpenSystemSettingAndCloseDialog) + state.eventSink.invoke(PermissionsEvent.OpenSystemSettingAndCloseDialog) }, - onDismiss = { state.eventSink.invoke(PermissionsEvents.CloseDialog) }, + onDismiss = { state.eventSink.invoke(PermissionsEvent.CloseDialog) }, icon = icon, ) } diff --git a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt index 99f42a2a0c..42331e001a 100644 --- a/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt +++ b/libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt @@ -28,7 +28,7 @@ import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject import dev.zacsweers.metro.ContributesBinding import io.element.android.libraries.core.log.logger.LoggerTag -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.permissions.api.PermissionsState import io.element.android.libraries.permissions.api.PermissionsStore @@ -100,19 +100,19 @@ class DefaultPermissionsPresenter( val showDialog = rememberSaveable { mutableStateOf(false) } - fun handleEvent(event: PermissionsEvents) { + fun handleEvent(event: PermissionsEvent) { when (event) { - PermissionsEvents.CloseDialog -> { + PermissionsEvent.CloseDialog -> { showDialog.value = false } - PermissionsEvents.RequestPermissions -> { + PermissionsEvent.RequestPermissions -> { if (permissionState.status !is PermissionStatus.Granted && isAlreadyDenied) { showDialog.value = true } else { permissionState.launchPermissionRequest() } } - PermissionsEvents.OpenSystemSettingAndCloseDialog -> { + PermissionsEvent.OpenSystemSettingAndCloseDialog -> { permissionActions.openSettings(permission) showDialog.value = false } diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt index e15a8a5a77..5335849cbd 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt @@ -13,7 +13,7 @@ package io.element.android.libraries.permissions.impl import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionStatus import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsStore import io.element.android.libraries.permissions.impl.action.FakePermissionActions import io.element.android.libraries.permissions.impl.action.PermissionActions @@ -64,10 +64,10 @@ class DefaultPermissionsPresenterTest { presenter.test { skipItems(1) val initialState = awaitItem() - initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) + initialState.eventSink.invoke(PermissionsEvent.RequestPermissions) val withDialogState = awaitItem() assertThat(withDialogState.showDialog).isTrue() - withDialogState.eventSink.invoke(PermissionsEvents.CloseDialog) + withDialogState.eventSink.invoke(PermissionsEvent.CloseDialog) assertThat(awaitItem().showDialog).isFalse() } } @@ -95,11 +95,11 @@ class DefaultPermissionsPresenterTest { presenter.test { skipItems(1) val initialState = awaitItem() - initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) + initialState.eventSink.invoke(PermissionsEvent.RequestPermissions) val withDialogState = awaitItem() assertThat(withDialogState.showDialog).isTrue() openSettingsAction.assertions().isNeverCalled() - withDialogState.eventSink.invoke(PermissionsEvents.OpenSystemSettingAndCloseDialog) + withDialogState.eventSink.invoke(PermissionsEvent.OpenSystemSettingAndCloseDialog) assertThat(awaitItem().showDialog).isFalse() openSettingsAction.assertions().isCalledOnce().with(value(A_PERMISSION)) } @@ -119,7 +119,7 @@ class DefaultPermissionsPresenterTest { presenter.test { val initialState = awaitItem() assertThat(initialState.showDialog).isFalse() - initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) + initialState.eventSink.invoke(PermissionsEvent.RequestPermissions) assertThat(permissionState.launchPermissionRequestCalled).isTrue() // User does not grant permission permissionStateProvider.userGiveAnswer(answer = false, firstTime = true) @@ -146,7 +146,7 @@ class DefaultPermissionsPresenterTest { presenter.test { val initialState = awaitItem() assertThat(initialState.showDialog).isFalse() - initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) + initialState.eventSink.invoke(PermissionsEvent.RequestPermissions) assertThat(permissionState.launchPermissionRequestCalled).isTrue() // User does not grant permission permissionStateProvider.userGiveAnswer(answer = false, firstTime = false) @@ -178,7 +178,7 @@ class DefaultPermissionsPresenterTest { presenter.test { skipItems(1) val initialState = awaitItem() - initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) + initialState.eventSink.invoke(PermissionsEvent.RequestPermissions) val withDialogState = awaitItem() assertThat(withDialogState.showDialog).isTrue() assertThat(withDialogState.permissionGranted).isFalse() @@ -201,7 +201,7 @@ class DefaultPermissionsPresenterTest { presenter.test { val initialState = awaitItem() assertThat(initialState.showDialog).isFalse() - initialState.eventSink.invoke(PermissionsEvents.RequestPermissions) + initialState.eventSink.invoke(PermissionsEvent.RequestPermissions) assertThat(permissionState.launchPermissionRequestCalled).isTrue() // User grants permission permissionStateProvider.userGiveAnswer(answer = true, firstTime = true) diff --git a/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt b/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt index b15f4db3ee..efd584585f 100644 --- a/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt +++ b/libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt @@ -10,7 +10,7 @@ package io.element.android.libraries.permissions.test import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf -import io.element.android.libraries.permissions.api.PermissionsEvents +import io.element.android.libraries.permissions.api.PermissionsEvent import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.permissions.api.PermissionsState import io.element.android.libraries.permissions.api.aPermissionsState @@ -18,11 +18,11 @@ import io.element.android.libraries.permissions.api.aPermissionsState class FakePermissionsPresenter( private val initialState: PermissionsState = aPermissionsState(showDialog = false), ) : PermissionsPresenter { - private fun handleEvent(event: PermissionsEvents) { + private fun handleEvent(event: PermissionsEvent) { when (event) { - PermissionsEvents.RequestPermissions -> state.value = state.value.copy(showDialog = true, permissionAlreadyAsked = true) - PermissionsEvents.CloseDialog -> state.value = state.value.copy(showDialog = false) - PermissionsEvents.OpenSystemSettingAndCloseDialog -> state.value = state.value.copy(showDialog = false) + PermissionsEvent.RequestPermissions -> state.value = state.value.copy(showDialog = true, permissionAlreadyAsked = true) + PermissionsEvent.CloseDialog -> state.value = state.value.copy(showDialog = false) + PermissionsEvent.OpenSystemSettingAndCloseDialog -> state.value = state.value.copy(showDialog = false) } } From 9529c1cb906b00fc1e8c22e63971518186227c17 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 10 Dec 2025 10:56:52 +0100 Subject: [PATCH 085/347] Remove empty line --- .../permissions/impl/DefaultPermissionsPresenterTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt index 5335849cbd..c7a10ca8d1 100644 --- a/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt +++ b/libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt @@ -236,4 +236,3 @@ private fun aFakePermissionState( permission = permission, initialStatus = initialStatus, ) - From 0befce47439a52f780b5e6fa1c6380fa3b18c838 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 10 Dec 2025 11:26:07 +0100 Subject: [PATCH 086/347] misc(power level) : clean up code --- .../impl/messagecomposer/MessageComposerPresenter.kt | 3 ++- .../messages/impl/timeline/TimelinePresenter.kt | 2 +- .../features/messages/impl/MessagesPresenterTest.kt | 4 ++-- .../pinned/list/PinnedMessagesListPresenterTest.kt | 3 --- .../messages/impl/timeline/TimelinePresenterTest.kt | 5 +---- .../features/roomdetails/impl/MatrixRoomFixture.kt | 1 - .../roomdetails/impl/RoomDetailsPresenterTest.kt | 3 +-- .../impl/members/RoomMemberListPresenterTest.kt | 2 -- .../api/RoomDetailsEditPermissions.kt | 2 +- .../roomdetailsedit/impl/RoomDetailsEditPresenter.kt | 3 +-- .../userprofile/impl/root/UserProfilePresenter.kt | 2 +- .../matrix/api/room/powerlevels/RoomPermissions.kt | 12 +++++++++--- .../libraries/matrix/impl/room/RustBaseRoom.kt | 2 -- .../libraries/matrix/test/room/FakeBaseRoom.kt | 2 -- .../test/room/powerlevels/FakeRoomPermissions.kt | 2 -- .../impl/gallery/MediaGalleryPresenter.kt | 1 - 16 files changed, 19 insertions(+), 30 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 2d3ab5ac31..547bd5770c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -99,6 +99,7 @@ import timber.log.Timber import kotlin.time.Duration.Companion.seconds import io.element.android.libraries.core.mimetype.MimeTypes.Any as AnyMimeTypes +@Suppress("LargeClass") @AssistedInject class MessageComposerPresenter( @Assisted private val navigator: MessagesNavigator, @@ -397,7 +398,7 @@ class MessageComposerPresenter( val currentUserId = room.sessionId suspend fun canSendRoomMention(): Boolean { - val userCanSendAtRoom = room.roomPermissions().use(false){ perms -> + val userCanSendAtRoom = room.roomPermissions().use(false) { perms -> perms.canOwnUserTriggerRoomNotification() } return !room.isDm() && userCanSendAtRoom 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 4815602c8e..289ec2924d 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 @@ -39,7 +39,6 @@ import io.element.android.features.poll.api.actions.EndPollAction import io.element.android.features.poll.api.actions.SendPollResponseAction import io.element.android.features.roomcall.api.RoomCallState import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.featureflag.api.FeatureFlagService @@ -96,6 +95,7 @@ class TimelinePresenter( private val analyticsService: AnalyticsService, ) : Presenter { private val tag = "TimelinePresenter" + @AssistedFactory interface Factory { fun create( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index 28d75d65fd..2f3a48cf32 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -1234,13 +1234,13 @@ class MessagesPresenterTest { canPinUnpin: Boolean = true, ) = FakeRoomPermissions( canSendState = { type -> - when(type){ + when (type) { StateEventType.CALL_MEMBER -> canStartCall else -> lambdaError() } }, canSendMessage = { type -> - when(type){ + when (type) { MessageEventType.RoomMessage -> canSendMessage MessageEventType.Reaction -> canSendReaction else -> lambdaError() diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt index f17681eb4d..351f841fcf 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt @@ -22,8 +22,6 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatch 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.MessageEventType -import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo @@ -41,7 +39,6 @@ import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.lambda.assert -import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt index 2bbc163626..b84975c6a5 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt @@ -8,8 +8,6 @@ package io.element.android.features.messages.impl.timeline -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow import app.cash.turbine.ReceiveTurbine import app.cash.turbine.test import com.google.common.truth.Truth.assertThat @@ -37,7 +35,6 @@ import io.element.android.libraries.matrix.api.core.UniqueId import io.element.android.libraries.matrix.api.core.asEventId import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMembersState -import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.ReceiptType @@ -988,7 +985,7 @@ class TimelinePresenterTest { canPinUnpin: Boolean = false, ) = FakeRoomPermissions( canSendMessage = { type -> - when(type){ + when (type) { MessageEventType.RoomMessage -> canSendMessage MessageEventType.Reaction -> canSendReaction else -> lambdaError() diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt index 7056b80f99..2d85744345 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt @@ -13,7 +13,6 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.test.AN_AVATAR_URL diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt index fa3ec9bb2e..7d6219004e 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt @@ -634,7 +634,7 @@ class RoomDetailsPresenterTest { canChangeTopic: Boolean = true, canChangeAvatar: Boolean = true, canChangePowerLevels: Boolean = true, - ) : RoomPermissions{ + ): RoomPermissions { return FakeRoomPermissions( canInvite = canInvite, canKick = canKick, @@ -656,5 +656,4 @@ class RoomDetailsPresenterTest { } ) } - } diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt index 82ca8b249d..f1cab1524a 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt @@ -12,7 +12,6 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.CoroutineDispatchers -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipState @@ -181,7 +180,6 @@ class RoomMemberListPresenterTest { } } - @Test fun `present - RoomMemberSelected will open the moderation options`() = runTest { val presenter = createPresenter( diff --git a/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt index f95f4466f2..c400ec1220 100644 --- a/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt +++ b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt @@ -14,7 +14,7 @@ data class RoomDetailsEditPermissions( val canEditName: Boolean, val canEditTopic: Boolean, val canEditAvatar: Boolean, -){ +) { val hasAny = canEditName || canEditTopic || canEditAvatar diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt index 4713ab9255..9d7b5b656b 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt @@ -59,7 +59,6 @@ class RoomDetailsEditPresenter( @Composable override fun present(): RoomDetailsEditState { val cameraPermissionState = cameraPermissionPresenter.present() - val roomSyncUpdateFlow = room.syncUpdateFlow.collectAsState() val roomInfo by room.roomInfoFlow.collectAsState() val roomAvatarUri = roomInfo.avatarUrl var roomAvatarUriEdited by rememberSaveable { mutableStateOf(null) } @@ -94,7 +93,7 @@ class RoomDetailsEditPresenter( } } - val permissions by room.permissionsAsState(RoomDetailsEditPermissions.DEFAULT){perms -> + val permissions by room.permissionsAsState(RoomDetailsEditPermissions.DEFAULT) { perms -> perms.roomDetailsEditPermissions() } diff --git a/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt b/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt index 8b7eddca54..7e09a03ec3 100644 --- a/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt +++ b/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt @@ -76,7 +76,7 @@ class UserProfilePresenter( roomId ?.let { client.getRoom(it) } ?.use { room -> - room.roomPermissions().use(false){ perms -> perms.canCall()} + room.roomPermissions().use(false) { perms -> perms.canCall() } } .orFalse() } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt index 735627e10e..638bf5449c 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt @@ -18,7 +18,6 @@ import io.element.android.libraries.matrix.api.room.StateEventType import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map -import timber.log.Timber /** * Provides information about the permissions of users in a room. @@ -150,7 +149,15 @@ fun Result.use(default: T, block: (RoomPermissions) -> T): fun BaseRoom.permissionsFlow(default: T, block: (RoomPermissions) -> T): Flow { return roomInfoFlow - .map { info -> info.roomPowerLevels } + .map { info -> + // If the user is a privileged creator, we return a constant hashcode to avoid recomputing permissions + // each time the power levels change (as they have all permissions). + if (info.privilegedCreatorRole && info.creators.contains(sessionId)) { + Long.MAX_VALUE + } else { + info.roomPowerLevels?.hashCode() ?: 0L + } + } .distinctUntilChanged() .map { roomPermissions().use(default, block) @@ -160,7 +167,6 @@ fun BaseRoom.permissionsFlow(default: T, block: (RoomPermissions) -> T): Flo @Composable fun BaseRoom.permissionsAsState(default: T, block: (RoomPermissions) -> T): State { return remember(this, default, block) { - Timber.d("Computing permissionsAsState for room $roomId with default=$default") permissionsFlow(default, block) }.collectAsState(default) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt index 141957d1ed..1aeb8f445d 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt @@ -18,12 +18,10 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipObserver -import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt index 02b38703ca..b56066af73 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt @@ -15,11 +15,9 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState -import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt index 7820d9193c..b78dc9ba1b 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt @@ -32,7 +32,6 @@ data class FakeRoomPermissions( private val canUserSendMessage: (UserId, MessageEventType) -> Boolean = { _, _ -> false }, private val canUserSendState: (UserId, StateEventType) -> Boolean = { _, _ -> false }, ) : RoomPermissions { - override fun canOwnUserBan(): Boolean = canBan override fun canOwnUserInvite(): Boolean = canInvite override fun canOwnUserKick(): Boolean = canKick @@ -57,4 +56,3 @@ data class FakeRoomPermissions( // no-op for the fake } } - diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt index e5e493ee63..cc26e69c33 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt @@ -207,7 +207,6 @@ class MediaGalleryPresenter( CommonStrings.error_unknown } } - } private fun GroupedMediaItems?.find(eventId: EventId?): MediaItem.Event? { From de52c991fe1763178194b0c7e3523c1e53554148 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 4 Dec 2025 16:57:37 +0100 Subject: [PATCH 087/347] change(space settings): allow accessing edit details --- features/space/impl/build.gradle.kts | 1 + .../space/impl/settings/SpaceSettingsFlowNode.kt | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/features/space/impl/build.gradle.kts b/features/space/impl/build.gradle.kts index 4ee6822bc5..03c8cda4ac 100644 --- a/features/space/impl/build.gradle.kts +++ b/features/space/impl/build.gradle.kts @@ -42,6 +42,7 @@ dependencies { implementation(projects.libraries.previewutils) implementation(projects.features.securityandprivacy.api) implementation(projects.features.rolesandpermissions.api) + implementation(projects.features.roomdetailsedit.api) api(projects.features.space.api) testCommonDependencies(libs, true) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt index d299a43791..f7ccba6d93 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt @@ -20,6 +20,7 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.features.rolesandpermissions.api.RolesAndPermissionsEntryPoint +import io.element.android.features.roomdetailsedit.api.RoomDetailsEditEntryPoint import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint import io.element.android.features.space.impl.di.SpaceFlowScope import io.element.android.libraries.architecture.BackstackView @@ -35,6 +36,7 @@ class SpaceSettingsFlowNode( @Assisted plugins: List, private val securityAndPrivacyEntryPoint: SecurityAndPrivacyEntryPoint, private val rolesAndPermissionsEntryPoint: RolesAndPermissionsEntryPoint, + private val roomDetailsEditEntryPoint: RoomDetailsEditEntryPoint ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.Root, @@ -53,6 +55,9 @@ class SpaceSettingsFlowNode( @Parcelize data object Root : NavTarget + @Parcelize + data object EditDetails: NavTarget + @Parcelize data object SecurityAndPrivacy : NavTarget @@ -71,7 +76,7 @@ class SpaceSettingsFlowNode( } override fun navigateToEditDetails() { - // TODO + backstack.push(NavTarget.EditDetails) } override fun navigateToSpaceMembers() { @@ -113,6 +118,12 @@ class SpaceSettingsFlowNode( buildContext = buildContext, ) } + NavTarget.EditDetails -> { + roomDetailsEditEntryPoint.createNode( + parentNode = this, + buildContext = buildContext, + ) + } } } From dfc3ebb71841b8dd58c47c1cff5760a2c9c85849 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 10 Dec 2025 13:44:46 +0100 Subject: [PATCH 088/347] change(space settings): manage permissions --- .../space/impl/root/SpacePresenter.kt | 14 +++++-- .../impl/settings/SpaceSettingsPermissions.kt | 38 +++++++++++++++++++ .../impl/settings/SpaceSettingsPresenter.kt | 11 ++++-- .../space/impl/settings/SpaceSettingsState.kt | 1 + .../settings/SpaceSettingsStateProvider.kt | 2 + .../space/impl/settings/SpaceSettingsView.kt | 4 +- 6 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt index 3d36de0cea..0794d02920 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt @@ -17,11 +17,14 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject -import im.vector.app.features.analytics.plan.JoinedRoom +import im.vector.app.features.analytics.plan.JoinedRoom.Trigger +import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState import io.element.android.features.invite.api.toInviteData +import io.element.android.features.space.impl.settings.SpaceSettingsPermissions +import io.element.android.features.space.impl.settings.spaceSettingsPermissions import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.mapState @@ -33,6 +36,7 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.join.JoinRoom +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoomList import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar @@ -50,6 +54,7 @@ import kotlin.jvm.optionals.getOrNull @Inject class SpacePresenter( private val spaceRoomList: SpaceRoomList, + private val room: JoinedRoom, private val client: MatrixClient, private val seenInvitesStore: SeenInvitesStore, private val joinRoom: JoinRoom, @@ -82,6 +87,9 @@ class SpacePresenter( } }.collectAsState() + val permissions by room.permissionsAsState(SpaceSettingsPermissions.DEFAULT) { perms -> + perms.spaceSettingsPermissions() + } val isSpaceSettingsEnabled by remember { featureFlagService.isFeatureEnabledFlow(FeatureFlags.SpaceSettings) }.collectAsState(false) @@ -136,7 +144,7 @@ class SpacePresenter( joinActions = joinActions.toImmutableMap(), acceptDeclineInviteState = acceptDeclineInviteState, topicViewerState = topicViewerState, - canAccessSpaceSettings = isSpaceSettingsEnabled, + canAccessSpaceSettings = isSpaceSettingsEnabled && permissions.hasAny, eventSink = ::handleEvent, ) } @@ -150,7 +158,7 @@ class SpacePresenter( joinRoom.invoke( roomIdOrAlias = spaceRoom.roomId.toRoomIdOrAlias(), serverNames = spaceRoom.via, - trigger = JoinedRoom.Trigger.SpaceHierarchy, + trigger = Trigger.SpaceHierarchy, ).onFailure { setJoinActions(joinActions + mapOf(spaceRoom.roomId to AsyncAction.Failure(it))) } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt new file mode 100644 index 0000000000..d7588b59e1 --- /dev/null +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt @@ -0,0 +1,38 @@ +/* + * 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.space.impl.settings + +import io.element.android.features.roomdetailsedit.api.roomDetailsEditPermissions +import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions +import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class SpaceSettingsPermissions( + val canEditDetails: Boolean, + val canManageRolesAndPermissions: Boolean, + val canManageSecurityAndPrivacy: Boolean, +){ + + val hasAny = canEditDetails || canManageRolesAndPermissions || canManageSecurityAndPrivacy + + companion object { + val DEFAULT = SpaceSettingsPermissions( + canEditDetails = false, + canManageRolesAndPermissions = false, + canManageSecurityAndPrivacy = false, + ) + } +} + +fun RoomPermissions.spaceSettingsPermissions(): SpaceSettingsPermissions { + return SpaceSettingsPermissions( + canEditDetails = roomDetailsEditPermissions().hasAny, + canManageRolesAndPermissions = canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS), + canManageSecurityAndPrivacy = securityAndPrivacyPermissions().hasAny, + ) +} diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPresenter.kt index 5238914c56..96c3fcbab6 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPresenter.kt @@ -14,7 +14,7 @@ import androidx.compose.runtime.getValue import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.ui.room.isOwnUserAdmin +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState @Inject class SpaceSettingsPresenter( @@ -23,15 +23,18 @@ class SpaceSettingsPresenter( @Composable override fun present(): SpaceSettingsState { val roomInfo by room.roomInfoFlow.collectAsState() - val isUserAdmin = room.isOwnUserAdmin() + val permissions by room.permissionsAsState(SpaceSettingsPermissions.DEFAULT) { perms -> + perms.spaceSettingsPermissions() + } return SpaceSettingsState( roomId = room.roomId, name = roomInfo.name.orEmpty(), canonicalAlias = roomInfo.canonicalAlias, avatarUrl = roomInfo.avatarUrl, memberCount = roomInfo.activeMembersCount, - showRolesAndPermissions = isUserAdmin, - showSecurityAndPrivacy = isUserAdmin, + canEditDetails = permissions.canEditDetails, + showRolesAndPermissions = permissions.canManageRolesAndPermissions, + showSecurityAndPrivacy = permissions.canManageSecurityAndPrivacy, eventSink = {}, ) } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsState.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsState.kt index 40ceadc112..5c7e9b5c6e 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsState.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsState.kt @@ -17,6 +17,7 @@ data class SpaceSettingsState( val canonicalAlias: RoomAlias?, val avatarUrl: String?, val memberCount: Long, + val canEditDetails: Boolean, val showRolesAndPermissions: Boolean, val showSecurityAndPrivacy: Boolean, val eventSink: (SpaceSettingsEvents) -> Unit diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsStateProvider.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsStateProvider.kt index 2abe7efebe..2030b6885a 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsStateProvider.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsStateProvider.kt @@ -30,6 +30,7 @@ fun aSpaceSettingsState( memberCount: Long = 100, showRolesAndPermissions: Boolean = false, showSecurityAndPrivacy: Boolean = false, + canEditDetails: Boolean = false, eventSink: (SpaceSettingsEvents) -> Unit = {}, ) = SpaceSettingsState( roomId = roomId, @@ -37,6 +38,7 @@ fun aSpaceSettingsState( canonicalAlias = alias, avatarUrl = avatarUrl, memberCount = memberCount, + canEditDetails = canEditDetails, showRolesAndPermissions = showRolesAndPermissions, showSecurityAndPrivacy = showSecurityAndPrivacy, eventSink = eventSink, diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsView.kt index 379d75f1dd..5a8aac4a30 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsView.kt @@ -73,6 +73,7 @@ fun SpaceSettingsView( name = state.name, avatarUrl = state.avatarUrl, canonicalAlias = state.canonicalAlias?.value, + canEditDetails = state.canEditDetails, onSpaceInfoClick = onSpaceInfoClick, ) Section(isVisible = state.showSecurityAndPrivacy, content = { @@ -101,12 +102,13 @@ private fun SpaceInfoSection( name: String, avatarUrl: String?, canonicalAlias: String?, + canEditDetails: Boolean, onSpaceInfoClick: () -> Unit, ) { Row( modifier = Modifier .fillMaxWidth() - .clickable(onClick = onSpaceInfoClick) + .clickable(enabled = canEditDetails, onClick = onSpaceInfoClick) .padding(16.dp), verticalAlignment = Alignment.CenterVertically, ) { From b95c2f8772d18960d3f76fdbf4df59945439fee3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 10 Dec 2025 14:30:09 +0100 Subject: [PATCH 089/347] fix(editable avatar) : disable avatar editing if no permission --- .../features/roomdetailsedit/impl/RoomDetailsEditView.kt | 1 + .../libraries/matrix/ui/components/EditableAvatarView.kt | 2 ++ 2 files changed, 3 insertions(+) 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 268b30cb31..aedb9bd16b 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 @@ -110,6 +110,7 @@ fun RoomDetailsEditView( } else { AvatarType.Room() }, + enabled = state.canChangeAvatar, onAvatarClick = ::onAvatarClick, modifier = Modifier.fillMaxWidth(), ) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt index 7a005402e2..284ffcbab1 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt @@ -56,6 +56,7 @@ fun EditableAvatarView( avatarType: AvatarType, onAvatarClick: () -> Unit, modifier: Modifier = Modifier, + enabled: Boolean = true, ) { val a11yAvatar = stringResource(CommonStrings.a11y_avatar) val editIconRadius = 15.dp @@ -66,6 +67,7 @@ fun EditableAvatarView( .wrapContentSize() .size(height = parentHeight, width = parentWidth) .clickable( + enabled = enabled, interactionSource = remember { MutableInteractionSource() }, onClickLabel = stringResource(CommonStrings.a11y_edit_avatar), onClick = onAvatarClick, From 9621480cebcd1d194b46d95b7e11a5aa70f9f3bf Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 10 Dec 2025 15:14:35 +0100 Subject: [PATCH 090/347] localazy: download strings to match module --- .../src/main/res/values-cs/translations.xml | 4 +++ .../src/main/res/values-et/translations.xml | 8 +++++ .../src/main/res/values-fi/translations.xml | 4 +++ .../src/main/res/values-fr/translations.xml | 4 +++ .../src/main/res/values-hu/translations.xml | 4 +++ .../src/main/res/values-it/translations.xml | 4 +++ .../main/res/values-pt-rBR/translations.xml | 4 +++ .../src/main/res/values-ru/translations.xml | 4 +++ .../src/main/res/values-sk/translations.xml | 34 +++++++++++++++---- .../main/res/values-zh-rTW/translations.xml | 4 +++ .../impl/src/main/res/values/localazy.xml | 4 +++ .../src/main/res/values-cs/translations.xml | 4 --- .../src/main/res/values-et/translations.xml | 4 --- .../src/main/res/values-fi/translations.xml | 4 --- .../src/main/res/values-fr/translations.xml | 4 --- .../src/main/res/values-hu/translations.xml | 4 --- .../src/main/res/values-it/translations.xml | 4 --- .../main/res/values-pt-rBR/translations.xml | 4 --- .../src/main/res/values-ru/translations.xml | 4 --- .../main/res/values-zh-rTW/translations.xml | 4 --- .../src/main/res/values/localazy.xml | 4 --- tools/localazy/config.json | 1 + 22 files changed, 72 insertions(+), 47 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml index 3df8e0afbb..87936de3a7 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml @@ -2,9 +2,12 @@ "Správce" "Vykázat lidi" + "Změnit nastavení" "Odstranit zprávy" "Člen" "Pozvat přátele" + "Správa prostoru" + "Spravovat místnosti" "Spravovat členy" "Zprávy a obsah" "Moderátor" @@ -14,6 +17,7 @@ "Změnit název místnosti" "Změnit téma místnosti" "Odeslat zprávy" + "Oprávnění" "Upravit správce" "Tuto akci nebudete moci vrátit zpět. Upravujete oprávnění uživatele, tak aby měl stejnou úroveň jako vy." "Přidat správce?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml index 7924e7ce7b..4a2754c1e0 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml @@ -2,9 +2,12 @@ "Peakasutajad" "Suhtluskeelu seadmine" + "Muuda seadistusi" "Eemalda sõnumid" "Liikmed" "Osalejate kutsumine" + "Halda kogukonda" + "Halda jututuba" "Liikmete haldus" "Sõnumid ja sisu" "Moderaatorid" @@ -14,6 +17,7 @@ "Jututoa nime muutmine" "Jututoa teema muutmine" "Sõnumite saatmine" + "Õigused" "Muuda peakasutajaid" "Kuna sa annad teisele kasutajale sinu õigustega võrreldes samad õigused, siis sa ei saa seda muudatust hiljem tagasi pöörata." "Lisame peakasutaja?" @@ -47,6 +51,10 @@ "Eemalda suhtluskeeld jututoas" "Suhtluskeeluga kasutajad" "Liikmed" + + "%1$d saatis kutse" + "%1$d saatis kutse" + "Ootel" "Peakasutajad" "Moderaatorid" diff --git a/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml index 1322089dc8..29331bcd13 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml @@ -2,9 +2,12 @@ "Ylläpitäjä" "Porttikieltojen antaminen" + "Asetusten muuttaminen" "Viestien poistaminen" "Jäsen" "Ihmisten kutsuminen ja liittymispyyntöjen hyväksyminen" + "Tilan hallitseminen" + "Huoneiden hallitseminen" "Jäsenien hallinta" "Viestit ja sisältö" "Valvoja" @@ -14,6 +17,7 @@ "Huoneen nimen vaihtaminen" "Huoneen aiheen vaihtaminen" "Viestien lähettäminen" + "Oikeudet" "Muokkaa ylläpitäjiä" "Et voi peruuttaa tätä toimenpidettä. Ylennät käyttäjän samalle oikeustasolle kuin sinä." "Lisätäänkö ylläpitäjä?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml index f44072366d..874b6710cd 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml @@ -2,9 +2,12 @@ "Administrateurs" "Bannir des participants" + "Changer les paramètres" "Supprimer des messages" "Membre" "Inviter des personnes" + "Gérer l’espace" + "Gérer les salons" "Gérer les membres" "Messages et contenus" "Modérateurs" @@ -14,6 +17,7 @@ "Changer le nom du salon" "Changer le sujet du salon" "Envoyer des messages" + "Autorisations" "Modifier les administrateurs" "Vous ne pourrez pas annuler cette action. Vous êtes en train de promouvoir l’utilisateur pour qu’il ait le même niveau que vous." "Ajouter un administrateur ?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml index 77e6e3b389..7542774455 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml @@ -2,9 +2,12 @@ "Adminisztrátor" "Emberek kitiltása" + "Beállítások módosítása" "Üzenetek eltávolítása" "Tag" "Emberek meghívása" + "Tér kezelése" + "Szobák kezelése" "Tagok kezelése" "Üzenetek és tartalom" "Moderátor" @@ -14,6 +17,7 @@ "Szoba nevének módosítása" "Szoba témájának módosítása" "Üzenetek küldése" + "Jogosultságok" "Adminisztrátorok szerkesztése" "Ezt a műveletet nem fogja tudja visszavonni. Ugyanarra a szintre lépteti elő a felhasználót, mint amellyel Ön is rendelkezik." "Adminisztrátor hozzáadása?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml index 2b439a6c61..b1dea12151 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml @@ -2,9 +2,12 @@ "Amministratore" "Escludi membri" + "Modifica impostazioni" "Rimuovi messaggi" "Membro" "Invita persone" + "Gestire lo spazio" + "Gestisci le stanze" "Gestisci membri" "Messaggi e contenuti" "Moderatore" @@ -14,6 +17,7 @@ "Cambia il nome della stanza" "Cambiare l\'argomento della stanza" "Inviare messaggi" + "Autorizzazioni" "Modifica amministratori" "Non potrai annullare questa azione. Stai promuovendo l\'utente al tuo stesso livello di potere." "Aggiungi amministratore?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml index 886d3c541d..43fa8d83f2 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml @@ -2,9 +2,12 @@ "Administradores" "Banir pessoas" + "Alterar configurações" "Remover mensagens" "Membro" "Convidar pessoas" + "Gerenciar espaço" + "Gerenciar salas" "Gerenciar membros" "Mensagens e conteúdo" "Moderador" @@ -14,6 +17,7 @@ "Alterar nome da sala" "Alterar tópico da sala" "Enviar mensagens" + "Permissões" "Editar administradores" "Você não poderá desfazer essa ação. Você está promovendo o usuário a ter o mesmo nível de poder que você." "Adicionar administrador?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-ru/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-ru/translations.xml index f54b984ea3..d922e58550 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-ru/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-ru/translations.xml @@ -2,9 +2,12 @@ "Только администраторы" "Блокировать людей могут" + "Изменить настройки" "Удалить сообщения" "Участник" "Пригласить людей" + "Управление пространством" + "Управление комнатами" "Список участников" "Сообщения и содержание" "Модератор" @@ -14,6 +17,7 @@ "Менять название комнаты могут" "Менять тему комнаты могут" "Отправлять сообщения могут" + "Разрешения" "Редактировать роль администраторов" "Вы не сможете отменить это действие. Вы устанавливаете уровень пользователю соответствующий вашему." "Добавить администратора?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml index a707b48bc5..d159fb03f9 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml @@ -1,17 +1,23 @@ - "Iba správcovia" + "Správca" "Zakázať ľudí" + "Zmeniť nastavenia" "Odstrániť správy" - "Pozvite ľudí a prijmite žiadosti o pripojenie" + "Člen" + "Pozvať ľudí" + "Spravovať priestor" + "Spravovať miestnosti" + "Spravovať členov" "Správy a obsah" - "Správcovia a moderátori" - "Odstrániť ľudí a odmietnuť žiadosti o pripojenie" + "Moderátor" + "Odstrániť ľudí" "Zmeniť obrázok miestnosti" - "Upraviť miestnosť" + "Upraviť podrobnosti" "Zmeniť názov miestnosti" "Zmeniť tému miestnosti" "Odoslať správy" + "Povolenia" "Upraviť správcov" "Túto akciu nebudete môcť vrátiť späť. Zvyšujete úroveň používateľa na rovnakú úroveň výkonu ako máte vy." "Pridať správcu?" @@ -32,6 +38,13 @@ "Máte neuložené zmeny." "Uložiť zmeny?" "Neexistujú žiadni zablokovaní používatelia." + + "%1$d zakázaný" + "%1$d zakázaní" + "%1$d zakázaných" + + "Skontrolujte preklepy alebo skúste nové vyhľadávanie" + "Žiadne výsledky pre „%1$s“" "%1$d osoba" "%1$d osoby" @@ -44,8 +57,14 @@ "Zrušiť zákaz prístupu do miestnosti" "Zakázaní" "Členovia" - "Iba správcovia" - "Správcovia a moderátori" + + "%1$d pozvaný" + "%1$d pozvaní" + "%1$d pozvaných" + + "Čaká na schválenie" + "Správca" + "Moderátor" "Vlastník" "Členovia miestnosti" "Zrušenie zákazu %1$s" @@ -58,6 +77,7 @@ "Správy a obsah" "Moderátori" "Vlastníci" + "Povolenia" "Obnoviť povolenia" "Po obnovení oprávnení prídete o aktuálne nastavenia." "Obnoviť oprávnenia?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-zh-rTW/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-zh-rTW/translations.xml index 50555bf9ed..7bc662e2fc 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-zh-rTW/translations.xml @@ -2,9 +2,12 @@ "管理員" "管理黑名單" + "變更設定" "移除訊息" "成員" "邀請夥伴" + "管理空間" + "管理聊天室" "管理成員" "訊息與內容" "版主" @@ -14,6 +17,7 @@ "變更聊天室名稱" "變更聊天室主題" "傳送訊息" + "權限" "編輯管理員" "您將無法復原此動作。您正將使用者提昇至與您相同的權力等級。" "要新增管理員嗎?" diff --git a/features/rolesandpermissions/impl/src/main/res/values/localazy.xml b/features/rolesandpermissions/impl/src/main/res/values/localazy.xml index 70efa48e5a..e5ab3f1cd7 100644 --- a/features/rolesandpermissions/impl/src/main/res/values/localazy.xml +++ b/features/rolesandpermissions/impl/src/main/res/values/localazy.xml @@ -2,9 +2,12 @@ "Admin" "Ban people" + "Change settings" "Remove messages" "Member" "Invite people" + "Manage space" + "Manage rooms" "Manage members" "Messages and content" "Moderator" @@ -14,6 +17,7 @@ "Change name" "Change topic" "Send messages" + "Permissions" "Edit Admins" "You will not be able to undo this action. You are promoting the user to have the same power level as you." "Add Admin?" diff --git a/libraries/ui-strings/src/main/res/values-cs/translations.xml b/libraries/ui-strings/src/main/res/values-cs/translations.xml index d4f8550f7a..ccc293a691 100644 --- a/libraries/ui-strings/src/main/res/values-cs/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cs/translations.xml @@ -452,10 +452,6 @@ Opravdu chcete pokračovat?" "Vaše zpráva nebyla odeslána, protože%1$s neověřil(a) všechna zařízení" "Jedno nebo více vašich zařízení není ověřeno. Zprávu můžete přesto odeslat, nebo ji můžete prozatím zrušit a zkusit to znovu později, až ověříte všechna svá zařízení." "Vaše zpráva nebyla odeslána, protože jste neověřili jedno nebo více zařízení" - "Změnit nastavení" - "Správa prostoru" - "Spravovat místnosti" - "Oprávnění" "Upravit správce nebo vlastníky" "Nahrání média se nezdařilo, zkuste to prosím znovu." "Nepodařilo se načíst údaje o uživateli" diff --git a/libraries/ui-strings/src/main/res/values-et/translations.xml b/libraries/ui-strings/src/main/res/values-et/translations.xml index 4b8c38be6c..2732cb60de 100644 --- a/libraries/ui-strings/src/main/res/values-et/translations.xml +++ b/libraries/ui-strings/src/main/res/values-et/translations.xml @@ -445,10 +445,6 @@ Kas sa oled kindel, et soovid jätkata?" "Sinu sõnum on saatmata, kuna %1$s pole verifitseerinud kõiki oma seadmeid" "Üks või enam sinu seadet on verifitseerimata. Sa võid sõnumi ikkagi ära saata või katkestad saatmise ning proovid uuesti, kui oled kõik oma seadmed verifitseerinud." "Kuna sul on üks või enam verifitseerimata seadet, siis sinu sõnum jäi saatmata" - "Muuda seadistusi" - "Halda kogukonda" - "Halda jututuba" - "Õigused" "Muuda peakasutajaid või omanikke" "Meediafaili töötlemine enne üleslaadimist ei õnnestunud. Palun proovi uuesti." "Kasutaja andmete laadimine ei õnnestunud" 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 bc23e78b05..2faebac565 100644 --- a/libraries/ui-strings/src/main/res/values-fi/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fi/translations.xml @@ -445,10 +445,6 @@ Haluatko varmasti jatkaa?" "Viestiäsi ei lähetetty, koska %1$s ei ole vahvistanut kaikkia laitteitaan." "Yksi tai useampi laitteistasi on vahvistamaton. Voit lähettää viestin silti tai peruuttaa sen toistaiseksi ja yrittää uudelleen myöhemmin, kun olet vahvistanut kaikki laitteesi." "Viestiäsi ei lähetetty, koska et ole vahvistanut yhtä tai useampaa laitettasi." - "Asetusten muuttaminen" - "Tilan hallitseminen" - "Huoneiden hallitseminen" - "Oikeudet" "Muokkaa ylläpitäjiä tai omistajia" "Median käsittely epäonnistui, yritä uudelleen." "Käyttäjän tietojen hakeminen epäonnistui" 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 11834a4d06..ebc611015a 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -445,10 +445,6 @@ Raison : %1$s." "Votre message n’a pas été envoyé car %1$s n’a pas vérifié tous ses appareils" "Un ou plusieurs de vos appareils ne sont pas vérifiés. Vous pouvez quand même envoyer le message, ou vous pouvez annuler et réessayer plus tard après avoir vérifié tous vos appareils." "Votre message n’a pas été envoyé car vous n’avez pas vérifié tous vos appareils" - "Changer les paramètres" - "Gérer l’espace" - "Gérer les salons" - "Autorisations" "Modifier les administrateurs ou les propriétaires" "Échec du traitement des médias à télécharger, veuillez réessayer." "Impossible de récupérer les détails de l’utilisateur" diff --git a/libraries/ui-strings/src/main/res/values-hu/translations.xml b/libraries/ui-strings/src/main/res/values-hu/translations.xml index 4539d065a3..18e30f9684 100644 --- a/libraries/ui-strings/src/main/res/values-hu/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hu/translations.xml @@ -444,10 +444,6 @@ Biztos, hogy folytatja?" "Az üzenet nem lett elküldve, mert %1$s nem ellenőrizte az összes eszközét" "Egy vagy több eszköze nincs ellenőrizve. Így is elküldheti az üzenetet, vagy egyelőre megszakíthatja, és később, az összes eszköz ellenőrzése után újrapróbálkozhat." "Az üzenet nem lett elküldve, mert egy vagy több eszközét nem ellenőrizte" - "Beállítások módosítása" - "Tér kezelése" - "Szobák kezelése" - "Jogosultságok" "Adminisztrátorok vagy tulajdonosok szerkesztése" "Nem sikerült feldolgozni a feltöltendő médiát, próbálja újra." "Nem sikerült letölteni a felhasználói adatokat" diff --git a/libraries/ui-strings/src/main/res/values-it/translations.xml b/libraries/ui-strings/src/main/res/values-it/translations.xml index 793b115917..f790312501 100644 --- a/libraries/ui-strings/src/main/res/values-it/translations.xml +++ b/libraries/ui-strings/src/main/res/values-it/translations.xml @@ -445,10 +445,6 @@ Sei sicuro di voler continuare?" "Il tuo messaggio non è stato inviato perché %1$s non ha verificato tutti i dispositivi." "Uno o più dispositivi non sono verificati. Puoi inviare il messaggio comunque, oppure annullarlo e riprovare più tardi dopo aver verificato tutti i tuoi dispositivi." "Il tuo messaggio non è stato inviato perché non hai verificato uno o più dispositivi." - "Modifica impostazioni" - "Gestire lo spazio" - "Gestisci le stanze" - "Autorizzazioni" "Modifica amministratori o proprietari" "Elaborazione del file multimediale da caricare fallita, riprova." "Impossibile recuperare i dettagli dell\'utente" diff --git a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml index 2f9b4a13e8..d922cbe19f 100644 --- a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml @@ -445,10 +445,6 @@ Você tem certeza de que deseja continuar?" "Sua mensagem não foi enviada porque %1$s não verificou todos os dispositivos" "Um ou mais de seus dispositivos não foram verificados. Você pode enviar a mensagem mesmo assim ou pode cancelar por enquanto e tentar novamente mais tarde, depois de ter verificado todos os seus dispositivos." "Sua mensagem não foi enviada porque você não verificou um ou mais de seus dispositivos" - "Alterar configurações" - "Gerenciar espaço" - "Gerenciar salas" - "Permissões" "Editar administradores ou proprietários" "Falha ao processar a mídia para o envio. Tente novamente." "Não foi possível buscar os detalhes do usuário" 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 1290cb36c8..37241df5de 100644 --- a/libraries/ui-strings/src/main/res/values-ru/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ru/translations.xml @@ -454,10 +454,6 @@ "Ваше сообщение не было отправлено, потому что %1$s не проверил одно или несколько устройств" "Одно или несколько ваших устройств не проверены. Вы можете отправить сообщение в любом случае или отменить его пока и повторить попытку позже, проверив все свои устройства." "Ваше сообщение не было отправлено, поскольку вы не подтвердили одно или несколько своих устройств." - "Изменить настройки" - "Управление пространством" - "Управление комнатами" - "Разрешения" "Редактировать роль владельца и администратора" "Не удалось обработать медиафайл для загрузки, попробуйте еще раз." "Не удалось получить данные о пользователе" diff --git a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml index 1c88ac71df..013a2c8128 100644 --- a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml @@ -436,10 +436,6 @@ "未傳送您的訊息,因為 %1$s 尚未驗證所有裝置。" "您的一個或多個裝置未經驗證。您仍可傳送訊息,也可以取消並在您驗證您的所有裝置後再試一次。" "因為您尚未驗證一個或多個裝置,因為未傳送您的訊息" - "變更設定" - "管理空間" - "管理聊天室" - "權限" "編輯管理員或擁有者" "無法處理要上傳的媒體,請再試一次。" "無法擷取使用者詳細資訊" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index d422a4c35c..cd72d6c0c0 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -455,10 +455,6 @@ Are you sure you want to continue?" "Your message was not sent because %1$s has not verified all devices" "One or more of your devices are unverified. You can send the message anyway, or you can cancel for now and try again later after you have verified all of your devices." "Your message was not sent because you have not verified one or more of your devices" - "Change settings" - "Manage space" - "Manage rooms" - "Permissions" "Edit Admins or Owners" "Failed processing media to upload, please try again." "Could not retrieve user details" diff --git a/tools/localazy/config.json b/tools/localazy/config.json index f7463a6396..b7db5f05e6 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -381,6 +381,7 @@ "name" : ":features:rolesandpermissions:impl", "includeRegex" : [ "screen_room_change_.*", + "screen\\.room_change_permissions\\..*", "screen_room_roles_.*", "screen\\.room_roles_and_permissions\\..*", "screen_room_member_list.*", From 9c72310cb4fdf70bed370c722cc174ad0b719fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 28 Nov 2025 07:58:06 +0100 Subject: [PATCH 091/347] Add developer option to optimize the SDK DBs --- .../impl/developer/DeveloperSettingsEvents.kt | 1 + .../developer/DeveloperSettingsPresenter.kt | 5 ++++ .../impl/developer/DeveloperSettingsView.kt | 8 ++++++ .../impl/tasks/VacuumStoresUseCase.kt | 27 +++++++++++++++++++ .../libraries/matrix/api/MatrixClient.kt | 2 ++ .../libraries/matrix/impl/RustMatrixClient.kt | 6 +++++ 6 files changed, 49 insertions(+) create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/VacuumStoresUseCase.kt diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsEvents.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsEvents.kt index 3bf4f375d5..1804d7e070 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsEvents.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsEvents.kt @@ -21,4 +21,5 @@ sealed interface DeveloperSettingsEvents { data class SetShowColorPicker(val show: Boolean) : DeveloperSettingsEvents data class ChangeBrandColor(val color: Color?) : DeveloperSettingsEvents data object ClearCache : DeveloperSettingsEvents + data object VacuumStores : DeveloperSettingsEvents } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt index 52e522dc89..db35a1dc83 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt @@ -29,6 +29,7 @@ import io.element.android.features.preferences.impl.developer.tracing.toLogLevel import io.element.android.features.preferences.impl.model.EnabledFeature import io.element.android.features.preferences.impl.tasks.ClearCacheUseCase import io.element.android.features.preferences.impl.tasks.ComputeCacheSizeUseCase +import io.element.android.features.preferences.impl.tasks.VacuumStoresUseCase import io.element.android.features.rageshake.api.preferences.RageshakePreferencesState import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData @@ -61,6 +62,7 @@ class DeveloperSettingsPresenter( private val appPreferencesStore: AppPreferencesStore, private val buildMeta: BuildMeta, private val enterpriseService: EnterpriseService, + private val vacuumStoresUseCase: VacuumStoresUseCase, ) : Presenter { @Composable override fun present(): DeveloperSettingsState { @@ -151,6 +153,9 @@ class DeveloperSettingsPresenter( is DeveloperSettingsEvents.SetShowColorPicker -> { showColorPicker = event.show } + DeveloperSettingsEvents.VacuumStores -> coroutineScope.launch { + vacuumStoresUseCase() + } } } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt index 6d34e97f63..2bfb2f086a 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt @@ -146,6 +146,14 @@ fun DeveloperSettingsView( } val cache = state.cacheSize PreferenceCategory(title = "Cache") { + ListItem( + headlineContent = { + Text("Vacuum stores") + }, + onClick = { + state.eventSink(DeveloperSettingsEvents.VacuumStores) + } + ) ListItem( headlineContent = { Text("Clear cache") diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/VacuumStoresUseCase.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/VacuumStoresUseCase.kt new file mode 100644 index 0000000000..0e6068cb4d --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/VacuumStoresUseCase.kt @@ -0,0 +1,27 @@ +/* + * 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.preferences.impl.tasks + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.matrix.api.MatrixClient +import timber.log.Timber + +interface VacuumStoresUseCase { + suspend operator fun invoke() +} + +@ContributesBinding(AppScope::class) +class DefaultVacuumStoresUseCase( + private val matrixClient: MatrixClient, +) : VacuumStoresUseCase { + override suspend fun invoke() { + matrixClient.vacuumStores() + .onFailure { Timber.e(it, "Failed to vacuum stores") } + } +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 1718f810df..566434b6be 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -194,6 +194,8 @@ interface MatrixClient { * Use [Timeline.markAsRead] instead when possible. */ suspend fun markRoomAsFullyRead(roomId: RoomId, eventId: EventId): Result + + suspend fun vacuumStores(): Result } /** diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index fca2aaa197..31e80cf442 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -726,6 +726,12 @@ class RustMatrixClient( } } + override suspend fun vacuumStores(): Result = withContext(sessionDispatcher) { + runCatchingExceptions { + innerClient.optimizeStores() + } + } + private suspend fun getCacheSize( includeCryptoDb: Boolean = false, ): Long = withContext(sessionDispatcher) { From 482d7e0648b2060f5a2b8a6fb16ca3bb259bcad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 5 Dec 2025 14:19:36 +0100 Subject: [PATCH 092/347] Add a periodic DB vacuuming task --- .../impl/tasks/VacuumStoresUseCase.kt | 4 +- .../DeveloperSettingsPresenterTest.kt | 20 ++++++++++ .../libraries/matrix/api/MatrixClient.kt | 2 +- libraries/matrix/impl/build.gradle.kts | 2 + .../libraries/matrix/impl/RustMatrixClient.kt | 19 ++++++++- .../matrix/impl/RustMatrixClientFactory.kt | 3 ++ ...PerformDatabaseVacuumWorkManagerRequest.kt | 40 +++++++++++++++++++ .../impl/workmanager/VacuumDatabaseWorker.kt | 38 ++++++++++++++++++ .../impl/RustMatrixClientFactoryTest.kt | 12 +++++- .../matrix/impl/RustMatrixClientTest.kt | 2 + .../libraries/matrix/test/FakeMatrixClient.kt | 5 +++ .../NotificationResolverQueue.kt | 4 +- .../workmanager/FetchNotificationsWorker.kt | 2 +- .../SyncNotificationWorkManagerRequest.kt | 2 +- ...> SyncNotificationsWorkerDataConverter.kt} | 2 +- .../push/impl/push/DefaultPushHandlerTest.kt | 4 +- .../FetchNotificationWorkerTest.kt | 2 +- .../SyncNotificationWorkManagerRequestTest.kt | 4 +- .../workmanager/WorkerDataConverterTest.kt | 12 +++--- .../workmanager/api/WorkManagerScheduler.kt | 3 ++ .../impl/DefaultWorkManagerScheduler.kt | 5 +++ .../test/FakeWorkManagerScheduler.kt | 6 +++ 22 files changed, 172 insertions(+), 21 deletions(-) create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/PerformDatabaseVacuumWorkManagerRequest.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt rename libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/{WorkerDataConverter.kt => SyncNotificationsWorkerDataConverter.kt} (99%) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/VacuumStoresUseCase.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/VacuumStoresUseCase.kt index 0e6068cb4d..1d0de56f09 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/VacuumStoresUseCase.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/VacuumStoresUseCase.kt @@ -12,7 +12,7 @@ import dev.zacsweers.metro.ContributesBinding import io.element.android.libraries.matrix.api.MatrixClient import timber.log.Timber -interface VacuumStoresUseCase { +fun interface VacuumStoresUseCase { suspend operator fun invoke() } @@ -21,7 +21,7 @@ class DefaultVacuumStoresUseCase( private val matrixClient: MatrixClient, ) : VacuumStoresUseCase { override suspend fun invoke() { - matrixClient.vacuumStores() + matrixClient.performDatabaseVacuum() .onFailure { Timber.e(it, "Failed to vacuum stores") } } } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt index fe2d8445fd..75ae12b714 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt @@ -17,6 +17,7 @@ import io.element.android.features.enterprise.test.FakeEnterpriseService import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem import io.element.android.features.preferences.impl.tasks.FakeClearCacheUseCase import io.element.android.features.preferences.impl.tasks.FakeComputeCacheSizeUseCase +import io.element.android.features.preferences.impl.tasks.VacuumStoresUseCase import io.element.android.features.rageshake.api.preferences.aRageshakePreferencesState import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData @@ -212,6 +213,23 @@ class DeveloperSettingsPresenterTest { } } + @Test + fun `present - VacuumStores action invokes the VacuumStoresUseCase`() = runTest { + var vacuumCalled = false + val presenter = createDeveloperSettingsPresenter( + vacuumStoresUseCase = VacuumStoresUseCase { + vacuumCalled = true + } + ) + presenter.test { + val state = awaitItem() + assertThat(vacuumCalled).isFalse() + state.eventSink(DeveloperSettingsEvents.VacuumStores) + skipItems(1) + assertThat(vacuumCalled).isTrue() + } + } + private fun createDeveloperSettingsPresenter( sessionId: SessionId = A_SESSION_ID, featureFlagService: FakeFeatureFlagService = FakeFeatureFlagService( @@ -230,6 +248,7 @@ class DeveloperSettingsPresenterTest { preferencesStore: InMemoryAppPreferencesStore = InMemoryAppPreferencesStore(), buildMeta: BuildMeta = aBuildMeta(), enterpriseService: EnterpriseService = FakeEnterpriseService(), + vacuumStoresUseCase: VacuumStoresUseCase = VacuumStoresUseCase {}, ): DeveloperSettingsPresenter { return DeveloperSettingsPresenter( sessionId = sessionId, @@ -240,6 +259,7 @@ class DeveloperSettingsPresenterTest { appPreferencesStore = preferencesStore, buildMeta = buildMeta, enterpriseService = enterpriseService, + vacuumStoresUseCase = vacuumStoresUseCase, ) } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 566434b6be..ae803110d5 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -195,7 +195,7 @@ interface MatrixClient { */ suspend fun markRoomAsFullyRead(roomId: RoomId, eventId: EventId): Result - suspend fun vacuumStores(): Result + suspend fun performDatabaseVacuum(): Result } /** diff --git a/libraries/matrix/impl/build.gradle.kts b/libraries/matrix/impl/build.gradle.kts index 394cb2398e..6edf26008a 100644 --- a/libraries/matrix/impl/build.gradle.kts +++ b/libraries/matrix/impl/build.gradle.kts @@ -34,6 +34,7 @@ dependencies { implementation(projects.libraries.featureflag.api) implementation(projects.libraries.network) implementation(projects.libraries.preferences.api) + implementation(projects.libraries.workmanager.api) implementation(projects.services.analytics.api) implementation(projects.services.toolbox.api) api(projects.libraries.matrix.api) @@ -49,6 +50,7 @@ dependencies { testImplementation(projects.libraries.preferences.test) testImplementation(projects.libraries.previewutils) testImplementation(projects.libraries.sessionStorage.test) + testImplementation(projects.libraries.workmanager.test) testImplementation(projects.services.analytics.test) testImplementation(projects.services.toolbox.test) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 31e80cf442..8784a69d7c 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -75,7 +75,10 @@ import io.element.android.libraries.matrix.impl.util.SessionPathsProvider import io.element.android.libraries.matrix.impl.util.cancelAndDestroy import io.element.android.libraries.matrix.impl.util.mxCallbackFlow import io.element.android.libraries.matrix.impl.verification.RustSessionVerificationService +import io.element.android.libraries.matrix.impl.workmanager.PerformDatabaseVacuumWorkManagerRequest import io.element.android.libraries.sessionstorage.api.SessionStore +import io.element.android.libraries.workmanager.api.WorkManagerRequestType +import io.element.android.libraries.workmanager.api.WorkManagerScheduler import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.toolbox.api.systemclock.SystemClock import kotlinx.collections.immutable.ImmutableList @@ -133,6 +136,7 @@ class RustMatrixClient( timelineEventTypeFilterFactory: TimelineEventTypeFilterFactory, private val featureFlagService: FeatureFlagService, private val analyticsService: AnalyticsService, + private val workManagerScheduler: WorkManagerScheduler, ) : MatrixClient { override val sessionId: UserId = UserId(innerClient.userId()) override val deviceId: DeviceId = DeviceId(innerClient.deviceId()) @@ -276,6 +280,9 @@ class RustMatrixClient( // Force a refresh of the profile getUserProfile() } + + // Schedule regular database vacuuming to ensure DB performance remains optimal + scheduleDatabaseVacuum() } override fun userIdServerName(): String { @@ -726,8 +733,9 @@ class RustMatrixClient( } } - override suspend fun vacuumStores(): Result = withContext(sessionDispatcher) { + override suspend fun performDatabaseVacuum(): Result = withContext(sessionDispatcher) { runCatchingExceptions { + Timber.d("Performing database vacuuming for session $sessionId...") innerClient.optimizeStores() } } @@ -756,6 +764,15 @@ class RustMatrixClient( // Delete all the files for this session sessionPathsProvider.provides(sessionId)?.deleteRecursively() } + + private fun scheduleDatabaseVacuum() { + // If there's already a periodic work request, do not schedule another one + if (workManagerScheduler.hasPendingWork(sessionId, WorkManagerRequestType.DB_VACUUM)) return + + Timber.i("Scheduling periodic database vacuuming for session $sessionId") + val request = PerformDatabaseVacuumWorkManagerRequest(sessionId) + workManagerScheduler.submit(request) + } } private val defaultRoomCreationPowerLevels = PowerLevels( diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index 58e3485279..3d94f7554d 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.impl.util.anonymizedTokens import io.element.android.libraries.network.useragent.UserAgentProvider import io.element.android.libraries.sessionstorage.api.SessionData import io.element.android.libraries.sessionstorage.api.SessionStore +import io.element.android.libraries.workmanager.api.WorkManagerScheduler import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.toolbox.api.systemclock.SystemClock import kotlinx.coroutines.CoroutineScope @@ -63,6 +64,7 @@ class RustMatrixClientFactory( private val timelineEventTypeFilterFactory: TimelineEventTypeFilterFactory, private val clientBuilderProvider: ClientBuilderProvider, private val sqliteStoreBuilderProvider: SqliteStoreBuilderProvider, + private val workManagerScheduler: WorkManagerScheduler, ) { private val sessionDelegate = RustClientSessionDelegate(sessionStore, appCoroutineScope, coroutineDispatchers) @@ -116,6 +118,7 @@ class RustMatrixClientFactory( timelineEventTypeFilterFactory = timelineEventTypeFilterFactory, featureFlagService = featureFlagService, analyticsService = analyticsService, + workManagerScheduler = workManagerScheduler, ).also { Timber.tag(it.toString()).d("Creating Client with access token '$anonymizedAccessToken' and refresh token '$anonymizedRefreshToken'") } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/PerformDatabaseVacuumWorkManagerRequest.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/PerformDatabaseVacuumWorkManagerRequest.kt new file mode 100644 index 0000000000..9c192bd96d --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/PerformDatabaseVacuumWorkManagerRequest.kt @@ -0,0 +1,40 @@ +/* + * 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.workmanager + +import androidx.work.Constraints +import androidx.work.Data +import androidx.work.PeriodicWorkRequest +import androidx.work.WorkRequest +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.impl.workmanager.VacuumDatabaseWorker.Companion.SESSION_ID_PARAM +import io.element.android.libraries.workmanager.api.WorkManagerRequest +import io.element.android.libraries.workmanager.api.WorkManagerRequestType +import io.element.android.libraries.workmanager.api.workManagerTag +import java.util.concurrent.TimeUnit + +class PerformDatabaseVacuumWorkManagerRequest( + private val sessionId: SessionId, +) : WorkManagerRequest { + override fun build(): Result> { + val data = Data.Builder().putString(SESSION_ID_PARAM, sessionId.value).build() + val workRequest = PeriodicWorkRequest.Builder( + workerClass = VacuumDatabaseWorker::class, + // Run once a day + repeatInterval = 1, + repeatIntervalTimeUnit = TimeUnit.DAYS, + ) + .addTag(workManagerTag(sessionId, WorkManagerRequestType.DB_VACUUM)) + .setInputData(data) + // Only run when the device is idle to avoid impacting user experience + .setConstraints(Constraints.Builder().setRequiresDeviceIdle(true).build()) + .build() + + return Result.success(listOf(workRequest)) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt new file mode 100644 index 0000000000..0602c2fdc2 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt @@ -0,0 +1,38 @@ +/* + * 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.workmanager + +import android.content.Context +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.libraries.di.annotations.ApplicationContext +import io.element.android.libraries.matrix.api.MatrixClientProvider +import io.element.android.libraries.matrix.api.core.SessionId + +@AssistedInject +class VacuumDatabaseWorker( + @Assisted workerParams: WorkerParameters, + @ApplicationContext private val context: Context, + private val matrixClientProvider: MatrixClientProvider, +) : CoroutineWorker(context, workerParams) { + companion object { + const val SESSION_ID_PARAM = "session_id" + } + + override suspend fun doWork(): Result { + val sessionId = inputData.getString(SESSION_ID_PARAM)?.let(::SessionId) ?: return Result.failure() + val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return Result.failure() + return client.performDatabaseVacuum() + .fold( + onSuccess = { Result.success() }, + onFailure = { Result.failure() } + ) + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt index a1b52d430a..fa69752afe 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt @@ -19,8 +19,11 @@ import io.element.android.libraries.network.useragent.SimpleUserAgentProvider import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.test.InMemorySessionStore import io.element.android.libraries.sessionstorage.test.aSessionData +import io.element.android.libraries.workmanager.api.WorkManagerRequest +import io.element.android.libraries.workmanager.test.FakeWorkManagerScheduler import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.toolbox.test.systemclock.FakeSystemClock +import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest @@ -30,9 +33,14 @@ import java.io.File class RustMatrixClientFactoryTest { @Test fun test() = runTest { - val sut = createRustMatrixClientFactory() + val scheduleVacuumLambda = lambdaRecorder {} + val workManagerScheduler = FakeWorkManagerScheduler(submitLambda = scheduleVacuumLambda) + val sut = createRustMatrixClientFactory(workManagerScheduler = workManagerScheduler) + val result = sut.create(aSessionData()) + assertThat(result.sessionId).isEqualTo(SessionId("@alice:server.org")) + scheduleVacuumLambda.assertions().isCalledOnce() result.destroy() } } @@ -43,6 +51,7 @@ fun TestScope.createRustMatrixClientFactory( updateUserProfileResult = { _, _, _ -> }, ), clientBuilderProvider: ClientBuilderProvider = FakeClientBuilderProvider(), + workManagerScheduler: FakeWorkManagerScheduler = FakeWorkManagerScheduler(), ) = RustMatrixClientFactory( cacheDirectory = cacheDirectory, appCoroutineScope = backgroundScope, @@ -57,4 +66,5 @@ fun TestScope.createRustMatrixClientFactory( timelineEventTypeFilterFactory = FakeTimelineEventTypeFilterFactory(), clientBuilderProvider = clientBuilderProvider, sqliteStoreBuilderProvider = FakeSqliteStoreBuilderProvider(), + workManagerScheduler = workManagerScheduler, ) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt index c81d9f1c15..3c8619ed72 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt @@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.test.A_USER_NAME import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.test.InMemorySessionStore import io.element.android.libraries.sessionstorage.test.aSessionData +import io.element.android.libraries.workmanager.test.FakeWorkManagerScheduler import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.toolbox.test.systemclock.FakeSystemClock import io.element.android.tests.testutils.lambda.lambdaRecorder @@ -116,5 +117,6 @@ class RustMatrixClientTest { timelineEventTypeFilterFactory = FakeTimelineEventTypeFilterFactory(), featureFlagService = FakeFeatureFlagService(), analyticsService = FakeAnalyticsService(), + workManagerScheduler = FakeWorkManagerScheduler(submitLambda = {}), ) } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 940cce6164..38d4d1aefe 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -104,6 +104,7 @@ class FakeMatrixClient( private val getRecentEmojisLambda: () -> Result> = { Result.success(emptyList()) }, private val addRecentEmojiLambda: (String) -> Result = { Result.success(Unit) }, private val markRoomAsFullyReadResult: (RoomId, EventId) -> Result = { _, _ -> lambdaError() }, + private val performDatabaseVacuumLambda: () -> Result = { lambdaError() }, ) : MatrixClient { var setDisplayNameCalled: Boolean = false private set @@ -351,4 +352,8 @@ class FakeMatrixClient( override suspend fun markRoomAsFullyRead(roomId: RoomId, eventId: EventId): Result { return markRoomAsFullyReadResult(roomId, eventId) } + + override suspend fun performDatabaseVacuum(): Result { + return performDatabaseVacuumLambda() + } } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationResolverQueue.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationResolverQueue.kt index 0d1478cb9e..b40b3fe79f 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationResolverQueue.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationResolverQueue.kt @@ -17,7 +17,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.push.api.push.NotificationEventRequest import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent import io.element.android.libraries.push.impl.workmanager.SyncNotificationWorkManagerRequest -import io.element.android.libraries.push.impl.workmanager.WorkerDataConverter +import io.element.android.libraries.push.impl.workmanager.SyncNotificationsWorkerDataConverter import io.element.android.libraries.workmanager.api.WorkManagerScheduler import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider import kotlinx.coroutines.CoroutineScope @@ -50,7 +50,7 @@ class DefaultNotificationResolverQueue( private val appCoroutineScope: CoroutineScope, private val workManagerScheduler: WorkManagerScheduler, private val featureFlagService: FeatureFlagService, - private val workerDataConverter: WorkerDataConverter, + private val workerDataConverter: SyncNotificationsWorkerDataConverter, private val buildVersionSdkIntProvider: BuildVersionSdkIntProvider, ) : NotificationResolverQueue { companion object { diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationsWorker.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationsWorker.kt index ccc0a02749..eeac5ff66f 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationsWorker.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationsWorker.kt @@ -49,7 +49,7 @@ class FetchNotificationsWorker( private val workManagerScheduler: WorkManagerScheduler, private val syncOnNotifiableEvent: SyncOnNotifiableEvent, private val coroutineDispatchers: CoroutineDispatchers, - private val workerDataConverter: WorkerDataConverter, + private val workerDataConverter: SyncNotificationsWorkerDataConverter, private val buildVersionSdkIntProvider: BuildVersionSdkIntProvider, ) : CoroutineWorker(context, workerParams) { override suspend fun doWork(): Result = withContext(coroutineDispatchers.io) { diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationWorkManagerRequest.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationWorkManagerRequest.kt index b11b83d6e4..50ef28903c 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationWorkManagerRequest.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationWorkManagerRequest.kt @@ -26,7 +26,7 @@ import java.security.InvalidParameterException class SyncNotificationWorkManagerRequest( private val sessionId: SessionId, private val notificationEventRequests: List, - private val workerDataConverter: WorkerDataConverter, + private val workerDataConverter: SyncNotificationsWorkerDataConverter, private val buildVersionSdkIntProvider: BuildVersionSdkIntProvider, ) : WorkManagerRequest { override fun build(): Result> { diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/WorkerDataConverter.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationsWorkerDataConverter.kt similarity index 99% rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/WorkerDataConverter.kt rename to libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationsWorkerDataConverter.kt index 23e66396c6..46b7d760c0 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/WorkerDataConverter.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationsWorkerDataConverter.kt @@ -21,7 +21,7 @@ import io.element.android.libraries.push.api.push.NotificationEventRequest import timber.log.Timber @Inject -class WorkerDataConverter( +class SyncNotificationsWorkerDataConverter( private val json: JsonProvider, ) { fun serialize(notificationEventRequests: List): Result> { diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlerTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlerTest.kt index 89b8c0d319..7c95034985 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlerTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlerTest.kt @@ -47,7 +47,7 @@ import io.element.android.libraries.push.impl.notifications.model.NotifiableEven import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent import io.element.android.libraries.push.impl.test.DefaultTestPush import io.element.android.libraries.push.impl.troubleshoot.DiagnosticPushHandler -import io.element.android.libraries.push.impl.workmanager.WorkerDataConverter +import io.element.android.libraries.push.impl.workmanager.SyncNotificationsWorkerDataConverter import io.element.android.libraries.pushproviders.api.PushData import io.element.android.libraries.pushstore.api.UserPushStore import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret @@ -718,7 +718,7 @@ class DefaultPushHandlerTest { appCoroutineScope = backgroundScope, workManagerScheduler = workManagerScheduler, featureFlagService = featureFlagService, - workerDataConverter = WorkerDataConverter(DefaultJsonProvider()), + workerDataConverter = SyncNotificationsWorkerDataConverter(DefaultJsonProvider()), buildVersionSdkIntProvider = FakeBuildVersionSdkIntProvider(33), ), appCoroutineScope = backgroundScope, diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationWorkerTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationWorkerTest.kt index 23a38db66c..d40ef17b53 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationWorkerTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/FetchNotificationWorkerTest.kt @@ -177,7 +177,7 @@ class FetchNotificationWorkerTest { workManagerScheduler = workManagerScheduler, syncOnNotifiableEvent = syncOnNotifiableEvent, coroutineDispatchers = testCoroutineDispatchers(), - workerDataConverter = WorkerDataConverter(DefaultJsonProvider()), + workerDataConverter = SyncNotificationsWorkerDataConverter(DefaultJsonProvider()), buildVersionSdkIntProvider = FakeBuildVersionSdkIntProvider(33), ) diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationWorkManagerRequestTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationWorkManagerRequestTest.kt index 9dae435a9a..1f8d646e2b 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationWorkManagerRequestTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/SyncNotificationWorkManagerRequestTest.kt @@ -78,7 +78,7 @@ class SyncNotificationWorkManagerRequestTest { val request = createSyncNotificationWorkManagerRequest( sessionId = A_SESSION_ID, notificationEventRequests = listOf(aNotificationEventRequest()), - workerDataConverter = WorkerDataConverter({ error("error during serialization") }) + workerDataConverter = SyncNotificationsWorkerDataConverter({ error("error during serialization") }) ) val result = request.build() assertThat(result.isFailure).isTrue() @@ -88,7 +88,7 @@ class SyncNotificationWorkManagerRequestTest { private fun createSyncNotificationWorkManagerRequest( sessionId: SessionId, notificationEventRequests: List, - workerDataConverter: WorkerDataConverter = WorkerDataConverter(DefaultJsonProvider()), + workerDataConverter: SyncNotificationsWorkerDataConverter = SyncNotificationsWorkerDataConverter(DefaultJsonProvider()), sdkVersion: Int = 33, ) = SyncNotificationWorkManagerRequest( sessionId = sessionId, diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/WorkerDataConverterTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/WorkerDataConverterTest.kt index 6c6998cb35..85b55e0d62 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/WorkerDataConverterTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/workmanager/WorkerDataConverterTest.kt @@ -57,10 +57,10 @@ class WorkerDataConverterTest { providerInfo = "info$it", ) } - val sut = WorkerDataConverter(DefaultJsonProvider()) + val sut = SyncNotificationsWorkerDataConverter(DefaultJsonProvider()) val serialized = sut.serialize(data) assertThat(serialized.getOrNull()?.size).isGreaterThan(1) - assertThat(serialized.getOrNull()?.size).isEqualTo(100 / WorkerDataConverter.CHUNK_SIZE) + assertThat(serialized.getOrNull()?.size).isEqualTo(100 / SyncNotificationsWorkerDataConverter.CHUNK_SIZE) // All the items are present val deserialized = serialized.getOrNull()?.flatMap { sut.deserialize(it)!! } assertThat(deserialized).containsExactlyElementsIn(data) @@ -76,10 +76,10 @@ class WorkerDataConverterTest { providerInfo = "info$it", ) } - val sut = WorkerDataConverter(DefaultJsonProvider()) + val sut = SyncNotificationsWorkerDataConverter(DefaultJsonProvider()) val serialized = sut.serialize(data) assertThat(serialized.getOrNull()?.size).isGreaterThan(1) - assertThat(serialized.getOrNull()?.size).isEqualTo(100 / WorkerDataConverter.CHUNK_SIZE + 1) + assertThat(serialized.getOrNull()?.size).isEqualTo(100 / SyncNotificationsWorkerDataConverter.CHUNK_SIZE + 1) // All the items are present val deserialized = serialized.getOrNull()?.flatMap { sut.deserialize(it)!! } assertThat(deserialized).containsExactlyElementsIn(data) @@ -112,7 +112,7 @@ class WorkerDataConverterTest { ) } val data = (data1 + data2 + data3).shuffled() - val sut = WorkerDataConverter(DefaultJsonProvider()) + val sut = SyncNotificationsWorkerDataConverter(DefaultJsonProvider()) val serialized = sut.serialize(data) assertThat(serialized.getOrNull()?.size).isEqualTo(2) // All the items are present @@ -133,7 +133,7 @@ class WorkerDataConverterTest { } private fun testIdentity(data: List) { - val sut = WorkerDataConverter(DefaultJsonProvider()) + val sut = SyncNotificationsWorkerDataConverter(DefaultJsonProvider()) val serialized = sut.serialize(data).getOrThrow() val result = sut.deserialize(serialized.first()) assertThat(result).isEqualTo(data) diff --git a/libraries/workmanager/api/src/main/kotlin/io/element/android/libraries/workmanager/api/WorkManagerScheduler.kt b/libraries/workmanager/api/src/main/kotlin/io/element/android/libraries/workmanager/api/WorkManagerScheduler.kt index b385f0b2fb..b538486d35 100644 --- a/libraries/workmanager/api/src/main/kotlin/io/element/android/libraries/workmanager/api/WorkManagerScheduler.kt +++ b/libraries/workmanager/api/src/main/kotlin/io/element/android/libraries/workmanager/api/WorkManagerScheduler.kt @@ -12,16 +12,19 @@ import io.element.android.libraries.matrix.api.core.SessionId interface WorkManagerScheduler { fun submit(workManagerRequest: WorkManagerRequest) + fun hasPendingWork(sessionId: SessionId, requestType: WorkManagerRequestType): Boolean fun cancel(sessionId: SessionId) } fun workManagerTag(sessionId: SessionId, requestType: WorkManagerRequestType): String { val prefix = when (requestType) { WorkManagerRequestType.NOTIFICATION_SYNC -> "notifications" + WorkManagerRequestType.DB_VACUUM -> "db_vacuum" } return "$prefix-$sessionId" } enum class WorkManagerRequestType { NOTIFICATION_SYNC, + DB_VACUUM, } diff --git a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt index e5bd67c604..9a96d2ae73 100644 --- a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt +++ b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt @@ -11,6 +11,7 @@ package io.element.android.libraries.workmanager.impl import androidx.work.WorkManager import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.core.bool.orFalse import dev.zacsweers.metro.SingleIn import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.sessionstorage.api.observer.SessionListener @@ -51,6 +52,10 @@ class DefaultWorkManagerScheduler( ) } + override fun hasPendingWork(sessionId: SessionId, requestType: WorkManagerRequestType): Boolean { + return workManager.getWorkInfosByTag(workManagerTag(sessionId, requestType)).get()?.isNotEmpty().orFalse() + } + override fun cancel(sessionId: SessionId) { Timber.d("Cancelling work for sessionId: $sessionId") for (requestType in WorkManagerRequestType.entries) { diff --git a/libraries/workmanager/test/src/main/kotlin/io/element/android/libraries/workmanager/test/FakeWorkManagerScheduler.kt b/libraries/workmanager/test/src/main/kotlin/io/element/android/libraries/workmanager/test/FakeWorkManagerScheduler.kt index 94ee826ddc..f2caa8c743 100644 --- a/libraries/workmanager/test/src/main/kotlin/io/element/android/libraries/workmanager/test/FakeWorkManagerScheduler.kt +++ b/libraries/workmanager/test/src/main/kotlin/io/element/android/libraries/workmanager/test/FakeWorkManagerScheduler.kt @@ -10,17 +10,23 @@ package io.element.android.libraries.workmanager.test import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.workmanager.api.WorkManagerRequest +import io.element.android.libraries.workmanager.api.WorkManagerRequestType import io.element.android.libraries.workmanager.api.WorkManagerScheduler import io.element.android.tests.testutils.lambda.lambdaError class FakeWorkManagerScheduler( private val submitLambda: (WorkManagerRequest) -> Unit = { lambdaError() }, + private val hasPendingWorkLambda: (SessionId, WorkManagerRequestType) -> Boolean = { _, _ -> false }, private val cancelLambda: (SessionId) -> Unit = { lambdaError() }, ) : WorkManagerScheduler { override fun submit(workManagerRequest: WorkManagerRequest) { submitLambda(workManagerRequest) } + override fun hasPendingWork(sessionId: SessionId, requestType: WorkManagerRequestType): Boolean { + return hasPendingWorkLambda(sessionId, requestType) + } + override fun cancel(sessionId: SessionId) { cancelLambda(sessionId) } From 6887ca06d732d52849efa2e09da72c2e07f631f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 9 Dec 2025 10:11:54 +0100 Subject: [PATCH 093/347] Fix lint issues --- .../libraries/workmanager/impl/DefaultWorkManagerScheduler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt index 9a96d2ae73..476e5995a8 100644 --- a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt +++ b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt @@ -11,8 +11,8 @@ package io.element.android.libraries.workmanager.impl import androidx.work.WorkManager import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding -import io.element.android.libraries.core.bool.orFalse import dev.zacsweers.metro.SingleIn +import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.sessionstorage.api.observer.SessionListener import io.element.android.libraries.sessionstorage.api.observer.SessionObserver From d78e28be5e642a44a64022ed3c540fe336c527b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 9 Dec 2025 13:50:21 +0100 Subject: [PATCH 094/347] Make sure we schedule the vacuum task only if there isn't an existing one --- .../matrix/impl/workmanager/VacuumDatabaseWorker.kt | 12 ++++++++++-- .../workmanager/impl/DefaultWorkManagerScheduler.kt | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt index 0602c2fdc2..c6f1b32405 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt @@ -15,6 +15,7 @@ import dev.zacsweers.metro.AssistedInject import io.element.android.libraries.di.annotations.ApplicationContext import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.core.SessionId +import timber.log.Timber @AssistedInject class VacuumDatabaseWorker( @@ -27,12 +28,19 @@ class VacuumDatabaseWorker( } override suspend fun doWork(): Result { + Timber.d("Starting database vacuuming...") val sessionId = inputData.getString(SESSION_ID_PARAM)?.let(::SessionId) ?: return Result.failure() val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return Result.failure() return client.performDatabaseVacuum() .fold( - onSuccess = { Result.success() }, - onFailure = { Result.failure() } + onSuccess = { + Timber.d("Database vacuuming finished successfully") + Result.success() + }, + onFailure = { + Timber.e(it, "Database vacuuming failed") + Result.failure() + } ) } } diff --git a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt index 476e5995a8..ce16e323de 100644 --- a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt +++ b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt @@ -12,7 +12,6 @@ import androidx.work.WorkManager import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.SingleIn -import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.sessionstorage.api.observer.SessionListener import io.element.android.libraries.sessionstorage.api.observer.SessionObserver @@ -53,7 +52,9 @@ class DefaultWorkManagerScheduler( } override fun hasPendingWork(sessionId: SessionId, requestType: WorkManagerRequestType): Boolean { - return workManager.getWorkInfosByTag(workManagerTag(sessionId, requestType)).get()?.isNotEmpty().orFalse() + val workInfos = workManager.getWorkInfosByTag(workManagerTag(sessionId, requestType)).get().orEmpty() + // It has pending work if it's periodic or it isn't but it's not finished + return workInfos.any { it.periodicityInfo != null || !it.state.isFinished } } override fun cancel(sessionId: SessionId) { From 09cab10abc65a542cf624eb4f901f253703c425f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 9 Dec 2025 15:17:45 +0100 Subject: [PATCH 095/347] Fix dependency injection --- .../matrix/impl/workmanager/VacuumDatabaseWorker.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt index c6f1b32405..2f799b362b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt @@ -10,11 +10,17 @@ package io.element.android.libraries.matrix.impl.workmanager import android.content.Context import androidx.work.CoroutineWorker import androidx.work.WorkerParameters +import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject +import dev.zacsweers.metro.ContributesIntoMap +import dev.zacsweers.metro.binding import io.element.android.libraries.di.annotations.ApplicationContext import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.workmanager.api.di.MetroWorkerFactory +import io.element.android.libraries.workmanager.api.di.WorkerKey import timber.log.Timber @AssistedInject @@ -43,4 +49,9 @@ class VacuumDatabaseWorker( } ) } + + @ContributesIntoMap(AppScope::class, binding = binding>()) + @WorkerKey(VacuumDatabaseWorker::class) + @AssistedFactory + interface Factory : MetroWorkerFactory.WorkerInstanceFactory } From 7e3acd6b58c4f0cf5a47c11900902e65b36e3ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 10 Dec 2025 08:17:57 +0100 Subject: [PATCH 096/347] Add Sentry transaction so we can check how long it takes to vacuum and if there were any errors when doing it --- .../impl/workmanager/VacuumDatabaseWorker.kt | 28 +++++++++++-------- .../analytics/api/NoopAnalyticsTransaction.kt | 1 + .../api/AnalyticsTransaction.kt | 1 + .../sentry/SentryAnalyticsTransaction.kt | 3 ++ 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt index 2f799b362b..d52edddbb4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/workmanager/VacuumDatabaseWorker.kt @@ -21,6 +21,8 @@ import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.workmanager.api.di.MetroWorkerFactory import io.element.android.libraries.workmanager.api.di.WorkerKey +import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.recordTransaction import timber.log.Timber @AssistedInject @@ -28,6 +30,7 @@ class VacuumDatabaseWorker( @Assisted workerParams: WorkerParameters, @ApplicationContext private val context: Context, private val matrixClientProvider: MatrixClientProvider, + private val analyticsService: AnalyticsService, ) : CoroutineWorker(context, workerParams) { companion object { const val SESSION_ID_PARAM = "session_id" @@ -37,17 +40,20 @@ class VacuumDatabaseWorker( Timber.d("Starting database vacuuming...") val sessionId = inputData.getString(SESSION_ID_PARAM)?.let(::SessionId) ?: return Result.failure() val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return Result.failure() - return client.performDatabaseVacuum() - .fold( - onSuccess = { - Timber.d("Database vacuuming finished successfully") - Result.success() - }, - onFailure = { - Timber.e(it, "Database vacuuming failed") - Result.failure() - } - ) + return analyticsService.recordTransaction("Vacuuming DBs", "vacuuming") { transaction -> + client.performDatabaseVacuum() + .fold( + onSuccess = { + Timber.d("Database vacuuming finished successfully") + Result.success() + }, + onFailure = { error -> + transaction.attachError(error) + Timber.e(error, "Database vacuuming failed") + Result.failure() + } + ) + } } @ContributesIntoMap(AppScope::class, binding = binding>()) diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt index 024a7ac05e..e6f69ae99b 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt @@ -14,5 +14,6 @@ object NoopAnalyticsTransaction : AnalyticsTransaction { override fun setData(key: String, value: Any) {} override fun isFinished(): Boolean = true override fun traceId(): String? = null + override fun attachError(throwable: Throwable) {} override fun finish() {} } diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt index ea63a7f167..84575d5dd0 100644 --- a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt @@ -12,6 +12,7 @@ interface AnalyticsTransaction { fun setData(key: String, value: Any) fun isFinished(): Boolean fun traceId(): String? + fun attachError(throwable: Throwable) fun finish() } diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt index 75872b7d44..77a008b0a4 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt @@ -23,6 +23,9 @@ class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTra override fun setData(key: String, value: Any) = inner.setData(key, value) override fun traceId(): String? = inner.toSentryTrace().value override fun isFinished(): Boolean = inner.isFinished + override fun attachError(throwable: Throwable) { + inner.throwable = throwable + } override fun finish() { val name = if (inner is ITransaction) inner.name else inner.operation Timber.d("Finishing transaction: $name") From 1e52e1139fba1aca296a08035352fa59871854ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 10 Dec 2025 13:22:39 +0100 Subject: [PATCH 097/347] Tweak the `DefaultWorkManagerScheduler.hasPendingWork` logic --- .../workmanager/impl/DefaultWorkManagerScheduler.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt index ce16e323de..4f3806db62 100644 --- a/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt +++ b/libraries/workmanager/impl/src/main/kotlin/io/element/android/libraries/workmanager/impl/DefaultWorkManagerScheduler.kt @@ -8,6 +8,7 @@ package io.element.android.libraries.workmanager.impl +import androidx.work.WorkInfo import androidx.work.WorkManager import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding @@ -53,8 +54,14 @@ class DefaultWorkManagerScheduler( override fun hasPendingWork(sessionId: SessionId, requestType: WorkManagerRequestType): Boolean { val workInfos = workManager.getWorkInfosByTag(workManagerTag(sessionId, requestType)).get().orEmpty() - // It has pending work if it's periodic or it isn't but it's not finished - return workInfos.any { it.periodicityInfo != null || !it.state.isFinished } + return workInfos.any { info -> + val isPeriodic = info.periodicityInfo != null + val isCancelled = info.state == WorkInfo.State.CANCELLED + // It has pending work if: + // - It's not periodic and is not finished. + // - It's periodic and is not cancelled - since it'll be run again in a next iteration otherwise + !isPeriodic && !info.state.isFinished || isPeriodic && !isCancelled + } } override fun cancel(sessionId: SessionId) { From 03dd89a77ffdda854d8018639909daa2d2762b49 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 10 Dec 2025 15:16:00 +0100 Subject: [PATCH 098/347] change(room permissions): support space management --- .../impl/analytics/AnalyticUtils.kt | 4 ++-- .../ChangeRoomPermissionsPresenter.kt | 16 +++++++++++----- .../permissions/ChangeRoomPermissionsState.kt | 12 ++++++++---- .../ChangeRoomPermissionsStateProvider.kt | 3 ++- .../permissions/ChangeRoomPermissionsView.kt | 10 ++++++---- .../ChangeRoomPermissionsPresenterTest.kt | 5 +++-- .../permissions/ChangeRoomPermissionsViewTest.kt | 2 +- .../room/powerlevels/RoomPowerLevelsValues.kt | 3 ++- .../libraries/matrix/impl/room/JoinedRustRoom.kt | 4 +++- .../powerlevels/RoomPowerLevelsValuesMapper.kt | 3 ++- .../RoomPowerLevelsValuesMapperTest.kt | 3 ++- .../libraries/matrix/test/room/FakeBaseRoom.kt | 11 ++++++----- 12 files changed, 48 insertions(+), 28 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/analytics/AnalyticUtils.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/analytics/AnalyticUtils.kt index 9963a751f1..546d54c21a 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/analytics/AnalyticUtils.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/analytics/AnalyticUtils.kt @@ -34,8 +34,8 @@ internal fun AnalyticsService.trackPermissionChangeAnalytics(initial: RoomPowerL if (updated.kick != initial?.kick) { capture(RoomModeration(RoomModeration.Action.ChangePermissionsKickMembers, analyticsMemberRoleForPowerLevel(updated.kick))) } - if (updated.sendEvents != initial?.sendEvents) { - capture(RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, analyticsMemberRoleForPowerLevel(updated.sendEvents))) + if (updated.eventsDefault != initial?.eventsDefault) { + capture(RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, analyticsMemberRoleForPowerLevel(updated.eventsDefault))) } if (updated.redactEvents != initial?.redactEvents) { capture(RoomModeration(RoomModeration.Action.ChangePermissionsRedactMessages, analyticsMemberRoleForPowerLevel(updated.redactEvents))) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt index 99f5723bf9..c0e659ac04 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt @@ -36,8 +36,7 @@ class ChangeRoomPermissionsPresenter( ) : Presenter { companion object { private fun itemsForSection(section: RoomPermissionsSection) = when (section) { - RoomPermissionsSection.SpaceDetails, - RoomPermissionsSection.RoomDetails -> persistentListOf( + RoomPermissionsSection.EditDetails -> persistentListOf( RoomPermissionType.ROOM_NAME, RoomPermissionType.ROOM_AVATAR, RoomPermissionType.ROOM_TOPIC, @@ -51,14 +50,19 @@ class ChangeRoomPermissionsPresenter( RoomPermissionType.KICK, RoomPermissionType.BAN, ) + RoomPermissionsSection.ManageSpace -> persistentListOf( + RoomPermissionType.SPACE_MANAGE_ROOMS, + RoomPermissionType.CHANGE_SETTINGS, + ) + } private fun RoomPermissionsSection.shouldShow(isSpace: Boolean): Boolean { return when (this) { - RoomPermissionsSection.RoomDetails -> !isSpace + RoomPermissionsSection.EditDetails -> true RoomPermissionsSection.MembershipModeration -> true RoomPermissionsSection.MessagesAndContent -> !isSpace - RoomPermissionsSection.SpaceDetails -> isSpace + RoomPermissionsSection.ManageSpace -> isSpace } } @@ -99,11 +103,13 @@ class ChangeRoomPermissionsPresenter( RoomPermissionType.BAN -> currentPermissions?.copy(ban = powerLevel) RoomPermissionType.INVITE -> currentPermissions?.copy(invite = powerLevel) RoomPermissionType.KICK -> currentPermissions?.copy(kick = powerLevel) - RoomPermissionType.SEND_EVENTS -> currentPermissions?.copy(sendEvents = powerLevel) + RoomPermissionType.SEND_EVENTS -> currentPermissions?.copy(eventsDefault = powerLevel) RoomPermissionType.REDACT_EVENTS -> currentPermissions?.copy(redactEvents = powerLevel) RoomPermissionType.ROOM_NAME -> currentPermissions?.copy(roomName = powerLevel) RoomPermissionType.ROOM_AVATAR -> currentPermissions?.copy(roomAvatar = powerLevel) RoomPermissionType.ROOM_TOPIC -> currentPermissions?.copy(roomTopic = powerLevel) + RoomPermissionType.SPACE_MANAGE_ROOMS -> currentPermissions?.copy(spaceChild = powerLevel) + RoomPermissionType.CHANGE_SETTINGS -> currentPermissions?.copy(stateDefault = powerLevel) } } is ChangeRoomPermissionsEvent.Save -> coroutineScope.save() diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt index 0dde54db89..817be2a405 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt @@ -32,11 +32,13 @@ data class ChangeRoomPermissionsState( RoomPermissionType.BAN -> RoomMember.Role.forPowerLevel(currentPermissions.ban) RoomPermissionType.INVITE -> RoomMember.Role.forPowerLevel(currentPermissions.invite) RoomPermissionType.KICK -> RoomMember.Role.forPowerLevel(currentPermissions.kick) - RoomPermissionType.SEND_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.sendEvents) + RoomPermissionType.SEND_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.eventsDefault) RoomPermissionType.REDACT_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.redactEvents) RoomPermissionType.ROOM_NAME -> RoomMember.Role.forPowerLevel(currentPermissions.roomName) RoomPermissionType.ROOM_AVATAR -> RoomMember.Role.forPowerLevel(currentPermissions.roomAvatar) RoomPermissionType.ROOM_TOPIC -> RoomMember.Role.forPowerLevel(currentPermissions.roomTopic) + RoomPermissionType.SPACE_MANAGE_ROOMS -> RoomMember.Role.forPowerLevel(currentPermissions.spaceChild) + RoomPermissionType.CHANGE_SETTINGS -> RoomMember.Role.forPowerLevel(currentPermissions.stateDefault) } return when (role) { is RoomMember.Role.Owner, @@ -48,10 +50,10 @@ data class ChangeRoomPermissionsState( } enum class RoomPermissionsSection { - SpaceDetails, - RoomDetails, + EditDetails, MessagesAndContent, MembershipModeration, + ManageSpace } enum class SelectableRole : DropdownOption { @@ -80,5 +82,7 @@ enum class RoomPermissionType { REDACT_EVENTS, ROOM_NAME, ROOM_AVATAR, - ROOM_TOPIC + ROOM_TOPIC, + SPACE_MANAGE_ROOMS, + CHANGE_SETTINGS, } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt index 6280e4fd8f..b44bfc5075 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt @@ -51,12 +51,13 @@ private fun previewPermissions(): RoomPowerLevelsValues { ban = RoomMember.Role.User.powerLevel, // MessagesAndContent section redactEvents = RoomMember.Role.Moderator.powerLevel, - sendEvents = RoomMember.Role.Admin.powerLevel, + eventsDefault = RoomMember.Role.Admin.powerLevel, // RoomDetails section roomName = RoomMember.Role.Admin.powerLevel, roomAvatar = RoomMember.Role.Moderator.powerLevel, roomTopic = RoomMember.Role.User.powerLevel, // SpaceManagement section spaceChild = RoomMember.Role.Moderator.powerLevel, + stateDefault = RoomMember.Role.Moderator.powerLevel, ) } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt index 5ae8203eb4..fa3552673e 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt @@ -110,10 +110,10 @@ fun ChangeRoomPermissionsView( @Composable private fun titleForSection(section: RoomPermissionsSection): String = when (section) { - RoomPermissionsSection.SpaceDetails -> stringResource(R.string.screen_room_roles_and_permissions_space_details) - RoomPermissionsSection.RoomDetails -> stringResource(R.string.screen_room_roles_and_permissions_room_details) - RoomPermissionsSection.MessagesAndContent -> stringResource(R.string.screen_room_roles_and_permissions_messages_and_content) - RoomPermissionsSection.MembershipModeration -> stringResource(R.string.screen_room_roles_and_permissions_member_moderation) + RoomPermissionsSection.EditDetails -> stringResource(R.string.screen_room_change_permissions_room_details) + RoomPermissionsSection.MessagesAndContent -> stringResource(R.string.screen_room_change_permissions_messages_and_content) + RoomPermissionsSection.MembershipModeration -> stringResource(R.string.screen_room_change_permissions_member_moderation) + RoomPermissionsSection.ManageSpace -> stringResource(R.string.screen_room_change_permissions_manage_space) } @Composable @@ -126,6 +126,8 @@ private fun titleForType(type: RoomPermissionType): String = when (type) { RoomPermissionType.ROOM_NAME -> stringResource(R.string.screen_room_change_permissions_room_name) RoomPermissionType.ROOM_AVATAR -> stringResource(R.string.screen_room_change_permissions_room_avatar) RoomPermissionType.ROOM_TOPIC -> stringResource(R.string.screen_room_change_permissions_room_topic) + RoomPermissionType.SPACE_MANAGE_ROOMS -> stringResource(R.string.screen_room_change_permissions_manage_space_rooms) + RoomPermissionType.CHANGE_SETTINGS -> stringResource(R.string.screen_room_change_permissions_change_settings) } @PreviewsDayNight diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt index d666ec3ccc..2fb48bf6a4 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt @@ -53,7 +53,7 @@ class ChangeRoomPermissionsPresenterTest { presenter.present() }.test { val itemsBySection = awaitUpdatedItem().itemsBySection - assertThat(itemsBySection[RoomPermissionsSection.RoomDetails]).containsExactly( + assertThat(itemsBySection[RoomPermissionsSection.EditDetails]).containsExactly( RoomPermissionType.ROOM_NAME, RoomPermissionType.ROOM_AVATAR, RoomPermissionType.ROOM_TOPIC, @@ -115,8 +115,9 @@ class ChangeRoomPermissionsPresenterTest { invite = Moderator.powerLevel, kick = Moderator.powerLevel, ban = Moderator.powerLevel, + stateDefault = Moderator.powerLevel, redactEvents = Moderator.powerLevel, - sendEvents = Moderator.powerLevel, + eventsDefault = Moderator.powerLevel, roomName = Moderator.powerLevel, roomAvatar = Moderator.powerLevel, roomTopic = Moderator.powerLevel, diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt index 6b637efbed..f28c9c150f 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsViewTest.kt @@ -104,7 +104,7 @@ class ChangeRoomPermissionsViewTest { state = aChangeRoomPermissionsState( itemsBySection = persistentMapOf( // Makes sure there is only one item to click on - RoomPermissionsSection.RoomDetails to persistentListOf(RoomPermissionType.ROOM_NAME) + RoomPermissionsSection.EditDetails to persistentListOf(RoomPermissionType.ROOM_NAME) ), eventSink = recorder, ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt index a7eebbb99c..e8f88ed86d 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt @@ -12,7 +12,8 @@ data class RoomPowerLevelsValues( val ban: Long, val invite: Long, val kick: Long, - val sendEvents: Long, + val eventsDefault: Long, + val stateDefault: Long, val redactEvents: Long, val roomName: Long, val roomAvatar: Long, 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 943b5ee1d5..770efb3918 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 @@ -397,10 +397,12 @@ class JoinedRustRoom( invite = roomPowerLevelsValues.invite, kick = roomPowerLevelsValues.kick, redact = roomPowerLevelsValues.redactEvents, - eventsDefault = roomPowerLevelsValues.sendEvents, + stateDefault = roomPowerLevelsValues.stateDefault, + eventsDefault = roomPowerLevelsValues.eventsDefault, roomName = roomPowerLevelsValues.roomName, roomAvatar = roomPowerLevelsValues.roomAvatar, roomTopic = roomPowerLevelsValues.roomTopic, + spaceChild = roomPowerLevelsValues.spaceChild, ) innerRoom.applyPowerLevelChanges(changes) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapper.kt index 081d08457e..5e2a1c82da 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapper.kt @@ -19,7 +19,8 @@ object RoomPowerLevelsValuesMapper { ban = values.ban, invite = values.invite, kick = values.kick, - sendEvents = values.eventsDefault, + eventsDefault = values.eventsDefault, + stateDefault = values.stateDefault, redactEvents = values.redact, roomName = values.roomName, roomAvatar = values.roomAvatar, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapperTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapperTest.kt index 3c100283a1..f298da8b42 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapperTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RoomPowerLevelsValuesMapperTest.kt @@ -37,8 +37,9 @@ class RoomPowerLevelsValuesMapperTest { ban = 1, invite = 2, kick = 3, - sendEvents = 5, redactEvents = 4, + eventsDefault = 5, + stateDefault = 6, roomName = 8, roomAvatar = 9, roomTopic = 10, diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt index b56066af73..78765d1ec4 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt @@ -211,10 +211,11 @@ fun defaultRoomPowerLevelValues() = RoomPowerLevelsValues( ban = 50, invite = 0, kick = 50, - sendEvents = 0, + eventsDefault = 0, + stateDefault = 50, redactEvents = 50, - roomName = 100, - roomAvatar = 100, - roomTopic = 100, - spaceChild = 100, + roomName = 50, + roomAvatar = 50, + roomTopic = 50, + spaceChild = 50, ) From a59b9c86e91680bf4ee4e871a7619faf64fe39af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 10 Dec 2025 13:09:00 +0100 Subject: [PATCH 099/347] URL-encode deep link path segments in `DefaultDeepLinkCreator` Decode them later in `DefaultDeepLinkParser` too --- .../libraries/androidutils/text/TextUtils.kt | 15 ++++++ .../deeplink/impl/DefaultDeepLinkCreator.kt | 9 ++-- .../deeplink/impl/DefaultDeeplinkParser.kt | 3 +- .../impl/DefaultDeepLinkCreatorTest.kt | 53 +++++++++++++++---- .../impl/DefaultDeeplinkParserTest.kt | 15 ++++++ 5 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/text/TextUtils.kt diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/text/TextUtils.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/text/TextUtils.kt new file mode 100644 index 0000000000..dde63e79a6 --- /dev/null +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/text/TextUtils.kt @@ -0,0 +1,15 @@ +/* + * 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.androidutils.text + +import java.net.URLDecoder +import java.net.URLEncoder +import java.nio.charset.Charset + +fun String.urlEncoded(charset: Charset = Charsets.UTF_8): String = URLEncoder.encode(this, charset.name()) +fun String.urlDecoded(charset: Charset = Charsets.UTF_8): String = URLDecoder.decode(this, charset.name()) diff --git a/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreator.kt b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreator.kt index 97c6eeda3f..95b7ccf116 100644 --- a/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreator.kt +++ b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreator.kt @@ -10,6 +10,7 @@ package io.element.android.libraries.deeplink.impl import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.androidutils.text.urlEncoded import io.element.android.libraries.deeplink.api.DeepLinkCreator import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId @@ -21,13 +22,13 @@ class DefaultDeepLinkCreator : DeepLinkCreator { override fun create(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?, eventId: EventId?): String { return buildString { append("$SCHEME://$HOST/") - append(sessionId.value) + append(sessionId.value.urlEncoded()) append("/") - append(roomId?.value.orEmpty()) + append(roomId?.value?.urlEncoded().orEmpty()) append("/") - append(threadId?.value.orEmpty()) + append(threadId?.value?.urlEncoded().orEmpty()) append("/") - append(eventId?.value.orEmpty()) + append(eventId?.value?.urlEncoded().orEmpty()) } // Remove all possible trailing '/' characters: // No event id diff --git a/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParser.kt b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParser.kt index ca1a39d5d0..8c865b6557 100644 --- a/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParser.kt +++ b/libraries/deeplink/impl/src/main/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParser.kt @@ -12,6 +12,7 @@ import android.content.Intent import android.net.Uri import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.androidutils.text.urlDecoded import io.element.android.libraries.deeplink.api.DeeplinkData import io.element.android.libraries.deeplink.api.DeeplinkParser import io.element.android.libraries.matrix.api.core.EventId @@ -31,7 +32,7 @@ class DefaultDeeplinkParser : DeeplinkParser { private fun Uri.toDeeplinkData(): DeeplinkData? { if (scheme != SCHEME) return null if (host != HOST) return null - val pathBits = path.orEmpty().split("/").drop(1) + val pathBits = encodedPath.orEmpty().split("/").drop(1).map { it.urlDecoded() } val sessionId = pathBits.elementAtOrNull(0)?.let(::SessionId) ?: return null return when (val screenPathComponent = pathBits.elementAtOrNull(1)) { diff --git a/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt index 4e3a10e861..ee01b20a8f 100644 --- a/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt +++ b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt @@ -9,6 +9,11 @@ package io.element.android.libraries.deeplink.impl import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.androidutils.text.urlEncoded +import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID @@ -19,15 +24,43 @@ class DefaultDeepLinkCreatorTest { @Test fun create() { val sut = DefaultDeepLinkCreator() - assertThat(sut.create(A_SESSION_ID, null, null, null)) - .isEqualTo("elementx://open/@alice:server.org") - assertThat(sut.create(A_SESSION_ID, A_ROOM_ID, null, null)) - .isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain") - assertThat(sut.create(A_SESSION_ID, A_ROOM_ID, A_THREAD_ID, null)) - .isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId") - assertThat(sut.create(A_SESSION_ID, A_ROOM_ID, A_THREAD_ID, AN_EVENT_ID)) - .isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId/\$anEventId") - assertThat(sut.create(A_SESSION_ID, A_ROOM_ID, null, AN_EVENT_ID)) - .isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain//\$anEventId") + val sessionId = A_SESSION_ID + val roomId = A_ROOM_ID + val threadId = A_THREAD_ID + val eventId = AN_EVENT_ID + assertThat(sut.create(sessionId, null, null, null)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}") + assertThat(sut.create(sessionId, roomId, null, null)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}") + assertThat(sut.create(sessionId, roomId, threadId, null)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}/${threadId.urlEncoded()}") + assertThat(sut.create(sessionId, roomId, threadId, eventId)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}/${threadId.urlEncoded()}/${eventId.urlEncoded()}") + assertThat(sut.create(sessionId, roomId, null, eventId)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}//${eventId.urlEncoded()}") + } + + @Test + fun `create - with escaped invalid characters`() { + val sut = DefaultDeepLinkCreator() + val sessionId = SessionId("@a/:domain") + val roomId = RoomId("!a/RoomId:domain") + val threadId = ThreadId("\$a/ThreadId") + val eventId = EventId("\$an/EventId") + assertThat(sut.create(sessionId, null, null, null)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}") + assertThat(sut.create(sessionId, roomId, null, null)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}") + assertThat(sut.create(sessionId, roomId, threadId, null)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}/${threadId.urlEncoded()}") + assertThat(sut.create(sessionId, roomId, threadId, eventId)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}/${threadId.urlEncoded()}/${eventId.urlEncoded()}") + assertThat(sut.create(sessionId, roomId, null, eventId)) + .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}//${eventId.urlEncoded()}") } } + +private fun SessionId.urlEncoded() = this.value.urlEncoded() +private fun RoomId.urlEncoded() = this.value.urlEncoded() +private fun ThreadId.urlEncoded() = this.value.urlEncoded() +private fun EventId.urlEncoded() = this.value.urlEncoded() diff --git a/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParserTest.kt b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParserTest.kt index 4b79f2b08c..7f563ddd7f 100644 --- a/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParserTest.kt +++ b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeeplinkParserTest.kt @@ -12,6 +12,10 @@ import android.content.Intent import androidx.core.net.toUri import com.google.common.truth.Truth.assertThat import io.element.android.libraries.deeplink.api.DeeplinkData +import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID @@ -34,6 +38,8 @@ class DefaultDeeplinkParserTest { "elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId/\$anEventId" const val A_URI_WITH_ROOM_WITH_EVENT_AND_NO_THREAD = "elementx://open/@alice:server.org/!aRoomId:domain//\$anEventId" + const val A_URI_WITH_ROOM_WITH_THREAD_AND_EVENT_AND_INVALID_CHARACTERS = + "elementx://open/@a%2Flice:server.org/!a%2FRoomId:domain/\$a%2FThreadId/\$an%2FEventId" } @Test @@ -49,6 +55,15 @@ class DefaultDeeplinkParserTest { .isEqualTo(DeeplinkData.Room(A_SESSION_ID, A_ROOM_ID, A_THREAD_ID, AN_EVENT_ID)) assertThat(sut.getFromIntent(createIntent(A_URI_WITH_ROOM_WITH_EVENT_AND_NO_THREAD))) .isEqualTo(DeeplinkData.Room(A_SESSION_ID, A_ROOM_ID, null, AN_EVENT_ID)) + assertThat(sut.getFromIntent(createIntent(A_URI_WITH_ROOM_WITH_THREAD_AND_EVENT_AND_INVALID_CHARACTERS))) + .isEqualTo( + DeeplinkData.Room( + sessionId = SessionId("@a/lice:server.org"), + roomId = RoomId("!a/RoomId:domain"), + threadId = ThreadId("\$a/ThreadId"), + eventId = EventId("\$an/EventId"), + ) + ) } @Test From fc9ba17f8498ca3119374d83269357baa3c58930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 10 Dec 2025 15:27:36 +0100 Subject: [PATCH 100/347] Use the raw expected string for `DefaultDeepLinkCreatorTest` cases --- .../impl/DefaultDeepLinkCreatorTest.kt | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt index ee01b20a8f..b27a645802 100644 --- a/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt +++ b/libraries/deeplink/impl/src/test/kotlin/io/element/android/libraries/deeplink/impl/DefaultDeepLinkCreatorTest.kt @@ -9,7 +9,6 @@ package io.element.android.libraries.deeplink.impl import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.androidutils.text.urlEncoded import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId @@ -29,15 +28,15 @@ class DefaultDeepLinkCreatorTest { val threadId = A_THREAD_ID val eventId = AN_EVENT_ID assertThat(sut.create(sessionId, null, null, null)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}") + .isEqualTo("elementx://open/%40alice%3Aserver.org") assertThat(sut.create(sessionId, roomId, null, null)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}") + .isEqualTo("elementx://open/%40alice%3Aserver.org/%21aRoomId%3Adomain") assertThat(sut.create(sessionId, roomId, threadId, null)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}/${threadId.urlEncoded()}") + .isEqualTo("elementx://open/%40alice%3Aserver.org/%21aRoomId%3Adomain/%24aThreadId") assertThat(sut.create(sessionId, roomId, threadId, eventId)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}/${threadId.urlEncoded()}/${eventId.urlEncoded()}") + .isEqualTo("elementx://open/%40alice%3Aserver.org/%21aRoomId%3Adomain/%24aThreadId/%24anEventId") assertThat(sut.create(sessionId, roomId, null, eventId)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}//${eventId.urlEncoded()}") + .isEqualTo("elementx://open/%40alice%3Aserver.org/%21aRoomId%3Adomain//%24anEventId") } @Test @@ -47,20 +46,13 @@ class DefaultDeepLinkCreatorTest { val roomId = RoomId("!a/RoomId:domain") val threadId = ThreadId("\$a/ThreadId") val eventId = EventId("\$an/EventId") - assertThat(sut.create(sessionId, null, null, null)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}") assertThat(sut.create(sessionId, roomId, null, null)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}") + .isEqualTo("elementx://open/%40a%2F%3Adomain/%21a%2FRoomId%3Adomain") assertThat(sut.create(sessionId, roomId, threadId, null)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}/${threadId.urlEncoded()}") + .isEqualTo("elementx://open/%40a%2F%3Adomain/%21a%2FRoomId%3Adomain/%24a%2FThreadId") assertThat(sut.create(sessionId, roomId, threadId, eventId)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}/${threadId.urlEncoded()}/${eventId.urlEncoded()}") + .isEqualTo("elementx://open/%40a%2F%3Adomain/%21a%2FRoomId%3Adomain/%24a%2FThreadId/%24an%2FEventId") assertThat(sut.create(sessionId, roomId, null, eventId)) - .isEqualTo("elementx://open/${sessionId.urlEncoded()}/${roomId.urlEncoded()}//${eventId.urlEncoded()}") + .isEqualTo("elementx://open/%40a%2F%3Adomain/%21a%2FRoomId%3Adomain//%24an%2FEventId") } } - -private fun SessionId.urlEncoded() = this.value.urlEncoded() -private fun RoomId.urlEncoded() = this.value.urlEncoded() -private fun ThreadId.urlEncoded() = this.value.urlEncoded() -private fun EventId.urlEncoded() = this.value.urlEncoded() From 287d0a38d71c07c120fc56cc9a72cf6ec07a3f6b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 13:18:28 +0000 Subject: [PATCH 101/347] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.12.10 --- 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 8245e730af..1ed3ea4f4e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -177,7 +177,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.4" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.10" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } From 289c0751d53dd7e58eccafc50d5496848434c6f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 10 Dec 2025 15:55:44 +0100 Subject: [PATCH 102/347] Fix broken API changes: use `Room.latestEvent`, which will keep its name, but it'll be using the logic previously in `Room.newLatestEvent` --- .../matrix/impl/roomlist/RoomSummaryFactory.kt | 2 +- .../matrix/impl/fixtures/fakes/FakeFfiRoom.kt | 10 ++-------- .../impl/roomlist/RoomSummaryListProcessorTest.kt | 3 +-- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt index 3d5efedd54..4872dc48e8 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt @@ -24,7 +24,7 @@ class RoomSummaryFactory( ) { suspend fun create(room: Room): RoomSummary { val roomInfo = room.roomInfo().let(roomInfoMapper::map) - val latestEvent = room.newLatestEvent().use { event -> + val latestEvent = room.latestEvent().use { event -> when (event) { is RustLatestEventValue.None -> LatestEventValue.None is RustLatestEventValue.Local -> LatestEventValue.Local( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoom.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoom.kt index 7b60a9f4c2..953e42b132 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoom.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoom.kt @@ -12,7 +12,6 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomInfo import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.tests.testutils.lambda.lambdaError -import org.matrix.rustcomponents.sdk.EventTimelineItem import org.matrix.rustcomponents.sdk.LatestEventValue import org.matrix.rustcomponents.sdk.NoHandle import org.matrix.rustcomponents.sdk.Room @@ -25,8 +24,7 @@ class FakeFfiRoom( private val getMembers: () -> RoomMembersIterator = { lambdaError() }, private val getMembersNoSync: () -> RoomMembersIterator = { lambdaError() }, private val leaveLambda: () -> Unit = { lambdaError() }, - private val latestEventLambda: () -> EventTimelineItem? = { lambdaError() }, - private val newLatestEventLambda: () -> LatestEventValue = { lambdaError() }, + private val latestEventLambda: () -> LatestEventValue = { lambdaError() }, private val suggestedRoleForUserLambda: (String) -> RoomMemberRole = { lambdaError() }, private val roomInfo: RoomInfo = aRustRoomInfo(id = roomId.value), ) : Room(NoHandle) { @@ -50,7 +48,7 @@ class FakeFfiRoom( return roomInfo } - override suspend fun latestEvent(): EventTimelineItem? { + override suspend fun latestEvent(): LatestEventValue { return latestEventLambda() } @@ -58,10 +56,6 @@ class FakeFfiRoom( return suggestedRoleForUserLambda(userId) } - override suspend fun newLatestEvent(): LatestEventValue { - return newLatestEventLambda() - } - override fun close() { // No-op } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt index 36d5b81f42..78c4f54626 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt @@ -174,8 +174,7 @@ class RoomSummaryListProcessorTest { private fun aRustRoom(roomId: RoomId = A_ROOM_ID) = FakeFfiRoom( roomId = roomId, - latestEventLambda = { null }, - newLatestEventLambda = { LatestEventValue.None } + latestEventLambda = { LatestEventValue.None } ) private fun TestScope.createProcessor() = RoomSummaryListProcessor( From 9723a7c426fef9f950e02ea16ea32100bece4925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 10 Dec 2025 15:55:52 +0100 Subject: [PATCH 103/347] Add missing trace log packs --- .../android/libraries/matrix/api/tracing/TraceLogPack.kt | 6 ++++++ .../libraries/matrix/impl/tracing/TraceLogPacksMapping.kt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TraceLogPack.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TraceLogPack.kt index 4f71f7309c..a0e5050a23 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TraceLogPack.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TraceLogPack.kt @@ -20,6 +20,12 @@ enum class TraceLogPack(val key: String) { }, NOTIFICATION_CLIENT("notification_client") { override val title: String = "Notification Client" + }, + SYNC_PROFILING("sync_profiling") { + override val title: String = "Sync Profiling" + }, + LATEST_EVENTS("latest_events") { + override val title = "Latest Events" }; abstract val title: String diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/TraceLogPacksMapping.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/TraceLogPacksMapping.kt index 0e26935b5a..ec70fc90f8 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/TraceLogPacksMapping.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/TraceLogPacksMapping.kt @@ -16,6 +16,8 @@ fun TraceLogPack.map(): RustTraceLogPack = when (this) { TraceLogPack.EVENT_CACHE -> RustTraceLogPack.EVENT_CACHE TraceLogPack.TIMELINE -> RustTraceLogPack.TIMELINE TraceLogPack.NOTIFICATION_CLIENT -> RustTraceLogPack.NOTIFICATION_CLIENT + TraceLogPack.LATEST_EVENTS -> RustTraceLogPack.LATEST_EVENTS + TraceLogPack.SYNC_PROFILING -> RustTraceLogPack.SYNC_PROFILING } fun Collection.map(): List { From 8d0e2e669e6f2b536b26b55b8d9f5b5247ee95c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 10 Dec 2025 16:40:53 +0100 Subject: [PATCH 104/347] Improve proguard config to keep the names in the classes in out packages --- app/proguard-rules.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 96109425fa..320db8c4c1 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -69,4 +69,4 @@ -keep class org.matrix.rustcomponents.sdk.** { *;} -keep class uniffi.** { *;} -keep class io.element.android.x.di.** { *; } --keepnames class io.element.android.x.** +-keepnames class io.element.android.** From cf00b799f23cc6a72f67931a16d522b7d0dff5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 11 Dec 2025 09:38:39 +0100 Subject: [PATCH 105/347] Make explicit we want to keep the member names too, but we want to allow optimization of the code and shrinking when methods aren't used --- app/proguard-rules.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 320db8c4c1..d915d67a25 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -69,4 +69,4 @@ -keep class org.matrix.rustcomponents.sdk.** { *;} -keep class uniffi.** { *;} -keep class io.element.android.x.di.** { *; } --keepnames class io.element.android.** +-keepclasseswithmembernames,allowoptimization,allowshrinking class io.element.android.** { *; } From 6e2863ded68f0c1e7fb4376745dade6a33a78267 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 11 Dec 2025 11:54:12 +0100 Subject: [PATCH 106/347] change(room permissions): fix securityAndPrivacy permissions computation --- .../roomdetails/impl/RoomDetailsPresenter.kt | 17 +++++---- .../api/SecurityAndPrivacyPermissions.kt | 18 +++++++--- .../space/impl/root/SpacePresenter.kt | 7 +++- .../impl/settings/SpaceSettingsPermissions.kt | 35 ++++++++++++------- .../impl/settings/SpaceSettingsPresenter.kt | 12 +++++-- 5 files changed, 62 insertions(+), 27 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index 83840ad604..07b76d41b9 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -19,6 +19,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import dev.zacsweers.metro.Inject import im.vector.app.features.analytics.plan.Interaction +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.features.knockrequests.api.knockRequestPermissions import io.element.android.features.leaveroom.api.LeaveRoomEvent import io.element.android.features.leaveroom.api.LeaveRoomState @@ -26,6 +27,7 @@ import io.element.android.features.roomcall.api.RoomCallState import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter import io.element.android.features.roomdetailsedit.api.RoomDetailsEditPermissions import io.element.android.features.roomdetailsedit.api.roomDetailsEditPermissions +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions import io.element.android.libraries.androidutils.clipboard.ClipboardHelper import io.element.android.libraries.architecture.Presenter @@ -119,7 +121,10 @@ class RoomDetailsPresenter( room.knockRequestsFlow.collect { value = it.size } } val canShowKnockRequests by remember { - derivedStateOf { isKnockRequestsEnabled && permissions.canManageKnockRequests && joinRule == JoinRule.Knock } + derivedStateOf { isKnockRequestsEnabled && permissions.knockRequestsPermissions.hasAny && joinRule == JoinRule.Knock } + } + val canShowSecurityAndPrivacy by remember { + derivedStateOf { !isDm && permissions.securityAndPrivacyPermissions.hasAny(isSpace = false, joinRule = joinRule) } } val isDeveloperModeEnabled by remember { appPreferencesStore.isDeveloperModeEnabledFlow() @@ -186,7 +191,7 @@ class RoomDetailsPresenter( snackbarMessage = snackbarMessage, canShowKnockRequests = canShowKnockRequests, knockRequestsCount = knockRequestsCount, - canShowSecurityAndPrivacy = !isDm && permissions.canEditSecurityAndPrivacy, + canShowSecurityAndPrivacy = canShowSecurityAndPrivacy, hasMemberVerificationViolations = hasMemberVerificationViolations, canReportRoom = canReportRoom, isTombstoned = roomInfo.successorRoom != null, @@ -221,9 +226,9 @@ class RoomDetailsPresenter( private data class Permissions( val canInvite: Boolean = false, val editDetailsPermissions: RoomDetailsEditPermissions = RoomDetailsEditPermissions.DEFAULT, - val canManageKnockRequests: Boolean = false, + val knockRequestsPermissions: KnockRequestPermissions = KnockRequestPermissions.DEFAULT, + val securityAndPrivacyPermissions: SecurityAndPrivacyPermissions = SecurityAndPrivacyPermissions.DEFAULT, val canEditRolesAndPermissions: Boolean = false, - val canEditSecurityAndPrivacy: Boolean = false, ) @Composable @@ -232,9 +237,9 @@ class RoomDetailsPresenter( Permissions( canInvite = perms.canOwnUserInvite(), editDetailsPermissions = perms.roomDetailsEditPermissions(), - canManageKnockRequests = perms.knockRequestPermissions().hasAny, + knockRequestsPermissions = perms.knockRequestPermissions(), canEditRolesAndPermissions = perms.canEditRolesAndPermissions(), - canEditSecurityAndPrivacy = perms.securityAndPrivacyPermissions().hasAny, + securityAndPrivacyPermissions = perms.securityAndPrivacyPermissions(), ) } } diff --git a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt index bacd863ca6..3601f2c4e6 100644 --- a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt +++ b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt @@ -9,6 +9,7 @@ package io.element.android.features.securityandprivacy.api import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions data class SecurityAndPrivacyPermissions( @@ -17,10 +18,19 @@ data class SecurityAndPrivacyPermissions( val canChangeEncryption: Boolean, val canChangeRoomVisibility: Boolean, ) { - val hasAny = canChangeRoomAccess || - canChangeHistoryVisibility || - canChangeEncryption || - canChangeRoomVisibility + fun hasAny(isSpace: Boolean, joinRule: JoinRule?): Boolean { + val canChangeRoomVisibility = when (joinRule) { + is JoinRule.Public, + is JoinRule.Knock, + is JoinRule.KnockRestricted -> canChangeRoomVisibility + else -> false + } + return if (isSpace) { + canChangeRoomAccess || canChangeRoomVisibility + } else { + canChangeRoomAccess || canChangeRoomVisibility || canChangeHistoryVisibility || canChangeEncryption + } + } companion object { val DEFAULT = SecurityAndPrivacyPermissions( diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt index 0794d02920..40a58ddbd9 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt @@ -11,6 +11,7 @@ package io.element.android.features.space.impl.root 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 import androidx.compose.runtime.remember @@ -94,6 +95,10 @@ class SpacePresenter( featureFlagService.isFeatureEnabledFlow(FeatureFlags.SpaceSettings) }.collectAsState(false) + val roomInfo by room.roomInfoFlow.collectAsState() + val canAccessSpaceSettings by remember { + derivedStateOf { isSpaceSettingsEnabled && permissions.hasAny(roomInfo.joinRule) } + } val currentSpace by spaceRoomList.currentSpaceFlow.collectAsState() val (joinActions, setJoinActions) = remember { mutableStateOf(emptyMap>()) } @@ -144,7 +149,7 @@ class SpacePresenter( joinActions = joinActions.toImmutableMap(), acceptDeclineInviteState = acceptDeclineInviteState, topicViewerState = topicViewerState, - canAccessSpaceSettings = isSpaceSettingsEnabled && permissions.hasAny, + canAccessSpaceSettings = canAccessSpaceSettings, eventSink = ::handleEvent, ) } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt index d7588b59e1..9a90435f77 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt @@ -7,32 +7,41 @@ package io.element.android.features.space.impl.settings +import io.element.android.features.roomdetailsedit.api.RoomDetailsEditPermissions import io.element.android.features.roomdetailsedit.api.roomDetailsEditPermissions +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions -import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions +import io.element.android.libraries.matrix.api.room.powerlevels.canEditRolesAndPermissions data class SpaceSettingsPermissions( - val canEditDetails: Boolean, - val canManageRolesAndPermissions: Boolean, - val canManageSecurityAndPrivacy: Boolean, -){ + val editDetailsPermissions: RoomDetailsEditPermissions, + val canEditRolesAndPermissions: Boolean, + val securityAndPrivacyPermissions: SecurityAndPrivacyPermissions, +) { + + fun hasAny(joinRule: JoinRule?): Boolean { + return editDetailsPermissions.hasAny || + canEditRolesAndPermissions || + securityAndPrivacyPermissions.hasAny(isSpace = true, joinRule = joinRule) + } + - val hasAny = canEditDetails || canManageRolesAndPermissions || canManageSecurityAndPrivacy companion object { val DEFAULT = SpaceSettingsPermissions( - canEditDetails = false, - canManageRolesAndPermissions = false, - canManageSecurityAndPrivacy = false, + editDetailsPermissions = RoomDetailsEditPermissions.DEFAULT, + canEditRolesAndPermissions = false, + securityAndPrivacyPermissions = SecurityAndPrivacyPermissions.DEFAULT, ) } } -fun RoomPermissions.spaceSettingsPermissions(): SpaceSettingsPermissions { +fun RoomPermissions.spaceSettingsPermissions(): SpaceSettingsPermissions { return SpaceSettingsPermissions( - canEditDetails = roomDetailsEditPermissions().hasAny, - canManageRolesAndPermissions = canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS), - canManageSecurityAndPrivacy = securityAndPrivacyPermissions().hasAny, + editDetailsPermissions = roomDetailsEditPermissions(), + canEditRolesAndPermissions = canEditRolesAndPermissions(), + securityAndPrivacyPermissions = securityAndPrivacyPermissions(), ) } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPresenter.kt index 96c3fcbab6..565008a778 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPresenter.kt @@ -10,7 +10,9 @@ package io.element.android.features.space.impl.settings import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.room.JoinedRoom @@ -26,15 +28,19 @@ class SpaceSettingsPresenter( val permissions by room.permissionsAsState(SpaceSettingsPermissions.DEFAULT) { perms -> perms.spaceSettingsPermissions() } + val showSecurityAndPrivacy by remember { + derivedStateOf { permissions.securityAndPrivacyPermissions.hasAny(isSpace = false, joinRule = roomInfo.joinRule) } + } + return SpaceSettingsState( roomId = room.roomId, name = roomInfo.name.orEmpty(), canonicalAlias = roomInfo.canonicalAlias, avatarUrl = roomInfo.avatarUrl, memberCount = roomInfo.activeMembersCount, - canEditDetails = permissions.canEditDetails, - showRolesAndPermissions = permissions.canManageRolesAndPermissions, - showSecurityAndPrivacy = permissions.canManageSecurityAndPrivacy, + canEditDetails = permissions.editDetailsPermissions.hasAny, + showRolesAndPermissions = permissions.canEditRolesAndPermissions, + showSecurityAndPrivacy = showSecurityAndPrivacy, eventSink = {}, ) } From 6d93ce25aa92aee83362ec0b2d474cd7470f07d2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 11 Dec 2025 13:52:30 +0100 Subject: [PATCH 107/347] RoomSummary: move the icon related to the last message state on start of the message. --- .../home/impl/components/RoomSummaryRow.kt | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt index b722c63622..50b9559e94 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt @@ -121,7 +121,6 @@ internal fun RoomSummaryRow( ) { NameAndTimestampRow( name = room.name, - latestEvent = room.latestEvent, timestamp = room.timestamp, isHighlighted = room.isHighlighted ) @@ -138,7 +137,6 @@ internal fun RoomSummaryRow( ) { NameAndTimestampRow( name = room.name, - latestEvent = room.latestEvent, timestamp = null, isHighlighted = room.isHighlighted ) @@ -214,7 +212,6 @@ private fun RoomSummaryScaffoldRow( @Composable private fun NameAndTimestampRow( name: String?, - latestEvent: LatestEvent, timestamp: String?, isHighlighted: Boolean, modifier: Modifier = Modifier @@ -236,29 +233,6 @@ private fun NameAndTimestampRow( maxLines = 1, overflow = TextOverflow.Ellipsis ) - // Picto - when (latestEvent) { - is LatestEvent.Sending -> { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - modifier = Modifier.size(16.dp), - imageVector = CompoundIcons.Time(), - contentDescription = stringResource(CommonStrings.common_sending), - tint = ElementTheme.colors.iconTertiary, - ) - } - is LatestEvent.Error -> { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - modifier = Modifier.size(16.dp), - imageVector = CompoundIcons.ErrorSolid(), - // The last message contains the error. - contentDescription = null, - tint = ElementTheme.colors.iconCriticalPrimary, - ) - } - else -> Unit - } } // Timestamp Text( @@ -303,7 +277,6 @@ private fun MessagePreviewAndIndicatorRow( ) { Row( modifier = modifier.fillMaxWidth(), - horizontalArrangement = spacedBy(28.dp) ) { if (room.isTombstoned) { Text( @@ -317,6 +290,16 @@ private fun MessagePreviewAndIndicatorRow( ) } else { if (room.latestEvent is LatestEvent.Error) { + Icon( + modifier = Modifier + .padding(top = 2.dp) + .size(16.dp), + imageVector = CompoundIcons.ErrorSolid(), + // The last message contains the error. + contentDescription = null, + tint = ElementTheme.colors.iconCriticalPrimary, + ) + Spacer(modifier = Modifier.width(6.dp)) Text( modifier = Modifier.weight(1f), text = stringResource(CommonStrings.common_message_failed_to_send), @@ -327,6 +310,17 @@ private fun MessagePreviewAndIndicatorRow( overflow = TextOverflow.Ellipsis, ) } else { + if (room.latestEvent is LatestEvent.Sending) { + Icon( + modifier = Modifier + .padding(top = 2.dp) + .size(16.dp), + imageVector = CompoundIcons.Time(), + contentDescription = stringResource(CommonStrings.common_sending), + tint = ElementTheme.colors.iconTertiary, + ) + Spacer(modifier = Modifier.width(6.dp)) + } val messagePreview = room.latestEvent.content() val annotatedMessagePreview = messagePreview as? AnnotatedString ?: AnnotatedString(text = messagePreview.orEmpty().toString()) Text( @@ -340,7 +334,7 @@ private fun MessagePreviewAndIndicatorRow( ) } } - + Spacer(modifier = Modifier.width(16.dp)) // Call and unread Row( modifier = Modifier From 6876d0da223918239d3b2f42b9a82f2552fc6d0e Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 11 Dec 2025 14:06:53 +0000 Subject: [PATCH 108/347] Update screenshots --- ...ures.home.impl.components_RoomListContentView_Day_0_en.png | 4 ++-- ...ures.home.impl.components_RoomListContentView_Day_5_en.png | 4 ++-- ...es.home.impl.components_RoomListContentView_Night_0_en.png | 4 ++-- ...es.home.impl.components_RoomListContentView_Night_5_en.png | 4 ++-- ...features.home.impl.components_RoomSummaryRow_Day_36_en.png | 4 ++-- ...features.home.impl.components_RoomSummaryRow_Day_37_en.png | 4 ++-- .../features.home.impl.components_RoomSummaryRow_Day_4_en.png | 4 ++-- ...atures.home.impl.components_RoomSummaryRow_Night_36_en.png | 4 ++-- ...atures.home.impl.components_RoomSummaryRow_Night_37_en.png | 4 ++-- ...eatures.home.impl.components_RoomSummaryRow_Night_4_en.png | 4 ++-- ...atures.home.impl.search_RoomListSearchContent_Day_1_en.png | 4 ++-- ...ures.home.impl.search_RoomListSearchContent_Night_1_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeViewA11y_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_0_en.png | 4 ++-- .../images/features.home.impl_HomeView_Day_13_en.png | 4 ++-- .../images/features.home.impl_HomeView_Day_14_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_1_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_2_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_5_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_9_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_0_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_13_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_14_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_1_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_2_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_5_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_9_en.png | 4 ++-- ...crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png | 3 --- ...ypto.historyvisible_HistoryVisibleStateView_Night_1_en.png | 3 --- ...historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png | 3 --- ...storyvisible_MessagesViewWithHistoryVisible_Night_1_en.png | 3 --- 31 files changed, 54 insertions(+), 66 deletions(-) delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_0_en.png index a3abd4937d..2b4bab0904 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4013ad25e9f4e38109e7ee49921814adc8ec5e4952c8f8d4d6946a4badf67081 -size 41513 +oid sha256:5ad4cbbad7f8d12579ea2336dbe90519d164baf1ba5ca1d1398f598c699a37b3 +size 41814 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_5_en.png index 53a25223bd..bbf55e44a9 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d035c3d696dae89026dbcc8cfc918a98cc8bb8b3f79548b57d36b96b29f097f -size 59908 +oid sha256:b9a6f816acf13335c15e188cb6d9d240aa9f19e76f80c65cb6ce5d02036b4d92 +size 60017 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_0_en.png index dd6b0742fd..2721654be9 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1720068dd3f0b75076ef81642d680f00e52f7162247beb30dc515fb74c25cf2a -size 41164 +oid sha256:2cffbce8a793651437dc5ff93c697d859df047a71a6a128996c41af918ad18fc +size 41499 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_5_en.png index 71048bb36d..53fc2dba28 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomListContentView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf2cedb0979d0eb916df2a1810c7d872d159214b0e26d5b3a353001dfed0aa06 -size 58935 +oid sha256:ca660f44ee031e98540134d3b37743dbb893566a6a8359dfbd4dd4da87bc2e83 +size 59128 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_36_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_36_en.png index fb772998e4..9462c2e058 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_36_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_36_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:761e963499f97f21b5c5b8b80e5d75092fbc4305371bcc413f595b503890d511 -size 13085 +oid sha256:c125c71ef07cc228ea24bd34a43091e0728d529d2303e44684529f32beaa09f8 +size 13113 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_37_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_37_en.png index 42db131266..93c9eb369e 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_37_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_37_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de31aa3dbb9c9427189621d35022211220197de8ed8584f36801eb99d613f0b1 -size 13728 +oid sha256:c7b78a9d066b454130ad08bfa035a2afafa6ec1711d88921a7fabb84a73b01ee +size 13616 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_4_en.png index b95547f00a..e6443ec3f7 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:929d7eb7ea27b4638a8bb71093f6c0d7c01da4d7bf563ebaf31c91657f3db7fb -size 20629 +oid sha256:2a8c23e9560ba89e226390862ab0b724465ebb2ab7c20e5a41f2df72b9ee76a1 +size 21024 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_36_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_36_en.png index bb29aaa4b5..132c8a716a 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_36_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_36_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f7327f29c9236b549d7f5037e3483e487a23902c5c30bd20a7a4bc0e6c13bec -size 13009 +oid sha256:a49cc5e58070d5af3fb905076a41ce5cb0bf77eda4d34550d8e7ac1f4c771472 +size 12981 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_37_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_37_en.png index c8ce9b58a1..640ad68f5b 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_37_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_37_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f92a70303d515a135eb87eac344dc4a974183da8773524a48f790b31a70338e8 -size 13528 +oid sha256:3377bf16f847083f340218bd6bf4f4f3290d354c06193a808402f26ee34ea8a7 +size 13432 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_4_en.png index 73823e4199..c8c2170780 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:112dcba335114372a39a531be0ad6350f1bcdffe03d4c6033d2a4799715bed6d -size 20300 +oid sha256:ff0df80592079fadfbf82b192ed79e9684dce58d146bf2e571a04c6784a9e6bc +size 20696 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.search_RoomListSearchContent_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.search_RoomListSearchContent_Day_1_en.png index fdf4fd6693..bc04f12385 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.search_RoomListSearchContent_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.search_RoomListSearchContent_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10d68a9d1c5913fe9c14edd6d3663b7692f9c9031dd08205ad290c4d1f1593bf -size 43973 +oid sha256:de647a2d609bb2ac37875767780dccfa34d47b68da504b59ebb27e2f8d989452 +size 44250 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.search_RoomListSearchContent_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.search_RoomListSearchContent_Night_1_en.png index 30bb25d9f9..93624ab755 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl.search_RoomListSearchContent_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.search_RoomListSearchContent_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6fb9912ee3b7489424e9f364610cb4f9c7c3276e17f7e6fe75c2be7a3cd84bf4 -size 43434 +oid sha256:1decbfcf1afc6d2f827d570ef0145674ab1f598ce375b95331ca83975793509e +size 43762 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png index e2340106b8..7323ddc95f 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3530f2d4ba4b189c7e40c19548fe1d44fea844505ed411cd476eb41add5aac5 -size 122437 +oid sha256:88dff52e06c62a7df91c08ed0237068a2e8bcdfd5f83426a52cf7a3097ee8cfa +size 122935 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_0_en.png index c87b2327c8..3e870ea8d7 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60f321d5352e1966b44e13b4b9e56da3f2cfd14e5eb4a468b61b1939799d364a -size 61182 +oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1 +size 61515 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_13_en.png index 7728b33306..343550c109 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf7d32047c608340c06edfb8ade3cc8b92858eaa763fedafa915c16439657fc2 -size 88205 +oid sha256:821cb6a2068561375d0988d4ba5404e52411a6d9b73cefbe1a6bd7bc6d467673 +size 88367 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_14_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_14_en.png index 32cf426e12..191d910e04 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:abf95575cbd55470c798accf988bc6a509daea71eded4108857595993873df4e -size 81038 +oid sha256:f9f5fef39d80aacb9666deeea43e4df48f7c70231bd8ec41edf2f3eed5f0aa42 +size 81149 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_1_en.png index c87b2327c8..3e870ea8d7 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60f321d5352e1966b44e13b4b9e56da3f2cfd14e5eb4a468b61b1939799d364a -size 61182 +oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1 +size 61515 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_2_en.png index c87b2327c8..3e870ea8d7 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60f321d5352e1966b44e13b4b9e56da3f2cfd14e5eb4a468b61b1939799d364a -size 61182 +oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1 +size 61515 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_5_en.png index c87b2327c8..3e870ea8d7 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60f321d5352e1966b44e13b4b9e56da3f2cfd14e5eb4a468b61b1939799d364a -size 61182 +oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1 +size 61515 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_9_en.png index 4c31f1f2ee..277cd740bb 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:196cad6f5c3d01d52c88713526848d7905b59b49866f27f6e420df0b6b8f9e73 -size 80857 +oid sha256:a5a68b4d8951b7c516561d538c5d328a84948c66af7eb7c80ac77cd005620cf2 +size 80977 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_0_en.png index 2366c44bf9..a46c9d21bf 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e9b4b3247cf2f540866286de61760a45956d8179891aeb669b4763bdd29393d -size 57993 +oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e +size 58325 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_13_en.png index 54fd5321eb..8094781a7f 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7ff4652d94dec6bc98b3f1dea0d182576c7bfc72e39f232d224046e6492b55e -size 83764 +oid sha256:541740cdd54ef7b9a868c1409330a6ca7417bce9f022b22c3d395ac9b215d470 +size 83939 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_14_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_14_en.png index 766b356208..40695d7c0c 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb1d9b5143703ec9a8035e11374c7e56ce4d3f836005632a109e5556b141c59b -size 77098 +oid sha256:a44897f23fc0e6a90779fe96638c560973caf7dbb9a7c92ec4d2f5b56de3ddcc +size 77280 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_1_en.png index 2366c44bf9..a46c9d21bf 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e9b4b3247cf2f540866286de61760a45956d8179891aeb669b4763bdd29393d -size 57993 +oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e +size 58325 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_2_en.png index 2366c44bf9..a46c9d21bf 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e9b4b3247cf2f540866286de61760a45956d8179891aeb669b4763bdd29393d -size 57993 +oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e +size 58325 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_5_en.png index 2366c44bf9..a46c9d21bf 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e9b4b3247cf2f540866286de61760a45956d8179891aeb669b4763bdd29393d -size 57993 +oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e +size 58325 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_9_en.png index fdfec064e2..fc269825f1 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:101d0425024c30f2dce8b6d91ed2416fc115c4bf3719fd6c46093705ba4ef772 -size 76985 +oid sha256:49ea33ae74532c350b4176355203561cfc5eb79c93c4993d6ffb0cf933f8ad2f +size 77167 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png deleted file mode 100644 index d19a140456..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:96bc0c555188cee4b3f3e3e0f28f944a4225e27b9a1069edf2b10a2993ee3080 -size 26078 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png deleted file mode 100644 index d21a12dd64..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a103daf8447cb571a0c5010d062a7790aaa0f3dce30f052bf86884708f4881a5 -size 28769 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png deleted file mode 100644 index 22d05e61fa..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9682cdd7e08e32591fa47f56da5e6ef4cc3a777700931c2c86e9b802a9cf25cb -size 67342 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png deleted file mode 100644 index b2bb8ac3fc..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d20c04c6385e675bd71d93d2d5d832509b1300a27708245755f263392b33bc8a -size 69457 From 4f5ce5711d41d2ca4a960c6bb19262763007a29e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 11 Dec 2025 17:05:42 +0100 Subject: [PATCH 109/347] Remove nullability --- .../io/element/android/libraries/qrcode/QRCodeAnalyzer.kt | 7 +++++-- .../element/android/libraries/qrcode/QrCodeCameraView.kt | 7 +------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QRCodeAnalyzer.kt b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QRCodeAnalyzer.kt index ab2ee2ce7b..e9d43d86a3 100644 --- a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QRCodeAnalyzer.kt +++ b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QRCodeAnalyzer.kt @@ -15,7 +15,7 @@ import timber.log.Timber import zxingcpp.BarcodeReader internal class QRCodeAnalyzer( - private val onScanQrCode: (result: ByteArray?) -> Unit + private val onScanQrCode: (data: ByteArray) -> Unit ) : ImageAnalysis.Analyzer { private val reader by lazy { BarcodeReader() } @@ -23,7 +23,10 @@ internal class QRCodeAnalyzer( if (image.format in SUPPORTED_IMAGE_FORMATS) { try { val bytes = reader.read(image).firstNotNullOfOrNull { it.bytes } - bytes?.let { onScanQrCode(it) } + if (bytes != null) { + Timber.d("QR code scanned!") + onScanQrCode(bytes) + } } catch (e: Exception) { Timber.w(e, "Error decoding QR code") } finally { diff --git a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt index a0d6613a3f..8c7563c5f8 100644 --- a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt +++ b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt @@ -80,12 +80,7 @@ fun QrCodeCameraView( .build() imageAnalysis.setAnalyzer( ContextCompat.getMainExecutor(previewView.context), - QRCodeAnalyzer { result -> - result?.let { - Timber.d("QR code scanned!") - onScanQrCode(it) - } - } + QRCodeAnalyzer(onScanQrCode) ) try { // Make sure we unbind all use cases before binding them again From efa5c7794d575014583f37af4e1eabad80c5571e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 11 Dec 2025 17:07:55 +0100 Subject: [PATCH 110/347] Improve code --- .../libraries/qrcode/QRCodeAnalyzer.kt | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QRCodeAnalyzer.kt b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QRCodeAnalyzer.kt index e9d43d86a3..168e898965 100644 --- a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QRCodeAnalyzer.kt +++ b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QRCodeAnalyzer.kt @@ -20,17 +20,19 @@ internal class QRCodeAnalyzer( private val reader by lazy { BarcodeReader() } override fun analyze(image: ImageProxy) { - if (image.format in SUPPORTED_IMAGE_FORMATS) { - try { - val bytes = reader.read(image).firstNotNullOfOrNull { it.bytes } - if (bytes != null) { - Timber.d("QR code scanned!") - onScanQrCode(bytes) + image.use { + if (image.format in SUPPORTED_IMAGE_FORMATS) { + try { + val bytes = reader.read(image).firstNotNullOfOrNull { it.bytes } + if (bytes != null) { + Timber.d("QR code scanned!") + onScanQrCode(bytes) + } + } catch (e: Exception) { + Timber.w(e, "Error decoding QR code") } - } catch (e: Exception) { - Timber.w(e, "Error decoding QR code") - } finally { - image.close() + } else { + Timber.w("Unsupported image format: ${image.format}") } } } From 6100d4944f0f7f87b8a2975a56de3bf2af45200e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 11 Dec 2025 17:23:34 +0100 Subject: [PATCH 111/347] Cleanup --- .../screens/qrcode/scan/QrCodeScanView.kt | 2 +- .../libraries/qrcode/QrCodeCameraView.kt | 26 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanView.kt index 4f444b14bc..6fa3d1b0c7 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/qrcode/scan/QrCodeScanView.kt @@ -106,7 +106,7 @@ private fun Content( QrCodeCameraView( modifier = Modifier.fillMaxSize(), onScanQrCode = { state.eventSink.invoke(QrCodeScanEvents.QrCodeScanned(it)) }, - renderPreview = state.isScanning, + isScanning = state.isScanning, ) } } diff --git a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt index 8c7563c5f8..e687d4a945 100644 --- a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt +++ b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt @@ -45,7 +45,7 @@ import kotlin.coroutines.suspendCoroutine @Composable fun QrCodeCameraView( onScanQrCode: (ByteArray) -> Unit, - renderPreview: Boolean, + isScanning: Boolean, modifier: Modifier = Modifier, ) { if (LocalInspectionMode.current) { @@ -73,13 +73,13 @@ fun QrCodeCameraView( cameraProvider = localContext.getCameraProvider() } - suspend fun startQRCodeAnalysis(cameraProvider: ProcessCameraProvider, previewView: PreviewView, attempt: Int = 1) { + suspend fun startQRCodeAnalysis(cameraProvider: ProcessCameraProvider, attempt: Int = 1) { lastFrame = null val cameraSelector = CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build() imageAnalysis.setAnalyzer( - ContextCompat.getMainExecutor(previewView.context), + ContextCompat.getMainExecutor(localContext), QRCodeAnalyzer(onScanQrCode) ) try { @@ -100,7 +100,7 @@ fun QrCodeCameraView( } else { Timber.e(e, "Use case binding failed (attempt #$attempt). Retrying after a delay...") delay(100) - startQRCodeAnalysis(cameraProvider, previewView, attempt + 1) + startQRCodeAnalysis(cameraProvider, attempt + 1) } } } @@ -123,16 +123,18 @@ fun QrCodeCameraView( AndroidView( factory = { context -> val previewView = PreviewView(context) - previewUseCase.setSurfaceProvider(previewView.surfaceProvider) + previewUseCase.surfaceProvider = previewView.surfaceProvider previewView.previewStreamState.observe(lifecycleOwner) { state -> previewView.alpha = if (state == PreviewView.StreamState.STREAMING) 1f else 0f } previewView }, update = { previewView -> - if (renderPreview) { + if (isScanning) { cameraProvider?.let { provider -> - coroutineScope.launch { startQRCodeAnalysis(provider, previewView) } + coroutineScope.launch { + startQRCodeAnalysis(provider) + } } } else { stopQRCodeAnalysis(previewView) @@ -150,12 +152,14 @@ fun QrCodeCameraView( } } -@Suppress("BlockingMethodInNonBlockingContext") private suspend fun Context.getCameraProvider(): ProcessCameraProvider = suspendCoroutine { continuation -> ProcessCameraProvider.getInstance(this).also { cameraProvider -> - cameraProvider.addListener({ - continuation.resume(cameraProvider.get()) - }, ContextCompat.getMainExecutor(this)) + cameraProvider.addListener( + { + continuation.resume(cameraProvider.get()) + }, + ContextCompat.getMainExecutor(this) + ) } } From 06c20e3abf6870595b342ad6ad40d6ad0d2fc467 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 11 Dec 2025 17:33:24 +0100 Subject: [PATCH 112/347] Move usage of LocalInspectionMode.current into the deeper block. --- .../libraries/qrcode/QrCodeCameraView.kt | 134 +++++++++--------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt index e687d4a945..7f089818d0 100644 --- a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt +++ b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt @@ -48,78 +48,78 @@ fun QrCodeCameraView( isScanning: Boolean, modifier: Modifier = Modifier, ) { - if (LocalInspectionMode.current) { - Box( - modifier = modifier - .background(color = ElementTheme.colors.bgSubtlePrimary), - contentAlignment = Alignment.Center, - ) { - Text("CameraView") - } - } else { - val coroutineScope = rememberCoroutineScope() - val localContext = LocalContext.current - val lifecycleOwner = LocalLifecycleOwner.current - var cameraProvider by remember { mutableStateOf(null) } - val previewUseCase = remember { Preview.Builder().build() } - var lastFrame by remember { mutableStateOf(null) } - val imageAnalysis = remember { - ImageAnalysis.Builder() - .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) - .build() - } + val coroutineScope = rememberCoroutineScope() + val localContext = LocalContext.current + val lifecycleOwner = LocalLifecycleOwner.current + var cameraProvider by remember { mutableStateOf(null) } + val previewUseCase = remember { Preview.Builder().build() } + var lastFrame by remember { mutableStateOf(null) } + val imageAnalysis = remember { + ImageAnalysis.Builder() + .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) + .build() + } - LaunchedEffect(Unit) { - cameraProvider = localContext.getCameraProvider() - } + LaunchedEffect(Unit) { + cameraProvider = localContext.getCameraProvider() + } - suspend fun startQRCodeAnalysis(cameraProvider: ProcessCameraProvider, attempt: Int = 1) { - lastFrame = null - val cameraSelector = CameraSelector.Builder() - .requireLensFacing(CameraSelector.LENS_FACING_BACK) - .build() - imageAnalysis.setAnalyzer( - ContextCompat.getMainExecutor(localContext), - QRCodeAnalyzer(onScanQrCode) + suspend fun startQRCodeAnalysis(cameraProvider: ProcessCameraProvider, attempt: Int = 1) { + lastFrame = null + val cameraSelector = CameraSelector.Builder() + .requireLensFacing(CameraSelector.LENS_FACING_BACK) + .build() + imageAnalysis.setAnalyzer( + ContextCompat.getMainExecutor(localContext), + QRCodeAnalyzer(onScanQrCode) + ) + try { + // Make sure we unbind all use cases before binding them again + cameraProvider.unbindAll() + + cameraProvider.bindToLifecycle( + lifecycleOwner, + cameraSelector, + previewUseCase, + imageAnalysis, ) - try { - // Make sure we unbind all use cases before binding them again - cameraProvider.unbindAll() - - cameraProvider.bindToLifecycle( - lifecycleOwner, - cameraSelector, - previewUseCase, - imageAnalysis - ) - lastFrame = null - } catch (e: Exception) { - val maxAttempts = 3 - if (attempt > maxAttempts) { - Timber.e(e, "Use case binding failed after $maxAttempts attempts. Giving up.") - } else { - Timber.e(e, "Use case binding failed (attempt #$attempt). Retrying after a delay...") - delay(100) - startQRCodeAnalysis(cameraProvider, attempt + 1) - } + lastFrame = null + } catch (e: Exception) { + val maxAttempts = 3 + if (attempt > maxAttempts) { + Timber.e(e, "Use case binding failed after $maxAttempts attempts. Giving up.") + } else { + Timber.e(e, "Use case binding failed (attempt #$attempt). Retrying after a delay...") + delay(100) + startQRCodeAnalysis(cameraProvider, attempt + 1) } } + } - fun stopQRCodeAnalysis(previewView: PreviewView) { - // Stop analyzer - imageAnalysis.clearAnalyzer() + fun stopQRCodeAnalysis(previewView: PreviewView) { + // Stop analyzer + imageAnalysis.clearAnalyzer() - // Save last frame to display it as the 'frozen' preview - if (lastFrame == null) { - lastFrame = previewView.bitmap - Timber.d("Saving last frame for frozen preview.") - } - - // Unbind preview use case - cameraProvider?.unbindAll() + // Save last frame to display it as the 'frozen' preview + if (lastFrame == null) { + lastFrame = previewView.bitmap + Timber.d("Saving last frame for frozen preview.") } - Box(modifier.clipToBounds()) { + // Unbind preview use case + cameraProvider?.unbindAll() + } + + Box(modifier.clipToBounds()) { + if (LocalInspectionMode.current) { + Box( + modifier = modifier + .background(color = ElementTheme.colors.bgSubtlePrimary), + contentAlignment = Alignment.Center, + ) { + Text("CameraView") + } + } else { AndroidView( factory = { context -> val previewView = PreviewView(context) @@ -145,9 +145,9 @@ fun QrCodeCameraView( cameraProvider = null }, ) - lastFrame?.let { - Image(bitmap = it.asImageBitmap(), contentDescription = null) - } + } + lastFrame?.let { + Image(bitmap = it.asImageBitmap(), contentDescription = null) } } } @@ -159,7 +159,7 @@ private suspend fun Context.getCameraProvider(): ProcessCameraProvider = { continuation.resume(cameraProvider.get()) }, - ContextCompat.getMainExecutor(this) + ContextCompat.getMainExecutor(this), ) } } From d06f3a07980470e85dd4c96aa6ace6c20d2cd6a5 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 11 Dec 2025 17:39:10 +0100 Subject: [PATCH 113/347] change(room permissions): ensure closing screen without permissions --- .../api/RolesAndPermissionsEntryPoint.kt | 17 +++++++++-- .../DefaultRolesAndPermissionsEntryPoint.kt | 8 +++-- .../impl/RolesAndPermissionsFlowNode.kt | 21 ++++++++++++++ .../impl/root/RolesAndPermissionsNode.kt | 24 --------------- .../test/FakeRolesAndPermissionsEntryPoint.kt | 2 +- .../roomdetails/impl/RoomDetailsFlowNode.kt | 11 ++++++- .../impl/SecurityAndPrivacyFlowNode.kt | 29 +++++++++++++++++++ .../impl/settings/SpaceSettingsFlowNode.kt | 6 ++++ 8 files changed, 88 insertions(+), 30 deletions(-) diff --git a/features/rolesandpermissions/api/src/main/kotlin/io/element/android/features/rolesandpermissions/api/RolesAndPermissionsEntryPoint.kt b/features/rolesandpermissions/api/src/main/kotlin/io/element/android/features/rolesandpermissions/api/RolesAndPermissionsEntryPoint.kt index 1e9fe6a1c4..bd3cea0439 100644 --- a/features/rolesandpermissions/api/src/main/kotlin/io/element/android/features/rolesandpermissions/api/RolesAndPermissionsEntryPoint.kt +++ b/features/rolesandpermissions/api/src/main/kotlin/io/element/android/features/rolesandpermissions/api/RolesAndPermissionsEntryPoint.kt @@ -8,6 +8,19 @@ package io.element.android.features.rolesandpermissions.api -import io.element.android.libraries.architecture.SimpleFeatureEntryPoint +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import io.element.android.libraries.architecture.FeatureEntryPoint -fun interface RolesAndPermissionsEntryPoint : SimpleFeatureEntryPoint +fun interface RolesAndPermissionsEntryPoint : FeatureEntryPoint { + interface Callback : Plugin { + fun onDone() + } + + fun createNode( + parentNode: Node, + buildContext: BuildContext, + callback: Callback, + ): Node +} diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/DefaultRolesAndPermissionsEntryPoint.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/DefaultRolesAndPermissionsEntryPoint.kt index 2f281a596a..5f27365857 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/DefaultRolesAndPermissionsEntryPoint.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/DefaultRolesAndPermissionsEntryPoint.kt @@ -17,7 +17,11 @@ import io.element.android.libraries.di.RoomScope @ContributesBinding(RoomScope::class) class DefaultRolesAndPermissionsEntryPoint : RolesAndPermissionsEntryPoint { - override fun createNode(parentNode: Node, buildContext: BuildContext): Node { - return parentNode.createNode(buildContext) + override fun createNode( + parentNode: Node, + buildContext: BuildContext, + callback: RolesAndPermissionsEntryPoint.Callback, + ): Node { + return parentNode.createNode(buildContext, listOf(callback)) } } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/RolesAndPermissionsFlowNode.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/RolesAndPermissionsFlowNode.kt index 5966a4f0ed..4bd88071c3 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/RolesAndPermissionsFlowNode.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/RolesAndPermissionsFlowNode.kt @@ -14,7 +14,10 @@ import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.lifecycle.Lifecycle import androidx.lifecycle.coroutineScope +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin @@ -25,17 +28,24 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.features.rolesandpermissions.api.ChangeRoomMemberRolesListType +import io.element.android.features.rolesandpermissions.api.RolesAndPermissionsEntryPoint import io.element.android.features.rolesandpermissions.impl.permissions.ChangeRoomPermissionsNode import io.element.android.features.rolesandpermissions.impl.roles.ChangeRolesNode import io.element.android.features.rolesandpermissions.impl.root.RolesAndPermissionsNode import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode +import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.createNode import io.element.android.libraries.designsystem.components.async.AsyncIndicator import io.element.android.libraries.designsystem.components.async.AsyncIndicatorHost import io.element.android.libraries.designsystem.components.async.AsyncIndicatorState import io.element.android.libraries.di.RoomScope +import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.room.powerlevels.canEditRolesAndPermissions +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsFlow import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize @@ -44,6 +54,7 @@ import kotlinx.parcelize.Parcelize class RolesAndPermissionsFlowNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, + private val room: JoinedRoom, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.Root, @@ -66,6 +77,7 @@ class RolesAndPermissionsFlowNode( data object ChangeRoomPermissions : NavTarget } + private val callback: RolesAndPermissionsEntryPoint.Callback = callback() private val asyncIndicatorState = AsyncIndicatorState() override fun onBuilt() { @@ -76,6 +88,15 @@ class RolesAndPermissionsFlowNode( onChangeComplete(changesSaved) } } + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.CREATED) { + room.permissionsFlow(false) { perms -> perms.canEditRolesAndPermissions() } + .filter { canEdit -> !canEdit } + .first() + // If the user can no longer edit roles and permissions, exit the flow + callback.onDone() + } + } } private fun onChangeComplete(changesSaved: Boolean) { diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt index 4469eb8f37..d6efa661bc 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt @@ -11,7 +11,6 @@ package io.element.android.features.rolesandpermissions.impl.root import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.ui.Modifier -import androidx.lifecycle.lifecycleScope import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin @@ -21,13 +20,6 @@ import io.element.android.annotations.ContributesNode import io.element.android.libraries.architecture.callback import io.element.android.libraries.di.RoomScope import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.ui.model.roleOf -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.take -import kotlinx.coroutines.launch @ContributesNode(RoomScope::class) @AssistedInject @@ -54,22 +46,6 @@ class RolesAndPermissionsNode( } } - override fun onBuilt() { - super.onBuilt() - - // If the user is not an admin anymore, exit this section since they won't have permissions to use it - lifecycleScope.launch { - room.roomInfoFlow - .filter { info -> - val role = info.roleOf(room.sessionId) - role != RoomMember.Role.Admin && role !is RoomMember.Role.Owner - } - .take(1) - .onEach { navigateUp() } - .collect() - } - } - @Composable override fun View(modifier: Modifier) { val state = presenter.present() diff --git a/features/rolesandpermissions/test/src/main/kotlin/io/element/android/features/changeroommemberroles/test/FakeRolesAndPermissionsEntryPoint.kt b/features/rolesandpermissions/test/src/main/kotlin/io/element/android/features/changeroommemberroles/test/FakeRolesAndPermissionsEntryPoint.kt index 01f2787778..62cf3285f3 100644 --- a/features/rolesandpermissions/test/src/main/kotlin/io/element/android/features/changeroommemberroles/test/FakeRolesAndPermissionsEntryPoint.kt +++ b/features/rolesandpermissions/test/src/main/kotlin/io/element/android/features/changeroommemberroles/test/FakeRolesAndPermissionsEntryPoint.kt @@ -14,7 +14,7 @@ import io.element.android.features.rolesandpermissions.api.RolesAndPermissionsEn import io.element.android.tests.testutils.lambda.lambdaError class FakeRolesAndPermissionsEntryPoint : RolesAndPermissionsEntryPoint { - override fun createNode(parentNode: Node, buildContext: BuildContext): Node { + override fun createNode(parentNode: Node, buildContext: BuildContext, callback: RolesAndPermissionsEntryPoint.Callback): Node { lambdaError() } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index 9ea060ef6c..03adbded1b 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -349,7 +349,16 @@ class RoomDetailsFlowNode( } is NavTarget.AdminSettings -> { - rolesAndPermissionsEntryPoint.createNode(this, buildContext) + val callback = object : RolesAndPermissionsEntryPoint.Callback { + override fun onDone() { + backstack.pop() + } + } + rolesAndPermissionsEntryPoint.createNode( + parentNode = this, + buildContext = buildContext, + callback = callback, + ) } NavTarget.PinnedMessagesList -> { val params = MessagesEntryPoint.Params( diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index 13c5b454a2..3d62e7b5d7 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -11,6 +11,9 @@ package io.element.android.features.securityandprivacy.impl import android.os.Parcelable import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin @@ -19,6 +22,7 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint +import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions import io.element.android.features.securityandprivacy.impl.editroomaddress.EditRoomAddressNode import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyNode import io.element.android.libraries.architecture.BackstackView @@ -26,6 +30,12 @@ import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.RoomScope +import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.room.powerlevels.use +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize @ContributesNode(RoomScope::class) @@ -33,6 +43,7 @@ import kotlinx.parcelize.Parcelize class SecurityAndPrivacyFlowNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, + private val room: JoinedRoom, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.SecurityAndPrivacy, @@ -52,6 +63,24 @@ class SecurityAndPrivacyFlowNode( private val callback: SecurityAndPrivacyEntryPoint.Callback = callback() private val navigator = BackstackSecurityAndPrivacyNavigator(callback, backstack) + override fun onBuilt() { + super.onBuilt() + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.CREATED) { + room.roomInfoFlow + .map { roomInfo -> + room.roomPermissions().use(false) { perms -> + perms.securityAndPrivacyPermissions().hasAny(roomInfo.isSpace, roomInfo.joinRule) + } + } + .filter { canEdit -> !canEdit } + .first() + // If the user can no longer edit security and privacy, exit the flow + callback.onDone() + } + } + } + override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { return when (navTarget) { NavTarget.SecurityAndPrivacy -> { diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt index f7ccba6d93..b5f0495bcb 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt @@ -113,9 +113,15 @@ class SpaceSettingsFlowNode( ) } is NavTarget.RolesAndPermissions -> { + val callback = object : RolesAndPermissionsEntryPoint.Callback { + override fun onDone() { + backstack.pop() + } + } rolesAndPermissionsEntryPoint.createNode( parentNode = this, buildContext = buildContext, + callback = callback, ) } NavTarget.EditDetails -> { From 76be78857cf53c95ae8199331d6e85ccc851bea0 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 12 Dec 2025 11:15:22 +0100 Subject: [PATCH 114/347] fix(security&privacy): ensure edited settings are reset when options are hidden --- .../impl/root/SecurityAndPrivacyPresenter.kt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index 81bfe22697..472f71ddfb 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -182,9 +182,20 @@ class SecurityAndPrivacyPresenter( eventSink = ::handleEvent, ) - // If the history visibility is not available for the current access, use the fallback. - LaunchedEffect(state.availableHistoryVisibilities) { - if (editedSettings.historyVisibility !in state.availableHistoryVisibilities) { + // Revert changes that the user is not allowed to make anymore + LaunchedEffect(permissions, state.editedSettings.roomAccess) { + if (!state.showRoomAccessSection) { + editedRoomAccess = savedSettings.roomAccess + } + if (!state.showEncryptionSection) { + editedIsEncrypted = savedSettings.isEncrypted + } + if (!state.showRoomVisibilitySections) { + editedVisibleInRoomDirectory = savedSettings.isVisibleInRoomDirectory + } + if (!state.showHistoryVisibilitySection) { + editedHistoryVisibility = savedSettings.historyVisibility + } else if (editedSettings.historyVisibility !in state.availableHistoryVisibilities) { editedHistoryVisibility = editedSettings.historyVisibility.fallback() } } From 2dc8018c371c0ddc6c7ffb3f60193c7e3d648985 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 5 Dec 2025 12:53:58 +0100 Subject: [PATCH 115/347] misc(power level) : introduce RoomPermissions --- .../libraries/matrix/api/room/BaseRoom.kt | 6 + .../api/room/powerlevels/RoomPermissions.kt | 142 ++++++++++++++++++ .../matrix/impl/room/RustBaseRoom.kt | 8 + .../room/powerlevels/RustRoomPermissions.kt | 95 ++++++++++++ .../matrix/test/room/FakeBaseRoom.kt | 7 + .../room/powerlevels/FakeRoomPermissions.kt | 58 +++++++ 6 files changed, 316 insertions(+) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RustRoomPermissions.kt create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt index 41e6ce0e62..cde3a5eff7 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt @@ -14,6 +14,7 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.draft.ComposerDraft +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility @@ -99,6 +100,11 @@ interface BaseRoom : Closeable { */ suspend fun userRole(userId: UserId): Result + /** + * Gets the permissions of the room. + */ + suspend fun roomPermissions(): Result + /** * Gets the display name of the user with the provided [userId] in the room. */ diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt new file mode 100644 index 0000000000..cdc735b819 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt @@ -0,0 +1,142 @@ +/* + * 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.powerlevels + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.StateEventType + +/** + * Provides information about the permissions of users in a room. + */ +interface RoomPermissions : AutoCloseable { + fun canOwnUserBan(): Boolean + + /** + * Returns true if the current user is able to invite in the room. + */ + fun canOwnUserInvite(): Boolean + + /** + * Returns true if the current user is able to kick in the room. + */ + fun canOwnUserKick(): Boolean + + /** + * Returns true if the current user is able to pin or unpin events in the + * room. + */ + fun canOwnUserPinUnpin(): Boolean + + /** + * Returns true if the current user user is able to redact messages of + * other users in the room. + */ + fun canOwnUserRedactOther(): Boolean + + /** + * Returns true if the current user is able to redact their own messages in + * the room. + */ + fun canOwnUserRedactOwn(): Boolean + + /** + * Returns true if the current user is able to send a specific message type + * in the room. + */ + fun canOwnUserSendMessage(message: MessageEventType): Boolean + + /** + * Returns true if the current user is able to send a specific state event + * type in the room. + */ + fun canOwnUserSendState(stateEvent: StateEventType): Boolean + + /** + * Returns true if the current user is able to trigger a notification in + * the room. + */ + fun canOwnUserTriggerRoomNotification(): Boolean + + /** + * Returns true if the user with the given userId is able to ban in the + * room. + */ + fun canUserBan(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to invite in the + * room. + */ + fun canUserInvite(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to kick in the + * room. + */ + fun canUserKick(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to pin or unpin + * events in the room. + */ + fun canUserPinUnpin(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to redact + * messages of other users in the room. + */ + fun canUserRedactOther(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to redact + * their own messages in the room. + */ + fun canUserRedactOwn(userId: UserId): Boolean + + /** + * Returns true if the user with the given userId is able to send a + * specific message type in the room. + */ + fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean + + /** + * Returns true if the user with the given userId is able to send a + * specific state event type in the room. + */ + fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean + + /** + * Returns true if the user with the given userId is able to trigger a + * notification in the room. + * + * The call may fail if there is an error in getting the power levels. + */ + fun canUserTriggerRoomNotification(userId: UserId): Boolean +} + +fun RoomPermissions.canEditRoomDetails(): Boolean { + return canOwnUserSendState(StateEventType.ROOM_NAME) || + canOwnUserSendState(StateEventType.ROOM_TOPIC) || + canOwnUserSendState(StateEventType.ROOM_AVATAR) +} + +fun RoomPermissions.canManageKnockRequests(): Boolean { + return canOwnUserInvite() || canOwnUserBan() || canOwnUserKick() +} + +fun RoomPermissions.canEditSecurityAndPrivacy(): Boolean { + return canOwnUserSendState(StateEventType.ROOM_JOIN_RULES) || + canOwnUserSendState(StateEventType.ROOM_HISTORY_VISIBILITY) || + canOwnUserSendState(StateEventType.ROOM_CANONICAL_ALIAS) || + canOwnUserSendState(StateEventType.ROOM_ENCRYPTION) +} + +fun RoomPermissions.canEditRolesAndPermissions(): Boolean { + return canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS) +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt index be7f6240ee..eec9591e32 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.draft.ComposerDraft +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility @@ -33,6 +34,7 @@ import io.element.android.libraries.matrix.impl.room.draft.into import io.element.android.libraries.matrix.impl.room.member.RoomMemberListFetcher import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.powerlevels.RoomPowerLevelsValuesMapper +import io.element.android.libraries.matrix.impl.room.powerlevels.RustRoomPermissions import io.element.android.libraries.matrix.impl.room.tombstone.map import io.element.android.libraries.matrix.impl.roomdirectory.map import io.element.android.libraries.matrix.impl.timeline.toRustReceiptType @@ -178,6 +180,12 @@ class RustBaseRoom( } } + override suspend fun roomPermissions(): Result = withContext(roomDispatcher) { + runCatchingExceptions { + RustRoomPermissions(innerRoom.getPowerLevels()) + } + } + override suspend fun canUserInvite(userId: UserId): Result = withContext(roomDispatcher) { runCatchingExceptions { innerRoom.getPowerLevels().use { it.canUserInvite(userId.value) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RustRoomPermissions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RustRoomPermissions.kt new file mode 100644 index 0000000000..57e20b166f --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/powerlevels/RustRoomPermissions.kt @@ -0,0 +1,95 @@ +/* + * 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.powerlevels + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions +import io.element.android.libraries.matrix.impl.room.map +import org.matrix.rustcomponents.sdk.RoomPowerLevels + +class RustRoomPermissions( + private val inner: RoomPowerLevels, +) : RoomPermissions { + override fun canOwnUserBan(): Boolean { + return inner.canOwnUserBan() + } + + override fun canOwnUserInvite(): Boolean { + return inner.canOwnUserInvite() + } + + override fun canOwnUserKick(): Boolean { + return inner.canOwnUserKick() + } + + override fun canOwnUserPinUnpin(): Boolean { + return inner.canOwnUserPinUnpin() + } + + override fun canOwnUserRedactOther(): Boolean { + return inner.canOwnUserRedactOther() + } + + override fun canOwnUserRedactOwn(): Boolean { + return inner.canOwnUserRedactOwn() + } + + override fun canOwnUserSendMessage(message: MessageEventType): Boolean { + return inner.canOwnUserSendMessage(message.map()) + } + + override fun canOwnUserSendState(stateEvent: StateEventType): Boolean { + return inner.canOwnUserSendState(stateEvent.map()) + } + + override fun canOwnUserTriggerRoomNotification(): Boolean { + return inner.canOwnUserTriggerRoomNotification() + } + + override fun canUserBan(userId: UserId): Boolean { + return inner.canUserBan(userId.value) + } + + override fun canUserInvite(userId: UserId): Boolean { + return inner.canUserInvite(userId.value) + } + + override fun canUserKick(userId: UserId): Boolean { + return inner.canUserKick(userId.value) + } + + override fun canUserPinUnpin(userId: UserId): Boolean { + return inner.canUserPinUnpin(userId.value) + } + + override fun canUserRedactOther(userId: UserId): Boolean { + return inner.canUserRedactOther(userId.value) + } + + override fun canUserRedactOwn(userId: UserId): Boolean { + return inner.canUserRedactOwn(userId.value) + } + + override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean { + return inner.canUserSendMessage(userId.value, message.map()) + } + + override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean { + return inner.canUserSendState(userId.value, stateEvent.map()) + } + + override fun canUserTriggerRoomNotification(userId: UserId): Boolean { + return inner.canUserTriggerRoomNotification(userId.value) + } + + override fun close() { + inner.close() + } +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt index 56f880dc11..b05eff77e2 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt @@ -21,12 +21,14 @@ import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.draft.ComposerDraft +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.simulateLongTask import kotlinx.coroutines.CoroutineScope @@ -48,6 +50,7 @@ class FakeBaseRoom( private val userRoleResult: () -> Result = { lambdaError() }, private val getUpdatedMemberResult: (UserId) -> Result = { lambdaError() }, private val joinRoomResult: () -> Result = { lambdaError() }, + private val roomPermissionsResult: () -> Result = { Result.success(FakeRoomPermissions()) }, private val canInviteResult: (UserId) -> Result = { lambdaError() }, private val canKickResult: (UserId) -> Result = { lambdaError() }, private val canBanResult: (UserId) -> Result = { lambdaError() }, @@ -129,6 +132,10 @@ class FakeBaseRoom( return userRoleResult() } + override suspend fun roomPermissions(): Result { + return roomPermissionsResult() + } + override suspend fun getPermalink(): Result { return roomPermalinkResult() } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt new file mode 100644 index 0000000000..04ecb1f60b --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt @@ -0,0 +1,58 @@ +/* + * 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.test.room.powerlevels + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class FakeRoomPermissions( + val ownerCanBan: Boolean = false, + val ownerCanInvite: Boolean = false, + val ownerCanKick: Boolean = false, + val ownerCanPinUnpin: Boolean = false, + val ownerCanRedactOther: Boolean = false, + val ownerCanRedactOwn: Boolean = false, + val ownerCanTriggerRoomNotification: Boolean = false, + val ownerCanSendMessage: (MessageEventType) -> Boolean = { false }, + val ownerCanSendState: (StateEventType) -> Boolean = { false }, + val userCanBan: (UserId) -> Boolean = { false }, + val userCanInvite: (UserId) -> Boolean = { false }, + val userCanKick: (UserId) -> Boolean = { false }, + val userCanPinUnpin: (UserId) -> Boolean = { false }, + val userCanRedactOther: (UserId) -> Boolean = { false }, + val userCanRedactOwn: (UserId) -> Boolean = { false }, + val userCanTriggerRoomNotification: (UserId) -> Boolean = { false }, + val userCanSendMessage: (UserId, MessageEventType) -> Boolean = { _, _ -> false }, + val userCanSendState: (UserId, StateEventType) -> Boolean = { _, _ -> false }, +) : RoomPermissions { + + override fun canOwnUserBan(): Boolean = ownerCanBan + override fun canOwnUserInvite(): Boolean = ownerCanInvite + override fun canOwnUserKick(): Boolean = ownerCanKick + override fun canOwnUserPinUnpin(): Boolean = ownerCanPinUnpin + override fun canOwnUserRedactOther(): Boolean = ownerCanRedactOther + override fun canOwnUserRedactOwn(): Boolean = ownerCanRedactOwn + override fun canOwnUserSendMessage(message: MessageEventType): Boolean = ownerCanSendMessage(message) + override fun canOwnUserSendState(stateEvent: StateEventType): Boolean = ownerCanSendState(stateEvent) + override fun canOwnUserTriggerRoomNotification(): Boolean = ownerCanTriggerRoomNotification + override fun canUserBan(userId: UserId): Boolean = userCanBan(userId) + override fun canUserInvite(userId: UserId): Boolean = userCanInvite(userId) + override fun canUserKick(userId: UserId): Boolean = userCanKick(userId) + override fun canUserPinUnpin(userId: UserId): Boolean = userCanPinUnpin(userId) + override fun canUserRedactOther(userId: UserId): Boolean = userCanRedactOther(userId) + override fun canUserRedactOwn(userId: UserId): Boolean = userCanRedactOwn(userId) + override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean = userCanSendMessage(userId, message) + override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean = userCanSendState(userId, stateEvent) + override fun canUserTriggerRoomNotification(userId: UserId): Boolean = userCanTriggerRoomNotification(userId) + + override fun close() { + // no-op for the fake + } +} From ee38fb5f633a7cb7b5c9005dacdc0d627018e91f Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 8 Dec 2025 22:23:07 +0100 Subject: [PATCH 116/347] misc(power level) : use new api --- .../api/KnockRequestPermissions.kt | 34 +++++++++ .../banner/KnockRequestsBannerPresenter.kt | 2 +- .../impl/data/KnockRequestPermissions.kt | 33 --------- .../impl/data/KnockRequestsModule.kt | 7 +- .../impl/data/KnockRequestsService.kt | 1 + .../impl/list/KnockRequestsListState.kt | 2 +- .../list/KnockRequestsListStateProvider.kt | 2 +- .../KnockRequestsBannerPresenterTest.kt | 2 +- .../list/KnockRequestsListPresenterTest.kt | 2 +- .../messages/impl/MessagesPresenter.kt | 30 ++------ .../messages/impl/UserEventPermissions.kt | 13 ++++ .../MessageComposerPresenter.kt | 5 +- .../list/PinnedMessagesListPresenter.kt | 69 ++++++++---------- .../impl/timeline/TimelinePresenter.kt | 19 +++-- .../roomcall/impl/RoomCallStatePresenter.kt | 6 +- .../roomdetails/impl/RoomDetailsPresenter.kt | 71 +++++++++---------- .../impl/members/RoomMemberListPresenter.kt | 5 +- .../api/RoomDetailsEditPermissions.kt | 37 ++++++++++ .../impl/RoomDetailsEditPresenter.kt | 21 +++--- .../impl/RoomMemberModerationPresenter.kt | 30 ++++---- .../api/SecurityAndPrivacyPermissions.kt | 24 +++---- .../impl/root/SecurityAndPrivacyPresenter.kt | 8 ++- .../impl/root/UserProfilePresenter.kt | 7 +- .../libraries/matrix/api/room/BaseRoom.kt | 51 ------------- .../api/room/powerlevels/RoomPermissions.kt | 58 ++++++++++----- .../room/powerlevels/RoomPowerLevelsValues.kt | 52 -------------- .../impl/gallery/MediaGalleryPresenter.kt | 14 ++-- .../impl/model/MediaPermissions.kt | 29 ++++++++ .../impl/viewer/MediaViewerPresenter.kt | 12 ++-- 29 files changed, 312 insertions(+), 334 deletions(-) create mode 100644 features/knockrequests/api/src/main/kotlin/io/element/android/features/knockrequests/api/KnockRequestPermissions.kt delete mode 100644 features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestPermissions.kt create mode 100644 features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt create mode 100644 libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/model/MediaPermissions.kt diff --git a/features/knockrequests/api/src/main/kotlin/io/element/android/features/knockrequests/api/KnockRequestPermissions.kt b/features/knockrequests/api/src/main/kotlin/io/element/android/features/knockrequests/api/KnockRequestPermissions.kt new file mode 100644 index 0000000000..82bceb5be0 --- /dev/null +++ b/features/knockrequests/api/src/main/kotlin/io/element/android/features/knockrequests/api/KnockRequestPermissions.kt @@ -0,0 +1,34 @@ +/* + * 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.knockrequests.api + +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class KnockRequestPermissions( + val canAccept: Boolean, + val canDecline: Boolean, + val canBan: Boolean, +) { + val hasAny = canAccept || canDecline || canBan + + companion object { + val DEFAULT = KnockRequestPermissions( + canAccept = false, + canDecline = false, + canBan = false, + ) + } +} + +fun RoomPermissions.knockRequestPermissions(): KnockRequestPermissions { + return KnockRequestPermissions( + canAccept = canOwnUserInvite(), + canDecline = canOwnUserKick(), + canBan = canOwnUserBan(), + ) +} diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt index 641efffaa3..f340d597b1 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenter.kt @@ -49,7 +49,7 @@ class KnockRequestsBannerPresenter( val shouldShowBanner by remember { derivedStateOf { - permissions.canHandle && knockRequests.isNotEmpty() + permissions.hasAny && knockRequests.isNotEmpty() } } diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestPermissions.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestPermissions.kt deleted file mode 100644 index 2ca4d4df74..0000000000 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestPermissions.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.knockrequests.impl.data - -import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.powerlevels.canBan -import io.element.android.libraries.matrix.api.room.powerlevels.canInvite -import io.element.android.libraries.matrix.api.room.powerlevels.canKick -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map - -data class KnockRequestPermissions( - val canAccept: Boolean, - val canDecline: Boolean, - val canBan: Boolean, -) { - val canHandle = canAccept || canDecline || canBan -} - -fun JoinedRoom.knockRequestPermissionsFlow(): Flow { - return syncUpdateFlow.map { - val canAccept = canInvite().getOrDefault(false) - val canDecline = canKick().getOrDefault(false) - val canBan = canBan().getOrDefault(false) - KnockRequestPermissions(canAccept, canDecline, canBan) - } -} diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsModule.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsModule.kt index eeba54f87d..b51b78f105 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsModule.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsModule.kt @@ -12,10 +12,13 @@ import dev.zacsweers.metro.BindingContainer import dev.zacsweers.metro.ContributesTo import dev.zacsweers.metro.Provides import dev.zacsweers.metro.SingleIn +import io.element.android.features.knockrequests.api.KnockRequestPermissions +import io.element.android.features.knockrequests.api.knockRequestPermissions import io.element.android.libraries.di.RoomScope import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsFlow @BindingContainer @ContributesTo(RoomScope::class) @@ -25,7 +28,9 @@ object KnockRequestsModule { fun knockRequestsService(room: JoinedRoom, featureFlagService: FeatureFlagService): KnockRequestsService { return KnockRequestsService( knockRequestsFlow = room.knockRequestsFlow, - permissionsFlow = room.knockRequestPermissionsFlow(), + permissionsFlow = room.permissionsFlow(KnockRequestPermissions.DEFAULT) { perms -> + perms.knockRequestPermissions() + }, isKnockFeatureEnabledFlow = featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock), coroutineScope = room.roomCoroutineScope ) diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsService.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsService.kt index 04c2f7b316..98570e6b28 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsService.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/data/KnockRequestsService.kt @@ -8,6 +8,7 @@ package io.element.android.features.knockrequests.impl.data +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.room.knock.KnockRequest diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt index a1bb90cae8..ae770a297d 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListState.kt @@ -9,7 +9,7 @@ package io.element.android.features.knockrequests.impl.list import androidx.compose.runtime.Immutable -import io.element.android.features.knockrequests.impl.data.KnockRequestPermissions +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.features.knockrequests.impl.data.KnockRequestPresentable import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStateProvider.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStateProvider.kt index 2c4c92a6b6..85fc0675ad 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStateProvider.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListStateProvider.kt @@ -9,7 +9,7 @@ package io.element.android.features.knockrequests.impl.list import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.knockrequests.impl.data.KnockRequestPermissions +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.features.knockrequests.impl.data.KnockRequestPresentable import io.element.android.features.knockrequests.impl.data.aKnockRequestPresentable import io.element.android.libraries.architecture.AsyncAction diff --git a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt index 9eaa51cecb..3161d3e81f 100644 --- a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt +++ b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/banner/KnockRequestsBannerPresenterTest.kt @@ -9,7 +9,7 @@ package io.element.android.features.knockrequests.impl.banner import com.google.common.truth.Truth.assertThat -import io.element.android.features.knockrequests.impl.data.KnockRequestPermissions +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.features.knockrequests.impl.data.KnockRequestsService import io.element.android.libraries.matrix.api.room.knock.KnockRequest import io.element.android.libraries.matrix.test.A_USER_ID diff --git a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt index b0d0b68c91..7102b01773 100644 --- a/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt +++ b/features/knockrequests/impl/src/test/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenterTest.kt @@ -11,7 +11,7 @@ package io.element.android.features.knockrequests.impl.list import com.google.common.truth.Truth.assertThat -import io.element.android.features.knockrequests.impl.data.KnockRequestPermissions +import io.element.android.features.knockrequests.api.KnockRequestPermissions import io.element.android.features.knockrequests.impl.data.KnockRequestsService import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index a5b3106b3d..8a5f3cf423 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -12,12 +12,10 @@ import android.os.Build import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState -import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable @@ -76,14 +74,10 @@ import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.permalink.PermalinkParser import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.isDm -import io.element.android.libraries.matrix.api.room.powerlevels.canPinUnpin -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn -import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.ui.messages.reply.map import io.element.android.libraries.matrix.ui.model.getAvatarData @@ -170,7 +164,9 @@ class MessagesPresenter( val roomCallState = roomCallStatePresenter.present() val roomMemberModerationState = roomMemberModerationPresenter.present() - val userEventPermissions by userEventPermissions(roomInfo) + val userEventPermissions by room.permissionsAsState(UserEventPermissions.DEFAULT) { perms -> + perms.userEventPermissions() + } val roomAvatar by remember { derivedStateOf { roomInfo.avatarData() } @@ -301,24 +297,6 @@ class MessagesPresenter( ) } - @Composable - private fun userEventPermissions(roomInfo: RoomInfo): State { - val key = if (roomInfo.privilegedCreatorRole && roomInfo.creators.contains(room.sessionId)) { - Long.MAX_VALUE - } else { - roomInfo.roomPowerLevels?.hashCode() ?: 0L - } - return produceState(UserEventPermissions.DEFAULT, key1 = key) { - value = UserEventPermissions( - canSendMessage = room.canSendMessage(type = MessageEventType.RoomMessage).getOrElse { true }, - canSendReaction = room.canSendMessage(type = MessageEventType.Reaction).getOrElse { true }, - canRedactOwn = room.canRedactOwn().getOrElse { false }, - canRedactOther = room.canRedactOther().getOrElse { false }, - canPinUnpin = room.canPinUnpin().getOrElse { false }, - ) - } - } - private fun RoomInfo.avatarData(): AvatarData { return AvatarData( id = id.value, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/UserEventPermissions.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/UserEventPermissions.kt index f7d221950b..349c8e58dc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/UserEventPermissions.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/UserEventPermissions.kt @@ -8,6 +8,9 @@ package io.element.android.features.messages.impl +import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + /** * Represents the permissions a user has in a room. * It's dependent of the user's power level in the room. @@ -29,3 +32,13 @@ data class UserEventPermissions( ) } } + +fun RoomPermissions.userEventPermissions(): UserEventPermissions { + return UserEventPermissions( + canRedactOwn = canOwnUserRedactOwn(), + canRedactOther = canOwnUserRedactOther(), + canSendMessage = canOwnUserSendMessage(MessageEventType.RoomMessage), + canSendReaction = canOwnUserSendMessage(MessageEventType.Reaction), + canPinUnpin = canOwnUserPinUnpin() + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index b193e97fa3..b2c5182a0a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -55,6 +55,7 @@ import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.draft.ComposerDraftType import io.element.android.libraries.matrix.api.room.getDirectRoomMember import io.element.android.libraries.matrix.api.room.isDm +import io.element.android.libraries.matrix.api.room.powerlevels.use import io.element.android.libraries.matrix.api.timeline.TimelineException import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails @@ -396,7 +397,9 @@ class MessageComposerPresenter( val currentUserId = room.sessionId suspend fun canSendRoomMention(): Boolean { - val userCanSendAtRoom = room.canUserTriggerRoomNotification(currentUserId).getOrDefault(false) + val userCanSendAtRoom = room.roomPermissions().use(false){ perms -> + perms.canOwnUserTriggerRoomNotification() + } return !room.isDm() && userCanSendAtRoom } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt index cdc1f85f1d..b2d2caa7f9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenter.kt @@ -10,11 +10,10 @@ package io.element.android.features.messages.impl.pinned.list import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue @@ -35,6 +34,7 @@ import io.element.android.features.messages.impl.timeline.factories.TimelineItem import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState import io.element.android.features.messages.impl.typing.TypingNotificationState +import io.element.android.features.messages.impl.userEventPermissions import io.element.android.features.roomcall.api.aStandByCallState import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter @@ -44,11 +44,9 @@ import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.powerlevels.canPinUnpin -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn +import io.element.android.libraries.matrix.api.room.isDm +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomMembers -import io.element.android.libraries.matrix.ui.room.isDmAsState import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analyticsproviders.api.trackers.captureInteraction @@ -97,31 +95,33 @@ class PinnedMessagesListPresenter( @Composable override fun present(): PinnedMessagesListState { htmlConverterProvider.Update() - val isDm by room.isDmAsState() - - val timelineRoomInfo = remember(isDm) { - TimelineRoomInfo( - isDm = isDm, - name = room.info().name, - // We don't need to compute those values - userHasPermissionToSendMessage = false, - userHasPermissionToSendReaction = false, - // We do not care about the call state here. - roomCallState = aStandByCallState(), - // don't compute this value or the pin icon will be shown - pinnedEventIds = persistentListOf(), - typingNotificationState = TypingNotificationState( - renderTypingNotifications = false, - typingMembers = persistentListOf(), - reserveSpace = false, - ), - predecessorRoom = room.predecessorRoom(), - ) + val roomInfo by room.roomInfoFlow.collectAsState() + val timelineRoomInfo by remember { + derivedStateOf { + TimelineRoomInfo( + isDm = roomInfo.isDm, + name = roomInfo.name, + // We don't need to compute those values + userHasPermissionToSendMessage = false, + userHasPermissionToSendReaction = false, + // We do not care about the call state here. + roomCallState = aStandByCallState(), + // don't compute this value or the pin icon will be shown + pinnedEventIds = persistentListOf(), + typingNotificationState = TypingNotificationState( + renderTypingNotifications = false, + typingMembers = persistentListOf(), + reserveSpace = false, + ), + predecessorRoom = room.predecessorRoom(), + ) + } } val timelineProtectionState = timelineProtectionPresenter.present() val linkState = linkPresenter.present() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - val userEventPermissions by userEventPermissions(syncUpdateFlow.value) + val userEventPermissions by room.permissionsAsState(UserEventPermissions.DEFAULT) { perms -> + perms.userEventPermissions() + } val displayThreadSummaries by featureFlagService.isFeatureEnabledFlow(FeatureFlags.Threads).collectAsState(false) @@ -192,19 +192,6 @@ class PinnedMessagesListPresenter( } } - @Composable - private fun userEventPermissions(updateKey: Long): State { - return produceState(UserEventPermissions.DEFAULT, key1 = updateKey) { - value = UserEventPermissions( - canSendMessage = false, - canSendReaction = false, - canRedactOwn = room.canRedactOwn().getOrElse { false }, - canRedactOther = room.canRedactOther().getOrElse { false }, - canPinUnpin = room.canPinUnpin().getOrElse { false }, - ) - } - } - @Composable private fun PinnedMessagesListEffect(onItemsChange: (AsyncData>) -> Unit) { val updatedOnItemsChange by rememberUpdatedState(onItemsChange) 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 e44cac4f27..4815602c8e 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 @@ -24,6 +24,7 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject import io.element.android.features.messages.impl.MessagesNavigator +import io.element.android.features.messages.impl.UserEventPermissions import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureEvents import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureState import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory @@ -32,6 +33,7 @@ import io.element.android.features.messages.impl.timeline.model.NewEventState import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemTypingNotificationModel import io.element.android.features.messages.impl.typing.TypingNotificationState +import io.element.android.features.messages.impl.userEventPermissions import io.element.android.features.messages.impl.voicemessages.timeline.RedactedVoiceMessageManager import io.element.android.features.poll.api.actions.EndPollAction import io.element.android.features.poll.api.actions.SendPollResponseAction @@ -46,14 +48,13 @@ import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.UniqueId import io.element.android.libraries.matrix.api.core.asEventId import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.isDm +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin -import io.element.android.libraries.matrix.ui.room.canSendMessageAsState import io.element.android.libraries.preferences.api.store.SessionPreferencesStore import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.DisplayFirstTimelineItems import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline @@ -128,11 +129,6 @@ class TimelinePresenter( val roomInfo by room.roomInfoFlow.collectAsState() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - - val userHasPermissionToSendMessage by room.canSendMessageAsState(type = MessageEventType.RoomMessage, updateKey = syncUpdateFlow.value) - val userHasPermissionToSendReaction by room.canSendMessageAsState(type = MessageEventType.Reaction, updateKey = syncUpdateFlow.value) - val prevMostRecentItemId = rememberSaveable { mutableStateOf(null) } val newEventState = remember { mutableStateOf(NewEventState.None) } @@ -285,13 +281,16 @@ class TimelinePresenter( val typingNotificationState = typingNotificationPresenter.present() val roomCallState = roomCallStatePresenter.present() + val userEventPermissions by room.permissionsAsState(UserEventPermissions.DEFAULT) { perms -> + perms.userEventPermissions() + } val timelineRoomInfo by remember(typingNotificationState, roomCallState, roomInfo) { derivedStateOf { TimelineRoomInfo( name = roomInfo.name, - isDm = roomInfo.isDm.orFalse(), - userHasPermissionToSendMessage = userHasPermissionToSendMessage, - userHasPermissionToSendReaction = userHasPermissionToSendReaction, + isDm = roomInfo.isDm, + userHasPermissionToSendMessage = userEventPermissions.canSendMessage, + userHasPermissionToSendReaction = userEventPermissions.canSendReaction, roomCallState = roomCallState, pinnedEventIds = roomInfo.pinnedEventIds, typingNotificationState = typingNotificationState, diff --git a/features/roomcall/impl/src/main/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenter.kt b/features/roomcall/impl/src/main/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenter.kt index 5de47f9ff2..b18a2772a3 100644 --- a/features/roomcall/impl/src/main/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenter.kt +++ b/features/roomcall/impl/src/main/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenter.kt @@ -21,7 +21,8 @@ import io.element.android.features.enterprise.api.SessionEnterpriseService import io.element.android.features.roomcall.api.RoomCallState import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.ui.room.canCall +import io.element.android.libraries.matrix.api.room.powerlevels.canCall +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState @Inject class RoomCallStatePresenter( @@ -35,8 +36,7 @@ class RoomCallStatePresenter( value = sessionEnterpriseService.isElementCallAvailable() } val roomInfo by room.roomInfoFlow.collectAsState() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - val canJoinCall by room.canCall(updateKey = syncUpdateFlow.value) + val canJoinCall by room.permissionsAsState(false) { perms -> perms.canCall() } val isUserInTheCall by remember { derivedStateOf { room.sessionId in roomInfo.activeRoomCallParticipants diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index 95c4f1e9e2..83840ad604 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -10,6 +10,7 @@ package io.element.android.features.roomdetails.impl import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue @@ -18,11 +19,14 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import dev.zacsweers.metro.Inject import im.vector.app.features.analytics.plan.Interaction +import io.element.android.features.knockrequests.api.knockRequestPermissions import io.element.android.features.leaveroom.api.LeaveRoomEvent import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.roomcall.api.RoomCallState import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter -import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissionsAsState +import io.element.android.features.roomdetailsedit.api.RoomDetailsEditPermissions +import io.element.android.features.roomdetailsedit.api.roomDetailsEditPermissions +import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions import io.element.android.libraries.androidutils.clipboard.ClipboardHelper import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.CoroutineDispatchers @@ -36,17 +40,13 @@ import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.room.RoomMembersState -import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.room.join.JoinRule -import io.element.android.libraries.matrix.api.room.powerlevels.canInvite -import io.element.android.libraries.matrix.api.room.powerlevels.canSendState +import io.element.android.libraries.matrix.api.room.powerlevels.canEditRolesAndPermissions +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomNotificationSettings -import io.element.android.libraries.matrix.ui.room.canHandleKnockRequestsAsState import io.element.android.libraries.matrix.ui.room.getCurrentRoomMember import io.element.android.libraries.matrix.ui.room.getDirectRoomMember -import io.element.android.libraries.matrix.ui.room.isDmAsState -import io.element.android.libraries.matrix.ui.room.isOwnUserAdmin import io.element.android.libraries.matrix.ui.room.roomMemberIdentityStateChange import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.ui.strings.CommonStrings @@ -77,8 +77,6 @@ class RoomDetailsPresenter( val scope = rememberCoroutineScope() val leaveRoomState = leaveRoomPresenter.present() val roomInfo by room.roomInfoFlow.collectAsState() - val isUserAdmin = room.isOwnUserAdmin() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val roomAvatar by remember { derivedStateOf { roomInfo.avatarUrl } } val roomName by remember { derivedStateOf { roomInfo.name?.trim().orEmpty() } } @@ -93,15 +91,11 @@ class RoomDetailsPresenter( observeNotificationSettings() } + val isDm = roomInfo.isDm val membersState by room.membersStateFlow.collectAsState() - val canInvite by getCanInvite(membersState) - + val permissions by getPermissions() val canonicalAlias by remember { derivedStateOf { roomInfo.canonicalAlias } } val isEncrypted by remember { derivedStateOf { roomInfo.isEncrypted == true } } - val isDm by room.isDmAsState() - val canEditName by getCanSendState(membersState, StateEventType.ROOM_NAME) - val canEditAvatar by getCanSendState(membersState, StateEventType.ROOM_AVATAR) - val canEditTopic by getCanSendState(membersState, StateEventType.ROOM_TOPIC) val dmMember by room.getDirectRoomMember(membersState) val currentMember by room.getCurrentRoomMember(membersState) val roomMemberDetailsPresenter = roomMemberDetailsPresenter(dmMember) @@ -109,16 +103,15 @@ class RoomDetailsPresenter( val roomCallState = roomCallStatePresenter.present() val joinedMemberCount by remember { derivedStateOf { roomInfo.joinedMembersCount } } - val topicState = remember(canEditTopic, roomTopic, roomType) { + val topicState = remember(permissions.editDetailsPermissions.canEditTopic, roomTopic, roomType) { val topic = roomTopic when { !topic.isNullOrBlank() -> RoomTopicState.ExistingTopic(topic) - canEditTopic && roomType is RoomDetailsType.Room -> RoomTopicState.CanAddTopic + permissions.editDetailsPermissions.canEditTopic && roomType is RoomDetailsType.Room -> RoomTopicState.CanAddTopic else -> RoomTopicState.Hidden } } - val canHandleKnockRequests by room.canHandleKnockRequestsAsState(syncUpdateFlow.value) val isKnockRequestsEnabled by remember { featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock) }.collectAsState(false) @@ -126,7 +119,7 @@ class RoomDetailsPresenter( room.knockRequestsFlow.collect { value = it.size } } val canShowKnockRequests by remember { - derivedStateOf { isKnockRequestsEnabled && canHandleKnockRequests && joinRule == JoinRule.Knock } + derivedStateOf { isKnockRequestsEnabled && permissions.canManageKnockRequests && joinRule == JoinRule.Knock } } val isDeveloperModeEnabled by remember { appPreferencesStore.isDeveloperModeEnabledFlow() @@ -162,13 +155,6 @@ class RoomDetailsPresenter( val roomMemberDetailsState = roomMemberDetailsPresenter?.present() - val securityAndPrivacyPermissions = room.securityAndPrivacyPermissionsAsState(syncUpdateFlow.value) - val canShowSecurityAndPrivacy by remember { - derivedStateOf { - roomType is RoomDetailsType.Room && securityAndPrivacyPermissions.value.hasAny - } - } - val hasMemberVerificationViolations by produceState(false) { room.roomMemberIdentityStateChange(waitForEncryption = true) .onEach { identities -> value = identities.any { it.identityState == IdentityState.VerificationViolation } } @@ -185,22 +171,22 @@ class RoomDetailsPresenter( roomTopic = topicState, memberCount = joinedMemberCount, isEncrypted = isEncrypted, - canInvite = canInvite, - canEdit = (canEditAvatar || canEditName || canEditTopic) && roomType == RoomDetailsType.Room, + canInvite = permissions.canInvite, + canEdit = roomType == RoomDetailsType.Room && permissions.editDetailsPermissions.hasAny, roomCallState = roomCallState, roomType = roomType, roomMemberDetailsState = roomMemberDetailsState, leaveRoomState = leaveRoomState, roomNotificationSettings = roomNotificationSettingsState.roomNotificationSettings(), isFavorite = isFavorite, - displayRolesAndPermissionsSettings = !isDm && isUserAdmin, + displayRolesAndPermissionsSettings = !isDm && permissions.canEditRolesAndPermissions, isPublic = joinRule == JoinRule.Public, heroes = roomInfo.heroes.toImmutableList(), pinnedMessagesCount = pinnedMessagesCount, snackbarMessage = snackbarMessage, canShowKnockRequests = canShowKnockRequests, knockRequestsCount = knockRequestsCount, - canShowSecurityAndPrivacy = canShowSecurityAndPrivacy, + canShowSecurityAndPrivacy = !isDm && permissions.canEditSecurityAndPrivacy, hasMemberVerificationViolations = hasMemberVerificationViolations, canReportRoom = canReportRoom, isTombstoned = roomInfo.successorRoom != null, @@ -232,14 +218,25 @@ class RoomDetailsPresenter( } } - @Composable - private fun getCanInvite(membersState: RoomMembersState) = produceState(false, membersState) { - value = room.canInvite().getOrElse { false } - } + private data class Permissions( + val canInvite: Boolean = false, + val editDetailsPermissions: RoomDetailsEditPermissions = RoomDetailsEditPermissions.DEFAULT, + val canManageKnockRequests: Boolean = false, + val canEditRolesAndPermissions: Boolean = false, + val canEditSecurityAndPrivacy: Boolean = false, + ) @Composable - private fun getCanSendState(membersState: RoomMembersState, type: StateEventType) = produceState(false, membersState) { - value = room.canSendState(type).getOrElse { false } + private fun getPermissions(): State { + return room.permissionsAsState(Permissions()) { perms -> + Permissions( + canInvite = perms.canOwnUserInvite(), + editDetailsPermissions = perms.roomDetailsEditPermissions(), + canManageKnockRequests = perms.knockRequestPermissions().hasAny, + canEditRolesAndPermissions = perms.canEditRolesAndPermissions(), + canEditSecurityAndPrivacy = perms.securityAndPrivacyPermissions().hasAny, + ) + } } private fun CoroutineScope.observeNotificationSettings() { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index f1d3f61f7e..6917057a06 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -32,10 +32,10 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.room.toMatrixUser import io.element.android.libraries.matrix.ui.room.PowerLevelRoomMemberComparator -import io.element.android.libraries.matrix.ui.room.canInviteAsState import io.element.android.libraries.matrix.ui.room.roomMemberIdentityStateChange import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.persistentMapOf @@ -58,8 +58,7 @@ class RoomMemberListPresenter( override fun present(): RoomMemberListState { var searchQuery by rememberSaveable { mutableStateOf("") } val membersState by room.membersStateFlow.collectAsState() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - val canInvite by room.canInviteAsState(syncUpdateFlow.value) + val canInvite by room.permissionsAsState(false) { perms -> perms.canOwnUserInvite() } val roomModerationState = roomMembersModerationPresenter.present() val roomMemberIdentityStates by produceState(persistentMapOf()) { diff --git a/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt new file mode 100644 index 0000000000..f95f4466f2 --- /dev/null +++ b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt @@ -0,0 +1,37 @@ +/* + * 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.roomdetailsedit.api + +import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class RoomDetailsEditPermissions( + val canEditName: Boolean, + val canEditTopic: Boolean, + val canEditAvatar: Boolean, +){ + val hasAny = canEditName || + canEditTopic || + canEditAvatar + + companion object { + val DEFAULT = RoomDetailsEditPermissions( + canEditName = false, + canEditTopic = false, + canEditAvatar = false, + ) + } +} + +fun RoomPermissions.roomDetailsEditPermissions(): RoomDetailsEditPermissions { + return RoomDetailsEditPermissions( + canEditName = canOwnUserSendState(StateEventType.ROOM_NAME), + canEditTopic = canOwnUserSendState(StateEventType.ROOM_TOPIC), + canEditAvatar = canOwnUserSendState(StateEventType.ROOM_AVATAR), + ) +} diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt index 5e685ff81f..ed729928d8 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt @@ -23,6 +23,8 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.core.net.toUri import dev.zacsweers.metro.Inject +import io.element.android.features.roomdetailsedit.api.RoomDetailsEditPermissions +import io.element.android.features.roomdetailsedit.api.roomDetailsEditPermissions import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter @@ -30,8 +32,7 @@ import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.matrix.api.room.JoinedRoom -import io.element.android.libraries.matrix.api.room.StateEventType -import io.element.android.libraries.matrix.api.room.powerlevels.canSendState +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider @@ -93,14 +94,8 @@ class RoomDetailsEditPresenter( } } - var canChangeName by remember { mutableStateOf(false) } - var canChangeTopic by remember { mutableStateOf(false) } - var canChangeAvatar by remember { mutableStateOf(false) } - - LaunchedEffect(roomSyncUpdateFlow.value) { - canChangeName = room.canSendState(StateEventType.ROOM_NAME).getOrElse { false } - canChangeTopic = room.canSendState(StateEventType.ROOM_TOPIC).getOrElse { false } - canChangeAvatar = room.canSendState(StateEventType.ROOM_AVATAR).getOrElse { false } + val permissions by room.permissionsAsState(RoomDetailsEditPermissions.DEFAULT){perms -> + perms.roomDetailsEditPermissions() } val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker( @@ -181,11 +176,11 @@ class RoomDetailsEditPresenter( return RoomDetailsEditState( roomId = room.roomId, roomRawName = roomRawNameEdited, - canChangeName = canChangeName, + canChangeName = permissions.canEditName, roomTopic = roomTopicEdited, - canChangeTopic = canChangeTopic, + canChangeTopic = permissions.canEditTopic, roomAvatarUrl = roomAvatarUriEdited, - canChangeAvatar = canChangeAvatar, + canChangeAvatar = permissions.canEditAvatar, avatarActions = avatarActions, saveButtonEnabled = saveButtonEnabled, saveAction = saveAction.value, diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt index 31ff2da2b2..96749ba5ac 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt @@ -30,10 +30,9 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.matrix.ui.room.canBanAsState -import io.element.android.libraries.matrix.ui.room.canKickAsState import io.element.android.libraries.matrix.ui.room.userPowerLevelAsState import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList @@ -56,8 +55,12 @@ class RoomMemberModerationPresenter( override fun present(): RoomMemberModerationState { val coroutineScope = rememberCoroutineScope() val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - val canBan = room.canBanAsState(syncUpdateFlow.value) - val canKick = room.canKickAsState(syncUpdateFlow.value) + val permissions by room.permissionsAsState(Permissions()) { perms -> + Permissions( + canKick = perms.canOwnUserKick(), + canBan = perms.canOwnUserBan(), + ) + } val currentUserMemberPowerLevel = room.userPowerLevelAsState(syncUpdateFlow.value) val kickUserAsyncAction = @@ -80,8 +83,7 @@ class RoomMemberModerationPresenter( } moderationActions.value = computeModerationActions( member = member, - canKick = canKick.value, - canBan = canBan.value, + permissions = permissions, currentUserMemberPowerLevel = currentUserMemberPowerLevel.value, ) } @@ -134,8 +136,8 @@ class RoomMemberModerationPresenter( } return InternalRoomMemberModerationState( - canKick = canKick.value, - canBan = canBan.value, + canKick = permissions.canKick, + canBan = permissions.canBan, selectedUser = selectedUser, actions = moderationActions.value, kickUserAsyncAction = kickUserAsyncAction.value, @@ -147,8 +149,7 @@ class RoomMemberModerationPresenter( private fun computeModerationActions( member: RoomMember?, - canKick: Boolean, - canBan: Boolean, + permissions: Permissions, currentUserMemberPowerLevel: Long, ): ImmutableList { return buildList { @@ -158,11 +159,11 @@ class RoomMemberModerationPresenter( val canModerateThisUser = currentUserMemberPowerLevel > targetMemberPowerLevel // Assume the member is joined when it's unknown val membership = member?.membership ?: RoomMembershipState.JOIN - if (canKick) { + if (permissions.canKick) { val isKickEnabled = canModerateThisUser && membership.isActive() add(ModerationActionState(action = ModerationAction.KickUser, isEnabled = isKickEnabled)) } - if (canBan) { + if (permissions.canBan) { if (membership == RoomMembershipState.BAN) { add(ModerationActionState(action = ModerationAction.UnbanUser, isEnabled = canModerateThisUser)) } else { @@ -208,6 +209,11 @@ class RoomMemberModerationPresenter( ) } + private data class Permissions( + val canKick: Boolean = false, + val canBan: Boolean = false, + ) + private fun CoroutineScope.runActionAndWaitForMembershipChange( action: MutableState>, block: suspend () -> Result diff --git a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt index 82ab30581e..bacd863ca6 100644 --- a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt +++ b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt @@ -8,13 +8,8 @@ package io.element.android.features.securityandprivacy.api -import androidx.compose.runtime.Composable -import androidx.compose.runtime.State -import androidx.compose.runtime.produceState -import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions.Companion.DEFAULT -import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.StateEventType -import io.element.android.libraries.matrix.api.room.powerlevels.canSendState +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions data class SecurityAndPrivacyPermissions( val canChangeRoomAccess: Boolean, @@ -37,14 +32,11 @@ data class SecurityAndPrivacyPermissions( } } -@Composable -fun BaseRoom.securityAndPrivacyPermissionsAsState(updateKey: Long): State { - return produceState(DEFAULT, key1 = updateKey) { - value = SecurityAndPrivacyPermissions( - canChangeRoomAccess = canSendState(type = StateEventType.ROOM_JOIN_RULES).getOrElse { false }, - canChangeHistoryVisibility = canSendState(type = StateEventType.ROOM_HISTORY_VISIBILITY).getOrElse { false }, - canChangeEncryption = canSendState(type = StateEventType.ROOM_ENCRYPTION).getOrElse { false }, - canChangeRoomVisibility = canSendState(type = StateEventType.ROOM_CANONICAL_ALIAS).getOrElse { false }, - ) - } +fun RoomPermissions.securityAndPrivacyPermissions(): SecurityAndPrivacyPermissions { + return SecurityAndPrivacyPermissions( + canChangeRoomAccess = canOwnUserSendState(StateEventType.ROOM_JOIN_RULES), + canChangeHistoryVisibility = canOwnUserSendState(StateEventType.ROOM_HISTORY_VISIBILITY), + canChangeEncryption = canOwnUserSendState(StateEventType.ROOM_ENCRYPTION), + canChangeRoomVisibility = canOwnUserSendState(StateEventType.ROOM_CANONICAL_ALIAS), + ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index b77ad0e7d6..af0f44be38 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -21,7 +21,8 @@ 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.securityandprivacy.api.securityAndPrivacyPermissionsAsState +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions +import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.features.securityandprivacy.impl.editroomaddress.matchesServer import io.element.android.libraries.architecture.AsyncAction @@ -37,6 +38,7 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomInfo 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.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async @@ -106,7 +108,9 @@ class SecurityAndPrivacyPresenter( ) var showEnableEncryptionConfirmation by remember(savedSettings.isEncrypted) { mutableStateOf(false) } - val permissions by room.securityAndPrivacyPermissionsAsState(syncUpdateFlow.value) + val permissions by room.permissionsAsState(SecurityAndPrivacyPermissions.DEFAULT) { perms -> + perms.securityAndPrivacyPermissions() + } fun handleEvent(event: SecurityAndPrivacyEvent) { when (event) { diff --git a/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt b/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt index 9bf31e0b07..8b7eddca54 100644 --- a/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt +++ b/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt @@ -34,6 +34,8 @@ import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.powerlevels.canCall +import io.element.android.libraries.matrix.api.room.powerlevels.use import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.distinctUntilChanged @@ -56,7 +58,7 @@ class UserProfilePresenter( @Composable private fun getDmRoomId(): State { - return produceState(initialValue = null) { + return produceState(initialValue = null) { value = client.findDM(userId).getOrNull() } } @@ -66,7 +68,6 @@ class UserProfilePresenter( val isElementCallAvailable by produceState(initialValue = false, roomId) { value = sessionEnterpriseService.isElementCallAvailable() } - return produceState(initialValue = false, isElementCallAvailable, roomId) { value = when { isElementCallAvailable.not() -> false @@ -75,7 +76,7 @@ class UserProfilePresenter( roomId ?.let { client.getRoom(it) } ?.use { room -> - room.canUserJoinCall(client.sessionId).getOrNull() + room.roomPermissions().use(false){ perms -> perms.canCall()} } .orFalse() } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt index cde3a5eff7..481171ace0 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/BaseRoom.kt @@ -130,57 +130,6 @@ interface BaseRoom : Closeable { */ suspend fun forget(): Result - /** - * Returns `true` if the user with the provided [userId] can invite other users to the room. - */ - suspend fun canUserInvite(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can kick other users from the room. - */ - suspend fun canUserKick(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can ban other users from the room. - */ - suspend fun canUserBan(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can redact their own messages. - */ - suspend fun canUserRedactOwn(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can redact messages from other users. - */ - suspend fun canUserRedactOther(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can send state events. - */ - suspend fun canUserSendState(userId: UserId, type: StateEventType): Result - - /** - * Returns `true` if the user with the provided [userId] can send messages. - */ - suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result - - /** - * Returns `true` if the user with the provided [userId] can trigger an `@room` notification. - */ - suspend fun canUserTriggerRoomNotification(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can pin or unpin messages. - */ - suspend fun canUserPinUnpin(userId: UserId): Result - - /** - * Returns `true` if the user with the provided [userId] can join or starts calls. - */ - suspend fun canUserJoinCall(userId: UserId): Result = - canUserSendState(userId, StateEventType.CALL_MEMBER) - /** * Sets the room as favorite or not, based on the [isFavorite] parameter. */ diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt index cdc735b819..735627e10e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt @@ -7,9 +7,18 @@ package io.element.android.libraries.matrix.api.room.powerlevels +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.remember import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.StateEventType +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.map +import timber.log.Timber /** * Provides information about the permissions of users in a room. @@ -120,23 +129,38 @@ interface RoomPermissions : AutoCloseable { fun canUserTriggerRoomNotification(userId: UserId): Boolean } -fun RoomPermissions.canEditRoomDetails(): Boolean { - return canOwnUserSendState(StateEventType.ROOM_NAME) || - canOwnUserSendState(StateEventType.ROOM_TOPIC) || - canOwnUserSendState(StateEventType.ROOM_AVATAR) -} - -fun RoomPermissions.canManageKnockRequests(): Boolean { - return canOwnUserInvite() || canOwnUserBan() || canOwnUserKick() -} - -fun RoomPermissions.canEditSecurityAndPrivacy(): Boolean { - return canOwnUserSendState(StateEventType.ROOM_JOIN_RULES) || - canOwnUserSendState(StateEventType.ROOM_HISTORY_VISIBILITY) || - canOwnUserSendState(StateEventType.ROOM_CANONICAL_ALIAS) || - canOwnUserSendState(StateEventType.ROOM_ENCRYPTION) -} - fun RoomPermissions.canEditRolesAndPermissions(): Boolean { return canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS) } + +fun RoomPermissions.canCall(): Boolean { + return canOwnUserSendState(StateEventType.CALL_MEMBER) +} + +fun Result.use(default: T, block: (RoomPermissions) -> T): T { + return fold( + onSuccess = { perms -> + perms.use(block) + }, + onFailure = { + default + } + ) +} + +fun BaseRoom.permissionsFlow(default: T, block: (RoomPermissions) -> T): Flow { + return roomInfoFlow + .map { info -> info.roomPowerLevels } + .distinctUntilChanged() + .map { + roomPermissions().use(default, block) + } +} + +@Composable +fun BaseRoom.permissionsAsState(default: T, block: (RoomPermissions) -> T): State { + return remember(this, default, block) { + Timber.d("Computing permissionsAsState for room $roomId with default=$default") + permissionsFlow(default, block) + }.collectAsState(default) +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt index d20b6141eb..a7eebbb99c 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPowerLevelsValues.kt @@ -8,11 +8,6 @@ package io.element.android.libraries.matrix.api.room.powerlevels -import io.element.android.libraries.core.extensions.runCatchingExceptions -import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.MessageEventType -import io.element.android.libraries.matrix.api.room.StateEventType - data class RoomPowerLevelsValues( val ban: Long, val invite: Long, @@ -24,50 +19,3 @@ data class RoomPowerLevelsValues( val roomTopic: Long, val spaceChild: Long, ) - -/** - * Shortcut for calling [BaseRoom.canUserInvite] with our own user. - */ -suspend fun BaseRoom.canInvite(): Result = canUserInvite(sessionId) - -/** - * Shortcut for calling [BaseRoom.canUserKick] with our own user. - */ -suspend fun BaseRoom.canKick(): Result = canUserKick(sessionId) - -/** - * Shortcut for calling [BaseRoom.canUserBan] with our own user. - */ -suspend fun BaseRoom.canBan(): Result = canUserBan(sessionId) - -/** - * Shortcut for calling [BaseRoom.canUserSendState] with our own user. - */ -suspend fun BaseRoom.canSendState(type: StateEventType): Result = canUserSendState(sessionId, type) - -/** - * Shortcut for calling [BaseRoom.canUserSendMessage] with our own user. - */ -suspend fun BaseRoom.canSendMessage(type: MessageEventType): Result = canUserSendMessage(sessionId, type) - -/** - * Shortcut for calling [BaseRoom.canUserRedactOwn] with our own user. - */ -suspend fun BaseRoom.canRedactOwn(): Result = canUserRedactOwn(sessionId) - -/** - * Shortcut for calling [BaseRoom.canRedactOther] with our own user. - */ -suspend fun BaseRoom.canRedactOther(): Result = canUserRedactOther(sessionId) - -/** - * Shortcut for checking if current user can handle knock requests. - */ -suspend fun BaseRoom.canHandleKnockRequests(): Result = runCatchingExceptions { - canInvite().getOrThrow() || canBan().getOrThrow() || canKick().getOrThrow() -} - -/** - * Shortcut for calling [BaseRoom.canUserPinUnpin] with our own user. - */ -suspend fun BaseRoom.canPinUnpin(): Result = canUserPinUnpin(sessionId) diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt index aee9af82b7..e5e493ee63 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt @@ -30,8 +30,7 @@ import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarM import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.mediaviewer.api.local.LocalMedia import io.element.android.libraries.mediaviewer.api.local.LocalMediaFactory import io.element.android.libraries.mediaviewer.impl.datasource.MediaGalleryDataSource @@ -39,8 +38,10 @@ import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetSta import io.element.android.libraries.mediaviewer.impl.local.LocalMediaActions import io.element.android.libraries.mediaviewer.impl.model.GroupedMediaItems import io.element.android.libraries.mediaviewer.impl.model.MediaItem +import io.element.android.libraries.mediaviewer.impl.model.MediaPermissions import io.element.android.libraries.mediaviewer.impl.model.eventId import io.element.android.libraries.mediaviewer.impl.model.mediaInfo +import io.element.android.libraries.mediaviewer.impl.model.mediaPermissions import io.element.android.libraries.mediaviewer.impl.model.mediaSource import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.coroutines.launch @@ -80,6 +81,10 @@ class MediaGalleryPresenter( mediaGalleryDataSource.start() } + val permissions by room.permissionsAsState(MediaPermissions.DEFAULT) { perms -> + perms.mediaPermissions() + } + val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState() localMediaActions.Configure() @@ -119,8 +124,8 @@ class MediaGalleryPresenter( eventId = event.mediaItem.eventId(), canDelete = when (event.mediaItem.mediaInfo().senderId) { null -> false - room.sessionId -> room.canRedactOwn().getOrElse { false } && event.mediaItem.eventId() != null - else -> room.canRedactOther().getOrElse { false } && event.mediaItem.eventId() != null + room.sessionId -> permissions.canRedactOwn && event.mediaItem.eventId() != null + else -> permissions.canRedactOther && event.mediaItem.eventId() != null }, mediaInfo = event.mediaItem.mediaInfo(), thumbnailSource = when (event.mediaItem) { @@ -202,6 +207,7 @@ class MediaGalleryPresenter( CommonStrings.error_unknown } } + } private fun GroupedMediaItems?.find(eventId: EventId?): MediaItem.Event? { diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/model/MediaPermissions.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/model/MediaPermissions.kt new file mode 100644 index 0000000000..4a111965e9 --- /dev/null +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/model/MediaPermissions.kt @@ -0,0 +1,29 @@ +/* + * 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.mediaviewer.impl.model + +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class MediaPermissions( + val canRedactOwn: Boolean, + val canRedactOther: Boolean, +) { + companion object { + val DEFAULT = MediaPermissions( + canRedactOwn = false, + canRedactOther = false, + ) + } +} + +fun RoomPermissions.mediaPermissions(): MediaPermissions { + return MediaPermissions( + canRedactOwn = canOwnUserRedactOwn(), + canRedactOther = canOwnUserRedactOther(), + ) +} diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt index 4709a4ec51..dc0feb70cf 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenter.kt @@ -32,8 +32,7 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState 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.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn +import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState 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.mediaviewer.api.MediaViewerEntryPoint @@ -41,6 +40,8 @@ import io.element.android.libraries.mediaviewer.api.local.LocalMedia import io.element.android.libraries.mediaviewer.impl.R import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState import io.element.android.libraries.mediaviewer.impl.local.LocalMediaActions +import io.element.android.libraries.mediaviewer.impl.model.MediaPermissions +import io.element.android.libraries.mediaviewer.impl.model.mediaPermissions import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.CoroutineScope @@ -81,6 +82,9 @@ class MediaViewerPresenter( NoMoreItemsBackwardSnackBarDisplayer(currentIndex, data) NoMoreItemsForwardSnackBarDisplayer(currentIndex, data) + val permissions by room.permissionsAsState(MediaPermissions.DEFAULT) { perms -> + perms.mediaPermissions() + } var mediaBottomSheetState by remember { mutableStateOf(MediaBottomSheetState.Hidden) } DisposableEffect(Unit) { @@ -131,8 +135,8 @@ class MediaViewerPresenter( eventId = event.data.eventId, canDelete = when (event.data.mediaInfo.senderId) { null -> false - room.sessionId -> room.canRedactOwn().getOrElse { false } && event.data.eventId != null - else -> room.canRedactOther().getOrElse { false } && event.data.eventId != null + room.sessionId -> permissions.canRedactOwn && event.data.eventId != null + else -> permissions.canRedactOther && event.data.eventId != null }, mediaInfo = event.data.mediaInfo, thumbnailSource = event.data.thumbnailSource, From 29c1f33638b53b484d0cf2cae29924c8a13c0ba3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 8 Dec 2025 22:23:17 +0100 Subject: [PATCH 117/347] misc(power level) : remove old api --- .../matrix/impl/room/RustBaseRoom.kt | 54 ------------- .../matrix/ui/room/MatrixRoomState.kt | 79 ------------------- 2 files changed, 133 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt index eec9591e32..141957d1ed 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt @@ -186,60 +186,6 @@ class RustBaseRoom( } } - override suspend fun canUserInvite(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserInvite(userId.value) } - } - } - - override suspend fun canUserKick(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserKick(userId.value) } - } - } - - override suspend fun canUserBan(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserBan(userId.value) } - } - } - - override suspend fun canUserRedactOwn(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserRedactOwn(userId.value) } - } - } - - override suspend fun canUserRedactOther(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserRedactOther(userId.value) } - } - } - - override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserSendState(userId.value, type.map()) } - } - } - - override suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserSendMessage(userId.value, type.map()) } - } - } - - override suspend fun canUserTriggerRoomNotification(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserTriggerRoomNotification(userId.value) } - } - } - - override suspend fun canUserPinUnpin(userId: UserId): Result = withContext(roomDispatcher) { - runCatchingExceptions { - innerRoom.getPowerLevels().use { it.canUserPinUnpin(userId.value) } - } - } - override suspend fun clearEventCacheStorage(): Result = withContext(roomDispatcher) { runCatchingExceptions { innerRoom.clearEventCacheStorage() diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt index 03e0e5bea1..d4e6127b69 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt @@ -14,88 +14,9 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.produceState import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.room.isDm -import io.element.android.libraries.matrix.api.room.powerlevels.canBan -import io.element.android.libraries.matrix.api.room.powerlevels.canHandleKnockRequests -import io.element.android.libraries.matrix.api.room.powerlevels.canInvite -import io.element.android.libraries.matrix.api.room.powerlevels.canKick -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther -import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn -import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage import io.element.android.libraries.matrix.ui.model.roleOf -@Composable -fun BaseRoom.canSendMessageAsState(type: MessageEventType, updateKey: Long): State { - return produceState(initialValue = true, key1 = updateKey) { - value = canSendMessage(type).getOrElse { true } - } -} - -@Composable -fun BaseRoom.canInviteAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canInvite().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canRedactOwnAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canRedactOwn().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canRedactOtherAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canRedactOther().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canCall(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canUserJoinCall(sessionId).getOrElse { false } - } -} - -@Composable -fun BaseRoom.canPinUnpin(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canUserPinUnpin(sessionId).getOrElse { false } - } -} - -@Composable -fun BaseRoom.isDmAsState(): State { - return produceState(initialValue = false) { - roomInfoFlow.collect { value = it.isDm } - } -} - -@Composable -fun BaseRoom.canKickAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canKick().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canBanAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canBan().getOrElse { false } - } -} - -@Composable -fun BaseRoom.canHandleKnockRequestsAsState(updateKey: Long): State { - return produceState(initialValue = false, key1 = updateKey) { - value = canHandleKnockRequests().getOrElse { false } - } -} - @Composable fun BaseRoom.userPowerLevelAsState(updateKey: Long): State { return produceState(initialValue = 0, key1 = updateKey) { From 5c8fd831e31a27fda1a104cf2077c8cc69bbfef0 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 9 Dec 2025 20:50:31 +0100 Subject: [PATCH 118/347] misc(power level) : update tests following api change --- .../MessageComposerPresenter.kt | 3 +- .../impl/timeline/TimelinePresenter.kt | 2 +- .../messages/impl/MessagesPresenterTest.kt | 196 +++++--------- .../MessageComposerPresenterTest.kt | 45 +++- .../list/PinnedMessagesListPresenterTest.kt | 43 ++- .../impl/timeline/TimelinePresenterTest.kt | 151 +++++------ .../impl/RoomCallStatePresenterTest.kt | 28 +- .../roomdetails/impl/MatrixRoomFixture.kt | 27 +- .../impl/RoomDetailsPresenterTest.kt | 246 ++++++------------ .../members/RoomMemberListPresenterTest.kt | 23 +- .../api/RoomDetailsEditPermissions.kt | 2 +- .../impl/RoomDetailsEditPresenter.kt | 3 +- .../impl/RoomDetailsEditPresenterTest.kt | 65 ++--- .../impl/RoomMemberModerationPresenterTest.kt | 7 +- .../impl/root/SecurityAndPrivacyPresenter.kt | 1 - .../impl/SecurityAndPrivacyPresenterTest.kt | 39 ++- .../impl/root/UserProfilePresenter.kt | 2 +- .../impl/UserProfilePresenterTest.kt | 24 +- .../api/room/powerlevels/RoomPermissions.kt | 12 +- .../matrix/impl/room/RustBaseRoom.kt | 2 - .../matrix/test/room/FakeBaseRoom.kt | 56 +--- .../room/powerlevels/FakeRoomPermissions.kt | 72 ++--- .../impl/gallery/MediaGalleryPresenter.kt | 1 - .../impl/gallery/MediaGalleryPresenterTest.kt | 17 +- .../impl/viewer/MediaViewerPresenterTest.kt | 45 +++- 25 files changed, 475 insertions(+), 637 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index b2c5182a0a..fd803109c7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -99,6 +99,7 @@ import timber.log.Timber import kotlin.time.Duration.Companion.seconds import io.element.android.libraries.core.mimetype.MimeTypes.Any as AnyMimeTypes +@Suppress("LargeClass") @AssistedInject class MessageComposerPresenter( @Assisted private val navigator: MessagesNavigator, @@ -397,7 +398,7 @@ class MessageComposerPresenter( val currentUserId = room.sessionId suspend fun canSendRoomMention(): Boolean { - val userCanSendAtRoom = room.roomPermissions().use(false){ perms -> + val userCanSendAtRoom = room.roomPermissions().use(false) { perms -> perms.canOwnUserTriggerRoomNotification() } return !room.isDm() && userCanSendAtRoom 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 4815602c8e..289ec2924d 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 @@ -39,7 +39,6 @@ import io.element.android.features.poll.api.actions.EndPollAction import io.element.android.features.poll.api.actions.SendPollResponseAction import io.element.android.features.roomcall.api.RoomCallState import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.featureflag.api.FeatureFlagService @@ -96,6 +95,7 @@ class TimelinePresenter( private val analyticsService: AnalyticsService, ) : Presenter { private val tag = "TimelinePresenter" + @AssistedFactory interface Factory { fun create( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index de2c8a81c9..cd5bcf8a6d 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -64,6 +64,7 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkParser import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo @@ -86,6 +87,7 @@ import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.test.timeline.aTimelineItemDebugInfo import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails @@ -143,11 +145,7 @@ class MessagesPresenterTest { fun `present - check that the room's unread flag is removed`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), markAsReadResult = { lambdaError() } ), typingNoticeResult = { Result.success(Unit) }, @@ -173,11 +171,7 @@ class MessagesPresenterTest { } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -223,11 +217,7 @@ class MessagesPresenterTest { } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -288,11 +278,7 @@ class MessagesPresenterTest { val event = aMessageEvent() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), eventPermalinkResult = { Result.success("a link") }, ), typingNoticeResult = { Result.success(Unit) }, @@ -514,11 +500,7 @@ class MessagesPresenterTest { val liveTimeline = FakeTimeline() val joinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = liveTimeline, typingNoticeResult = { Result.success(Unit) }, @@ -586,11 +568,7 @@ class MessagesPresenterTest { fun `present - shows prompt to reinvite users in DM`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(isDirect = true, joinedMembersCount = 1, activeMembersCount = 1)) }, @@ -619,11 +597,7 @@ class MessagesPresenterTest { fun `present - doesn't show reinvite prompt in non-direct room`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(isDirect = false, joinedMembersCount = 1, activeMembersCount = 1)) }, @@ -645,11 +619,7 @@ class MessagesPresenterTest { fun `present - doesn't show reinvite prompt if other party is present`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(isDirect = true, joinedMembersCount = 2, activeMembersCount = 2)) }, @@ -672,11 +642,7 @@ class MessagesPresenterTest { val inviteUserResult = lambdaRecorder { _: UserId -> Result.success(Unit) } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, inviteUserResult = inviteUserResult, @@ -707,11 +673,7 @@ class MessagesPresenterTest { val inviteUserResult = lambdaRecorder { _: UserId -> Result.success(Unit) } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, inviteUserResult = inviteUserResult, @@ -744,11 +706,7 @@ class MessagesPresenterTest { fun `present - handle reinviting other user when memberlist is not ready`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -769,11 +727,7 @@ class MessagesPresenterTest { fun `present - handle reinviting other user when inviting fails`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, inviteUserResult = { Result.failure(RuntimeException("Oops!")) }, @@ -807,17 +761,7 @@ class MessagesPresenterTest { fun `present - permission to post`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, - canUserSendMessageResult = { _, messageEventType -> - when (messageEventType) { - MessageEventType.RoomMessage -> Result.success(true) - MessageEventType.Reaction -> Result.success(true) - else -> lambdaError() - } - }, + roomPermissions = roomPermissions(), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -833,17 +777,9 @@ class MessagesPresenterTest { fun `present - no permission to post`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, - canUserSendMessageResult = { _, messageEventType -> - when (messageEventType) { - MessageEventType.RoomMessage -> Result.success(false) - MessageEventType.Reaction -> Result.success(false) - else -> lambdaError() - } - }, + roomPermissions = roomPermissions( + canSendMessage = false + ), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -859,11 +795,9 @@ class MessagesPresenterTest { fun `present - permission to redact own`() = runTest { val joinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOtherResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canRedactOther = false + ), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -880,11 +814,9 @@ class MessagesPresenterTest { fun `present - permission to redact other`() = runTest { val joinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOtherResult = { Result.success(true) }, - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canRedactOwn = false + ), ), typingNoticeResult = { Result.success(Unit) }, ) @@ -929,11 +861,7 @@ class MessagesPresenterTest { val timeline = FakeTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -973,11 +901,7 @@ class MessagesPresenterTest { val analyticsService = FakeAnalyticsService() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -1074,11 +998,7 @@ class MessagesPresenterTest { } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ), liveTimeline = timeline, typingNoticeResult = { Result.success(Unit) }, @@ -1115,11 +1035,7 @@ class MessagesPresenterTest { val successorReason = "This room has been moved to a new location" val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), initialRoomInfo = aRoomInfo( successorRoom = SuccessorRoom( roomId = successorRoomId, @@ -1143,11 +1059,7 @@ class MessagesPresenterTest { fun `present - room without successor room has null successor info in state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), initialRoomInfo = aRoomInfo(successorRoom = null) ), typingNoticeResult = { Result.success(Unit) }, @@ -1165,11 +1077,13 @@ class MessagesPresenterTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( sessionId = A_SESSION_ID, - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canSendState = { true }, + canSendMessage = { true }, + canRedactOther = true, + canRedactOwn = true, + canPinUnpin = true, + ), initialRoomInfo = aRoomInfo(isDirect = true, isEncrypted = true) ).apply { givenRoomMembersState(RoomMembersState.Ready(persistentListOf(aRoomMember(userId = A_SESSION_ID), aRoomMember(userId = A_USER_ID_2)))) @@ -1312,16 +1226,44 @@ class MessagesPresenterTest { } } + private fun roomPermissions( + canStartCall: Boolean = true, + canRedactOther: Boolean = true, + canRedactOwn: Boolean = true, + canSendMessage: Boolean = true, + canSendReaction: Boolean = true, + canPinUnpin: Boolean = true, + ) = FakeRoomPermissions( + canSendState = { type -> + when (type) { + StateEventType.CALL_MEMBER -> canStartCall + else -> lambdaError() + } + }, + canSendMessage = { type -> + when (type) { + MessageEventType.RoomMessage -> canSendMessage + MessageEventType.Reaction -> canSendReaction + else -> lambdaError() + } + }, + canRedactOther = canRedactOther, + canRedactOwn = canRedactOwn, + canPinUnpin = canPinUnpin, + ) + private fun TestScope.createMessagesPresenter( coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(), timeline: Timeline = FakeTimeline(), joinedRoom: FakeJoinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canSendState = { true }, + canSendMessage = { true }, + canRedactOther = true, + canRedactOwn = true, + canPinUnpin = true, + ), ).apply { givenRoomInfo(aRoomInfo(id = roomId, name = "")) }, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt index 4a6e777116..2feafbc9e5 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt @@ -69,6 +69,7 @@ import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails import io.element.android.libraries.mediapickers.api.PickerProvider @@ -991,9 +992,12 @@ class MessageComposerPresenterTest { val invitedUser = aRoomMember(userId = A_USER_ID_3, membership = RoomMembershipState.INVITE) val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN) val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) - var canUserTriggerRoomNotificationResult = true val room = FakeJoinedRoom( - baseRoom = FakeBaseRoom(canUserTriggerRoomNotificationResult = { Result.success(canUserTriggerRoomNotificationResult) }), + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions( + canTriggerRoomNotification = true, + ) + ), typingNoticeResult = { Result.success(Unit) } ).apply { givenRoomMembersState( @@ -1033,10 +1037,38 @@ class MessageComposerPresenterTest { // If the suggestion isn't a mention, no suggestions are returned initialState.eventSink(MessageComposerEvent.SuggestionReceived(Suggestion(0, 0, SuggestionType.Command, ""))) assertThat(awaitItem().suggestions).isEmpty() + } + } - // If user has no permission to send `@room` mentions, `RoomMemberSuggestion.Room` is not returned - canUserTriggerRoomNotificationResult = false + @Test + fun `present - room mention suggestions no permission`() = runTest { + val currentUser = aRoomMember(userId = A_USER_ID, membership = RoomMembershipState.JOIN) + val invitedUser = aRoomMember(userId = A_USER_ID_3, membership = RoomMembershipState.INVITE) + val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN) + val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions( + canTriggerRoomNotification = false, + ) + ), + typingNoticeResult = { Result.success(Unit) } + ).apply { + givenRoomMembersState( + RoomMembersState.Ready( + persistentListOf(currentUser, invitedUser, bob, david), + ) + ) + givenRoomInfo(aRoomInfo(isDirect = false)) + } + val presenter = createPresenter(room) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + // An empty suggestion returns the joined members that are not the current user, but not the room initialState.eventSink(MessageComposerEvent.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, ""))) + skipItems(1) assertThat(awaitItem().suggestions) .containsExactly(ResolvedSuggestion.Member(bob), ResolvedSuggestion.Member(david)) } @@ -1049,7 +1081,9 @@ class MessageComposerPresenterTest { val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN) val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) val room = FakeJoinedRoom( - baseRoom = FakeBaseRoom(canUserTriggerRoomNotificationResult = { Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions(canTriggerRoomNotification = true), + ), typingNoticeResult = { Result.success(Unit) } ).apply { givenRoomMembersState( @@ -1069,7 +1103,6 @@ class MessageComposerPresenterTest { presenter.present() }.test { val initialState = awaitItem() - // An empty suggestion returns the joined members that are not the current user, but not the room initialState.eventSink(MessageComposerEvent.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, ""))) skipItems(1) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt index 8807951d9d..351f841fcf 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListPresenterTest.kt @@ -31,6 +31,7 @@ import io.element.android.libraries.matrix.test.A_UNIQUE_ID import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.sync.FakeSyncService import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.test.timeline.aMessageContent @@ -55,9 +56,7 @@ class PinnedMessagesListPresenterTest { fun `present - initial state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) } @@ -74,9 +73,7 @@ class PinnedMessagesListPresenterTest { fun `present - timeline failure state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -95,9 +92,7 @@ class PinnedMessagesListPresenterTest { fun `present - empty state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf())) }, @@ -117,9 +112,7 @@ class PinnedMessagesListPresenterTest { val pinnedEventsTimeline = createPinnedMessagesTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -146,9 +139,7 @@ class PinnedMessagesListPresenterTest { val analyticsService = FakeAnalyticsService() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -194,9 +185,7 @@ class PinnedMessagesListPresenterTest { val pinnedEventsTimeline = createPinnedMessagesTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -225,9 +214,7 @@ class PinnedMessagesListPresenterTest { val pinnedEventsTimeline = createPinnedMessagesTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -256,9 +243,7 @@ class PinnedMessagesListPresenterTest { val pinnedEventsTimeline = createPinnedMessagesTimeline() val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, - canRedactOtherResult = { Result.success(true) }, - canUserPinUnpinResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(pinnedEventIds = listOf(AN_EVENT_ID))) }, @@ -295,6 +280,16 @@ class PinnedMessagesListPresenterTest { ) } + private fun roomPermissions( + canRedactOther: Boolean = true, + canRedactOwn: Boolean = true, + canPinUnpin: Boolean = true, + ) = FakeRoomPermissions( + canRedactOther = canRedactOther, + canRedactOwn = canRedactOwn, + canPinUnpin = canPinUnpin, + ) + private fun TestScope.createPinnedMessagesListPresenter( navigator: PinnedMessagesListNavigator = FakePinnedMessagesListNavigator(), room: JoinedRoom = FakeJoinedRoom(), diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt index 13c28da6e9..b84975c6a5 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt @@ -8,8 +8,6 @@ package io.element.android.features.messages.impl.timeline -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow import app.cash.turbine.ReceiveTurbine import app.cash.turbine.test import com.google.common.truth.Truth.assertThat @@ -35,6 +33,7 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UniqueId import io.element.android.libraries.matrix.api.core.asEventId +import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem @@ -55,6 +54,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.test.timeline.aMessageContent import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem @@ -66,6 +66,7 @@ import io.element.android.tests.testutils.awaitLastSequentialItem import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.lambda.any import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test @@ -97,9 +98,7 @@ class TimelinePresenterTest { @Test fun `present - initial state`() = runTest { val presenter = createTimelinePresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.timelineItems).isEmpty() assertThat(initialState.isLive).isTrue() @@ -118,9 +117,7 @@ class TimelinePresenterTest { this.paginateLambda = paginateLambda } val presenter = createTimelinePresenter(timeline = timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink.invoke(TimelineEvents.LoadMore(Timeline.PaginationDirection.BACKWARDS)) initialState.eventSink.invoke(TimelineEvents.LoadMore(Timeline.PaginationDirection.FORWARDS)) @@ -166,9 +163,6 @@ class TimelinePresenterTest { ) val room = FakeJoinedRoom( liveTimeline = timeline, - baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, - ) ) val sessionPreferencesStore = InMemorySessionPreferencesStore(isSendPublicReadReceiptsEnabled = isSendPublicReadReceiptsEnabled) val presenter = createTimelinePresenter( @@ -176,9 +170,7 @@ class TimelinePresenterTest { room = room, sessionPreferencesStore = sessionPreferencesStore, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.OnScrollFinished(0)) runCurrent() @@ -211,9 +203,7 @@ class TimelinePresenterTest { this.sendReadReceiptLambda = sendReadReceiptsLambda } val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) awaitItem().run { eventSink.invoke(TimelineEvents.OnScrollFinished(1)) @@ -252,9 +242,7 @@ class TimelinePresenterTest { timeline = timeline, sessionPreferencesStore = sessionPreferencesStore, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) awaitItem().run { eventSink.invoke(TimelineEvents.OnScrollFinished(0)) @@ -290,9 +278,7 @@ class TimelinePresenterTest { this.sendReadReceiptLambda = sendReadReceiptsLambda } val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) awaitItem().run { eventSink.invoke(TimelineEvents.OnScrollFinished(1)) @@ -320,9 +306,7 @@ class TimelinePresenterTest { this.sendReadReceiptLambda = sendReadReceiptsLambda } val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.OnScrollFinished(1)) @@ -339,9 +323,7 @@ class TimelinePresenterTest { markAsReadResult = { Result.success(Unit) }, ) val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.newEventState).isEqualTo(NewEventState.None) assertThat(initialState.timelineItems.size).isEqualTo(0) @@ -390,9 +372,7 @@ class TimelinePresenterTest { timelineItems = timelineItems, ) val presenter = createTimelinePresenter(timeline) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.newEventState).isEqualTo(NewEventState.None) assertThat(initialState.timelineItems.size).isEqualTo(0) @@ -446,9 +426,7 @@ class TimelinePresenterTest { val presenter = createTimelinePresenter( sendPollResponseAction = sendPollResponseAction, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.SelectPollAnswer(AN_EVENT_ID, "anAnswerId")) } @@ -462,9 +440,7 @@ class TimelinePresenterTest { val presenter = createTimelinePresenter( endPollAction = endPollAction, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.EndPoll(AN_EVENT_ID)) } @@ -481,9 +457,7 @@ class TimelinePresenterTest { val presenter = createTimelinePresenter( messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitFirstItem().eventSink(TimelineEvents.EditPoll(AN_EVENT_ID)) onEditPollClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID)) } @@ -500,9 +474,7 @@ class TimelinePresenterTest { ), redactedVoiceMessageManager = redactedVoiceMessageManager, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { assertThat(redactedVoiceMessageManager.invocations.size).isEqualTo(0) skipItems(2) assertThat(redactedVoiceMessageManager.invocations.size).isEqualTo(1) @@ -528,16 +500,14 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { _ -> Result.success(null) }, ), ) val presenter = createTimelinePresenter( room = room, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) awaitItem().also { state -> @@ -579,15 +549,13 @@ class TimelinePresenterTest { ) ), baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { Result.success(null) }, ), ), timelineItemIndexer = timelineItemIndexer, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() advanceUntilIdle() @@ -619,14 +587,12 @@ class TimelinePresenterTest { ), createTimelineResult = { Result.failure(RuntimeException("An error")) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { _ -> Result.success(null) }, ), ) ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) awaitItem().also { state -> @@ -668,7 +634,7 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { _ -> Result.success(threadId) }, ), ) @@ -679,9 +645,7 @@ class TimelinePresenterTest { timeline = liveTimeline, messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) @@ -729,7 +693,7 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), threadRootIdForEventResult = { _ -> Result.success(threadId) }, ), ) @@ -740,9 +704,7 @@ class TimelinePresenterTest { timeline = liveTimeline, messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) @@ -785,7 +747,7 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), // Use a different thread id threadRootIdForEventResult = { _ -> Result.success(A_THREAD_ID_2) }, ), @@ -797,9 +759,7 @@ class TimelinePresenterTest { timeline = liveTimeline, messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) @@ -846,7 +806,7 @@ class TimelinePresenterTest { liveTimeline = liveTimeline, createTimelineResult = { Result.success(detachedTimeline) }, baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), // The event is in the main timeline, not in a thread threadRootIdForEventResult = { _ -> Result.success(null) }, ), @@ -858,9 +818,7 @@ class TimelinePresenterTest { timeline = liveTimeline, messagesNavigator = navigator, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() initialState.eventSink.invoke(TimelineEvents.FocusOnEvent(AN_EVENT_ID)) @@ -891,9 +849,7 @@ class TimelinePresenterTest { fun `present - show shield hide shield`() = runTest { val presenter = createTimelinePresenter() val shield = aCriticalShield() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.messageShield).isNull() initialState.eventSink(TimelineEvents.ShowShieldDialog(shield)) @@ -929,7 +885,9 @@ class TimelinePresenterTest { ) val room = FakeJoinedRoom( liveTimeline = timeline, - baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + ), ).apply { givenRoomMembersState(RoomMembersState.Unknown) } @@ -937,9 +895,7 @@ class TimelinePresenterTest { val avatarUrl = "https://domain.com/avatar.jpg" val presenter = createTimelinePresenter(timeline, room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = consumeItemsUntilPredicate(30.seconds) { it.timelineItems.isNotEmpty() }.last() val event = initialState.timelineItems.first() as TimelineItem.Event assertThat(event.senderAvatar.url).isNull() @@ -963,15 +919,13 @@ class TimelinePresenterTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), predecessorRoomResult = { predecessorRoom } ), ) val presenter = createTimelinePresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.timelineRoomInfo.predecessorRoom).isNotNull() assertThat(initialState.timelineRoomInfo.predecessorRoom?.roomId).isEqualTo(predecessorRoomId) @@ -982,14 +936,12 @@ class TimelinePresenterTest { fun `present - timeline room info no predecessor`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), predecessorRoomResult = { null } ), ) val presenter = createTimelinePresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitFirstItem() assertThat(initialState.timelineRoomInfo.predecessorRoom).isNull() } @@ -999,7 +951,7 @@ class TimelinePresenterTest { fun `present - timeline event navigate to room`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserSendMessageResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ), ) val onNavigateToRoomLambda = lambdaRecorder, Unit> { _, _, _ -> } @@ -1025,11 +977,32 @@ class TimelinePresenterTest { return awaitItem() } + private fun roomPermissions( + canRedactOther: Boolean = false, + canRedactOwn: Boolean = true, + canSendMessage: Boolean = true, + canSendReaction: Boolean = true, + canPinUnpin: Boolean = false, + ) = FakeRoomPermissions( + canSendMessage = { type -> + when (type) { + MessageEventType.RoomMessage -> canSendMessage + MessageEventType.Reaction -> canSendReaction + else -> lambdaError() + } + }, + canRedactOther = canRedactOther, + canRedactOwn = canRedactOwn, + canPinUnpin = canPinUnpin, + ) + private fun TestScope.createTimelinePresenter( timeline: Timeline = FakeTimeline(), room: FakeJoinedRoom = FakeJoinedRoom( liveTimeline = timeline, - baseRoom = FakeBaseRoom(canUserSendMessageResult = { _, _ -> Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + ), ), redactedVoiceMessageManager: RedactedVoiceMessageManager = FakeRedactedVoiceMessageManager(), messagesNavigator: FakeMessagesNavigator = FakeMessagesNavigator(), diff --git a/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt b/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt index 1aceee227a..bb0dc04c18 100644 --- a/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt +++ b/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt @@ -15,9 +15,12 @@ import io.element.android.features.call.test.FakeCurrentCallService import io.element.android.features.enterprise.test.FakeSessionEnterpriseService import io.element.android.features.roomcall.api.RoomCallState import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.test import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest @@ -28,7 +31,7 @@ class RoomCallStatePresenterTest { fun `present - initial state`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(false) }, + roomPermissions = roomPermissions(false), ) ) val presenter = createRoomCallStatePresenter(joinedRoom = room) @@ -47,7 +50,7 @@ class RoomCallStatePresenterTest { fun `present - element call not available`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(false) }, + roomPermissions = roomPermissions(false), ) ) val presenter = createRoomCallStatePresenter( @@ -66,7 +69,7 @@ class RoomCallStatePresenterTest { fun `present - initial state - user can join call`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(true), ) ) val presenter = createRoomCallStatePresenter(joinedRoom = room) @@ -85,7 +88,7 @@ class RoomCallStatePresenterTest { fun `present - call is disabled if user cannot join it even if there is an ongoing call`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(false) }, + roomPermissions = roomPermissions(false), initialRoomInfo = aRoomInfo(hasRoomCall = true), ) ) @@ -106,7 +109,7 @@ class RoomCallStatePresenterTest { fun `present - user has joined the call on another session`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(true), ).apply { givenRoomInfo( aRoomInfo( @@ -133,7 +136,7 @@ class RoomCallStatePresenterTest { fun `present - user has joined the call locally`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(true), ).apply { givenRoomInfo( aRoomInfo( @@ -163,7 +166,7 @@ class RoomCallStatePresenterTest { fun `present - user leaves the call`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(true), ).apply { givenRoomInfo( aRoomInfo( @@ -223,6 +226,17 @@ class RoomCallStatePresenterTest { } } + private fun roomPermissions(canJoinCall: Boolean): FakeRoomPermissions { + return FakeRoomPermissions( + canSendState = { stateEvent -> + when (stateEvent) { + StateEventType.CALL_MEMBER -> canJoinCall + else -> lambdaError() + } + } + ) + } + private fun createRoomCallStatePresenter( joinedRoom: JoinedRoom, currentCallService: CurrentCallService = FakeCurrentCallService(), diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt index 5043aea88c..2d85744345 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/MatrixRoomFixture.kt @@ -13,8 +13,8 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.join.JoinRule +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.A_ROOM_ALIAS import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.test.notificationsettings.FakeNotific import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.tests.testutils.lambda.lambdaError fun aRoom( @@ -35,6 +36,7 @@ fun aRoom( topic: String? = A_ROOM_TOPIC, avatarUrl: String? = AN_AVATAR_URL, canonicalAlias: RoomAlias? = A_ROOM_ALIAS, + roomPermissions: RoomPermissions = FakeRoomPermissions(), isEncrypted: Boolean = true, isPublic: Boolean = true, isDirect: Boolean = false, @@ -42,29 +44,20 @@ fun aRoom( activeMemberCount: Long = 1, joinedMemberCount: Long = 1, invitedMemberCount: Long = 0, - canInviteResult: (UserId) -> Result = { lambdaError() }, - canBanResult: (UserId) -> Result = { lambdaError() }, - canKickResult: (UserId) -> Result = { lambdaError() }, - canSendStateResult: (UserId, StateEventType) -> Result = { _, _ -> lambdaError() }, userDisplayNameResult: (UserId) -> Result = { lambdaError() }, userAvatarUrlResult: () -> Result = { lambdaError() }, - canUserJoinCallResult: (UserId) -> Result = { lambdaError() }, getUpdatedMemberResult: (UserId) -> Result = { lambdaError() }, userRoleResult: () -> Result = { lambdaError() }, setIsFavoriteResult: (Boolean) -> Result = { lambdaError() }, ) = FakeBaseRoom( sessionId = sessionId, roomId = roomId, - canInviteResult = canInviteResult, - canBanResult = canBanResult, - canKickResult = canKickResult, - canSendStateResult = canSendStateResult, userDisplayNameResult = userDisplayNameResult, userAvatarUrlResult = userAvatarUrlResult, - canUserJoinCallResult = canUserJoinCallResult, getUpdatedMemberResult = getUpdatedMemberResult, userRoleResult = userRoleResult, setIsFavoriteResult = setIsFavoriteResult, + roomPermissions = roomPermissions, initialRoomInfo = aRoomInfo( name = displayName, rawName = rawName, @@ -89,6 +82,7 @@ fun aJoinedRoom( topic: String? = A_ROOM_TOPIC, avatarUrl: String? = AN_AVATAR_URL, canonicalAlias: RoomAlias? = A_ROOM_ALIAS, + roomPermissions: RoomPermissions = FakeRoomPermissions(), isEncrypted: Boolean = true, isPublic: Boolean = true, isDirect: Boolean = false, @@ -97,17 +91,12 @@ fun aJoinedRoom( joinedMemberCount: Long = 1, invitedMemberCount: Long = 0, notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(), - canInviteResult: (UserId) -> Result = { lambdaError() }, - canBanResult: (UserId) -> Result = { lambdaError() }, - canKickResult: (UserId) -> Result = { lambdaError() }, - canSendStateResult: (UserId, StateEventType) -> Result = { _, _ -> lambdaError() }, userDisplayNameResult: (UserId) -> Result = { lambdaError() }, userAvatarUrlResult: () -> Result = { lambdaError() }, setNameResult: (String) -> Result = { lambdaError() }, setTopicResult: (String) -> Result = { lambdaError() }, updateAvatarResult: (String, ByteArray) -> Result = { _, _ -> lambdaError() }, removeAvatarResult: () -> Result = { lambdaError() }, - canUserJoinCallResult: (UserId) -> Result = { lambdaError() }, getUpdatedMemberResult: (UserId) -> Result = { lambdaError() }, userRoleResult: () -> Result = { lambdaError() }, kickUserResult: (UserId, String?) -> Result = { _, _ -> lambdaError() }, @@ -132,13 +121,9 @@ fun aJoinedRoom( baseRoom = aRoom( sessionId = sessionId, roomId = roomId, - canInviteResult = canInviteResult, - canBanResult = canBanResult, - canKickResult = canKickResult, - canSendStateResult = canSendStateResult, + roomPermissions = roomPermissions, userDisplayNameResult = userDisplayNameResult, userAvatarUrlResult = userAvatarUrlResult, - canUserJoinCallResult = canUserJoinCallResult, getUpdatedMemberResult = getUpdatedMemberResult, userRoleResult = userRoleResult, setIsFavoriteResult = setIsFavoriteResult, diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt index 9cf46c41c0..7d6219004e 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt @@ -30,6 +30,7 @@ import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.join.JoinRule +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME @@ -41,6 +42,7 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore import io.element.android.services.analytics.api.AnalyticsService @@ -119,9 +121,7 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state is created from initial room info`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -148,9 +148,7 @@ class RoomDetailsPresenterTest { pinnedEventIds = listOf(AN_EVENT_ID), ) val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(roomInfo) } @@ -170,9 +168,7 @@ class RoomDetailsPresenterTest { fun `present - initial state with no room name`() = runTest { val room = aJoinedRoom( displayName = "", - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -188,9 +184,7 @@ class RoomDetailsPresenterTest { val myRoomMember = aRoomMember(A_SESSION_ID) val otherRoomMember = aRoomMember(A_USER_ID_2) val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getUpdatedMemberResult = { userId -> when (userId) { A_SESSION_ID -> Result.success(myRoomMember) @@ -225,9 +219,9 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can invite others to room`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions( + canInvite = true, + ), ) val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers()) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -243,26 +237,9 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can not invite others to room`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(false) }, - canKickResult = { Result.success(false) }, - canBanResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, - ) - val presenter = createRoomDetailsPresenter(room) - presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { - assertThat(awaitItem().canInvite).isFalse() - - cancelAndIgnoreRemainingEvents() - } - } - - @Test - fun `present - initial state when canInvite errors`() = runTest { - val room = aJoinedRoom( - canInviteResult = { Result.failure(RuntimeException("Whoops")) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions( + canInvite = false, + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -275,17 +252,11 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can edit one attribute`() = runTest { val room = aJoinedRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_TOPIC -> Result.success(true) - StateEventType.ROOM_NAME -> Result.success(false) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canBanResult = { Result.success(false) }, - canKickResult = { Result.success(false) }, - canInviteResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canChangeName = true, + canChangeTopic = false, + canChangeAvatar = false, + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -303,18 +274,7 @@ class RoomDetailsPresenterTest { val myRoomMember = aRoomMember(A_SESSION_ID) val otherRoomMember = aRoomMember(A_USER_ID_2) val room = aJoinedRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME, - StateEventType.ROOM_AVATAR -> Result.success(true) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canKickResult = { Result.success(false) }, - canBanResult = { Result.success(false) }, - canInviteResult = { Result.success(false) }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(), getUpdatedMemberResult = { userId -> when (userId) { A_SESSION_ID -> Result.success(myRoomMember) @@ -354,18 +314,9 @@ class RoomDetailsPresenterTest { val room = aJoinedRoom( isDirect = true, topic = null, - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_AVATAR, - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME -> Result.success(true) - else -> Result.failure(RuntimeException("Whelp")) - } - }, + roomPermissions = roomPermissions(), userDisplayNameResult = { Result.success(A_USER_NAME) }, userAvatarUrlResult = { Result.success(AN_AVATAR_URL) }, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, getUpdatedMemberResult = { userId -> when (userId) { A_SESSION_ID -> Result.success(myRoomMember) @@ -400,24 +351,11 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can edit all attributes`() = runTest { val room = aJoinedRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME, - StateEventType.ROOM_AVATAR -> Result.success(true) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canKickResult = { - Result.success(false) - }, - canBanResult = { - Result.success(false) - }, - canInviteResult = { - Result.success(false) - }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canChangeAvatar = true, + canChangeName = true, + canChangeTopic = true, + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -433,24 +371,11 @@ class RoomDetailsPresenterTest { @Test fun `present - initial state when user can edit no attributes`() = runTest { val room = aJoinedRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME, - StateEventType.ROOM_AVATAR -> Result.success(false) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canBanResult = { - Result.success(false) - }, - canKickResult = { - Result.success(false) - }, - canInviteResult = { - Result.success(false) - }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canChangeAvatar = false, + canChangeName = false, + canChangeTopic = false, + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -465,24 +390,9 @@ class RoomDetailsPresenterTest { fun `present - topic state is hidden when no topic and user has no permission`() = runTest { val room = aJoinedRoom( topic = null, - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_AVATAR, - StateEventType.ROOM_NAME -> Result.success(true) - StateEventType.ROOM_TOPIC -> Result.success(false) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canKickResult = { - Result.success(false) - }, - canBanResult = { - Result.success(false) - }, - canInviteResult = { - Result.success(false) - }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions( + canChangeTopic = false + ), ) val presenter = createRoomDetailsPresenter(room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -497,24 +407,7 @@ class RoomDetailsPresenterTest { fun `present - topic state is 'can add topic' when no topic and user has permission`() = runTest { val room = aJoinedRoom( topic = null, - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_AVATAR, - StateEventType.ROOM_TOPIC, - StateEventType.ROOM_NAME -> Result.success(true) - else -> Result.failure(RuntimeException("Whelp")) - } - }, - canKickResult = { - Result.success(false) - }, - canBanResult = { - Result.success(false) - }, - canInviteResult = { - Result.success(false) - }, - canUserJoinCallResult = { Result.success(true) }, + roomPermissions = roomPermissions(), ).apply { givenRoomInfo(aRoomInfo(topic = null)) } @@ -534,9 +427,7 @@ class RoomDetailsPresenterTest { fun `present - leave room event is passed on to leave room presenter`() = runTest { val leaveRoomEventRecorder = EventsRecorder() val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter( room = room, @@ -555,9 +446,7 @@ class RoomDetailsPresenterTest { val notificationSettingsService = FakeNotificationSettingsService() val room = aJoinedRoom( notificationSettingsService = notificationSettingsService, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter( room = room, @@ -584,9 +473,7 @@ class RoomDetailsPresenterTest { FakeNotificationSettingsService(initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY) val room = aJoinedRoom( notificationSettingsService = notificationSettingsService, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter( room = room, @@ -612,9 +499,7 @@ class RoomDetailsPresenterTest { ) val room = aJoinedRoom( notificationSettingsService = notificationSettingsService, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter( room = room, @@ -637,9 +522,7 @@ class RoomDetailsPresenterTest { val setIsFavoriteResult = lambdaRecorder> { _ -> Result.success(Unit) } val room = aJoinedRoom( setIsFavoriteResult = setIsFavoriteResult, - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val analyticsService = FakeAnalyticsService() val presenter = @@ -665,9 +548,7 @@ class RoomDetailsPresenterTest { @Test fun `present - changes in room info updates the is favorite flag`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val presenter = createRoomDetailsPresenter(room = room) presenter.testWithLifecycleOwner(lifecycleOwner = fakeLifecycleOwner) { @@ -686,9 +567,7 @@ class RoomDetailsPresenterTest { @Test fun `present - show knock requests`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), joinRule = JoinRule.Knock, ) val featureFlagService = FakeFeatureFlagService( @@ -712,9 +591,7 @@ class RoomDetailsPresenterTest { @Test fun `present - show security and privacy`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val featureFlagService = FakeFeatureFlagService() val presenter = createRoomDetailsPresenter(room = room, featureFlagService = featureFlagService) @@ -729,9 +606,7 @@ class RoomDetailsPresenterTest { @Test fun `present - show debug info`() = runTest { val room = aJoinedRoom( - canInviteResult = { Result.success(true) }, - canUserJoinCallResult = { Result.success(true) }, - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), ) val inMemoryAppPreferencesStore = InMemoryAppPreferencesStore( isDeveloperModeEnabled = true, @@ -744,4 +619,41 @@ class RoomDetailsPresenterTest { } } } + + private fun roomPermissions( + canInvite: Boolean = true, + canKick: Boolean = true, + canBan: Boolean = true, + canRedactOther: Boolean = true, + canRedactOwn: Boolean = true, + canChangeRoomAccess: Boolean = true, + canChangeHistoryVisibility: Boolean = true, + canChangeEncryption: Boolean = true, + canChangeRoomVisibility: Boolean = true, + canChangeName: Boolean = true, + canChangeTopic: Boolean = true, + canChangeAvatar: Boolean = true, + canChangePowerLevels: Boolean = true, + ): RoomPermissions { + return FakeRoomPermissions( + canInvite = canInvite, + canKick = canKick, + canBan = canBan, + canRedactOther = canRedactOther, + canRedactOwn = canRedactOwn, + canSendState = { eventType -> + when (eventType) { + StateEventType.ROOM_JOIN_RULES -> canChangeRoomAccess + StateEventType.ROOM_HISTORY_VISIBILITY -> canChangeHistoryVisibility + StateEventType.ROOM_ENCRYPTION -> canChangeEncryption + StateEventType.ROOM_CANONICAL_ALIAS -> canChangeRoomVisibility + StateEventType.ROOM_AVATAR -> canChangeAvatar + StateEventType.ROOM_NAME -> canChangeName + StateEventType.ROOM_TOPIC -> canChangeTopic + StateEventType.ROOM_POWER_LEVELS -> canChangePowerLevels + else -> lambdaError() + } + } + ) + } } diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt index 8d3d0e35e3..f1cab1524a 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt @@ -12,7 +12,6 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.CoroutineDispatchers -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipState @@ -20,6 +19,7 @@ import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers @@ -171,20 +171,7 @@ class RoomMemberListPresenterTest { fun `present - asynchronously sets canInvite when user does not have correct power level`() = runTest { val presenter = createPresenter( joinedRoom = createFakeJoinedRoom( - canInviteResult = { Result.success(false) }, - ) - ) - presenter.test { - val loadedState = awaitItem() - assertThat(loadedState.canInvite).isFalse() - } - } - - @Test - fun `present - asynchronously sets canInvite when power level check fails`() = runTest { - val presenter = createPresenter( - joinedRoom = createFakeJoinedRoom( - canInviteResult = { Result.failure(RuntimeException("Eek")) }, + canInvite = false, ) ) presenter.test { @@ -207,12 +194,14 @@ class RoomMemberListPresenterTest { private fun createFakeJoinedRoom( updateMembersResult: () -> Unit = { }, - canInviteResult: (UserId) -> Result = { Result.success(true) }, + canInvite: Boolean = true, ): FakeJoinedRoom { return FakeJoinedRoom( baseRoom = FakeBaseRoom( updateMembersResult = updateMembersResult, - canInviteResult = canInviteResult, + roomPermissions = FakeRoomPermissions( + canInvite = canInvite, + ), ).apply { // Needed to avoid discarding the loaded members as a partial and invalid result givenRoomInfo(aRoomInfo(joinedMembersCount = 2)) diff --git a/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt index f95f4466f2..c400ec1220 100644 --- a/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt +++ b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt @@ -14,7 +14,7 @@ data class RoomDetailsEditPermissions( val canEditName: Boolean, val canEditTopic: Boolean, val canEditAvatar: Boolean, -){ +) { val hasAny = canEditName || canEditTopic || canEditAvatar diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt index ed729928d8..24f8f49e81 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenter.kt @@ -59,7 +59,6 @@ class RoomDetailsEditPresenter( @Composable override fun present(): RoomDetailsEditState { val cameraPermissionState = cameraPermissionPresenter.present() - val roomSyncUpdateFlow = room.syncUpdateFlow.collectAsState() val roomInfo by room.roomInfoFlow.collectAsState() val roomAvatarUri = roomInfo.avatarUrl var roomAvatarUriEdited by rememberSaveable { mutableStateOf(null) } @@ -94,7 +93,7 @@ class RoomDetailsEditPresenter( } } - val permissions by room.permissionsAsState(RoomDetailsEditPermissions.DEFAULT){perms -> + val permissions by room.permissionsAsState(RoomDetailsEditPermissions.DEFAULT) { perms -> perms.roomDetailsEditPermissions() } diff --git a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt index e438cecf50..9c7f840af2 100644 --- a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt +++ b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt @@ -13,7 +13,6 @@ import com.google.common.truth.Truth.assertThat import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.core.mimetype.MimeTypes -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -23,6 +22,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_TOPIC import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.mediapickers.test.FakePickerProvider import io.element.android.libraries.mediaupload.api.MediaUploadInfo @@ -102,7 +102,6 @@ class RoomDetailsEditPresenterTest { avatarUrl = AN_AVATAR_URL, displayName = A_ROOM_NAME, rawName = A_ROOM_RAW_NAME, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -127,17 +126,15 @@ class RoomDetailsEditPresenterTest { @Test fun `present - sets canChangeName if user has permission`() = runTest { - val room = FakeJoinedRoom( - FakeBaseRoom( - canSendStateResult = { _, stateEventType -> - when (stateEventType) { - StateEventType.ROOM_NAME -> Result.success(true) - StateEventType.ROOM_AVATAR -> Result.success(false) - StateEventType.ROOM_TOPIC -> Result.failure(RuntimeException("Oops")) - else -> lambdaError() - } - }, - ) + val room = aJoinedRoom( + canSendState = { stateEventType -> + when (stateEventType) { + StateEventType.ROOM_NAME -> true + StateEventType.ROOM_AVATAR -> false + StateEventType.ROOM_TOPIC -> false + else -> lambdaError() + } + } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -163,11 +160,11 @@ class RoomDetailsEditPresenterTest { fun `present - sets canChangeAvatar if user has permission`() = runTest { val room = aJoinedRoom( avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, stateEventType -> + canSendState = { stateEventType -> when (stateEventType) { - StateEventType.ROOM_NAME -> Result.success(false) - StateEventType.ROOM_AVATAR -> Result.success(true) - StateEventType.ROOM_TOPIC -> Result.failure(RuntimeException("Oops")) + StateEventType.ROOM_NAME -> false + StateEventType.ROOM_AVATAR -> true + StateEventType.ROOM_TOPIC -> false else -> lambdaError() } } @@ -195,11 +192,11 @@ class RoomDetailsEditPresenterTest { fun `present - sets canChangeTopic if user has permission`() = runTest { val room = aJoinedRoom( avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, stateEventType -> + canSendState = { stateEventType -> when (stateEventType) { - StateEventType.ROOM_NAME -> Result.success(false) - StateEventType.ROOM_AVATAR -> Result.failure(RuntimeException("Oops")) - StateEventType.ROOM_TOPIC -> Result.success(true) + StateEventType.ROOM_NAME -> false + StateEventType.ROOM_AVATAR -> false + StateEventType.ROOM_TOPIC -> true else -> lambdaError() } } @@ -229,7 +226,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -274,7 +270,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(anotherAvatarUri) val deleteCallback = lambdaRecorder {} @@ -298,7 +293,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(anotherAvatarUri) val fakePermissionsPresenter = FakePermissionsPresenter() @@ -339,7 +333,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(roomAvatarUri) val deleteCallback = lambdaRecorder {} @@ -389,7 +382,6 @@ class RoomDetailsEditPresenterTest { topic = null, displayName = "fallback", avatarUrl = null, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(roomAvatarUri) val deleteCallback = lambdaRecorder {} @@ -445,7 +437,6 @@ class RoomDetailsEditPresenterTest { setNameResult = setNameResult, setTopicResult = setTopicResult, removeAvatarResult = removeAvatarResult, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -471,7 +462,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -493,7 +483,6 @@ class RoomDetailsEditPresenterTest { topic = null, displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -515,7 +504,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -539,7 +527,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, updateAvatarResult = updateAvatarResult, - canSendStateResult = { _, _ -> Result.success(true) } ) givenPickerReturnsFile() val deleteCallback = lambdaRecorder {} @@ -566,7 +553,6 @@ class RoomDetailsEditPresenterTest { topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, - canSendStateResult = { _, _ -> Result.success(true) } ) fakePickerProvider.givenResult(anotherAvatarUri) fakeMediaPreProcessor.givenResult(Result.failure(RuntimeException("Oh no"))) @@ -591,7 +577,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, setNameResult = { Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) saveAndAssertFailure(room, RoomDetailsEditEvent.UpdateRoomName("New name"), deleteCallbackNumberOfInvocation = 1) } @@ -603,7 +588,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, setTopicResult = { Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) saveAndAssertFailure(room, RoomDetailsEditEvent.UpdateRoomTopic("New topic"), deleteCallbackNumberOfInvocation = 1) } @@ -615,7 +599,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, removeAvatarResult = { Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove), deleteCallbackNumberOfInvocation = 2) } @@ -628,7 +611,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, updateAvatarResult = { _, _ -> Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto), deleteCallbackNumberOfInvocation = 2) } @@ -641,7 +623,6 @@ class RoomDetailsEditPresenterTest { displayName = "Name", avatarUrl = AN_AVATAR_URL, setTopicResult = { Result.failure(RuntimeException("!")) }, - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -663,7 +644,6 @@ class RoomDetailsEditPresenterTest { fun `present - leave without saving - cancel`() = runTest { val room = aJoinedRoom( displayName = "Name", - canSendStateResult = { _, _ -> Result.success(true) } ) val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( @@ -693,7 +673,6 @@ class RoomDetailsEditPresenterTest { fun `present - leave no changes, no confirmation`() = runTest { val room = aJoinedRoom( displayName = "Name", - canSendStateResult = { _, _ -> Result.success(true) } ) val presenter = createRoomDetailsEditPresenter( room = room, @@ -711,7 +690,7 @@ class RoomDetailsEditPresenterTest { fun `present - leave without saving - confirm`() = runTest { val room = aJoinedRoom( displayName = "Name", - canSendStateResult = { _, _ -> Result.success(true) } + canSendState = { _ -> true } ) val presenter = createRoomDetailsEditPresenter( room = room, @@ -782,11 +761,13 @@ class RoomDetailsEditPresenterTest { setTopicResult: (String) -> Result = { Result.success(Unit) }, updateAvatarResult: (String, ByteArray) -> Result = { _, _ -> Result.success(Unit) }, removeAvatarResult: () -> Result = { Result.success(Unit) }, - canSendStateResult: (UserId, StateEventType) -> Result, + canSendState: (StateEventType) -> Boolean = { true }, ): JoinedRoom { return FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = canSendStateResult, + roomPermissions = FakeRoomPermissions( + canSendState = canSendState, + ), initialRoomInfo = aRoomInfo( name = displayName, topic = topic, diff --git a/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt b/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt index 2b3f71e770..4ce50a2488 100644 --- a/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt +++ b/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule @@ -355,8 +356,10 @@ class RoomMemberModerationPresenterTest { banUserResult = { _, _ -> banUserResult }, unBanUserResult = { _, _ -> unBanUserResult }, baseRoom = FakeBaseRoom( - canBanResult = { _ -> Result.success(canBan) }, - canKickResult = { _ -> Result.success(canKick) }, + roomPermissions = FakeRoomPermissions( + canBan = canBan, + canKick = canKick + ), userRoleResult = { Result.success(myUserRole) }, updateMembersResult = { Result.success(Unit) } ), diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index af0f44be38..81bfe22697 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -67,7 +67,6 @@ class SecurityAndPrivacyPresenter( }.collectAsState(false) val saveAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } val homeserverName = remember { matrixClient.userIdServerName() } - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val roomInfo by room.roomInfoFlow.collectAsState() val savedIsVisibleInRoomDirectory = remember { mutableStateOf>(AsyncData.Uninitialized) } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index 7d88706996..a4542b02a1 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -18,15 +18,19 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.libraries.matrix.api.room.StateEventType 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.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import io.element.android.libraries.matrix.test.A_ROOM_ALIAS import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.test import kotlinx.coroutines.test.runTest @@ -66,7 +70,7 @@ class SecurityAndPrivacyPresenterTest { fun `present - room info change updates saved and edited settings`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), initialRoomInfo = aRoomInfo( joinRule = JoinRule.Public, historyVisibility = RoomHistoryVisibility.WorldReadable, @@ -173,7 +177,7 @@ class SecurityAndPrivacyPresenterTest { fun `present - room visibility loading and change`() = runTest { val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared) ) @@ -222,7 +226,7 @@ class SecurityAndPrivacyPresenterTest { val updateRoomHistoryVisibilityLambda = lambdaRecorder> { Result.success(Unit) } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, initialRoomInfo = aRoomInfo(joinRule = JoinRule.Invite, historyVisibility = RoomHistoryVisibility.Shared) ), @@ -272,8 +276,8 @@ class SecurityAndPrivacyPresenterTest { isEncrypted = true, ) ) - // Saved settings are updated 3 times to match the edited settings - skipItems(3) + // Saved settings are updated 2 times to match the edited settings + skipItems(2) with(awaitItem()) { assertThat(saveAction).isEqualTo(AsyncAction.Success(Unit)) assertThat(savedSettings).isEqualTo(editedSettings) @@ -297,7 +301,7 @@ class SecurityAndPrivacyPresenterTest { val updateRoomHistoryVisibilityLambda = lambdaRecorder> { Result.success(Unit) } val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, joinRule = JoinRule.Private) ), @@ -340,7 +344,7 @@ class SecurityAndPrivacyPresenterTest { ) ) // Saved settings are updated 2 times to match the edited settings - skipItems(3) + skipItems(2) val state = awaitItem() with(state) { assertThat(saveAction).isInstanceOf(AsyncAction.Failure::class.java) @@ -374,11 +378,30 @@ class SecurityAndPrivacyPresenterTest { } } + private fun roomPermissions( + canChangeRoomAccess: Boolean = true, + canChangeHistoryVisibility: Boolean = true, + canChangeEncryption: Boolean = true, + canChangeRoomVisibility: Boolean = true, + ): RoomPermissions { + return FakeRoomPermissions( + canSendState = { eventType -> + when (eventType) { + StateEventType.ROOM_JOIN_RULES -> canChangeRoomAccess + StateEventType.ROOM_HISTORY_VISIBILITY -> canChangeHistoryVisibility + StateEventType.ROOM_ENCRYPTION -> canChangeEncryption + StateEventType.ROOM_CANONICAL_ALIAS -> canChangeRoomVisibility + else -> lambdaError() + } + } + ) + } + private fun createSecurityAndPrivacyPresenter( serverName: String = "matrix.org", room: FakeJoinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canSendStateResult = { _, _ -> Result.success(true) }, + roomPermissions = roomPermissions(), getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, initialRoomInfo = aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, joinRule = JoinRule.Private) ), diff --git a/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt b/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt index 8b7eddca54..7e09a03ec3 100644 --- a/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt +++ b/features/userprofile/impl/src/main/kotlin/io/element/android/features/userprofile/impl/root/UserProfilePresenter.kt @@ -76,7 +76,7 @@ class UserProfilePresenter( roomId ?.let { client.getRoom(it) } ?.use { room -> - room.roomPermissions().use(false){ perms -> perms.canCall()} + room.roomPermissions().use(false) { perms -> perms.canCall() } } .orFalse() } diff --git a/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt b/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt index aa984f0066..b10cf3e48d 100644 --- a/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt +++ b/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt @@ -28,6 +28,7 @@ import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.encryption.identity.IdentityState +import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -36,9 +37,11 @@ import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.room.FakeBaseRoom +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.lambda.any +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test @@ -89,15 +92,7 @@ class UserProfilePresenterTest { @Test fun `present - canCall is false when canUserJoinCall returns false`() { testCanCall( - canUserJoinCallResult = Result.success(false), - expectedResult = false, - ) - } - - @Test - fun `present - canCall is false when canUserJoinCall fails`() { - testCanCall( - canUserJoinCallResult = Result.failure(AN_EXCEPTION), + canUserJoinCall = false, expectedResult = false, ) } @@ -128,7 +123,7 @@ class UserProfilePresenterTest { private fun testCanCall( isElementCallAvailable: Boolean = true, - canUserJoinCallResult: Result = Result.success(true), + canUserJoinCall: Boolean = true, dmRoom: RoomId? = A_ROOM_ID, canFindRoom: Boolean = true, expectedResult: Boolean, @@ -136,7 +131,14 @@ class UserProfilePresenterTest { checkThatRoomIsDestroyed: Boolean = false, ) = runTest { val room = FakeBaseRoom( - canUserJoinCallResult = { canUserJoinCallResult }, + roomPermissions = FakeRoomPermissions( + canSendState = { type -> + when (type) { + StateEventType.CALL_MEMBER -> canUserJoinCall + else -> lambdaError() + } + } + ), ) val client = createFakeMatrixClient().apply { if (canFindRoom) { diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt index 735627e10e..638bf5449c 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt @@ -18,7 +18,6 @@ import io.element.android.libraries.matrix.api.room.StateEventType import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map -import timber.log.Timber /** * Provides information about the permissions of users in a room. @@ -150,7 +149,15 @@ fun Result.use(default: T, block: (RoomPermissions) -> T): fun BaseRoom.permissionsFlow(default: T, block: (RoomPermissions) -> T): Flow { return roomInfoFlow - .map { info -> info.roomPowerLevels } + .map { info -> + // If the user is a privileged creator, we return a constant hashcode to avoid recomputing permissions + // each time the power levels change (as they have all permissions). + if (info.privilegedCreatorRole && info.creators.contains(sessionId)) { + Long.MAX_VALUE + } else { + info.roomPowerLevels?.hashCode() ?: 0L + } + } .distinctUntilChanged() .map { roomPermissions().use(default, block) @@ -160,7 +167,6 @@ fun BaseRoom.permissionsFlow(default: T, block: (RoomPermissions) -> T): Flo @Composable fun BaseRoom.permissionsAsState(default: T, block: (RoomPermissions) -> T): State { return remember(this, default, block) { - Timber.d("Computing permissionsAsState for room $roomId with default=$default") permissionsFlow(default, block) }.collectAsState(default) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt index 141957d1ed..1aeb8f445d 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt @@ -18,12 +18,10 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipObserver -import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt index b05eff77e2..b56066af73 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeBaseRoom.kt @@ -15,11 +15,9 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState -import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues @@ -42,6 +40,7 @@ class FakeBaseRoom( override val sessionId: SessionId = A_SESSION_ID, override val roomId: RoomId = A_ROOM_ID, initialRoomInfo: RoomInfo = aRoomInfo(), + private val roomPermissions: RoomPermissions = FakeRoomPermissions(), override val roomCoroutineScope: CoroutineScope = TestScope(), private var roomPermalinkResult: () -> Result = { lambdaError() }, private var eventPermalinkResult: (EventId) -> Result = { lambdaError() }, @@ -50,17 +49,6 @@ class FakeBaseRoom( private val userRoleResult: () -> Result = { lambdaError() }, private val getUpdatedMemberResult: (UserId) -> Result = { lambdaError() }, private val joinRoomResult: () -> Result = { lambdaError() }, - private val roomPermissionsResult: () -> Result = { Result.success(FakeRoomPermissions()) }, - private val canInviteResult: (UserId) -> Result = { lambdaError() }, - private val canKickResult: (UserId) -> Result = { lambdaError() }, - private val canBanResult: (UserId) -> Result = { lambdaError() }, - private val canRedactOwnResult: (UserId) -> Result = { lambdaError() }, - private val canRedactOtherResult: (UserId) -> Result = { lambdaError() }, - private val canSendStateResult: (UserId, StateEventType) -> Result = { _, _ -> lambdaError() }, - private val canUserSendMessageResult: (UserId, MessageEventType) -> Result = { _, _ -> lambdaError() }, - private val canUserTriggerRoomNotificationResult: (UserId) -> Result = { lambdaError() }, - private val canUserJoinCallResult: (UserId) -> Result = { lambdaError() }, - private val canUserPinUnpinResult: (UserId) -> Result = { lambdaError() }, private val setIsFavoriteResult: (Boolean) -> Result = { lambdaError() }, private val markAsReadResult: (ReceiptType) -> Result = { Result.success(Unit) }, private val powerLevelsResult: () -> Result = { lambdaError() }, @@ -133,7 +121,7 @@ class FakeBaseRoom( } override suspend fun roomPermissions(): Result { - return roomPermissionsResult() + return Result.success(roomPermissions) } override suspend fun getPermalink(): Result { @@ -160,46 +148,6 @@ class FakeBaseRoom( return forgetResult() } - override suspend fun canUserBan(userId: UserId): Result { - return canBanResult(userId) - } - - override suspend fun canUserKick(userId: UserId): Result { - return canKickResult(userId) - } - - override suspend fun canUserInvite(userId: UserId): Result { - return canInviteResult(userId) - } - - override suspend fun canUserRedactOwn(userId: UserId): Result { - return canRedactOwnResult(userId) - } - - override suspend fun canUserRedactOther(userId: UserId): Result { - return canRedactOtherResult(userId) - } - - override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result { - return canSendStateResult(userId, type) - } - - override suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result { - return canUserSendMessageResult(userId, type) - } - - override suspend fun canUserTriggerRoomNotification(userId: UserId): Result { - return canUserTriggerRoomNotificationResult(userId) - } - - override suspend fun canUserJoinCall(userId: UserId): Result { - return canUserJoinCallResult(userId) - } - - override suspend fun canUserPinUnpin(userId: UserId): Result { - return canUserPinUnpinResult(userId) - } - override suspend fun setIsFavorite(isFavorite: Boolean): Result { return setIsFavoriteResult(isFavorite) } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt index 04ecb1f60b..b78dc9ba1b 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/powerlevels/FakeRoomPermissions.kt @@ -13,44 +13,44 @@ import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions data class FakeRoomPermissions( - val ownerCanBan: Boolean = false, - val ownerCanInvite: Boolean = false, - val ownerCanKick: Boolean = false, - val ownerCanPinUnpin: Boolean = false, - val ownerCanRedactOther: Boolean = false, - val ownerCanRedactOwn: Boolean = false, - val ownerCanTriggerRoomNotification: Boolean = false, - val ownerCanSendMessage: (MessageEventType) -> Boolean = { false }, - val ownerCanSendState: (StateEventType) -> Boolean = { false }, - val userCanBan: (UserId) -> Boolean = { false }, - val userCanInvite: (UserId) -> Boolean = { false }, - val userCanKick: (UserId) -> Boolean = { false }, - val userCanPinUnpin: (UserId) -> Boolean = { false }, - val userCanRedactOther: (UserId) -> Boolean = { false }, - val userCanRedactOwn: (UserId) -> Boolean = { false }, - val userCanTriggerRoomNotification: (UserId) -> Boolean = { false }, - val userCanSendMessage: (UserId, MessageEventType) -> Boolean = { _, _ -> false }, - val userCanSendState: (UserId, StateEventType) -> Boolean = { _, _ -> false }, + private val canBan: Boolean = false, + private val canInvite: Boolean = false, + private val canKick: Boolean = false, + private val canPinUnpin: Boolean = false, + private val canRedactOther: Boolean = false, + private val canRedactOwn: Boolean = false, + private val canTriggerRoomNotification: Boolean = false, + private val canSendMessage: (MessageEventType) -> Boolean = { false }, + private val canSendState: (StateEventType) -> Boolean = { false }, + private val canUserBan: (UserId) -> Boolean = { false }, + private val canUserInvite: (UserId) -> Boolean = { false }, + private val canUserKick: (UserId) -> Boolean = { false }, + private val canUserPinUnpin: (UserId) -> Boolean = { false }, + private val canUserRedactOther: (UserId) -> Boolean = { false }, + private val canUserRedactOwn: (UserId) -> Boolean = { false }, + private val canUserTriggerRoomNotification: (UserId) -> Boolean = { false }, + private val canUserSendMessage: (UserId, MessageEventType) -> Boolean = { _, _ -> false }, + private val canUserSendState: (UserId, StateEventType) -> Boolean = { _, _ -> false }, ) : RoomPermissions { + override fun canOwnUserBan(): Boolean = canBan + override fun canOwnUserInvite(): Boolean = canInvite + override fun canOwnUserKick(): Boolean = canKick + override fun canOwnUserPinUnpin(): Boolean = canPinUnpin + override fun canOwnUserRedactOther(): Boolean = canRedactOther + override fun canOwnUserRedactOwn(): Boolean = canRedactOwn + override fun canOwnUserSendMessage(message: MessageEventType): Boolean = canSendMessage(message) + override fun canOwnUserSendState(stateEvent: StateEventType): Boolean = canSendState(stateEvent) - override fun canOwnUserBan(): Boolean = ownerCanBan - override fun canOwnUserInvite(): Boolean = ownerCanInvite - override fun canOwnUserKick(): Boolean = ownerCanKick - override fun canOwnUserPinUnpin(): Boolean = ownerCanPinUnpin - override fun canOwnUserRedactOther(): Boolean = ownerCanRedactOther - override fun canOwnUserRedactOwn(): Boolean = ownerCanRedactOwn - override fun canOwnUserSendMessage(message: MessageEventType): Boolean = ownerCanSendMessage(message) - override fun canOwnUserSendState(stateEvent: StateEventType): Boolean = ownerCanSendState(stateEvent) - override fun canOwnUserTriggerRoomNotification(): Boolean = ownerCanTriggerRoomNotification - override fun canUserBan(userId: UserId): Boolean = userCanBan(userId) - override fun canUserInvite(userId: UserId): Boolean = userCanInvite(userId) - override fun canUserKick(userId: UserId): Boolean = userCanKick(userId) - override fun canUserPinUnpin(userId: UserId): Boolean = userCanPinUnpin(userId) - override fun canUserRedactOther(userId: UserId): Boolean = userCanRedactOther(userId) - override fun canUserRedactOwn(userId: UserId): Boolean = userCanRedactOwn(userId) - override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean = userCanSendMessage(userId, message) - override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean = userCanSendState(userId, stateEvent) - override fun canUserTriggerRoomNotification(userId: UserId): Boolean = userCanTriggerRoomNotification(userId) + override fun canOwnUserTriggerRoomNotification(): Boolean = canTriggerRoomNotification + override fun canUserBan(userId: UserId): Boolean = canUserBan(userId) + override fun canUserInvite(userId: UserId): Boolean = canUserInvite(userId) + override fun canUserKick(userId: UserId): Boolean = canUserKick(userId) + override fun canUserPinUnpin(userId: UserId): Boolean = canUserPinUnpin(userId) + override fun canUserRedactOther(userId: UserId): Boolean = canUserRedactOther(userId) + override fun canUserRedactOwn(userId: UserId): Boolean = canUserRedactOwn(userId) + override fun canUserSendMessage(userId: UserId, message: MessageEventType): Boolean = canUserSendMessage(userId, message) + override fun canUserSendState(userId: UserId, stateEvent: StateEventType): Boolean = canUserSendState(userId, stateEvent) + override fun canUserTriggerRoomNotification(userId: UserId): Boolean = canUserTriggerRoomNotification(userId) override fun close() { // no-op for the fake diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt index e5e493ee63..cc26e69c33 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenter.kt @@ -207,7 +207,6 @@ class MediaGalleryPresenter( CommonStrings.error_unknown } } - } private fun GroupedMediaItems?.find(eventId: EventId?): MediaItem.Event? { diff --git a/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenterTest.kt b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenterTest.kt index e890b7f036..3069a4fd9d 100644 --- a/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenterTest.kt +++ b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/MediaGalleryPresenterTest.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.mediaviewer.impl.datasource.FakeMediaGalleryDataSource import io.element.android.libraries.mediaviewer.impl.datasource.MediaGalleryDataSource @@ -109,7 +110,9 @@ class MediaGalleryPresenterTest { baseRoom = FakeBaseRoom( sessionId = A_USER_ID, initialRoomInfo = aRoomInfo(name = A_ROOM_NAME), - canRedactOwnResult = { Result.success(canDeleteOwn) } + roomPermissions = FakeRoomPermissions( + canRedactOwn = canDeleteOwn + ), ), ) ) @@ -153,7 +156,9 @@ class MediaGalleryPresenterTest { baseRoom = FakeBaseRoom( sessionId = A_USER_ID, initialRoomInfo = aRoomInfo(name = A_ROOM_NAME), - canRedactOtherResult = { Result.success(canDeleteOther) }, + roomPermissions = FakeRoomPermissions( + canRedactOther = canDeleteOther + ), ), createTimelineResult = { Result.success(FakeTimeline()) } ) @@ -355,7 +360,9 @@ class MediaGalleryPresenterTest { room = FakeJoinedRoom( createTimelineResult = { Result.success(FakeTimeline()) }, baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), ), ), navigator = navigator, @@ -386,7 +393,9 @@ class MediaGalleryPresenterTest { room = FakeJoinedRoom( createTimelineResult = { Result.success(FakeTimeline()) }, baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), ), ), navigator = navigator, diff --git a/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenterTest.kt b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenterTest.kt index d9769aac13..a9d1704bdc 100644 --- a/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenterTest.kt +++ b/libraries/mediaviewer/impl/src/test/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerPresenterTest.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader import io.element.android.libraries.matrix.test.media.aMediaSource import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint import io.element.android.libraries.mediaviewer.api.anApkMediaInfo @@ -83,7 +84,9 @@ class MediaViewerPresenterTest { localMediaFactory = localMediaFactory, room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), ) ) ) @@ -104,7 +107,9 @@ class MediaViewerPresenterTest { canShowInfo = false, room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), ) ) ) @@ -125,7 +130,9 @@ class MediaViewerPresenterTest { eventId = AN_EVENT_ID, room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), ) ) ) @@ -147,7 +154,9 @@ class MediaViewerPresenterTest { room = FakeJoinedRoom( baseRoom = FakeBaseRoom( sessionId = A_SESSION_ID_2, - canRedactOtherResult = { Result.success(false) }, + roomPermissions = FakeRoomPermissions( + canRedactOther = false + ), ) ) ) @@ -236,7 +245,9 @@ class MediaViewerPresenterTest { mediaGalleryDataSource = mediaGalleryDataSource, room = FakeJoinedRoom( baseRoom = FakeBaseRoom( - canRedactOwnResult = { Result.success(true) }, + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), ) ) ) @@ -460,7 +471,11 @@ class MediaViewerPresenterTest { localMediaFactory = localMediaFactory, room = FakeJoinedRoom( liveTimeline = timeline, - baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), + ), ), mediaGalleryDataSource = mediaGalleryDataSource, mediaViewerNavigator = FakeMediaViewerNavigator( @@ -769,7 +784,11 @@ class MediaViewerPresenterTest { localMediaFactory = localMediaFactory, mediaViewerNavigator = navigator, room = FakeJoinedRoom( - baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), + ), ) ) presenter.test { @@ -794,7 +813,11 @@ class MediaViewerPresenterTest { localMediaFactory = localMediaFactory, mediaViewerNavigator = navigator, room = FakeJoinedRoom( - baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), + ), ), ) presenter.test { @@ -821,7 +844,11 @@ class MediaViewerPresenterTest { localMediaFactory = localMediaFactory, mediaViewerNavigator = navigator, room = FakeJoinedRoom( - baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }), + baseRoom = FakeBaseRoom( + roomPermissions = FakeRoomPermissions( + canRedactOwn = true + ), + ), ), ) presenter.test { From 6791890bf98299eab941138f7c2ba5225d985d2a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 12 Dec 2025 12:20:13 +0100 Subject: [PATCH 119/347] Import Compound tokens from release v6.4.2 https://github.com/element-hq/compound-design-tokens/releases/tag/v6.4.2 --- .../compound/src/main/assets/theme.iife.js | 39 +------------------ .../tokens/generated/CompoundIcons.kt | 39 ++++++++++++------- .../tokens/generated/SemanticColors.kt | 38 ++++++++---------- .../tokens/generated/SemanticColorsDark.kt | 18 ++++----- .../tokens/generated/SemanticColorsDarkHc.kt | 18 ++++----- .../tokens/generated/SemanticColorsLight.kt | 18 ++++----- .../tokens/generated/SemanticColorsLightHc.kt | 18 ++++----- .../tokens/generated/TypographyTokens.kt | 4 -- .../generated/internal/DarkColorTokens.kt | 3 -- .../generated/internal/DarkHcColorTokens.kt | 3 -- .../generated/internal/LightColorTokens.kt | 3 -- .../generated/internal/LightHcColorTokens.kt | 3 -- .../drawable/ic_compound_exit_full_screen.xml | 9 +++++ .../res/drawable/ic_compound_full_screen.xml | 9 +++++ .../drawable/ic_compound_left_panel_close.xml | 9 +++++ .../main/res/drawable/ic_compound_space.xml | 9 +++++ .../res/drawable/ic_compound_space_solid.xml | 9 +++++ .../main/res/drawable/ic_compound_threads.xml | 12 +++--- .../drawable/ic_compound_threads_solid.xml | 6 +-- .../res/drawable/ic_compound_workspace.xml | 9 ----- .../drawable/ic_compound_workspace_solid.xml | 9 ----- 21 files changed, 132 insertions(+), 153 deletions(-) create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_exit_full_screen.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_full_screen.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_left_panel_close.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_space.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_space_solid.xml delete mode 100644 libraries/compound/src/main/res/drawable/ic_compound_workspace.xml delete mode 100644 libraries/compound/src/main/res/drawable/ic_compound_workspace_solid.xml diff --git a/libraries/compound/src/main/assets/theme.iife.js b/libraries/compound/src/main/assets/theme.iife.js index 4be509b11c..71ce6b0013 100644 --- a/libraries/compound/src/main/assets/theme.iife.js +++ b/libraries/compound/src/main/assets/theme.iife.js @@ -1,38 +1 @@ -var CompoundTheme=(function(Fe){"use strict";const Xe=(e,t=0,r=1)=>Zt(Jt(t,e),r),Yt=e=>{e._clipped=!1,e._unclipped=e.slice(0);for(let t=0;t<=3;t++)t<3?((e[t]<0||e[t]>255)&&(e._clipped=!0),e[t]=Xe(e[t],0,255)):t===3&&(e[t]=Xe(e[t],0,1));return e},co={};for(let e of["Boolean","Number","String","Function","Array","Date","RegExp","Undefined","Null"])co[`[object ${e}]`]=e.toLowerCase();function S(e){return co[Object.prototype.toString.call(e)]||"object"}const P=(e,t=null)=>e.length>=3?Array.prototype.slice.call(e):S(e[0])=="object"&&t?t.split("").filter(r=>e[0][r]!==void 0).map(r=>e[0][r]):e[0],pt=e=>{if(e.length<2)return null;const t=e.length-1;return S(e[t])=="string"?e[t].toLowerCase():null},{PI:mt,min:Zt,max:Jt}=Math,we=mt*2,Wt=mt/3,Ac=mt/180,Lc=180/mt,L={format:{},autodetect:[]};let C=class{constructor(...t){const r=this;if(S(t[0])==="object"&&t[0].constructor&&t[0].constructor===this.constructor)return t[0];let n=pt(t),o=!1;if(!n){o=!0,L.sorted||(L.autodetect=L.autodetect.sort((a,s)=>s.p-a.p),L.sorted=!0);for(let a of L.autodetect)if(n=a.test(...t),n)break}if(L.format[n]){const a=L.format[n].apply(null,o?t:t.slice(0,-1));r._rgb=Yt(a)}else throw new Error("unknown format: "+t);r._rgb.length===3&&r._rgb.push(1)}toString(){return S(this.hex)=="function"?this.hex():`[${this._rgb.join(",")}]`}};const Ec="2.6.0",O=(...e)=>new O.Color(...e);O.Color=C,O.version=Ec;const Tc=(...e)=>{e=P(e,"cmyk");const[t,r,n,o]=e,a=e.length>4?e[4]:1;return o===1?[0,0,0,a]:[t>=1?0:255*(1-t)*(1-o),r>=1?0:255*(1-r)*(1-o),n>=1?0:255*(1-n)*(1-o),a]},{max:io}=Math,Sc=(...e)=>{let[t,r,n]=P(e,"rgb");t=t/255,r=r/255,n=n/255;const o=1-io(t,io(r,n)),a=o<1?1/(1-o):0,s=(1-t-o)*a,c=(1-r-o)*a,i=(1-n-o)*a;return[s,c,i,o]};C.prototype.cmyk=function(){return Sc(this._rgb)},O.cmyk=(...e)=>new C(...e,"cmyk"),L.format.cmyk=Tc,L.autodetect.push({p:2,test:(...e)=>{if(e=P(e,"cmyk"),S(e)==="array"&&e.length===4)return"cmyk"}});const Ut=e=>Math.round(e*100)/100,Pc=(...e)=>{const t=P(e,"hsla");let r=pt(e)||"lsa";return t[0]=Ut(t[0]||0),t[1]=Ut(t[1]*100)+"%",t[2]=Ut(t[2]*100)+"%",r==="hsla"||t.length>3&&t[3]<1?(t[3]=t.length>3?t[3]:1,r="hsla"):t.length=3,`${r}(${t.join(",")})`},uo=(...e)=>{e=P(e,"rgba");let[t,r,n]=e;t/=255,r/=255,n/=255;const o=Zt(t,r,n),a=Jt(t,r,n),s=(a+o)/2;let c,i;return a===o?(c=0,i=Number.NaN):c=s<.5?(a-o)/(a+o):(a-o)/(2-a-o),t==a?i=(r-n)/(a-o):r==a?i=2+(n-t)/(a-o):n==a&&(i=4+(t-r)/(a-o)),i*=60,i<0&&(i+=360),e.length>3&&e[3]!==void 0?[i,c,s,e[3]]:[i,c,s]},{round:Qt}=Math,jc=(...e)=>{const t=P(e,"rgba");let r=pt(e)||"rgb";return r.substr(0,3)=="hsl"?Pc(uo(t),r):(t[0]=Qt(t[0]),t[1]=Qt(t[1]),t[2]=Qt(t[2]),(r==="rgba"||t.length>3&&t[3]<1)&&(t[3]=t.length>3?t[3]:1,r="rgba"),`${r}(${t.slice(0,r==="rgb"?3:4).join(",")})`)},{round:er}=Math,tr=(...e)=>{e=P(e,"hsl");const[t,r,n]=e;let o,a,s;if(r===0)o=a=s=n*255;else{const c=[0,0,0],i=[0,0,0],u=n<.5?n*(1+r):n+r-n*r,f=2*n-u,l=t/360;c[0]=l+1/3,c[1]=l,c[2]=l-1/3;for(let h=0;h<3;h++)c[h]<0&&(c[h]+=1),c[h]>1&&(c[h]-=1),6*c[h]<1?i[h]=f+(u-f)*6*c[h]:2*c[h]<1?i[h]=u:3*c[h]<2?i[h]=f+(u-f)*(2/3-c[h])*6:i[h]=f;[o,a,s]=[er(i[0]*255),er(i[1]*255),er(i[2]*255)]}return e.length>3?[o,a,s,e[3]]:[o,a,s,1]},fo=/^rgb\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*\)$/,lo=/^rgba\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*,\s*([01]|[01]?\.\d+)\)$/,ho=/^rgb\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/,bo=/^rgba\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/,po=/^hsl\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/,mo=/^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/,{round:go}=Math,rr=e=>{e=e.toLowerCase().trim();let t;if(L.format.named)try{return L.format.named(e)}catch{}if(t=e.match(fo)){const r=t.slice(1,4);for(let n=0;n<3;n++)r[n]=+r[n];return r[3]=1,r}if(t=e.match(lo)){const r=t.slice(1,5);for(let n=0;n<4;n++)r[n]=+r[n];return r}if(t=e.match(ho)){const r=t.slice(1,4);for(let n=0;n<3;n++)r[n]=go(r[n]*2.55);return r[3]=1,r}if(t=e.match(bo)){const r=t.slice(1,5);for(let n=0;n<3;n++)r[n]=go(r[n]*2.55);return r[3]=+r[3],r}if(t=e.match(po)){const r=t.slice(1,4);r[1]*=.01,r[2]*=.01;const n=tr(r);return n[3]=1,n}if(t=e.match(mo)){const r=t.slice(1,4);r[1]*=.01,r[2]*=.01;const n=tr(r);return n[3]=+t[4],n}};rr.test=e=>fo.test(e)||lo.test(e)||ho.test(e)||bo.test(e)||po.test(e)||mo.test(e),C.prototype.css=function(e){return jc(this._rgb,e)},O.css=(...e)=>new C(...e,"css"),L.format.css=rr,L.autodetect.push({p:5,test:(e,...t)=>{if(!t.length&&S(e)==="string"&&rr.test(e))return"css"}}),L.format.gl=(...e)=>{const t=P(e,"rgba");return t[0]*=255,t[1]*=255,t[2]*=255,t},O.gl=(...e)=>new C(...e,"gl"),C.prototype.gl=function(){const e=this._rgb;return[e[0]/255,e[1]/255,e[2]/255,e[3]]};const{floor:Bc}=Math,Gc=(...e)=>{e=P(e,"hcg");let[t,r,n]=e,o,a,s;n=n*255;const c=r*255;if(r===0)o=a=s=n;else{t===360&&(t=0),t>360&&(t-=360),t<0&&(t+=360),t/=60;const i=Bc(t),u=t-i,f=n*(1-r),l=f+c*(1-u),h=f+c*u,d=f+c;switch(i){case 0:[o,a,s]=[d,h,f];break;case 1:[o,a,s]=[l,d,f];break;case 2:[o,a,s]=[f,d,h];break;case 3:[o,a,s]=[f,l,d];break;case 4:[o,a,s]=[h,f,d];break;case 5:[o,a,s]=[d,f,l];break}}return[o,a,s,e.length>3?e[3]:1]},Ic=(...e)=>{const[t,r,n]=P(e,"rgb"),o=Zt(t,r,n),a=Jt(t,r,n),s=a-o,c=s*100/255,i=o/(255-s)*100;let u;return s===0?u=Number.NaN:(t===a&&(u=(r-n)/s),r===a&&(u=2+(n-t)/s),n===a&&(u=4+(t-r)/s),u*=60,u<0&&(u+=360)),[u,c,i]};C.prototype.hcg=function(){return Ic(this._rgb)},O.hcg=(...e)=>new C(...e,"hcg"),L.format.hcg=Gc,L.autodetect.push({p:1,test:(...e)=>{if(e=P(e,"hcg"),S(e)==="array"&&e.length===3)return"hcg"}});const zc=/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,Fc=/^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/,vo=e=>{if(e.match(zc)){(e.length===4||e.length===7)&&(e=e.substr(1)),e.length===3&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]);const t=parseInt(e,16),r=t>>16,n=t>>8&255,o=t&255;return[r,n,o,1]}if(e.match(Fc)){(e.length===5||e.length===9)&&(e=e.substr(1)),e.length===4&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]+e[3]+e[3]);const t=parseInt(e,16),r=t>>24&255,n=t>>16&255,o=t>>8&255,a=Math.round((t&255)/255*100)/100;return[r,n,o,a]}throw new Error(`unknown hex color: ${e}`)},{round:gt}=Math,_o=(...e)=>{let[t,r,n,o]=P(e,"rgba"),a=pt(e)||"auto";o===void 0&&(o=1),a==="auto"&&(a=o<1?"rgba":"rgb"),t=gt(t),r=gt(r),n=gt(n);let c="000000"+(t<<16|r<<8|n).toString(16);c=c.substr(c.length-6);let i="0"+gt(o*255).toString(16);switch(i=i.substr(i.length-2),a.toLowerCase()){case"rgba":return`#${c}${i}`;case"argb":return`#${i}${c}`;default:return`#${c}`}};C.prototype.hex=function(e){return _o(this._rgb,e)},O.hex=(...e)=>new C(...e,"hex"),L.format.hex=vo,L.autodetect.push({p:4,test:(e,...t)=>{if(!t.length&&S(e)==="string"&&[3,4,5,6,7,8,9].indexOf(e.length)>=0)return"hex"}});const{cos:Ke}=Math,Xc=(...e)=>{e=P(e,"hsi");let[t,r,n]=e,o,a,s;return isNaN(t)&&(t=0),isNaN(r)&&(r=0),t>360&&(t-=360),t<0&&(t+=360),t/=360,t<1/3?(s=(1-r)/3,o=(1+r*Ke(we*t)/Ke(Wt-we*t))/3,a=1-(s+o)):t<2/3?(t-=1/3,o=(1-r)/3,a=(1+r*Ke(we*t)/Ke(Wt-we*t))/3,s=1-(o+a)):(t-=2/3,a=(1-r)/3,s=(1+r*Ke(we*t)/Ke(Wt-we*t))/3,o=1-(a+s)),o=Xe(n*o*3),a=Xe(n*a*3),s=Xe(n*s*3),[o*255,a*255,s*255,e.length>3?e[3]:1]},{min:Kc,sqrt:Dc,acos:Vc}=Math,Yc=(...e)=>{let[t,r,n]=P(e,"rgb");t/=255,r/=255,n/=255;let o;const a=Kc(t,r,n),s=(t+r+n)/3,c=s>0?1-a/s:0;return c===0?o=NaN:(o=(t-r+(t-n))/2,o/=Dc((t-r)*(t-r)+(t-n)*(r-n)),o=Vc(o),n>r&&(o=we-o),o/=we),[o*360,c,s]};C.prototype.hsi=function(){return Yc(this._rgb)},O.hsi=(...e)=>new C(...e,"hsi"),L.format.hsi=Xc,L.autodetect.push({p:2,test:(...e)=>{if(e=P(e,"hsi"),S(e)==="array"&&e.length===3)return"hsi"}}),C.prototype.hsl=function(){return uo(this._rgb)},O.hsl=(...e)=>new C(...e,"hsl"),L.format.hsl=tr,L.autodetect.push({p:2,test:(...e)=>{if(e=P(e,"hsl"),S(e)==="array"&&e.length===3)return"hsl"}});const{floor:Zc}=Math,Jc=(...e)=>{e=P(e,"hsv");let[t,r,n]=e,o,a,s;if(n*=255,r===0)o=a=s=n;else{t===360&&(t=0),t>360&&(t-=360),t<0&&(t+=360),t/=60;const c=Zc(t),i=t-c,u=n*(1-r),f=n*(1-r*i),l=n*(1-r*(1-i));switch(c){case 0:[o,a,s]=[n,l,u];break;case 1:[o,a,s]=[f,n,u];break;case 2:[o,a,s]=[u,n,l];break;case 3:[o,a,s]=[u,f,n];break;case 4:[o,a,s]=[l,u,n];break;case 5:[o,a,s]=[n,u,f];break}}return[o,a,s,e.length>3?e[3]:1]},{min:Wc,max:Uc}=Math,Qc=(...e)=>{e=P(e,"rgb");let[t,r,n]=e;const o=Wc(t,r,n),a=Uc(t,r,n),s=a-o;let c,i,u;return u=a/255,a===0?(c=Number.NaN,i=0):(i=s/a,t===a&&(c=(r-n)/s),r===a&&(c=2+(n-t)/s),n===a&&(c=4+(t-r)/s),c*=60,c<0&&(c+=360)),[c,i,u]};C.prototype.hsv=function(){return Qc(this._rgb)},O.hsv=(...e)=>new C(...e,"hsv"),L.format.hsv=Jc,L.autodetect.push({p:2,test:(...e)=>{if(e=P(e,"hsv"),S(e)==="array"&&e.length===3)return"hsv"}});const se={Kn:18,Xn:.95047,Yn:1,Zn:1.08883,t0:.137931034,t1:.206896552,t2:.12841855,t3:.008856452},{pow:e0}=Math,yo=(...e)=>{e=P(e,"lab");const[t,r,n]=e;let o,a,s,c,i,u;return a=(t+16)/116,o=isNaN(r)?a:a+r/500,s=isNaN(n)?a:a-n/200,a=se.Yn*or(a),o=se.Xn*or(o),s=se.Zn*or(s),c=nr(3.2404542*o-1.5371385*a-.4985314*s),i=nr(-.969266*o+1.8760108*a+.041556*s),u=nr(.0556434*o-.2040259*a+1.0572252*s),[c,i,u,e.length>3?e[3]:1]},nr=e=>255*(e<=.00304?12.92*e:1.055*e0(e,1/2.4)-.055),or=e=>e>se.t1?e*e*e:se.t2*(e-se.t0),{pow:wo}=Math,ko=(...e)=>{const[t,r,n]=P(e,"rgb"),[o,a,s]=t0(t,r,n),c=116*a-16;return[c<0?0:c,500*(o-a),200*(a-s)]},sr=e=>(e/=255)<=.04045?e/12.92:wo((e+.055)/1.055,2.4),ar=e=>e>se.t3?wo(e,1/3):e/se.t2+se.t0,t0=(e,t,r)=>{e=sr(e),t=sr(t),r=sr(r);const n=ar((.4124564*e+.3575761*t+.1804375*r)/se.Xn),o=ar((.2126729*e+.7151522*t+.072175*r)/se.Yn),a=ar((.0193339*e+.119192*t+.9503041*r)/se.Zn);return[n,o,a]};C.prototype.lab=function(){return ko(this._rgb)},O.lab=(...e)=>new C(...e,"lab"),L.format.lab=yo,L.autodetect.push({p:2,test:(...e)=>{if(e=P(e,"lab"),S(e)==="array"&&e.length===3)return"lab"}});const{sin:r0,cos:n0}=Math,$o=(...e)=>{let[t,r,n]=P(e,"lch");return isNaN(n)&&(n=0),n=n*Ac,[t,n0(n)*r,r0(n)*r]},Co=(...e)=>{e=P(e,"lch");const[t,r,n]=e,[o,a,s]=$o(t,r,n),[c,i,u]=yo(o,a,s);return[c,i,u,e.length>3?e[3]:1]},o0=(...e)=>{const t=P(e,"hcl").reverse();return Co(...t)},{sqrt:s0,atan2:a0,round:c0}=Math,xo=(...e)=>{const[t,r,n]=P(e,"lab"),o=s0(r*r+n*n);let a=(a0(n,r)*Lc+360)%360;return c0(o*1e4)===0&&(a=Number.NaN),[t,o,a]},Ro=(...e)=>{const[t,r,n]=P(e,"rgb"),[o,a,s]=ko(t,r,n);return xo(o,a,s)};C.prototype.lch=function(){return Ro(this._rgb)},C.prototype.hcl=function(){return Ro(this._rgb).reverse()},O.lch=(...e)=>new C(...e,"lch"),O.hcl=(...e)=>new C(...e,"hcl"),L.format.lch=Co,L.format.hcl=o0,["lch","hcl"].forEach(e=>L.autodetect.push({p:2,test:(...t)=>{if(t=P(t,e),S(t)==="array"&&t.length===3)return e}}));const De={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",laserlemon:"#ffff54",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrod:"#fafad2",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",maroon2:"#7f0000",maroon3:"#b03060",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",purple2:"#7f007f",purple3:"#a020f0",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};C.prototype.name=function(){const e=_o(this._rgb,"rgb");for(let t of Object.keys(De))if(De[t]===e)return t.toLowerCase();return e},L.format.named=e=>{if(e=e.toLowerCase(),De[e])return vo(De[e]);throw new Error("unknown color name: "+e)},L.autodetect.push({p:5,test:(e,...t)=>{if(!t.length&&S(e)==="string"&&De[e.toLowerCase()])return"named"}});const i0=e=>{if(S(e)=="number"&&e>=0&&e<=16777215){const t=e>>16,r=e>>8&255,n=e&255;return[t,r,n,1]}throw new Error("unknown num color: "+e)},u0=(...e)=>{const[t,r,n]=P(e,"rgb");return(t<<16)+(r<<8)+n};C.prototype.num=function(){return u0(this._rgb)},O.num=(...e)=>new C(...e,"num"),L.format.num=i0,L.autodetect.push({p:5,test:(...e)=>{if(e.length===1&&S(e[0])==="number"&&e[0]>=0&&e[0]<=16777215)return"num"}});const{round:Ho}=Math;C.prototype.rgb=function(e=!0){return e===!1?this._rgb.slice(0,3):this._rgb.slice(0,3).map(Ho)},C.prototype.rgba=function(e=!0){return this._rgb.slice(0,4).map((t,r)=>r<3?e===!1?t:Ho(t):t)},O.rgb=(...e)=>new C(...e,"rgb"),L.format.rgb=(...e)=>{const t=P(e,"rgba");return t[3]===void 0&&(t[3]=1),t},L.autodetect.push({p:3,test:(...e)=>{if(e=P(e,"rgba"),S(e)==="array"&&(e.length===3||e.length===4&&S(e[3])=="number"&&e[3]>=0&&e[3]<=1))return"rgb"}});const{log:vt}=Math,qo=e=>{const t=e/100;let r,n,o;return t<66?(r=255,n=t<6?0:-155.25485562709179-.44596950469579133*(n=t-2)+104.49216199393888*vt(n),o=t<20?0:-254.76935184120902+.8274096064007395*(o=t-10)+115.67994401066147*vt(o)):(r=351.97690566805693+.114206453784165*(r=t-55)-40.25366309332127*vt(r),n=325.4494125711974+.07943456536662342*(n=t-50)-28.0852963507957*vt(n),o=255),[r,n,o,1]},{round:f0}=Math,l0=(...e)=>{const t=P(e,"rgb"),r=t[0],n=t[2];let o=1e3,a=4e4;const s=.4;let c;for(;a-o>s;){c=(a+o)*.5;const i=qo(c);i[2]/i[0]>=n/r?a=c:o=c}return f0(c)};C.prototype.temp=C.prototype.kelvin=C.prototype.temperature=function(){return l0(this._rgb)},O.temp=O.kelvin=O.temperature=(...e)=>new C(...e,"temp"),L.format.temp=L.format.kelvin=L.format.temperature=qo;const{pow:_t,sign:h0}=Math,Mo=(...e)=>{e=P(e,"lab");const[t,r,n]=e,o=_t(t+.3963377774*r+.2158037573*n,3),a=_t(t-.1055613458*r-.0638541728*n,3),s=_t(t-.0894841775*r-1.291485548*n,3);return[255*cr(4.0767416621*o-3.3077115913*a+.2309699292*s),255*cr(-1.2684380046*o+2.6097574011*a-.3413193965*s),255*cr(-.0041960863*o-.7034186147*a+1.707614701*s),e.length>3?e[3]:1]};function cr(e){const t=Math.abs(e);return t>.0031308?(h0(e)||1)*(1.055*_t(t,.4166666666666667)-.055):e*12.92}const{cbrt:ir,pow:d0,sign:b0}=Math,Oo=(...e)=>{const[t,r,n]=P(e,"rgb"),[o,a,s]=[ur(t/255),ur(r/255),ur(n/255)],c=ir(.4122214708*o+.5363325363*a+.0514459929*s),i=ir(.2119034982*o+.6806995451*a+.1073969566*s),u=ir(.0883024619*o+.2817188376*a+.6299787005*s);return[.2104542553*c+.793617785*i-.0040720468*u,1.9779984951*c-2.428592205*i+.4505937099*u,.0259040371*c+.7827717662*i-.808675766*u]};function ur(e){const t=Math.abs(e);return t<.04045?e/12.92:(b0(e)||1)*d0((t+.055)/1.055,2.4)}C.prototype.oklab=function(){return Oo(this._rgb)},O.oklab=(...e)=>new C(...e,"oklab"),L.format.oklab=Mo,L.autodetect.push({p:3,test:(...e)=>{if(e=P(e,"oklab"),S(e)==="array"&&e.length===3)return"oklab"}});const p0=(...e)=>{e=P(e,"lch");const[t,r,n]=e,[o,a,s]=$o(t,r,n),[c,i,u]=Mo(o,a,s);return[c,i,u,e.length>3?e[3]:1]},m0=(...e)=>{const[t,r,n]=P(e,"rgb"),[o,a,s]=Oo(t,r,n);return xo(o,a,s)};C.prototype.oklch=function(){return m0(this._rgb)},O.oklch=(...e)=>new C(...e,"oklch"),L.format.oklch=p0,L.autodetect.push({p:3,test:(...e)=>{if(e=P(e,"oklch"),S(e)==="array"&&e.length===3)return"oklch"}}),C.prototype.alpha=function(e,t=!1){return e!==void 0&&S(e)==="number"?t?(this._rgb[3]=e,this):new C([this._rgb[0],this._rgb[1],this._rgb[2],e],"rgb"):this._rgb[3]},C.prototype.clipped=function(){return this._rgb._clipped||!1},C.prototype.darken=function(e=1){const t=this,r=t.lab();return r[0]-=se.Kn*e,new C(r,"lab").alpha(t.alpha(),!0)},C.prototype.brighten=function(e=1){return this.darken(-e)},C.prototype.darker=C.prototype.darken,C.prototype.brighter=C.prototype.brighten,C.prototype.get=function(e){const[t,r]=e.split("."),n=this[t]();if(r){const o=t.indexOf(r)-(t.substr(0,2)==="ok"?2:0);if(o>-1)return n[o];throw new Error(`unknown channel ${r} in mode ${t}`)}else return n};const{pow:g0}=Math,v0=1e-7,_0=20;C.prototype.luminance=function(e,t="rgb"){if(e!==void 0&&S(e)==="number"){if(e===0)return new C([0,0,0,this._rgb[3]],"rgb");if(e===1)return new C([255,255,255,this._rgb[3]],"rgb");let r=this.luminance(),n=_0;const o=(s,c)=>{const i=s.interpolate(c,.5,t),u=i.luminance();return Math.abs(e-u)e?o(s,i):o(i,c)},a=(r>e?o(new C([0,0,0]),this):o(this,new C([255,255,255]))).rgb();return new C([...a,this._rgb[3]])}return y0(...this._rgb.slice(0,3))};const y0=(e,t,r)=>(e=fr(e),t=fr(t),r=fr(r),.2126*e+.7152*t+.0722*r),fr=e=>(e/=255,e<=.03928?e/12.92:g0((e+.055)/1.055,2.4)),re={},ct=(e,t,r=.5,...n)=>{let o=n[0]||"lrgb";if(!re[o]&&!n.length&&(o=Object.keys(re)[0]),!re[o])throw new Error(`interpolation mode ${o} is not defined`);return S(e)!=="object"&&(e=new C(e)),S(t)!=="object"&&(t=new C(t)),re[o](e,t,r).alpha(e.alpha()+r*(t.alpha()-e.alpha()))};C.prototype.mix=C.prototype.interpolate=function(e,t=.5,...r){return ct(this,e,t,...r)},C.prototype.premultiply=function(e=!1){const t=this._rgb,r=t[3];return e?(this._rgb=[t[0]*r,t[1]*r,t[2]*r,r],this):new C([t[0]*r,t[1]*r,t[2]*r,r],"rgb")},C.prototype.saturate=function(e=1){const t=this,r=t.lch();return r[1]+=se.Kn*e,r[1]<0&&(r[1]=0),new C(r,"lch").alpha(t.alpha(),!0)},C.prototype.desaturate=function(e=1){return this.saturate(-e)},C.prototype.set=function(e,t,r=!1){const[n,o]=e.split("."),a=this[n]();if(o){const s=n.indexOf(o)-(n.substr(0,2)==="ok"?2:0);if(s>-1){if(S(t)=="string")switch(t.charAt(0)){case"+":a[s]+=+t;break;case"-":a[s]+=+t;break;case"*":a[s]*=+t.substr(1);break;case"/":a[s]/=+t.substr(1);break;default:a[s]=+t}else if(S(t)==="number")a[s]=t;else throw new Error("unsupported value for Color.set");const c=new C(a,n);return r?(this._rgb=c._rgb,this):c}throw new Error(`unknown channel ${o} in mode ${n}`)}else return a},C.prototype.tint=function(e=.5,...t){return ct(this,"white",e,...t)},C.prototype.shade=function(e=.5,...t){return ct(this,"black",e,...t)};const w0=(e,t,r)=>{const n=e._rgb,o=t._rgb;return new C(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"rgb")};re.rgb=w0;const{sqrt:lr,pow:Ve}=Math,k0=(e,t,r)=>{const[n,o,a]=e._rgb,[s,c,i]=t._rgb;return new C(lr(Ve(n,2)*(1-r)+Ve(s,2)*r),lr(Ve(o,2)*(1-r)+Ve(c,2)*r),lr(Ve(a,2)*(1-r)+Ve(i,2)*r),"rgb")};re.lrgb=k0;const $0=(e,t,r)=>{const n=e.lab(),o=t.lab();return new C(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"lab")};re.lab=$0;const Ye=(e,t,r,n)=>{let o,a;n==="hsl"?(o=e.hsl(),a=t.hsl()):n==="hsv"?(o=e.hsv(),a=t.hsv()):n==="hcg"?(o=e.hcg(),a=t.hcg()):n==="hsi"?(o=e.hsi(),a=t.hsi()):n==="lch"||n==="hcl"?(n="hcl",o=e.hcl(),a=t.hcl()):n==="oklch"&&(o=e.oklch().reverse(),a=t.oklch().reverse());let s,c,i,u,f,l;(n.substr(0,1)==="h"||n==="oklch")&&([s,i,f]=o,[c,u,l]=a);let h,d,p,v;return!isNaN(s)&&!isNaN(c)?(c>s&&c-s>180?v=c-(s+360):c180?v=c+360-s:v=c-s,d=s+r*v):isNaN(s)?isNaN(c)?d=Number.NaN:(d=c,(f==1||f==0)&&n!="hsv"&&(h=u)):(d=s,(l==1||l==0)&&n!="hsv"&&(h=i)),h===void 0&&(h=i+r*(u-i)),p=f+r*(l-f),n==="oklch"?new C([p,h,d],n):new C([d,h,p],n)},No=(e,t,r)=>Ye(e,t,r,"lch");re.lch=No,re.hcl=No;const C0=(e,t,r)=>{const n=e.num(),o=t.num();return new C(n+r*(o-n),"num")};re.num=C0;const x0=(e,t,r)=>Ye(e,t,r,"hcg");re.hcg=x0;const R0=(e,t,r)=>Ye(e,t,r,"hsi");re.hsi=R0;const H0=(e,t,r)=>Ye(e,t,r,"hsl");re.hsl=H0;const q0=(e,t,r)=>Ye(e,t,r,"hsv");re.hsv=q0;const M0=(e,t,r)=>{const n=e.oklab(),o=t.oklab();return new C(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"oklab")};re.oklab=M0;const O0=(e,t,r)=>Ye(e,t,r,"oklch");re.oklch=O0;const{pow:hr,sqrt:dr,PI:br,cos:Ao,sin:Lo,atan2:N0}=Math,A0=(e,t="lrgb",r=null)=>{const n=e.length;r||(r=Array.from(new Array(n)).map(()=>1));const o=n/r.reduce(function(l,h){return l+h});if(r.forEach((l,h)=>{r[h]*=o}),e=e.map(l=>new C(l)),t==="lrgb")return L0(e,r);const a=e.shift(),s=a.get(t),c=[];let i=0,u=0;for(let l=0;l{const d=l.get(t);f+=l.alpha()*r[h+1];for(let p=0;p=360;)h-=360;s[l]=h}else s[l]=s[l]/c[l];return f/=n,new C(s,t).alpha(f>.99999?1:f,!0)},L0=(e,t)=>{const r=e.length,n=[0,0,0,0];for(let o=0;o.9999999&&(n[3]=1),new C(Yt(n))},{pow:E0}=Math;function yt(e){let t="rgb",r=O("#ccc"),n=0,o=[0,1],a=[],s=[0,0],c=!1,i=[],u=!1,f=0,l=1,h=!1,d={},p=!0,v=1;const m=function(b){if(b=b||["#fff","#000"],b&&S(b)==="string"&&O.brewer&&O.brewer[b.toLowerCase()]&&(b=O.brewer[b.toLowerCase()]),S(b)==="array"){b.length===1&&(b=[b[0],b[0]]),b=b.slice(0);for(let _=0;_=c[k];)k++;return k-1}return 0};let R=b=>b,x=b=>b;const M=function(b,_){let k,y;if(_==null&&(_=!1),isNaN(b)||b===null)return r;_?y=b:c&&c.length>2?y=g(b)/(c.length-2):l!==f?y=(b-f)/(l-f):y=1,y=x(y),_||(y=R(y)),v!==1&&(y=E0(y,v)),y=s[0]+y*(1-s[0]-s[1]),y=Xe(y,0,1);const q=Math.floor(y*1e4);if(p&&d[q])k=d[q];else{if(S(i)==="array")for(let H=0;H=A&&H===a.length-1){k=i[H];break}if(y>A&&yd={};m(e);const w=function(b){const _=O(M(b));return u&&_[u]?_[u]():_};return w.classes=function(b){if(b!=null){if(S(b)==="array")c=b,o=[b[0],b[b.length-1]];else{const _=O.analyze(o);b===0?c=[_.min,_.max]:c=O.limits(_,"e",b)}return w}return c},w.domain=function(b){if(!arguments.length)return o;f=b[0],l=b[b.length-1],a=[];const _=i.length;if(b.length===_&&f!==l)for(let k of Array.from(b))a.push((k-f)/(l-f));else{for(let k=0;k<_;k++)a.push(k/(_-1));if(b.length>2){const k=b.map((q,H)=>H/(b.length-1)),y=b.map(q=>(q-f)/(l-f));y.every((q,H)=>k[H]===q)||(x=q=>{if(q<=0||q>=1)return q;let H=0;for(;q>=y[H+1];)H++;const A=(q-y[H])/(y[H+1]-y[H]);return k[H]+A*(k[H+1]-k[H])})}}return o=[f,l],w},w.mode=function(b){return arguments.length?(t=b,N(),w):t},w.range=function(b,_){return m(b),w},w.out=function(b){return u=b,w},w.spread=function(b){return arguments.length?(n=b,w):n},w.correctLightness=function(b){return b==null&&(b=!0),h=b,N(),h?R=function(_){const k=M(0,!0).lab()[0],y=M(1,!0).lab()[0],q=k>y;let H=M(_,!0).lab()[0];const A=k+(y-k)*_;let I=H-A,K=0,D=1,U=20;for(;Math.abs(I)>.01&&U-- >0;)(function(){return q&&(I*=-1),I<0?(K=_,_+=(D-_)*.5):(D=_,_+=(K-_)*.5),H=M(_,!0).lab()[0],I=H-A})();return _}:R=_=>_,w},w.padding=function(b){return b!=null?(S(b)==="number"&&(b=[b,b]),s=b,w):s},w.colors=function(b,_){arguments.length<2&&(_="hex");let k=[];if(arguments.length===0)k=i.slice(0);else if(b===1)k=[w(.5)];else if(b>1){const y=o[0],q=o[1]-y;k=T0(0,b).map(H=>w(y+H/(b-1)*q))}else{e=[];let y=[];if(c&&c.length>2)for(let q=1,H=c.length,A=1<=H;A?qH;A?q++:q--)y.push((c[q-1]+c[q])*.5);else y=o;k=y.map(q=>w(q))}return O[_]&&(k=k.map(y=>y[_]())),k},w.cache=function(b){return b!=null?(p=b,w):p},w.gamma=function(b){return b!=null?(v=b,w):v},w.nodata=function(b){return b!=null?(r=O(b),w):r},w}function T0(e,t,r){let n=[],o=ea;o?s++:s--)n.push(s);return n}const S0=function(e){let t=[1,1];for(let r=1;rnew C(a)),e.length===2)[r,n]=e.map(a=>a.lab()),t=function(a){const s=[0,1,2].map(c=>r[c]+a*(n[c]-r[c]));return new C(s,"lab")};else if(e.length===3)[r,n,o]=e.map(a=>a.lab()),t=function(a){const s=[0,1,2].map(c=>(1-a)*(1-a)*r[c]+2*(1-a)*a*n[c]+a*a*o[c]);return new C(s,"lab")};else if(e.length===4){let a;[r,n,o,a]=e.map(s=>s.lab()),t=function(s){const c=[0,1,2].map(i=>(1-s)*(1-s)*(1-s)*r[i]+3*(1-s)*(1-s)*s*n[i]+3*(1-s)*s*s*o[i]+s*s*s*a[i]);return new C(c,"lab")}}else if(e.length>=5){let a,s,c;a=e.map(i=>i.lab()),c=e.length-1,s=S0(c),t=function(i){const u=1-i,f=[0,1,2].map(l=>a.reduce((h,d,p)=>h+s[p]*u**(c-p)*i**p*d[l],0));return new C(f,"lab")}}else throw new RangeError("No point in running bezier with only one color.");return t},j0=e=>{const t=P0(e);return t.scale=()=>yt(t),t},he=(e,t,r)=>{if(!he[r])throw new Error("unknown blend mode "+r);return he[r](e,t)},Ne=e=>(t,r)=>{const n=O(r).rgb(),o=O(t).rgb();return O.rgb(e(n,o))},Ae=e=>(t,r)=>{const n=[];return n[0]=e(t[0],r[0]),n[1]=e(t[1],r[1]),n[2]=e(t[2],r[2]),n},B0=e=>e,G0=(e,t)=>e*t/255,I0=(e,t)=>e>t?t:e,z0=(e,t)=>e>t?e:t,F0=(e,t)=>255*(1-(1-e/255)*(1-t/255)),X0=(e,t)=>t<128?2*e*t/255:255*(1-2*(1-e/255)*(1-t/255)),K0=(e,t)=>255*(1-(1-t/255)/(e/255)),D0=(e,t)=>e===255?255:(e=255*(t/255)/(1-e/255),e>255?255:e);he.normal=Ne(Ae(B0)),he.multiply=Ne(Ae(G0)),he.screen=Ne(Ae(F0)),he.overlay=Ne(Ae(X0)),he.darken=Ne(Ae(I0)),he.lighten=Ne(Ae(z0)),he.dodge=Ne(Ae(D0)),he.burn=Ne(Ae(K0));const{pow:V0,sin:Y0,cos:Z0}=Math;function J0(e=300,t=-1.5,r=1,n=1,o=[0,1]){let a=0,s;S(o)==="array"?s=o[1]-o[0]:(s=0,o=[o,o]);const c=function(i){const u=we*((e+120)/360+t*i),f=V0(o[0]+s*i,n),h=(a!==0?r[0]+i*a:r)*f*(1-f)/2,d=Z0(u),p=Y0(u),v=f+h*(-.14861*d+1.78277*p),m=f+h*(-.29227*d-.90649*p),g=f+h*(1.97294*d);return O(Yt([v*255,m*255,g*255,1]))};return c.start=function(i){return i==null?e:(e=i,c)},c.rotations=function(i){return i==null?t:(t=i,c)},c.gamma=function(i){return i==null?n:(n=i,c)},c.hue=function(i){return i==null?r:(r=i,S(r)==="array"?(a=r[1]-r[0],a===0&&(r=r[1])):a=0,c)},c.lightness=function(i){return i==null?o:(S(i)==="array"?(o=i,s=i[1]-i[0]):(o=[i,i],s=0),c)},c.scale=()=>O.scale(c),c.hue(r),c}const W0="0123456789abcdef",{floor:U0,random:Q0}=Math,ei=()=>{let e="#";for(let t=0;t<6;t++)e+=W0.charAt(U0(Q0()*16));return new C(e,"hex")},{log:Eo,pow:ti,floor:ri,abs:ni}=Math;function To(e,t=null){const r={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0};return S(e)==="object"&&(e=Object.values(e)),e.forEach(n=>{t&&S(n)==="object"&&(n=n[t]),n!=null&&!isNaN(n)&&(r.values.push(n),r.sum+=n,nr.max&&(r.max=n),r.count+=1)}),r.domain=[r.min,r.max],r.limits=(n,o)=>So(r,n,o),r}function So(e,t="equal",r=7){S(e)=="array"&&(e=To(e));const{min:n,max:o}=e,a=e.values.sort((c,i)=>c-i);if(r===1)return[n,o];const s=[];if(t.substr(0,1)==="c"&&(s.push(n),s.push(o)),t.substr(0,1)==="e"){s.push(n);for(let c=1;c 0");const c=Math.LOG10E*Eo(n),i=Math.LOG10E*Eo(o);s.push(n);for(let u=1;u200&&(l=!1)}const p={};for(let m=0;mm-g),s.push(v[0]);for(let m=1;m{e=new C(e),t=new C(t);const r=e.luminance(),n=t.luminance();return r>n?(r+.05)/(n+.05):(n+.05)/(r+.05)},{sqrt:ke,pow:V,min:si,max:ai,atan2:Po,abs:jo,cos:wt,sin:Bo,exp:ci,PI:Go}=Math;function ii(e,t,r=1,n=1,o=1){var a=function(le){return 360*le/(2*Go)},s=function(le){return 2*Go*le/360};e=new C(e),t=new C(t);const[c,i,u]=Array.from(e.lab()),[f,l,h]=Array.from(t.lab()),d=(c+f)/2,p=ke(V(i,2)+V(u,2)),v=ke(V(l,2)+V(h,2)),m=(p+v)/2,g=.5*(1-ke(V(m,7)/(V(m,7)+V(25,7)))),R=i*(1+g),x=l*(1+g),M=ke(V(R,2)+V(u,2)),N=ke(V(x,2)+V(h,2)),w=(M+N)/2,b=a(Po(u,R)),_=a(Po(h,x)),k=b>=0?b:b+360,y=_>=0?_:_+360,q=jo(k-y)>180?(k+y+360)/2:(k+y)/2,H=1-.17*wt(s(q-30))+.24*wt(s(2*q))+.32*wt(s(3*q+6))-.2*wt(s(4*q-63));let A=y-k;A=jo(A)<=180?A:y<=k?A+360:A-360,A=2*ke(M*N)*Bo(s(A)/2);const I=f-c,K=N-M,D=1+.015*V(d-50,2)/ke(20+V(d-50,2)),U=1+.045*w,ge=1+.015*w*H,ye=30*ci(-V((q-275)/25,2)),fe=-(2*ke(V(w,7)/(V(w,7)+V(25,7))))*Bo(2*s(ye)),qe=ke(V(I/(r*D),2)+V(K/(n*U),2)+V(A/(o*ge),2)+fe*(K/(n*U))*(A/(o*ge)));return ai(0,si(100,qe))}function ui(e,t,r="lab"){e=new C(e),t=new C(t);const n=e.get(r),o=t.get(r);let a=0;for(let s in n){const c=(n[s]||0)-(o[s]||0);a+=c*c}return Math.sqrt(a)}const fi=(...e)=>{try{return new C(...e),!0}catch{return!1}},li={cool(){return yt([O.hsl(180,1,.9),O.hsl(250,.7,.4)])},hot(){return yt(["#000","#f00","#ff0","#fff"]).mode("rgb")}},kt={OrRd:["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"],PuBu:["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"],BuPu:["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"],Oranges:["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"],BuGn:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"],YlOrBr:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"],YlGn:["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],Reds:["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"],RdPu:["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"],Greens:["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"],YlGnBu:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],Purples:["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"],GnBu:["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],Greys:["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"],YlOrRd:["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"],PuRd:["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"],Blues:["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"],PuBuGn:["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"],Viridis:["#440154","#482777","#3f4a8a","#31678e","#26838f","#1f9d8a","#6cce5a","#b6de2b","#fee825"],Spectral:["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],RdYlGn:["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],RdBu:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],PiYG:["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],PRGn:["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],RdYlBu:["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],BrBG:["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],RdGy:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],PuOr:["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],Set2:["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],Accent:["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],Set1:["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],Set3:["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],Dark2:["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],Paired:["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],Pastel2:["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],Pastel1:["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]};for(let e of Object.keys(kt))kt[e.toLowerCase()]=kt[e];Object.assign(O,{average:A0,bezier:j0,blend:he,cubehelix:J0,mix:ct,interpolate:ct,random:ei,scale:yt,analyze:To,contrast:oi,deltaE:ii,distance:ui,limits:So,valid:fi,scales:li,input:L,colors:De,brewer:kt});function pr(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var mr,Io;function hi(){if(Io)return mr;Io=1;var e=e||{};e.Geometry=function(){},e.Geometry.intersectLineLine=function(r,n){var o=(r.intercept-n.intercept)/(n.slope-r.slope),a=r.slope*o+r.intercept;return{x:o,y:a}},e.Geometry.distanceFromOrigin=function(r){return Math.sqrt(Math.pow(r.x,2)+Math.pow(r.y,2))},e.Geometry.distanceLineFromOrigin=function(r){return Math.abs(r.intercept)/Math.sqrt(Math.pow(r.slope,2)+1)},e.Geometry.perpendicularThroughPoint=function(r,n){var o=-1/r.slope,a=n.y-o*n.x;return{slope:o,intercept:a}},e.Geometry.angleFromOrigin=function(r){return Math.atan2(r.y,r.x)},e.Geometry.normalizeAngle=function(r){var n=2*Math.PI;return(r%n+n)%n},e.Geometry.lengthOfRayUntilIntersect=function(r,n){return n.intercept/(Math.sin(r)-n.slope*Math.cos(r))},e.Hsluv=function(){},e.Hsluv.getBounds=function(r){for(var n=[],o=Math.pow(r+16,3)/1560896,a=o>e.Hsluv.epsilon?o:r/e.Hsluv.kappa,s=0;s<3;)for(var c=s++,i=e.Hsluv.m[c][0],u=e.Hsluv.m[c][1],f=e.Hsluv.m[c][2],l=0;l<2;){var h=l++,d=(284517*i-94839*f)*a,p=(838422*f+769860*u+731718*i)*r*a-769860*h*r,v=(632260*f-126452*u)*a+126452*h;n.push({slope:d/v,intercept:p/v})}return n},e.Hsluv.maxSafeChromaForL=function(r){for(var n=e.Hsluv.getBounds(r),o=1/0,a=0;a=0&&(s=Math.min(s,u))}return s},e.Hsluv.dotProduct=function(r,n){for(var o=0,a=0,s=r.length;a.04045?Math.pow((r+.055)/1.055,2.4):r/12.92},e.Hsluv.xyzToRgb=function(r){return[e.Hsluv.fromLinear(e.Hsluv.dotProduct(e.Hsluv.m[0],r)),e.Hsluv.fromLinear(e.Hsluv.dotProduct(e.Hsluv.m[1],r)),e.Hsluv.fromLinear(e.Hsluv.dotProduct(e.Hsluv.m[2],r))]},e.Hsluv.rgbToXyz=function(r){var n=[e.Hsluv.toLinear(r[0]),e.Hsluv.toLinear(r[1]),e.Hsluv.toLinear(r[2])];return[e.Hsluv.dotProduct(e.Hsluv.minv[0],n),e.Hsluv.dotProduct(e.Hsluv.minv[1],n),e.Hsluv.dotProduct(e.Hsluv.minv[2],n)]},e.Hsluv.yToL=function(r){return r<=e.Hsluv.epsilon?r/e.Hsluv.refY*e.Hsluv.kappa:116*Math.pow(r/e.Hsluv.refY,.3333333333333333)-16},e.Hsluv.lToY=function(r){return r<=8?e.Hsluv.refY*r/e.Hsluv.kappa:e.Hsluv.refY*Math.pow((r+16)/116,3)},e.Hsluv.xyzToLuv=function(r){var n=r[0],o=r[1],a=r[2],s=n+15*o+3*a,c=4*n,i=9*o;s!=0?(c/=s,i/=s):(c=NaN,i=NaN);var u=e.Hsluv.yToL(o);if(u==0)return[0,0,0];var f=13*u*(c-e.Hsluv.refU),l=13*u*(i-e.Hsluv.refV);return[u,f,l]},e.Hsluv.luvToXyz=function(r){var n=r[0],o=r[1],a=r[2];if(n==0)return[0,0,0];var s=o/(13*n)+e.Hsluv.refU,c=a/(13*n)+e.Hsluv.refV,i=e.Hsluv.lToY(n),u=0-9*i*s/((s-4)*c-s*c),f=(9*i-15*c*i-c*u)/(3*c);return[u,i,f]},e.Hsluv.luvToLch=function(r){var n=r[0],o=r[1],a=r[2],s=Math.sqrt(o*o+a*a),c;if(s<1e-8)c=0;else{var i=Math.atan2(a,o);c=i*180/Math.PI,c<0&&(c=360+c)}return[n,s,c]},e.Hsluv.lchToLuv=function(r){var n=r[0],o=r[1],a=r[2],s=a/360*2*Math.PI,c=Math.cos(s)*o,i=Math.sin(s)*o;return[n,c,i]},e.Hsluv.hsluvToLch=function(r){var n=r[0],o=r[1],a=r[2];if(a>99.9999999)return[100,0,n];if(a<1e-8)return[0,0,n];var s=e.Hsluv.maxChromaForLH(a,n),c=s/100*o;return[a,c,n]},e.Hsluv.lchToHsluv=function(r){var n=r[0],o=r[1],a=r[2];if(n>99.9999999)return[a,0,100];if(n<1e-8)return[a,0,0];var s=e.Hsluv.maxChromaForLH(n,a),c=o/s*100;return[a,c,n]},e.Hsluv.hpluvToLch=function(r){var n=r[0],o=r[1],a=r[2];if(a>99.9999999)return[100,0,n];if(a<1e-8)return[0,0,n];var s=e.Hsluv.maxSafeChromaForL(a),c=s/100*o;return[a,c,n]},e.Hsluv.lchToHpluv=function(r){var n=r[0],o=r[1],a=r[2];if(n>99.9999999)return[a,0,100];if(n<1e-8)return[a,0,0];var s=e.Hsluv.maxSafeChromaForL(n),c=o/s*100;return[a,c,n]},e.Hsluv.rgbToHex=function(r){for(var n="#",o=0;o<3;){var a=o++,s=r[a],c=Math.round(s*255),i=c%16,u=(c-i)/16|0;n+=e.Hsluv.hexChars.charAt(u)+e.Hsluv.hexChars.charAt(i)}return n},e.Hsluv.hexToRgb=function(r){r=r.toLowerCase();for(var n=[],o=0;o<3;){var a=o++,s=e.Hsluv.hexChars.indexOf(r.charAt(a*2+1)),c=e.Hsluv.hexChars.indexOf(r.charAt(a*2+2)),i=s*16+c;n.push(i/255)}return n},e.Hsluv.lchToRgb=function(r){return e.Hsluv.xyzToRgb(e.Hsluv.luvToXyz(e.Hsluv.lchToLuv(r)))},e.Hsluv.rgbToLch=function(r){return e.Hsluv.luvToLch(e.Hsluv.xyzToLuv(e.Hsluv.rgbToXyz(r)))},e.Hsluv.hsluvToRgb=function(r){return e.Hsluv.lchToRgb(e.Hsluv.hsluvToLch(r))},e.Hsluv.rgbToHsluv=function(r){return e.Hsluv.lchToHsluv(e.Hsluv.rgbToLch(r))},e.Hsluv.hpluvToRgb=function(r){return e.Hsluv.lchToRgb(e.Hsluv.hpluvToLch(r))},e.Hsluv.rgbToHpluv=function(r){return e.Hsluv.lchToHpluv(e.Hsluv.rgbToLch(r))},e.Hsluv.hsluvToHex=function(r){return e.Hsluv.rgbToHex(e.Hsluv.hsluvToRgb(r))},e.Hsluv.hpluvToHex=function(r){return e.Hsluv.rgbToHex(e.Hsluv.hpluvToRgb(r))},e.Hsluv.hexToHsluv=function(r){return e.Hsluv.rgbToHsluv(e.Hsluv.hexToRgb(r))},e.Hsluv.hexToHpluv=function(r){return e.Hsluv.rgbToHpluv(e.Hsluv.hexToRgb(r))},e.Hsluv.m=[[3.240969941904521,-1.537383177570093,-.498610760293],[-.96924363628087,1.87596750150772,.041555057407175],[.055630079696993,-.20397695888897,1.056971514242878]],e.Hsluv.minv=[[.41239079926595,.35758433938387,.18048078840183],[.21263900587151,.71516867876775,.072192315360733],[.019330818715591,.11919477979462,.95053215224966]],e.Hsluv.refY=1,e.Hsluv.refU=.19783000664283,e.Hsluv.refV=.46831999493879,e.Hsluv.kappa=903.2962962,e.Hsluv.epsilon=.0088564516,e.Hsluv.hexChars="0123456789abcdef";var t={hsluvToRgb:e.Hsluv.hsluvToRgb,rgbToHsluv:e.Hsluv.rgbToHsluv,hpluvToRgb:e.Hsluv.hpluvToRgb,rgbToHpluv:e.Hsluv.rgbToHpluv,hsluvToHex:e.Hsluv.hsluvToHex,hexToHsluv:e.Hsluv.hexToHsluv,hpluvToHex:e.Hsluv.hpluvToHex,hexToHpluv:e.Hsluv.hexToHpluv,lchToHpluv:e.Hsluv.lchToHpluv,hpluvToLch:e.Hsluv.hpluvToLch,lchToHsluv:e.Hsluv.lchToHsluv,hsluvToLch:e.Hsluv.hsluvToLch,lchToLuv:e.Hsluv.lchToLuv,luvToLch:e.Hsluv.luvToLch,xyzToLuv:e.Hsluv.xyzToLuv,luvToXyz:e.Hsluv.luvToXyz,xyzToRgb:e.Hsluv.xyzToRgb,rgbToXyz:e.Hsluv.rgbToXyz,lchToRgb:e.Hsluv.lchToRgb,rgbToLch:e.Hsluv.rgbToLch};return mr=t,mr}var di=hi();const gr=pr(di);var $t={exports:{}},vr,zo;function it(){if(zo)return vr;zo=1;function e(t,r){return Object.prototype.hasOwnProperty.call(t,r)}return vr=e,vr}var _r,Fo;function yr(){if(Fo)return _r;Fo=1;var e=it(),t,r;function n(){r=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],t=!0;for(var s in{toString:null})t=!1}function o(s,c,i){var u,f=0;t==null&&n();for(u in s)if(a(c,s,u,i)===!1)break;if(t)for(var l=s.constructor,h=!!l&&s===l.prototype;(u=r[f++])&&!((u!=="constructor"||!h&&e(s,u))&&s[u]!==Object.prototype[u]&&a(c,s,u,i)===!1););}function a(s,c,i,u){return s.call(u,c[i],i,c)}return _r=o,_r}var wr,Xo;function Ko(){if(Xo)return wr;Xo=1;var e=yr();function t(r){var n=[];return e(r,function(o,a){typeof o=="function"&&n.push(a)}),n.sort()}return wr=t,wr}var kr,Do;function ut(){if(Do)return kr;Do=1;function e(t,r,n){var o=t.length;r==null?r=0:r<0?r=Math.max(o+r,0):r=Math.min(r,o),n==null?n=o:n<0?n=Math.max(o+n,0):n=Math.min(n,o);for(var a=[];r1?n(arguments,1):e(a);r(c,function(i){a[i]=t(a[i],a)})}return Rr=o,Rr}var Hr,Jo;function Q(){if(Jo)return Hr;Jo=1;var e=it(),t=yr();function r(n,o,a){t(n,function(s,c){if(e(n,c))return o.call(a,n[c],c,n)})}return Hr=r,Hr}var qr,Wo;function mi(){if(Wo)return qr;Wo=1;function e(t){return t}return qr=e,qr}var Mr,Uo;function Qo(){if(Uo)return Mr;Uo=1;function e(t){return function(r){return r[t]}}return Mr=e,Mr}var Or,es;function Nr(){if(es)return Or;es=1;var e=/^\[object (.*)\]$/,t=Object.prototype.toString,r;function n(o){return o===null?"Null":o===r?"Undefined":e.exec(t.call(o))[1]}return Or=n,Or}var Ar,ts;function Lr(){if(ts)return Ar;ts=1;var e=Nr();function t(r,n){return e(r)===n}return Ar=t,Ar}var Er,rs;function gi(){if(rs)return Er;rs=1;var e=Lr(),t=Array.isArray||function(r){return e(r,"Array")};return Er=t,Er}var Tr,ns;function os(){if(ns)return Tr;ns=1;var e=Q(),t=gi();function r(s,c){for(var i=-1,u=s.length;++is&&(s=i,a=c);return a}return rn=t,rn}var nn,Ns;function on(){if(Ns)return nn;Ns=1;var e=Q();function t(r){var n=[];return e(r,function(o,a){n.push(o)}),n}return nn=t,nn}var sn,As;function Mi(){if(As)return sn;As=1;var e=qi(),t=on();function r(n,o){return e(t(n),o)}return sn=r,sn}var an,Ls;function Es(){if(Ls)return an;Ls=1;var e=Q();function t(n,o){for(var a=0,s=arguments.length,c;++a2;if(!t(n)&&!c)throw new Error("reduce of empty object with no initial value");return e(n,function(i,u,f){c?a=o.call(s,a,i,u,f):(a=i,c=!0)}),a}return yn=r,yn}var wn,Js;function Ii(){if(Js)return wn;Js=1;var e=_s(),t=Le();function r(n,o,a){return o=t(o,a),e(n,function(s,c,i){return!o(s,c,i)},a)}return wn=r,wn}var kn,Ws;function zi(){if(Ws)return kn;Ws=1;var e=Lr();function t(r){return e(r,"Function")}return kn=t,kn}var $n,Us;function Fi(){if(Us)return $n;Us=1;var e=zi();function t(r,n){var o=r[n];if(o!==void 0)return e(o)?o.call(r):o}return $n=t,$n}var Cn,Qs;function Xi(){if(Qs)return Cn;Qs=1;var e=Is();function t(r,n,o){var a=/^(.+)\.(.+)$/.exec(n);a?e(r,a[1])[a[2]]=o:r[n]=o}return Cn=t,Cn}var xn,ea;function Ki(){if(ea)return xn;ea=1;var e=xs();function t(r,n){if(e(r,n)){for(var o=n.split("."),a=o.pop();n=o.shift();)r=r[n];return delete r[a]}else return!0}return xn=t,xn}var Rn,ta;function Hn(){return ta||(ta=1,Rn={bindAll:pi(),contains:vi(),deepFillIn:_i(),deepMatches:os(),deepMixIn:yi(),equals:ki(),every:hs(),fillIn:$i(),filter:_s(),find:Ci(),flatten:xi(),forIn:yr(),forOwn:Q(),functions:Ko(),get:$s(),has:xs(),hasOwn:it(),keys:Ri(),map:qs(),matches:Hi(),max:Mi(),merge:Ai(),min:Ei(),mixIn:Es(),namespace:Is(),omit:Pi(),pick:ji(),pluck:Bi(),reduce:Gi(),reject:Ii(),result:Fi(),set:Xi(),size:Ys(),some:jr(),unset:Ki(),values:on()}),Rn}var ra;function na(){return ra||(ra=1,(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r=Hn(),n={A:{x:.44758,y:.40745},C:{x:.31006,y:.31616},D50:{x:.34567,y:.35851},D65:{x:.31272,y:.32903},D55:{x:.33243,y:.34744},D75:{x:.29903,y:.31488}},o=(0,r.map)(n,function(a){var s=100*(a.x/a.y),c=100,i=100*(1-a.x-a.y)/a.y;return[s,c,i]});t.default=o,e.exports=t.default})($t,$t.exports)),$t.exports}var Ct={exports:{}},oa;function sa(){return oa||(oa=1,(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r=Math,n=r.pow,o=r.sign,a=r.abs,s={decode:function(l){return l<=.04045?l/12.92:n((l+.055)/1.055,2.4)},encode:function(l){return l<=.0031308?12.92*l:1.055*n(l,1/2.4)-.055}},c={encode:function(l){return l<.001953125?16*l:n(l,1/1.8)},decode:function(l){return l<16*.001953125?l/16:n(l,1.8)}};function i(f){return{decode:function(h){return o(h)*n(a(h),f)},encode:function(h){return o(h)*n(a(h),1/f)}}}var u={sRGB:{r:{x:.64,y:.33},g:{x:.3,y:.6},b:{x:.15,y:.06},gamma:s},"Adobe RGB":{r:{x:.64,y:.33},g:{x:.21,y:.71},b:{x:.15,y:.06},gamma:i(2.2)},"Wide Gamut RGB":{r:{x:.7347,y:.2653},g:{x:.1152,y:.8264},b:{x:.1566,y:.0177},gamma:i(563/256)},"ProPhoto RGB":{r:{x:.7347,y:.2653},g:{x:.1596,y:.8404},b:{x:.0366,y:1e-4},gamma:c}};t.default=u,e.exports=t.default})(Ct,Ct.exports)),Ct.exports}var $e={},aa;function ca(){if(aa)return $e;aa=1,Object.defineProperty($e,"__esModule",{value:!0});function e(s){return[[s[0][0],s[1][0],s[2][0]],[s[0][1],s[1][1],s[2][1]],[s[0][2],s[1][2],s[2][2]]]}function t(s){return s[0][0]*(s[2][2]*s[1][1]-s[2][1]*s[1][2])+s[1][0]*(s[2][1]*s[0][2]-s[2][2]*s[0][1])+s[2][0]*(s[1][2]*s[0][1]-s[1][1]*s[0][2])}function r(s){var c=1/t(s);return[[(s[2][2]*s[1][1]-s[2][1]*s[1][2])*c,(s[2][1]*s[0][2]-s[2][2]*s[0][1])*c,(s[1][2]*s[0][1]-s[1][1]*s[0][2])*c],[(s[2][0]*s[1][2]-s[2][2]*s[1][0])*c,(s[2][2]*s[0][0]-s[2][0]*s[0][2])*c,(s[1][0]*s[0][2]-s[1][2]*s[0][0])*c],[(s[2][1]*s[1][0]-s[2][0]*s[1][1])*c,(s[2][0]*s[0][1]-s[2][1]*s[0][0])*c,(s[1][1]*s[0][0]-s[1][0]*s[0][1])*c]]}function n(s,c){return[s[0][0]*c[0]+s[0][1]*c[1]+s[0][2]*c[2],s[1][0]*c[0]+s[1][1]*c[1]+s[1][2]*c[2],s[2][0]*c[0]+s[2][1]*c[1]+s[2][2]*c[2]]}function o(s,c){return[[s[0][0]*c[0],s[0][1]*c[1],s[0][2]*c[2]],[s[1][0]*c[0],s[1][1]*c[1],s[1][2]*c[2]],[s[2][0]*c[0],s[2][1]*c[1],s[2][2]*c[2]]]}function a(s,c){return[[s[0][0]*c[0][0]+s[0][1]*c[1][0]+s[0][2]*c[2][0],s[0][0]*c[0][1]+s[0][1]*c[1][1]+s[0][2]*c[2][1],s[0][0]*c[0][2]+s[0][1]*c[1][2]+s[0][2]*c[2][2]],[s[1][0]*c[0][0]+s[1][1]*c[1][0]+s[1][2]*c[2][0],s[1][0]*c[0][1]+s[1][1]*c[1][1]+s[1][2]*c[2][1],s[1][0]*c[0][2]+s[1][1]*c[1][2]+s[1][2]*c[2][2]],[s[2][0]*c[0][0]+s[2][1]*c[1][0]+s[2][2]*c[2][0],s[2][0]*c[0][1]+s[2][1]*c[1][1]+s[2][2]*c[2][1],s[2][0]*c[0][2]+s[2][1]*c[1][2]+s[2][2]*c[2][2]]]}return $e.transpose=e,$e.determinant=t,$e.inverse=r,$e.multiply=n,$e.scalar=o,$e.product=a,$e}var lt={},ia;function Di(){if(ia)return lt;ia=1,Object.defineProperty(lt,"__esModule",{value:!0});var e=Math,t=e.PI;function r(o){for(var a=o*180/t;a<0;)a+=360;for(;a>360;)a-=360;return a}function n(o){for(var a=t*o/180;a<0;)a+=2*t;for(;a>2*t;)a-=2*t;return a}return lt.fromRadian=r,lt.toRadian=n,lt}var ht={},ua;function Vi(){if(ua)return ht;ua=1,Object.defineProperty(ht,"__esModule",{value:!0});var e=Math,t=e.round;function r(o){return o[0]=="#"&&(o=o.slice(1)),o.length<6&&(o=o.split("").map(function(a){return a+a}).join("")),o.match(/../g).map(function(a){return parseInt(a,16)/255})}function n(o){var a=o.map(function(s){return s=t(255*s).toString(16),s.length<2&&(s="0"+s),s}).join("");return"#"+a}return ht.fromHex=r,ht.toHex=n,ht}var xt={exports:{}},fa;function Yi(){return fa||(fa=1,(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r=ca(),n=u(r),o=na(),a=i(o),s=sa(),c=i(s);function i(l){return l&&l.__esModule?l:{default:l}}function u(l){if(l&&l.__esModule)return l;var h={};if(l!=null)for(var d in l)Object.prototype.hasOwnProperty.call(l,d)&&(h[d]=l[d]);return h.default=l,h}function f(){var l=arguments.length<=0||arguments[0]===void 0?c.default.sRGB:arguments[0],h=arguments.length<=1||arguments[1]===void 0?a.default.D65:arguments[1],d=[l.r,l.g,l.b],p=n.transpose(d.map(function(x){var M=x.x/x.y,N=1,w=(1-x.x-x.y)/x.y;return[M,N,w]})),v=l.gamma,m=n.multiply(n.inverse(p),h),g=n.scalar(p,m),R=n.inverse(g);return{fromRgb:function(M){return n.multiply(g,M.map(v.decode))},toRgb:function(M){return n.multiply(R,M).map(v.encode)}}}t.default=f,e.exports=t.default})(xt,xt.exports)),xt.exports}var qn,la;function Rt(){if(la)return qn;la=1;var e=na(),t=sa(),r=ca(),n=Di(),o=Vi(),a=Yi();return qn={illuminant:e,workspace:t,matrix:r,degree:n,rgb:o,xyz:a},qn}var Zi=Rt();const Ht=pr(Zi);var de={},ha;function qt(){if(ha)return de;ha=1,Object.defineProperty(de,"__esModule",{value:!0}),de.cfs=de.distance=de.lerp=de.corLerp=void 0;var e=Hn();function t(h,d,p){return d in h?Object.defineProperty(h,d,{value:p,enumerable:!0,configurable:!0,writable:!0}):h[d]=p,h}function r(h){if(Array.isArray(h)){for(var d=0,p=Array(h.length);dm/2&&(h>d?d+=m:h+=m)}return((1-p)*h+p*d)%(m||1/0)}function u(h,d,p){var v={};for(var m in h)v[m]=i(h[m],d[m],p,m);return v}function f(h,d){var p=0;for(var v in h)p+=a(h[v]-d[v],2);return s(p)}function l(h){return e.merge.apply(void 0,r(h.split("").map(function(d){return t({},d,!0)})))}return de.corLerp=i,de.lerp=u,de.distance=f,de.cfs=l,de}var Mt={exports:{}},da;function Ji(){return da||(da=1,(function(e,t){var r=(function(){function s(c,i){var u=[],f=!0,l=!1,h=void 0;try{for(var d=c[Symbol.iterator](),p;!(f=(p=d.next()).done)&&(u.push(p.value),!(i&&u.length===i));f=!0);}catch(v){l=!0,h=v}finally{try{!f&&d.return&&d.return()}finally{if(l)throw h}}return u}return function(c,i){if(Array.isArray(c))return c;if(Symbol.iterator in Object(c))return s(c,i);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();Object.defineProperty(t,"__esModule",{value:!0});var n=Rt(),o=qt();function a(s,c){var i=arguments.length<=2||arguments[2]===void 0?1e-6:arguments[2],u=-i,f=1+i,l=Math,h=l.min,d=l.max,p=["000","fff"].map(function(w){return c.fromXyz(s.fromRgb(n.rgb.fromHex(w)))}),v=r(p,2),m=v[0],g=v[1];function R(w){var b=s.toRgb(c.toXyz(w)),_=b.map(function(k){return k>=u&&k<=f}).reduce(function(k,y){return k&&y},!0);return[_,b]}function x(w,b){for(var _=arguments.length<=2||arguments[2]===void 0?.001:arguments[2];(0,o.distance)(w,b)>_;){var k=(0,o.lerp)(w,b,.5),y=R(k),q=r(y,1),H=q[0];H?w=k:b=k}return w}function M(w){return(0,o.lerp)(m,g,w)}function N(w){return w.map(function(b){return d(u,h(f,b))})}return{contains:R,limit:x,spine:M,crop:N}}t.default=a,e.exports=t.default})(Mt,Mt.exports)),Mt.exports}var Ot={exports:{}},be={},ba;function pa(){if(ba)return be;ba=1;var e=(function(){function l(h,d){var p=[],v=!0,m=!1,g=void 0;try{for(var R=h[Symbol.iterator](),x;!(v=(x=R.next()).done)&&(p.push(x.value),!(d&&p.length===d));v=!0);}catch(M){m=!0,g=M}finally{try{!v&&R.return&&R.return()}finally{if(m)throw g}}return p}return function(h,d){if(Array.isArray(h))return h;if(Symbol.iterator in Object(h))return l(h,d);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();Object.defineProperty(be,"__esModule",{value:!0}),be.toNotation=be.fromNotation=be.toHue=be.fromHue=void 0;var t=qt(),r=Math,n=r.floor,o=[{s:"R",h:20.14,e:.8,H:0},{s:"Y",h:90,e:.7,H:100},{s:"G",h:164.25,e:1,H:200},{s:"B",h:237.53,e:1.2,H:300},{s:"R",h:380.14,e:.8,H:400}],a=o.map(function(l){return l.s}).slice(0,-1).join("");function s(l){l50){var v=[d,h];h=v[0],d=v[1],p=100-p}return p<1?a[h]:a[h]+p.toFixed()+a[d]}return be.fromHue=s,be.toHue=c,be.fromNotation=u,be.toNotation=f,be}var ma;function Wi(){return ma||(ma=1,(function(e,t){var r=(function(){function I(K,D){var U=[],ge=!0,ye=!1,st=void 0;try{for(var fe=K[Symbol.iterator](),qe;!(ge=(qe=fe.next()).done)&&(U.push(qe.value),!(D&&U.length===D));ge=!0);}catch(le){ye=!0,st=le}finally{try{!ge&&fe.return&&fe.return()}finally{if(ye)throw st}}return U}return function(K,D){if(Array.isArray(K))return K;if(Symbol.iterator in Object(K))return I(K,D);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();Object.defineProperty(t,"__esModule",{value:!0});var n=Rt(),o=pa(),a=i(o),s=qt(),c=Hn();function i(I){if(I&&I.__esModule)return I;var K={};if(I!=null)for(var D in I)Object.prototype.hasOwnProperty.call(I,D)&&(K[D]=I[D]);return K.default=I,K}var u=Math,f=u.pow,l=u.sqrt,h=u.exp,d=u.abs,p=u.sign,v=Math,m=v.sin,g=v.cos,R=v.atan2,x={average:{F:1,c:.69,N_c:1},dim:{F:.9,c:.59,N_c:.9},dark:{F:.8,c:.535,N_c:.8}},M=[[.7328,.4296,-.1624],[-.7036,1.6975,.0061],[.003,.0136,.9834]],N=[[.38971,.68898,-.07868],[-.22981,1.1834,.04641],[0,0,1]],w=M,b=n.matrix.inverse(M),_=n.matrix.product(N,n.matrix.inverse(M)),k=n.matrix.product(M,n.matrix.inverse(N)),y={whitePoint:n.illuminant.D65,adaptingLuminance:40,backgroundLuminance:20,surroundType:"average",discounting:!1},q=(0,s.cfs)("QJMCshH"),H=(0,s.cfs)("JCh");function A(){var I=arguments.length<=0||arguments[0]===void 0?{}:arguments[0],K=arguments.length<=1||arguments[1]===void 0?q:arguments[1];I=(0,c.merge)(y,I);var D=I.whitePoint,U=I.adaptingLuminance,ge=I.backgroundLuminance,ye=x[I.surroundType],st=ye.F,fe=ye.c,qe=ye.N_c,le=D[1],wc=1/(5*U+1),Ge=.2*f(wc,4)*5*U+.1*f(1-f(wc,4),2)*f(5*U,1/3),Xt=ge/le,no=.725*f(1/Xt,.2),kc=no,$c=1.48+l(Xt),Cc=I.discounting?1:st*(1-1/3.6*h(-(U+42)/92)),$l=n.matrix.multiply(M,D),Cl=$l.map(function(G){return Cc*le/G+1-Cc}),oo=r(Cl,3),xc=oo[0],Rc=oo[1],Hc=oo[2],xl=qc(D),Rl=Mc(xl),Kt=Oc(Rl);function qc(G){var z=n.matrix.multiply(w,G),F=r(z,3),ee=F[0],W=F[1],ce=F[2];return[xc*ee,Rc*W,Hc*ce]}function Hl(G){var z=r(G,3),F=z[0],ee=z[1],W=z[2];return n.matrix.multiply(b,[F/xc,ee/Rc,W/Hc])}function Mc(G){return n.matrix.multiply(_,G).map(function(z){var F=f(Ge*d(z)/100,.42);return p(z)*400*F/(27.13+F)+.1})}function ql(G){return n.matrix.multiply(k,G.map(function(z){var F=z-.1;return p(F)*100/Ge*f(27.13*d(F)/(400-d(F)),2.380952380952381)}))}function Oc(G){var z=r(G,3),F=z[0],ee=z[1],W=z[2];return(F*2+ee+W/20-.305)*no}function so(G){return 4/fe*l(G/100)*(Kt+4)*f(Ge,.25)}function Ml(G){return 6.25*f(fe*G/((Kt+4)*f(Ge,.25)),2)}function Nc(G){return G*f(Ge,.25)}function Ol(G,z){return f(G/100,2)*z/f(Ge,.25)}function Nl(G){return G/f(Ge,.25)}function Al(G,z){return 100*l(G/z)}function ao(G,z){var F=z.Q,ee=z.J,W=z.M,ce=z.C,ve=z.s,Me=z.h,Oe=z.H,te={};return G.J&&(te.J=isNaN(ee)?Ml(F):ee),G.C&&(isNaN(ce)?isNaN(W)?(F=isNaN(F)?so(ee):F,te.C=Ol(ve,F)):te.C=Nl(W):te.C=z.C),G.h&&(te.h=isNaN(Me)?a.toHue(Oe):Me),G.Q&&(te.Q=isNaN(F)?so(ee):F),G.M&&(te.M=isNaN(W)?Nc(ce):W),G.s&&(isNaN(ve)?(F=isNaN(F)?so(ee):F,W=isNaN(W)?Nc(ce):W,te.s=Al(W,F)):te.s=ve),G.H&&(te.H=isNaN(Oe)?a.fromHue(Me):Oe),te}function Ll(G){var z=qc(G),F=Mc(z),ee=r(F,3),W=ee[0],ce=ee[1],ve=ee[2],Me=W-ce*12/11+ve/11,Oe=(W+ce-2*ve)/9,te=R(Oe,Me),at=n.degree.fromRadian(te),Dt=1/4*(g(te+2)+3.8),Vt=Oc(F),bt=100*f(Vt/Kt,fe*$c),Pe=5e4/13*qe*kc*Dt*l(Me*Me+Oe*Oe)/(W+ce+21/20*ve),je=f(Pe,.9)*l(bt/100)*f(1.64-f(.29,Xt),.73);return ao(K,{J:bt,C:je,h:at})}function El(G){var z=ao(H,G),F=z.J,ee=z.C,W=z.h,ce=n.degree.toRadian(W),ve=f(ee/(l(F/100)*f(1.64-f(.29,Xt),.73)),10/9),Me=1/4*(g(ce+2)+3.8),Oe=Kt*f(F/100,1/fe/$c),te=5e4/13*qe*kc*Me/ve,at=Oe/no+.305,Dt=at*61/20*460/1403,Vt=61/20*220/1403,bt=21/20*6300/1403-27/1403,Pe=m(ce),je=g(ce),Ie,ze;ve===0||isNaN(ve)?Ie=ze=0:d(Pe)>=d(je)?(ze=Dt/(te/Pe+Vt*je/Pe+bt),Ie=ze*je/Pe):(Ie=Dt/(te/je+Vt+bt*Pe/je),ze=Ie*Pe/je);var Tl=[20/61*at+451/1403*Ie+288/1403*ze,20/61*at-891/1403*Ie-261/1403*ze,20/61*at-220/1403*Ie-6300/1403*ze],Sl=ql(Tl),Pl=Hl(Sl);return Pl}return{fromXyz:Ll,toXyz:El,fillOut:ao}}t.default=A,e.exports=t.default})(Ot,Ot.exports)),Ot.exports}var Nt={exports:{}},ga;function Ui(){return ga||(ga=1,(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r=Rt(),n=Math,o=n.sqrt,a=n.pow,s=n.exp,c=n.log,i=n.cos,u=n.sin,f=n.atan2,l={LCD:{K_L:.77,c_1:.007,c_2:.0053},SCD:{K_L:1.24,c_1:.007,c_2:.0363},UCS:{K_L:1,c_1:.007,c_2:.0228}};function h(){var d=arguments.length<=0||arguments[0]===void 0?"UCS":arguments[0],p=l[d],v=p.K_L,m=p.c_1,g=p.c_2;function R(N){var w=N.J,b=N.M,_=N.h,k=r.degree.toRadian(_),y=(1+100*m)*w/(1+m*w),q=1/g*c(1+g*b),H=q*i(k),A=q*u(k);return{J_p:y,a_p:H,b_p:A}}function x(N){var w=N.J_p,b=N.a_p,_=N.b_p,k=-w/(m*w-100*m-1),y=o(a(b,2)+a(_,2)),q=(s(g*y)-1)/g,H=f(_,b),A=r.degree.fromRadian(H);return{J:k,M:q,h:A}}function M(N,w){return o(a((N.J_p-w.J_p)/v,2)+a(N.a_p-w.a_p,2)+a(N.b_p-w.b_p,2))}return{fromCam:R,toCam:x,distance:M}}t.default=h,e.exports=t.default})(Nt,Nt.exports)),Nt.exports}var Mn,va;function Qi(){if(va)return Mn;va=1;var e=qt(),t=Ji(),r=Wi(),n=Ui(),o=pa();return Mn={gamut:t,cfs:e.cfs,lerp:e.lerp,cam:r,ucs:n,hq:o},Mn}var eu=Qi();const _a=pr(eu),ya=_a.cam({whitePoint:Ht.illuminant.D65,adaptingLuminance:40,backgroundLuminance:20,surroundType:"average",discounting:!1},_a.cfs("JCh")),wa=Ht.xyz(Ht.workspace.sRGB,Ht.illuminant.D65),ka=e=>wa.toRgb(ya.toXyz({J:e[0],C:e[1],h:e[2]})),On=e=>{const t=ya.fromXyz(wa.fromRgb(e));return[t.J,t.C,t.h]},[tu,ru]=(()=>{const e={k_l:1,c1:.007,c2:.0228},t=Math.PI,r=64/t/5,n=1/(5*r+1),o=.2*n**4*(5*r)+.1*(1-n**4)**2*(5*r)**(1/3);return[a=>{const[s,c,i]=a,u=c*o**.25;let f=(1+100*e.c1)*s/(1+e.c1*s);f/=e.k_l;const l=1/e.c2*Math.log(1+e.c2*u),h=l*Math.cos(i*(t/180)),d=l*Math.sin(i*(t/180));return[f,h,d]},a=>{const[s,c,i]=a,u=Math.sqrt(c*c+i*i),f=(Math.exp(u*e.c2)-1)/e.c2,l=(180/t*Math.atan2(i,c)+360)%360,h=f/o**.25;return[s/(1+e.c1*(100-s)),h,l]}]})(),nu=e=>ka(ru(e)),$a=e=>tu(On(e)),At=console;At.color=(e,t="")=>{const n=O(e).luminance();At.log(`%c${e} ${t}`,`background-color: ${e};padding: 5px; border-radius: 5px; color: ${n>.5?"#000":"#fff"}`)},At.ramp=(e,t=1)=>{At.log("%c ",`font-size: 1px;line-height: 16px;background: ${O.getCSSGradient(e,t)};padding: 0 0 0 200px; border-radius: 2px;`)};const Ca=(e,t,r,n,o,a,s=.1)=>{if(e===r||t===n)return!0;const c=(n-t)/(r-e),i=(a+o/c-t+c*e)/(c+1/c),u=a+o/c-i/c;return(o-i)**2+(a-u)**2{const o=(t[0]+r[0])/2,a=e(o);return Ca(...t,...r,o,a,n)?null:[o,a]},Nn=(e,t,r,n=.1)=>{const o=(r-t)/10,a=[];for(let s=t;sMath.round(e*10**t)/10**t,su=(e,t=1,r=90,n=.005)=>{const o=Nn(i=>e(i).gl()[0],0,t,n),a=Nn(i=>e(i).gl()[1],0,t,n),s=Nn(i=>e(i).gl()[2],0,t,n),c=Array.from(new Set([...o.map(i=>Lt(i[0])),...a.map(i=>Lt(i[0])),...s.map(i=>Lt(i[0]))].sort((i,u)=>i-u)));return`linear-gradient(${r}deg, ${c.map(i=>`${e(i).hex()} ${Lt(i*100)}%`).join()});`},au=e=>{e.Color.prototype.jch=function(){return On(this._rgb.slice(0,3).map(o=>o/255))},e.jch=(...o)=>new e.Color(...ka(o).map(a=>Math.floor(a*255)),"rgb"),e.Color.prototype.jab=function(){return $a(this._rgb.slice(0,3).map(o=>o/255))},e.jab=(...o)=>new e.Color(...nu(o).map(a=>Math.floor(a*255)),"rgb"),e.Color.prototype.hsluv=function(){return gr.rgbToHsluv(this._rgb.slice(0,3).map(o=>o/255))},e.hsluv=(...o)=>new e.Color(...gr.hsluvToRgb(o).map(a=>Math.floor(a*255)),"rgb");const t=e.interpolate,r={jch:On,jab:$a,hsluv:gr.rgbToHsluv},n=(o,a,s)=>(Math.abs(o-a)>360/2&&(o>a?a+=360:o+=360),((1-s)*o+s*a)%360);e.interpolate=(o,a,s=.5,c="lrgb")=>{if(r[c]){typeof o!="object"&&(o=new e.Color(o)),typeof a!="object"&&(a=new e.Color(a));const i=r[c](o.gl()),u=r[c](a.gl()),f=Number.isNaN(o.hsl()[0]),l=Number.isNaN(a.hsl()[0]);let h,d,p;switch(c){case"hsluv":i[1]<1e-10&&(i[0]=u[0]),i[1]===0&&(i[1]=u[1]),u[1]<1e-10&&(u[0]=i[0]),u[1]===0&&(u[1]=i[1]),h=n(i[0],u[0],s),d=i[1]+(u[1]-i[1])*s,p=i[2]+(u[2]-i[2])*s;break;case"jch":f&&(i[2]=u[2]),l&&(u[2]=i[2]),h=i[0]+(u[0]-i[0])*s,d=i[1]+(u[1]-i[1])*s,p=n(i[2],u[2],s);break;default:h=i[0]+(u[0]-i[0])*s,d=i[1]+(u[1]-i[1])*s,p=i[2]+(u[2]-i[2])*s}return e[c](h,d,p).alpha(o.alpha()+s*(a.alpha()-o.alpha()))}return t(o,a,s,c)},e.getCSSGradient=su};/** @preserve -///// SAPC APCA - Advanced Perceptual Contrast Algorithm -///// Beta 0.1.9 W3 • contrast function only -///// DIST: W3 • Revision date: July 3, 2022 -///// Function to parse color values and determine Lc contrast -///// Copyright © 2019-2022 by Andrew Somers. All Rights Reserved. -///// LICENSE: W3 LICENSE -///// CONTACT: Please use the ISSUES or DISCUSSIONS tab at: -///// https://github.com/Myndex/SAPC-APCA/ -///// -/////////////////////////////////////////////////////////////////////////////// -///// -///// MINIMAL IMPORTS: -///// import { APCAcontrast, sRGBtoY, displayP3toY, -///// calcAPCA, fontLookupAPCA } from 'apca-w3'; -///// import { colorParsley } from 'colorparsley'; -///// -///// FORWARD CONTRAST USAGE: -///// Lc = APCAcontrast( sRGBtoY( TEXTcolor ) , sRGBtoY( BACKGNDcolor ) ); -///// Where the colors are sent as an rgba array [255,255,255,1] -///// -///// Retrieving an array of font sizes for the contrast: -///// fontArray = fontLookupAPCA(Lc); -///// -///// Live Demonstrator at https://www.myndex.com/APCA/ -// */const Y={mainTRC:2.4,sRco:.2126729,sGco:.7151522,sBco:.072175,normBG:.56,normTXT:.57,revTXT:.62,revBG:.65,blkThrs:.022,blkClmp:1.414,scaleBoW:1.14,scaleWoB:1.14,loBoWoffset:.027,loWoBoffset:.027,deltaYmin:5e-4,loClip:.1};function xa(e,t,r=-1){const n=[0,1.1];if(isNaN(e)||isNaN(t)||Math.min(e,t)n[1])return 0;let o=0,a=0,s="BoW";return e=e>Y.blkThrs?e:e+Math.pow(Y.blkThrs-e,Y.blkClmp),t=t>Y.blkThrs?t:t+Math.pow(Y.blkThrs-t,Y.blkClmp),Math.abs(t-e)e?(o=(Math.pow(t,Y.normBG)-Math.pow(e,Y.normTXT))*Y.scaleBoW,a=o-.1?0:o+Y.loWoBoffset),r<0?a*100:r==0?Math.round(Math.abs(a)*100)+""+s+"":Number.isInteger(r)?(a*100).toFixed(r):0)}function Et(e=[0,0,0]){function t(r){return Math.pow(r/255,Y.mainTRC)}return Y.sRco*t(e[0])+Y.sGco*t(e[1])+Y.sBco*t(e[2])}const Ra=(e,t,r,n,o,a,s,c,i)=>{const u=1-i,f=u*u,l=f*u,d=i*i*i,p=l*e+f*3*i*r+u*3*i*i*o+d*s,v=l*t+f*3*i*n+u*3*i*i*a+d*c;return{x:p,y:v}},cu=(e,t)=>{const r=[];let n={x:+e[0],y:+e[1]};for(let o=0,a=e.length;a-2*!0>o;o+=2){const s=[{x:+e[o-2],y:+e[o-1]},{x:+e[o],y:+e[o+1]},{x:+e[o+2],y:+e[o+3]},{x:+e[o+4],y:+e[o+5]}];a-4===o?s[3]=s[2]:o||(s[0]={x:+e[o],y:+e[o+1]}),r.push([n.x,n.y,(-s[0].x+6*s[1].x+s[2].x)/6,(-s[0].y+6*s[1].y+s[2].y)/6,(s[1].x+6*s[2].x-s[3].x)/6,(s[1].y+6*s[2].y-s[3].y)/6,s[2].x,s[2].y]),n=s[2]}return r},iu=(e,t,r,n,o,a,s,c)=>{let u=e,f=t,l=0;for(let h=1;h<5;h++){const{x:d,y:p}=Ra(e,t,r,n,o,a,s,c,h/5);l+=Math.hypot(d-u,p-f),u=d,f=p}return l+=Math.hypot(s-u,c-f),l},uu=(e,t,r,n,o,a,s,c)=>{const i=Math.floor(iu(e,t,r,n,o,a,s,c)*.75),u=[];let f=0;for(let l=0;l<=i;l++){const h=l/i,d=Ra(e,t,r,n,o,a,s,c,h),p=Math.round(d.x);if(u[p]=d.y,p-f>1){const v=u[f],m=u[p];for(let g=f+1;gu[Math.round(l)]||null},Ze={CAM02:"jab",CAM02p:"jch",HEX:"hex",HSL:"hsl",HSLuv:"hsluv",HSV:"hsv",LAB:"lab",LCH:"lch",RGB:"rgb",OKLAB:"oklab",OKLCH:"oklch"};function Ee(e,t=0){const r=10**t;return Math.round(e*r)/r}function fu(e,t){let r;return e>1?r=(e-1)*t+1:e<-1?r=(e+1)*t-1:r=1,Ee(r,2)}function lu(e){return O(String(e)).jch()}function hu(e){return O(String(e)).hsluv()}function du(e,t,r){const n=[[],[],[]];if(e.forEach((a,s)=>n.forEach((c,i)=>c.push(t[s],a[i]))),r==="hcl"){const a=n[1];for(let s=1;s{const s=[];for(let c=1;c{a[i]=a[c]}),s.length=0;break}if(s.length){const c=O("#ccc").jch()[2];s.forEach(i=>{a[i]=c})}s.length=0;for(let c=a.length-1;c>0;c-=2)if(Number.isNaN(a[c]))s.push(c);else{s.forEach(i=>{a[i]=a[c]});break}for(let c=1;ccu(a).map(s=>uu(...s)));return a=>{const s=o.map(c=>{for(let i=0;in*a**e+o}function An({swatches:e,colorKeys:t,colorspace:r="LAB",shift:n=1,fullScale:o=!0,smooth:a=!1,distributeLightness:s="linear",sortColor:c=!0,asFun:i=!1}={}){const u=Ze[r];if(!u)throw new Error(`Colorspace “${r}” not supported`);if(!t)throw new Error(`Colorkeys missing: returned “${t}”`);let f;if(o)f=t.map(R=>e-e*(O(R).jch()[0]/100)).sort((R,x)=>R-x).concat(e),f.unshift(0);else{let R=t.map(N=>O(N).jch()[0]/100),x=Math.min(...R),M=Math.max(...R);f=R.map(N=>N===0||isNaN((N-x)/(M-x))?0:e-(N-x)/(M-x)*e).sort((N,w)=>N-w)}let l=bu(n,[1,e],[1,e]);if(l=f.map(R=>Math.max(0,l(R))),f=l,s==="polynomial"){const R=N=>Math.sqrt(Math.sqrt((Math.pow(N,2.25)+Math.pow(N,4))/2));f=l.map(N=>N/e).map(N=>R(N)*e)}const h=t.map((R,x)=>({colorKeys:lu(R),index:x})).sort((R,x)=>x.colorKeys[0]-R.colorKeys[0]).map(R=>t[R.index]);let d=[],p;if(o){const R=u==="lch"?O.lch(...O("#fff").lch()):"#ffffff",x=u==="lch"?O.lch(...O("#000").lch()):"#000000";d=[R,...h,x]}else c?d=h:d=t;let v;if(a){const R=d;if(d=d.map(x=>O(String(x))[u]()),u==="hcl"&&d.forEach(x=>{x[1]=Number.isNaN(x[1])?0:x[1]}),u==="jch")for(let x=0;xp(M))}else p=O.scale(d.map(R=>typeof R=="object"&&R.constructor===O.Color?R:String(R))).domain(f).mode(u);return i?p:(!a||a===!1?p.colors(e):v).filter(R=>R!=null)}function pu(e,t){const r=[],n={};return Object.keys(e).forEach(s=>{n[e[s][t]]=e[s]}),Object.keys(n).forEach(s=>r.push(n[s])),r}function mu(e){return Number.isNaN(e)?0:e}function Ln(e,t,r=!1){if(!e)throw new Error(`Cannot convert color value of “${e}”`);if(!Ze[t])throw new Error(`Cannot convert to colorspace “${t}”`);const n=Ze[t],o=O(String(e))[n]();if(t==="HSL"&&o.pop(),t==="HEX"){if(r){const u=O(String(e)).rgb();return{r:u[0],g:u[1],b:u[2]}}return o}const a={};let s=o.map(mu);s=s.map((u,f)=>{let l=Ee(u),h=f;n==="hsluv"&&(h+=2);let d=n.charAt(h);return n==="jch"&&d==="c"&&(d="C"),a[d==="j"?"J":d]=l,n in{lab:1,lch:1,jab:1,jch:1}?r||((d==="l"||d==="j")&&(l+="%"),d==="h"&&(l+="deg")):n!=="hsluv"&&(d==="s"||d==="l"||d==="v"?(a[d]=Ee(u,2),r||(l=Ee(u*100),l+="%")):d==="h"&&!r&&(l+="deg")),l});const i=`${n}(${s.join(", ")})`;return r?a:i}function Ha(e,t,r){const n=[e,t,r].map(o=>(o/=255,o<=.03928?o/12.92:((o+.055)/1.055)**2.4));return n[0]*.2126+n[1]*.7152+n[2]*.0722}function gu(e,t,r,n="wcag2"){if(r===void 0){const o=O.rgb(...t).hsluv()[2];r=Ee(o/100,2)}if(n==="wcag2"){const o=Ha(e[0],e[1],e[2]),a=Ha(t[0],t[1],t[2]),s=(o+.05)/(a+.05),c=(a+.05)/(o+.05);return r<.5?s>=1?s:-c:s<1?c:s===1?s:-s}else{if(n==="wcag3")return r<.5?xa(Et(e),Et(t))*-1:xa(Et(e),Et(t));throw new Error(`Contrast calculation method ${n} unsupported; use 'wcag2' or 'wcag3'`)}}function vu(e,t){if(!e)throw new Error("Array undefined");if(!Array.isArray(e))throw new Error("Passed object is not an array");const r=t==="wcag2"?0:1;return Math.min(...e.filter(n=>n>=r))}function _u(e,t){if(!e)throw new Error("Ratios undefined");e=e.sort((c,i)=>c-i);const r=vu(e,t),n=e.indexOf(r),o=[],a=e.slice(0,n),s=e.slice(n,e.length);for(let c=0;cc-i),o}const yu=(e,t,r,n,o)=>{const s=An({swatches:3e3,colorKeys:e._modifiedKeys,colorspace:e._colorspace,shift:1,smooth:e._smooth,asFun:!0}),c={},i=l=>{if(c[l])return c[l];const h=O(s(l)).rgb(),d=gu(h,t,r,o);return c[l]=d,d},u=l=>{const h=i(0),d=i(3e3),p=hv&&x;)x--,m/=2,Rf.push(s(u(+l)))),f};let ae=class{constructor({name:t,colorKeys:r,colorspace:n="RGB",ratios:o,smooth:a=!1,output:s="HEX",saturation:c=100}){if(this._name=t,this._colorKeys=r,this._modifiedKeys=r,this._colorspace=n,this._ratios=o,this._smooth=a,this._output=s,this._saturation=c,!this._name)throw new Error("Color missing name");if(!this._colorKeys)throw new Error("Color Keys are undefined");if(!Ze[this._colorspace])throw new Error(`Colorspace “${n}” not supported`);if(!Ze[this._output])throw new Error(`Output “${n}” not supported`);for(let i=0;i{let n=O(`${r}`).oklch(),a=n[1]*(this._saturation/100),s=O.oklch(n[0],a,n[2]),c=O.rgb(s).hex();t.push(c)}),this._modifiedKeys=t,this._generateColorScale()}_generateColorScale(){this._colorScale=An({swatches:3e3,colorKeys:this._modifiedKeys,colorspace:this._colorspace,shift:1,smooth:this._smooth,asFun:!0})}};class qa extends ae{get backgroundColorScale(){return this._backgroundColorScale||this._generateColorScale(),this._backgroundColorScale}_generateColorScale(){ae.prototype._generateColorScale.call(this);const t=An({swatches:1e3,colorKeys:this._colorKeys,colorspace:this._colorspace,shift:1,smooth:this._smooth});t.push(...this.colorKeys);const r=t.map((a,s)=>({value:Math.round(hu(a)[2]),index:s})),o=pu(r,"value").map(a=>t[a.index]);return o.length>=101&&(o.length=100,o.push("#ffffff")),this._backgroundColorScale=o.map(a=>Ln(a,this._output)),this._backgroundColorScale}}class wu{constructor({colors:t,backgroundColor:r,lightness:n,contrast:o=1,saturation:a=100,output:s="HEX",formula:c="wcag2"}){if(this._output=s,this._colors=t,this._lightness=n,this._saturation=a,this._formula=c,this._setBackgroundColor(r),this._setBackgroundColorValue(),this._contrast=o,!this._colors)throw new Error("No colors are defined");if(!this._backgroundColor)throw new Error("Background color is undefined");if(t.forEach(i=>{if(!i.ratios)throw new Error(`Color ${i.name}'s ratios are undefined`)}),!Ze[this._output])throw new Error(`Output “${s}” not supported`);this._saturation<100&&this._updateColorSaturation(this._saturation),this._findContrastColors(),this._findContrastColorPairs(),this._findContrastColorValues()}set formula(t){this._formula=t,this._findContrastColors()}get formula(){return this._formula}set contrast(t){this._contrast=t,this._findContrastColors()}get contrast(){return this._contrast}set lightness(t){this._lightness=t,this._setBackgroundColor(this._backgroundColor),this._findContrastColors()}get lightness(){return this._lightness}set saturation(t){this._saturation=t,this._updateColorSaturation(t),this._findContrastColors()}get saturation(){return this._saturation}set backgroundColor(t){this._setBackgroundColor(t),this._findContrastColors()}get backgroundColorValue(){return this._backgroundColorValue}get backgroundColor(){return this._backgroundColor}set colors(t){this._colors=t,this._findContrastColors()}get colors(){return this._colors}set addColor(t){this._colors.push(t),this._findContrastColors()}set removeColor(t){const r=this._colors.filter(n=>n.name!==t.name);this._colors=r,this._findContrastColors()}set updateColor(t){if(Array.isArray(t))for(let r=0;rs.name===t[r].color);n=n[0];let o=this._colors.indexOf(n);const a=this._colors.filter(s=>s.name!==t[r].color);t[r].name&&(n.name=t[r].name),t[r].colorKeys&&(n.colorKeys=t[r].colorKeys),t[r].ratios&&(n.ratios=t[r].ratios),t[r].colorspace&&(n.colorspace=t[r].colorspace),t[r].smooth&&(n.smooth=t[r].smooth),n._generateColorScale(),a.splice(o,0,n),this._colors=a}else{let r=this._colors.filter(a=>a.name===t.color);r=r[0];let n=this._colors.indexOf(r);const o=this._colors.filter(a=>a.name!==t.color);t.name&&(r.name=t.name),t.colorKeys&&(r.colorKeys=t.colorKeys),t.ratios&&(r.ratios=t.ratios),t.colorspace&&(r.colorspace=t.colorspace),t.smooth&&(r.smooth=t.smooth),r._generateColorScale(),o.splice(n,0,r),this._colors=o}this._findContrastColors()}set output(t){this._output=t,this._colors.forEach(r=>{r.output=this._output}),this._backgroundColor.output=this._output,this._findContrastColors()}get output(){return this._output}get contrastColors(){return this._contrastColors}get contrastColorPairs(){return this._contrastColorPairs}get contrastColorValues(){return this._contrastColorValues}_setBackgroundColor(t){if(typeof t=="string"){const r=new qa({name:"background",colorKeys:[t],output:"RGB"}),n=Ee(O(String(t)).hsluv()[2]);this._backgroundColor=r,this._lightness=n,this._backgroundColorValue=r[this._lightness]}else{t.output="RGB";const r=t.backgroundColorScale[this._lightness];this._backgroundColor=t,this._backgroundColorValue=r}}_setBackgroundColorValue(){this._backgroundColorValue=this._backgroundColor.backgroundColorScale[this._lightness]}_updateColorSaturation(t){this._colors.map(r=>{r.saturation=t})}_findContrastColors(){const t=O(String(this._backgroundColorValue)).rgb(),r=this._lightness/100,o={background:Ln(this._backgroundColorValue,this._output)},a=[],s=[],c={...o};return a.push(o),this._colors.map(i=>{if(i.ratios!==void 0){let u;const f=[],l={name:i.name,values:f};let h;Array.isArray(i.ratios)?h=i.ratios:Array.isArray(i.ratios)||(u=Object.keys(i.ratios),h=Object.values(i.ratios)),h=h.map(p=>fu(+p,this._contrast));const d=yu(i,t,r,h,this._formula).map(p=>Ln(p,this._output));for(let p=0;pku($u(t,e),r),En=e=>{e._clipped=!1,e._unclipped=e.slice(0);for(let t=0;t<=3;t++)t<3?((e[t]<0||e[t]>255)&&(e._clipped=!0),e[t]=Be(e[t],0,255)):t===3&&(e[t]=Be(e[t],0,1));return e},Ma={};for(let e of["Boolean","Number","String","Function","Array","Date","RegExp","Undefined","Null"])Ma[`[object ${e}]`]=e.toLowerCase();function j(e){return Ma[Object.prototype.toString.call(e)]||"object"}const T=(e,t=null)=>e.length>=3?Array.prototype.slice.call(e):j(e[0])=="object"&&t?t.split("").filter(r=>e[0][r]!==void 0).map(r=>e[0][r]):e[0].slice(0),Je=e=>{if(e.length<2)return null;const t=e.length-1;return j(e[t])=="string"?e[t].toLowerCase():null},{PI:Tt,min:Oa,max:Na}=Math,ie=e=>Math.round(e*100)/100,Tn=e=>Math.round(e*100)/100,Ce=Tt*2,Sn=Tt/3,Cu=Tt/180,xu=180/Tt;function Aa(e){return[...e.slice(0,3).reverse(),...e.slice(3)]}const E={format:{},autodetect:[]};class ${constructor(...t){const r=this;if(j(t[0])==="object"&&t[0].constructor&&t[0].constructor===this.constructor)return t[0];let n=Je(t),o=!1;if(!n){o=!0,E.sorted||(E.autodetect=E.autodetect.sort((a,s)=>s.p-a.p),E.sorted=!0);for(let a of E.autodetect)if(n=a.test(...t),n)break}if(E.format[n]){const a=E.format[n].apply(null,o?t:t.slice(0,-1));r._rgb=En(a)}else throw new Error("unknown format: "+t);r._rgb.length===3&&r._rgb.push(1)}toString(){return j(this.hex)=="function"?this.hex():`[${this._rgb.join(",")}]`}}const Ru="3.1.2",B=(...e)=>new $(...e);B.version=Ru;const We={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",laserlemon:"#ffff54",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrod:"#fafad2",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",maroon2:"#7f0000",maroon3:"#b03060",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",purple2:"#7f007f",purple3:"#a020f0",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},Hu=/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,qu=/^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/,La=e=>{if(e.match(Hu)){(e.length===4||e.length===7)&&(e=e.substr(1)),e.length===3&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]);const t=parseInt(e,16),r=t>>16,n=t>>8&255,o=t&255;return[r,n,o,1]}if(e.match(qu)){(e.length===5||e.length===9)&&(e=e.substr(1)),e.length===4&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]+e[3]+e[3]);const t=parseInt(e,16),r=t>>24&255,n=t>>16&255,o=t>>8&255,a=Math.round((t&255)/255*100)/100;return[r,n,o,a]}throw new Error(`unknown hex color: ${e}`)},{round:St}=Math,Ea=(...e)=>{let[t,r,n,o]=T(e,"rgba"),a=Je(e)||"auto";o===void 0&&(o=1),a==="auto"&&(a=o<1?"rgba":"rgb"),t=St(t),r=St(r),n=St(n);let c="000000"+(t<<16|r<<8|n).toString(16);c=c.substr(c.length-6);let i="0"+St(o*255).toString(16);switch(i=i.substr(i.length-2),a.toLowerCase()){case"rgba":return`#${c}${i}`;case"argb":return`#${i}${c}`;default:return`#${c}`}};$.prototype.name=function(){const e=Ea(this._rgb,"rgb");for(let t of Object.keys(We))if(We[t]===e)return t.toLowerCase();return e},E.format.named=e=>{if(e=e.toLowerCase(),We[e])return La(We[e]);throw new Error("unknown color name: "+e)},E.autodetect.push({p:5,test:(e,...t)=>{if(!t.length&&j(e)==="string"&&We[e.toLowerCase()])return"named"}}),$.prototype.alpha=function(e,t=!1){return e!==void 0&&j(e)==="number"?t?(this._rgb[3]=e,this):new $([this._rgb[0],this._rgb[1],this._rgb[2],e],"rgb"):this._rgb[3]},$.prototype.clipped=function(){return this._rgb._clipped||!1};const _e={Kn:18,labWhitePoint:"d65",Xn:.95047,Yn:1,Zn:1.08883,kE:216/24389,kKE:8,kK:24389/27,RefWhiteRGB:{X:.95047,Y:1,Z:1.08883},MtxRGB2XYZ:{m00:.4124564390896922,m01:.21267285140562253,m02:.0193338955823293,m10:.357576077643909,m11:.715152155287818,m12:.11919202588130297,m20:.18043748326639894,m21:.07217499330655958,m22:.9503040785363679},MtxXYZ2RGB:{m00:3.2404541621141045,m01:-.9692660305051868,m02:.055643430959114726,m10:-1.5371385127977166,m11:1.8760108454466942,m12:-.2040259135167538,m20:-.498531409556016,m21:.041556017530349834,m22:1.0572251882231791},As:.9414285350000001,Bs:1.040417467,Cs:1.089532651,MtxAdaptMa:{m00:.8951,m01:-.7502,m02:.0389,m10:.2664,m11:1.7135,m12:-.0685,m20:-.1614,m21:.0367,m22:1.0296},MtxAdaptMaI:{m00:.9869929054667123,m01:.43230526972339456,m02:-.008528664575177328,m10:-.14705425642099013,m11:.5183602715367776,m12:.04004282165408487,m20:.15996265166373125,m21:.0492912282128556,m22:.9684866957875502}},Mu=new Map([["a",[1.0985,.35585]],["b",[1.0985,.35585]],["c",[.98074,1.18232]],["d50",[.96422,.82521]],["d55",[.95682,.92149]],["d65",[.95047,1.08883]],["e",[1,1,1]],["f2",[.99186,.67393]],["f7",[.95041,1.08747]],["f11",[1.00962,.6435]],["icc",[.96422,.82521]]]);function xe(e){const t=Mu.get(String(e).toLowerCase());if(!t)throw new Error("unknown Lab illuminant "+e);_e.labWhitePoint=e,_e.Xn=t[0],_e.Zn=t[1]}function dt(){return _e.labWhitePoint}const Pn=(...e)=>{e=T(e,"lab");const[t,r,n]=e,[o,a,s]=Ou(t,r,n),[c,i,u]=Ta(o,a,s);return[c,i,u,e.length>3?e[3]:1]},Ou=(e,t,r)=>{const{kE:n,kK:o,kKE:a,Xn:s,Yn:c,Zn:i}=_e,u=(e+16)/116,f=.002*t+u,l=u-.005*r,h=f*f*f,d=l*l*l,p=h>n?h:(116*f-16)/o,v=e>a?Math.pow((e+16)/116,3):e/o,m=d>n?d:(116*l-16)/o,g=p*s,R=v*c,x=m*i;return[g,R,x]},jn=e=>{const t=Math.sign(e);return e=Math.abs(e),(e<=.0031308?e*12.92:1.055*Math.pow(e,1/2.4)-.055)*t},Ta=(e,t,r)=>{const{MtxAdaptMa:n,MtxAdaptMaI:o,MtxXYZ2RGB:a,RefWhiteRGB:s,Xn:c,Yn:i,Zn:u}=_e,f=c*n.m00+i*n.m10+u*n.m20,l=c*n.m01+i*n.m11+u*n.m21,h=c*n.m02+i*n.m12+u*n.m22,d=s.X*n.m00+s.Y*n.m10+s.Z*n.m20,p=s.X*n.m01+s.Y*n.m11+s.Z*n.m21,v=s.X*n.m02+s.Y*n.m12+s.Z*n.m22,m=(e*n.m00+t*n.m10+r*n.m20)*(d/f),g=(e*n.m01+t*n.m11+r*n.m21)*(p/l),R=(e*n.m02+t*n.m12+r*n.m22)*(v/h),x=m*o.m00+g*o.m10+R*o.m20,M=m*o.m01+g*o.m11+R*o.m21,N=m*o.m02+g*o.m12+R*o.m22,w=jn(x*a.m00+M*a.m10+N*a.m20),b=jn(x*a.m01+M*a.m11+N*a.m21),_=jn(x*a.m02+M*a.m12+N*a.m22);return[w*255,b*255,_*255]},Bn=(...e)=>{const[t,r,n,...o]=T(e,"rgb"),[a,s,c]=Sa(t,r,n),[i,u,f]=Nu(a,s,c);return[i,u,f,...o.length>0&&o[0]<1?[o[0]]:[]]};function Nu(e,t,r){const{Xn:n,Yn:o,Zn:a,kE:s,kK:c}=_e,i=e/n,u=t/o,f=r/a,l=i>s?Math.pow(i,1/3):(c*i+16)/116,h=u>s?Math.pow(u,1/3):(c*u+16)/116,d=f>s?Math.pow(f,1/3):(c*f+16)/116;return[116*h-16,500*(l-h),200*(h-d)]}function Gn(e){const t=Math.sign(e);return e=Math.abs(e),(e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4))*t}const Sa=(e,t,r)=>{e=Gn(e/255),t=Gn(t/255),r=Gn(r/255);const{MtxRGB2XYZ:n,MtxAdaptMa:o,MtxAdaptMaI:a,Xn:s,Yn:c,Zn:i,As:u,Bs:f,Cs:l}=_e;let h=e*n.m00+t*n.m10+r*n.m20,d=e*n.m01+t*n.m11+r*n.m21,p=e*n.m02+t*n.m12+r*n.m22;const v=s*o.m00+c*o.m10+i*o.m20,m=s*o.m01+c*o.m11+i*o.m21,g=s*o.m02+c*o.m12+i*o.m22;let R=h*o.m00+d*o.m10+p*o.m20,x=h*o.m01+d*o.m11+p*o.m21,M=h*o.m02+d*o.m12+p*o.m22;return R*=v/u,x*=m/f,M*=g/l,h=R*a.m00+x*a.m10+M*a.m20,d=R*a.m01+x*a.m11+M*a.m21,p=R*a.m02+x*a.m12+M*a.m22,[h,d,p]};$.prototype.lab=function(){return Bn(this._rgb)},Object.assign(B,{lab:(...e)=>new $(...e,"lab"),getLabWhitePoint:dt,setLabWhitePoint:xe}),E.format.lab=Pn,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"lab"),j(e)==="array"&&e.length===3)return"lab"}}),$.prototype.darken=function(e=1){const t=this,r=t.lab();return r[0]-=_e.Kn*e,new $(r,"lab").alpha(t.alpha(),!0)},$.prototype.brighten=function(e=1){return this.darken(-e)},$.prototype.darker=$.prototype.darken,$.prototype.brighter=$.prototype.brighten,$.prototype.get=function(e){const[t,r]=e.split("."),n=this[t]();if(r){const o=t.indexOf(r)-(t.substr(0,2)==="ok"?2:0);if(o>-1)return n[o];throw new Error(`unknown channel ${r} in mode ${t}`)}else return n};const{pow:Au}=Math,Lu=1e-7,Eu=20;$.prototype.luminance=function(e,t="rgb"){if(e!==void 0&&j(e)==="number"){if(e===0)return new $([0,0,0,this._rgb[3]],"rgb");if(e===1)return new $([255,255,255,this._rgb[3]],"rgb");let r=this.luminance(),n=Eu;const o=(s,c)=>{const i=s.interpolate(c,.5,t),u=i.luminance();return Math.abs(e-u)e?o(s,i):o(i,c)},a=(r>e?o(new $([0,0,0]),this):o(this,new $([255,255,255]))).rgb();return new $([...a,this._rgb[3]])}return Tu(...this._rgb.slice(0,3))};const Tu=(e,t,r)=>(e=In(e),t=In(t),r=In(r),.2126*e+.7152*t+.0722*r),In=e=>(e/=255,e<=.03928?e/12.92:Au((e+.055)/1.055,2.4)),ne={},Ue=(e,t,r=.5,...n)=>{let o=n[0]||"lrgb";if(!ne[o]&&!n.length&&(o=Object.keys(ne)[0]),!ne[o])throw new Error(`interpolation mode ${o} is not defined`);return j(e)!=="object"&&(e=new $(e)),j(t)!=="object"&&(t=new $(t)),ne[o](e,t,r).alpha(e.alpha()+r*(t.alpha()-e.alpha()))};$.prototype.mix=$.prototype.interpolate=function(e,t=.5,...r){return Ue(this,e,t,...r)},$.prototype.premultiply=function(e=!1){const t=this._rgb,r=t[3];return e?(this._rgb=[t[0]*r,t[1]*r,t[2]*r,r],this):new $([t[0]*r,t[1]*r,t[2]*r,r],"rgb")};const{sin:Su,cos:Pu}=Math,Pa=(...e)=>{let[t,r,n]=T(e,"lch");return isNaN(n)&&(n=0),n=n*Cu,[t,Pu(n)*r,Su(n)*r]},zn=(...e)=>{e=T(e,"lch");const[t,r,n]=e,[o,a,s]=Pa(t,r,n),[c,i,u]=Pn(o,a,s);return[c,i,u,e.length>3?e[3]:1]},ju=(...e)=>{const t=Aa(T(e,"hcl"));return zn(...t)},{sqrt:Bu,atan2:Gu,round:Iu}=Math,ja=(...e)=>{const[t,r,n]=T(e,"lab"),o=Bu(r*r+n*n);let a=(Gu(n,r)*xu+360)%360;return Iu(o*1e4)===0&&(a=Number.NaN),[t,o,a]},Fn=(...e)=>{const[t,r,n,...o]=T(e,"rgb"),[a,s,c]=Bn(t,r,n),[i,u,f]=ja(a,s,c);return[i,u,f,...o.length>0&&o[0]<1?[o[0]]:[]]};$.prototype.lch=function(){return Fn(this._rgb)},$.prototype.hcl=function(){return Aa(Fn(this._rgb))},Object.assign(B,{lch:(...e)=>new $(...e,"lch"),hcl:(...e)=>new $(...e,"hcl")}),E.format.lch=zn,E.format.hcl=ju,["lch","hcl"].forEach(e=>E.autodetect.push({p:2,test:(...t)=>{if(t=T(t,e),j(t)==="array"&&t.length===3)return e}})),$.prototype.saturate=function(e=1){const t=this,r=t.lch();return r[1]+=_e.Kn*e,r[1]<0&&(r[1]=0),new $(r,"lch").alpha(t.alpha(),!0)},$.prototype.desaturate=function(e=1){return this.saturate(-e)},$.prototype.set=function(e,t,r=!1){const[n,o]=e.split("."),a=this[n]();if(o){const s=n.indexOf(o)-(n.substr(0,2)==="ok"?2:0);if(s>-1){if(j(t)=="string")switch(t.charAt(0)){case"+":a[s]+=+t;break;case"-":a[s]+=+t;break;case"*":a[s]*=+t.substr(1);break;case"/":a[s]/=+t.substr(1);break;default:a[s]=+t}else if(j(t)==="number")a[s]=t;else throw new Error("unsupported value for Color.set");const c=new $(a,n);return r?(this._rgb=c._rgb,this):c}throw new Error(`unknown channel ${o} in mode ${n}`)}else return a},$.prototype.tint=function(e=.5,...t){return Ue(this,"white",e,...t)},$.prototype.shade=function(e=.5,...t){return Ue(this,"black",e,...t)};const zu=(e,t,r)=>{const n=e._rgb,o=t._rgb;return new $(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"rgb")};ne.rgb=zu;const{sqrt:Xn,pow:Qe}=Math,Fu=(e,t,r)=>{const[n,o,a]=e._rgb,[s,c,i]=t._rgb;return new $(Xn(Qe(n,2)*(1-r)+Qe(s,2)*r),Xn(Qe(o,2)*(1-r)+Qe(c,2)*r),Xn(Qe(a,2)*(1-r)+Qe(i,2)*r),"rgb")};ne.lrgb=Fu;const Xu=(e,t,r)=>{const n=e.lab(),o=t.lab();return new $(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"lab")};ne.lab=Xu;const et=(e,t,r,n)=>{let o,a;n==="hsl"?(o=e.hsl(),a=t.hsl()):n==="hsv"?(o=e.hsv(),a=t.hsv()):n==="hcg"?(o=e.hcg(),a=t.hcg()):n==="hsi"?(o=e.hsi(),a=t.hsi()):n==="lch"||n==="hcl"?(n="hcl",o=e.hcl(),a=t.hcl()):n==="oklch"&&(o=e.oklch().reverse(),a=t.oklch().reverse());let s,c,i,u,f,l;(n.substr(0,1)==="h"||n==="oklch")&&([s,i,f]=o,[c,u,l]=a);let h,d,p,v;return!isNaN(s)&&!isNaN(c)?(c>s&&c-s>180?v=c-(s+360):c180?v=c+360-s:v=c-s,d=s+r*v):isNaN(s)?isNaN(c)?d=Number.NaN:(d=c,(f==1||f==0)&&n!="hsv"&&(h=u)):(d=s,(l==1||l==0)&&n!="hsv"&&(h=i)),h===void 0&&(h=i+r*(u-i)),p=f+r*(l-f),n==="oklch"?new $([p,h,d],n):new $([d,h,p],n)},Ba=(e,t,r)=>et(e,t,r,"lch");ne.lch=Ba,ne.hcl=Ba;const Ku=e=>{if(j(e)=="number"&&e>=0&&e<=16777215){const t=e>>16,r=e>>8&255,n=e&255;return[t,r,n,1]}throw new Error("unknown num color: "+e)},Du=(...e)=>{const[t,r,n]=T(e,"rgb");return(t<<16)+(r<<8)+n};$.prototype.num=function(){return Du(this._rgb)},Object.assign(B,{num:(...e)=>new $(...e,"num")}),E.format.num=Ku,E.autodetect.push({p:5,test:(...e)=>{if(e.length===1&&j(e[0])==="number"&&e[0]>=0&&e[0]<=16777215)return"num"}});const Vu=(e,t,r)=>{const n=e.num(),o=t.num();return new $(n+r*(o-n),"num")};ne.num=Vu;const{floor:Yu}=Math,Zu=(...e)=>{e=T(e,"hcg");let[t,r,n]=e,o,a,s;n=n*255;const c=r*255;if(r===0)o=a=s=n;else{t===360&&(t=0),t>360&&(t-=360),t<0&&(t+=360),t/=60;const i=Yu(t),u=t-i,f=n*(1-r),l=f+c*(1-u),h=f+c*u,d=f+c;switch(i){case 0:[o,a,s]=[d,h,f];break;case 1:[o,a,s]=[l,d,f];break;case 2:[o,a,s]=[f,d,h];break;case 3:[o,a,s]=[f,l,d];break;case 4:[o,a,s]=[h,f,d];break;case 5:[o,a,s]=[d,f,l];break}}return[o,a,s,e.length>3?e[3]:1]},Ju=(...e)=>{const[t,r,n]=T(e,"rgb"),o=Oa(t,r,n),a=Na(t,r,n),s=a-o,c=s*100/255,i=o/(255-s)*100;let u;return s===0?u=Number.NaN:(t===a&&(u=(r-n)/s),r===a&&(u=2+(n-t)/s),n===a&&(u=4+(t-r)/s),u*=60,u<0&&(u+=360)),[u,c,i]};$.prototype.hcg=function(){return Ju(this._rgb)};const Wu=(...e)=>new $(...e,"hcg");B.hcg=Wu,E.format.hcg=Zu,E.autodetect.push({p:1,test:(...e)=>{if(e=T(e,"hcg"),j(e)==="array"&&e.length===3)return"hcg"}});const Uu=(e,t,r)=>et(e,t,r,"hcg");ne.hcg=Uu;const{cos:tt}=Math,Qu=(...e)=>{e=T(e,"hsi");let[t,r,n]=e,o,a,s;return isNaN(t)&&(t=0),isNaN(r)&&(r=0),t>360&&(t-=360),t<0&&(t+=360),t/=360,t<1/3?(s=(1-r)/3,o=(1+r*tt(Ce*t)/tt(Sn-Ce*t))/3,a=1-(s+o)):t<2/3?(t-=1/3,o=(1-r)/3,a=(1+r*tt(Ce*t)/tt(Sn-Ce*t))/3,s=1-(o+a)):(t-=2/3,a=(1-r)/3,s=(1+r*tt(Ce*t)/tt(Sn-Ce*t))/3,o=1-(a+s)),o=Be(n*o*3),a=Be(n*a*3),s=Be(n*s*3),[o*255,a*255,s*255,e.length>3?e[3]:1]},{min:ef,sqrt:tf,acos:rf}=Math,nf=(...e)=>{let[t,r,n]=T(e,"rgb");t/=255,r/=255,n/=255;let o;const a=ef(t,r,n),s=(t+r+n)/3,c=s>0?1-a/s:0;return c===0?o=NaN:(o=(t-r+(t-n))/2,o/=tf((t-r)*(t-r)+(t-n)*(r-n)),o=rf(o),n>r&&(o=Ce-o),o/=Ce),[o*360,c,s]};$.prototype.hsi=function(){return nf(this._rgb)};const of=(...e)=>new $(...e,"hsi");B.hsi=of,E.format.hsi=Qu,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"hsi"),j(e)==="array"&&e.length===3)return"hsi"}});const sf=(e,t,r)=>et(e,t,r,"hsi");ne.hsi=sf;const Kn=(...e)=>{e=T(e,"hsl");const[t,r,n]=e;let o,a,s;if(r===0)o=a=s=n*255;else{const c=[0,0,0],i=[0,0,0],u=n<.5?n*(1+r):n+r-n*r,f=2*n-u,l=t/360;c[0]=l+1/3,c[1]=l,c[2]=l-1/3;for(let h=0;h<3;h++)c[h]<0&&(c[h]+=1),c[h]>1&&(c[h]-=1),6*c[h]<1?i[h]=f+(u-f)*6*c[h]:2*c[h]<1?i[h]=u:3*c[h]<2?i[h]=f+(u-f)*(2/3-c[h])*6:i[h]=f;[o,a,s]=[i[0]*255,i[1]*255,i[2]*255]}return e.length>3?[o,a,s,e[3]]:[o,a,s,1]},Ga=(...e)=>{e=T(e,"rgba");let[t,r,n]=e;t/=255,r/=255,n/=255;const o=Oa(t,r,n),a=Na(t,r,n),s=(a+o)/2;let c,i;return a===o?(c=0,i=Number.NaN):c=s<.5?(a-o)/(a+o):(a-o)/(2-a-o),t==a?i=(r-n)/(a-o):r==a?i=2+(n-t)/(a-o):n==a&&(i=4+(t-r)/(a-o)),i*=60,i<0&&(i+=360),e.length>3&&e[3]!==void 0?[i,c,s,e[3]]:[i,c,s]};$.prototype.hsl=function(){return Ga(this._rgb)};const af=(...e)=>new $(...e,"hsl");B.hsl=af,E.format.hsl=Kn,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"hsl"),j(e)==="array"&&e.length===3)return"hsl"}});const cf=(e,t,r)=>et(e,t,r,"hsl");ne.hsl=cf;const{floor:uf}=Math,ff=(...e)=>{e=T(e,"hsv");let[t,r,n]=e,o,a,s;if(n*=255,r===0)o=a=s=n;else{t===360&&(t=0),t>360&&(t-=360),t<0&&(t+=360),t/=60;const c=uf(t),i=t-c,u=n*(1-r),f=n*(1-r*i),l=n*(1-r*(1-i));switch(c){case 0:[o,a,s]=[n,l,u];break;case 1:[o,a,s]=[f,n,u];break;case 2:[o,a,s]=[u,n,l];break;case 3:[o,a,s]=[u,f,n];break;case 4:[o,a,s]=[l,u,n];break;case 5:[o,a,s]=[n,u,f];break}}return[o,a,s,e.length>3?e[3]:1]},{min:lf,max:hf}=Math,df=(...e)=>{e=T(e,"rgb");let[t,r,n]=e;const o=lf(t,r,n),a=hf(t,r,n),s=a-o;let c,i,u;return u=a/255,a===0?(c=Number.NaN,i=0):(i=s/a,t===a&&(c=(r-n)/s),r===a&&(c=2+(n-t)/s),n===a&&(c=4+(t-r)/s),c*=60,c<0&&(c+=360)),[c,i,u]};$.prototype.hsv=function(){return df(this._rgb)};const bf=(...e)=>new $(...e,"hsv");B.hsv=bf,E.format.hsv=ff,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"hsv"),j(e)==="array"&&e.length===3)return"hsv"}});const pf=(e,t,r)=>et(e,t,r,"hsv");ne.hsv=pf;function Pt(e,t){let r=e.length;Array.isArray(e[0])||(e=[e]),Array.isArray(t[0])||(t=t.map(s=>[s]));let n=t[0].length,o=t[0].map((s,c)=>t.map(i=>i[c])),a=e.map(s=>o.map(c=>Array.isArray(s)?s.reduce((i,u,f)=>i+u*(c[f]||0),0):c.reduce((i,u)=>i+u*s,0)));return r===1&&(a=a[0]),n===1?a.map(s=>s[0]):a}const Dn=(...e)=>{e=T(e,"lab");const[t,r,n,...o]=e,[a,s,c]=mf([t,r,n]),[i,u,f]=Ta(a,s,c);return[i,u,f,...o.length>0&&o[0]<1?[o[0]]:[]]};function mf(e){var t=[[1.2268798758459243,-.5578149944602171,.2813910456659647],[-.0405757452148008,1.112286803280317,-.0717110580655164],[-.0763729366746601,-.4214933324022432,1.5869240198367816]],r=[[1,.3963377773761749,.2158037573099136],[1,-.1055613458156586,-.0638541728258133],[1,-.0894841775298119,-1.2914855480194092]],n=Pt(r,e);return Pt(t,n.map(o=>o**3))}const Vn=(...e)=>{const[t,r,n,...o]=T(e,"rgb"),a=Sa(t,r,n);return[...gf(a),...o.length>0&&o[0]<1?[o[0]]:[]]};function gf(e){const t=[[.819022437996703,.3619062600528904,-.1288737815209879],[.0329836539323885,.9292868615863434,.0361446663506424],[.0481771893596242,.2642395317527308,.6335478284694309]],r=[[.210454268309314,.7936177747023054,-.0040720430116193],[1.9779985324311684,-2.42859224204858,.450593709617411],[.0259040424655478,.7827717124575296,-.8086757549230774]],n=Pt(t,e);return Pt(r,n.map(o=>Math.cbrt(o)))}$.prototype.oklab=function(){return Vn(this._rgb)},Object.assign(B,{oklab:(...e)=>new $(...e,"oklab")}),E.format.oklab=Dn,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"oklab"),j(e)==="array"&&e.length===3)return"oklab"}});const vf=(e,t,r)=>{const n=e.oklab(),o=t.oklab();return new $(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"oklab")};ne.oklab=vf;const _f=(e,t,r)=>et(e,t,r,"oklch");ne.oklch=_f;const{pow:Yn,sqrt:Zn,PI:Jn,cos:Ia,sin:za,atan2:yf}=Math,wf=(e,t="lrgb",r=null)=>{const n=e.length;r||(r=Array.from(new Array(n)).map(()=>1));const o=n/r.reduce(function(l,h){return l+h});if(r.forEach((l,h)=>{r[h]*=o}),e=e.map(l=>new $(l)),t==="lrgb")return kf(e,r);const a=e.shift(),s=a.get(t),c=[];let i=0,u=0;for(let l=0;l{const d=l.get(t);f+=l.alpha()*r[h+1];for(let p=0;p=360;)h-=360;s[l]=h}else s[l]=s[l]/c[l];return f/=n,new $(s,t).alpha(f>.99999?1:f,!0)},kf=(e,t)=>{const r=e.length,n=[0,0,0,0];for(let o=0;o.9999999&&(n[3]=1),new $(En(n))},{pow:$f}=Math;function jt(e){let t="rgb",r=B("#ccc"),n=0,o=[0,1],a=[],s=[0,0],c=!1,i=[],u=!1,f=0,l=1,h=!1,d={},p=!0,v=1;const m=function(b){if(b=b||["#fff","#000"],b&&j(b)==="string"&&B.brewer&&B.brewer[b.toLowerCase()]&&(b=B.brewer[b.toLowerCase()]),j(b)==="array"){b.length===1&&(b=[b[0],b[0]]),b=b.slice(0);for(let _=0;_=c[k];)k++;return k-1}return 0};let R=b=>b,x=b=>b;const M=function(b,_){let k,y;if(_==null&&(_=!1),isNaN(b)||b===null)return r;_?y=b:c&&c.length>2?y=g(b)/(c.length-2):l!==f?y=(b-f)/(l-f):y=1,y=x(y),_||(y=R(y)),v!==1&&(y=$f(y,v)),y=s[0]+y*(1-s[0]-s[1]),y=Be(y,0,1);const q=Math.floor(y*1e4);if(p&&d[q])k=d[q];else{if(j(i)==="array")for(let H=0;H=A&&H===a.length-1){k=i[H];break}if(y>A&&yd={};m(e);const w=function(b){const _=B(M(b));return u&&_[u]?_[u]():_};return w.classes=function(b){if(b!=null){if(j(b)==="array")c=b,o=[b[0],b[b.length-1]];else{const _=B.analyze(o);b===0?c=[_.min,_.max]:c=B.limits(_,"e",b)}return w}return c},w.domain=function(b){if(!arguments.length)return o;f=b[0],l=b[b.length-1],a=[];const _=i.length;if(b.length===_&&f!==l)for(let k of Array.from(b))a.push((k-f)/(l-f));else{for(let k=0;k<_;k++)a.push(k/(_-1));if(b.length>2){const k=b.map((q,H)=>H/(b.length-1)),y=b.map(q=>(q-f)/(l-f));y.every((q,H)=>k[H]===q)||(x=q=>{if(q<=0||q>=1)return q;let H=0;for(;q>=y[H+1];)H++;const A=(q-y[H])/(y[H+1]-y[H]);return k[H]+A*(k[H+1]-k[H])})}}return o=[f,l],w},w.mode=function(b){return arguments.length?(t=b,N(),w):t},w.range=function(b,_){return m(b),w},w.out=function(b){return u=b,w},w.spread=function(b){return arguments.length?(n=b,w):n},w.correctLightness=function(b){return b==null&&(b=!0),h=b,N(),h?R=function(_){const k=M(0,!0).lab()[0],y=M(1,!0).lab()[0],q=k>y;let H=M(_,!0).lab()[0];const A=k+(y-k)*_;let I=H-A,K=0,D=1,U=20;for(;Math.abs(I)>.01&&U-- >0;)(function(){return q&&(I*=-1),I<0?(K=_,_+=(D-_)*.5):(D=_,_+=(K-_)*.5),H=M(_,!0).lab()[0],I=H-A})();return _}:R=_=>_,w},w.padding=function(b){return b!=null?(j(b)==="number"&&(b=[b,b]),s=b,w):s},w.colors=function(b,_){arguments.length<2&&(_="hex");let k=[];if(arguments.length===0)k=i.slice(0);else if(b===1)k=[w(.5)];else if(b>1){const y=o[0],q=o[1]-y;k=Cf(0,b).map(H=>w(y+H/(b-1)*q))}else{e=[];let y=[];if(c&&c.length>2)for(let q=1,H=c.length,A=1<=H;A?qH;A?q++:q--)y.push((c[q-1]+c[q])*.5);else y=o;k=y.map(q=>w(q))}return B[_]&&(k=k.map(y=>y[_]())),k},w.cache=function(b){return b!=null?(p=b,w):p},w.gamma=function(b){return b!=null?(v=b,w):v},w.nodata=function(b){return b!=null?(r=B(b),w):r},w}function Cf(e,t,r){let n=[],o=ea;o?s++:s--)n.push(s);return n}const xf=function(e){let t=[1,1];for(let r=1;rnew $(a)),e.length===2)[r,n]=e.map(a=>a.lab()),t=function(a){const s=[0,1,2].map(c=>r[c]+a*(n[c]-r[c]));return new $(s,"lab")};else if(e.length===3)[r,n,o]=e.map(a=>a.lab()),t=function(a){const s=[0,1,2].map(c=>(1-a)*(1-a)*r[c]+2*(1-a)*a*n[c]+a*a*o[c]);return new $(s,"lab")};else if(e.length===4){let a;[r,n,o,a]=e.map(s=>s.lab()),t=function(s){const c=[0,1,2].map(i=>(1-s)*(1-s)*(1-s)*r[i]+3*(1-s)*(1-s)*s*n[i]+3*(1-s)*s*s*o[i]+s*s*s*a[i]);return new $(c,"lab")}}else if(e.length>=5){let a,s,c;a=e.map(i=>i.lab()),c=e.length-1,s=xf(c),t=function(i){const u=1-i,f=[0,1,2].map(l=>a.reduce((h,d,p)=>h+s[p]*u**(c-p)*i**p*d[l],0));return new $(f,"lab")}}else throw new RangeError("No point in running bezier with only one color.");return t},Hf=e=>{const t=Rf(e);return t.scale=()=>jt(t),t},{round:Fa}=Math;$.prototype.rgb=function(e=!0){return e===!1?this._rgb.slice(0,3):this._rgb.slice(0,3).map(Fa)},$.prototype.rgba=function(e=!0){return this._rgb.slice(0,4).map((t,r)=>r<3?e===!1?t:Fa(t):t)},Object.assign(B,{rgb:(...e)=>new $(...e,"rgb")}),E.format.rgb=(...e)=>{const t=T(e,"rgba");return t[3]===void 0&&(t[3]=1),t},E.autodetect.push({p:3,test:(...e)=>{if(e=T(e,"rgba"),j(e)==="array"&&(e.length===3||e.length===4&&j(e[3])=="number"&&e[3]>=0&&e[3]<=1))return"rgb"}});const pe=(e,t,r)=>{if(!pe[r])throw new Error("unknown blend mode "+r);return pe[r](e,t)},Te=e=>(t,r)=>{const n=B(r).rgb(),o=B(t).rgb();return B.rgb(e(n,o))},Se=e=>(t,r)=>{const n=[];return n[0]=e(t[0],r[0]),n[1]=e(t[1],r[1]),n[2]=e(t[2],r[2]),n},qf=e=>e,Mf=(e,t)=>e*t/255,Of=(e,t)=>e>t?t:e,Nf=(e,t)=>e>t?e:t,Af=(e,t)=>255*(1-(1-e/255)*(1-t/255)),Lf=(e,t)=>t<128?2*e*t/255:255*(1-2*(1-e/255)*(1-t/255)),Ef=(e,t)=>255*(1-(1-t/255)/(e/255)),Tf=(e,t)=>e===255?255:(e=255*(t/255)/(1-e/255),e>255?255:e);pe.normal=Te(Se(qf)),pe.multiply=Te(Se(Mf)),pe.screen=Te(Se(Af)),pe.overlay=Te(Se(Lf)),pe.darken=Te(Se(Of)),pe.lighten=Te(Se(Nf)),pe.dodge=Te(Se(Tf)),pe.burn=Te(Se(Ef));const{pow:Sf,sin:Pf,cos:jf}=Math;function Bf(e=300,t=-1.5,r=1,n=1,o=[0,1]){let a=0,s;j(o)==="array"?s=o[1]-o[0]:(s=0,o=[o,o]);const c=function(i){const u=Ce*((e+120)/360+t*i),f=Sf(o[0]+s*i,n),h=(a!==0?r[0]+i*a:r)*f*(1-f)/2,d=jf(u),p=Pf(u),v=f+h*(-.14861*d+1.78277*p),m=f+h*(-.29227*d-.90649*p),g=f+h*(1.97294*d);return B(En([v*255,m*255,g*255,1]))};return c.start=function(i){return i==null?e:(e=i,c)},c.rotations=function(i){return i==null?t:(t=i,c)},c.gamma=function(i){return i==null?n:(n=i,c)},c.hue=function(i){return i==null?r:(r=i,j(r)==="array"?(a=r[1]-r[0],a===0&&(r=r[1])):a=0,c)},c.lightness=function(i){return i==null?o:(j(i)==="array"?(o=i,s=i[1]-i[0]):(o=[i,i],s=0),c)},c.scale=()=>B.scale(c),c.hue(r),c}const Gf="0123456789abcdef",{floor:If,random:zf}=Math,Ff=()=>{let e="#";for(let t=0;t<6;t++)e+=Gf.charAt(If(zf()*16));return new $(e,"hex")},{log:Xa,pow:Xf,floor:Kf,abs:Df}=Math;function Ka(e,t=null){const r={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0};return j(e)==="object"&&(e=Object.values(e)),e.forEach(n=>{t&&j(n)==="object"&&(n=n[t]),n!=null&&!isNaN(n)&&(r.values.push(n),r.sum+=n,nr.max&&(r.max=n),r.count+=1)}),r.domain=[r.min,r.max],r.limits=(n,o)=>Da(r,n,o),r}function Da(e,t="equal",r=7){j(e)=="array"&&(e=Ka(e));const{min:n,max:o}=e,a=e.values.sort((c,i)=>c-i);if(r===1)return[n,o];const s=[];if(t.substr(0,1)==="c"&&(s.push(n),s.push(o)),t.substr(0,1)==="e"){s.push(n);for(let c=1;c 0");const c=Math.LOG10E*Xa(n),i=Math.LOG10E*Xa(o);s.push(n);for(let u=1;u200&&(l=!1)}const p={};for(let m=0;mm-g),s.push(v[0]);for(let m=1;m{e=new $(e),t=new $(t);const r=e.luminance(),n=t.luminance();return r>n?(r+.05)/(n+.05):(n+.05)/(r+.05)};/** - * @license - * - * The APCA contrast prediction algorithm is based of the formulas published - * in the APCA-1.0.98G specification by Myndex. The specification is available at: - * https://raw.githubusercontent.com/Myndex/apca-w3/master/images/APCAw3_0.1.17_APCA0.0.98G.svg - * - * Note that the APCA implementation is still beta, so please update to - * future versions of chroma.js when they become available. - * - * You can read more about the APCA Readability Criterion at - * https://readtech.org/ARC/ - */const Va=.027,Yf=5e-4,Zf=.1,Ya=1.14,Bt=.022,Za=1.414,Jf=(e,t)=>{e=new $(e),t=new $(t),e.alpha()<1&&(e=Ue(t,e,e.alpha(),"rgb"));const r=Ja(...e.rgb()),n=Ja(...t.rgb()),o=r>=Bt?r:r+Math.pow(Bt-r,Za),a=n>=Bt?n:n+Math.pow(Bt-n,Za),s=Math.pow(a,.56)-Math.pow(o,.57),c=Math.pow(a,.65)-Math.pow(o,.62),i=Math.abs(a-o)0?i-Va:i+Va)*100};function Ja(e,t,r){return .2126729*Math.pow(e/255,2.4)+.7151522*Math.pow(t/255,2.4)+.072175*Math.pow(r/255,2.4)}const{sqrt:Re,pow:Z,min:Wf,max:Uf,atan2:Wa,abs:Ua,cos:Gt,sin:Qa,exp:Qf,PI:ec}=Math;function el(e,t,r=1,n=1,o=1){var a=function(le){return 360*le/(2*ec)},s=function(le){return 2*ec*le/360};e=new $(e),t=new $(t);const[c,i,u]=Array.from(e.lab()),[f,l,h]=Array.from(t.lab()),d=(c+f)/2,p=Re(Z(i,2)+Z(u,2)),v=Re(Z(l,2)+Z(h,2)),m=(p+v)/2,g=.5*(1-Re(Z(m,7)/(Z(m,7)+Z(25,7)))),R=i*(1+g),x=l*(1+g),M=Re(Z(R,2)+Z(u,2)),N=Re(Z(x,2)+Z(h,2)),w=(M+N)/2,b=a(Wa(u,R)),_=a(Wa(h,x)),k=b>=0?b:b+360,y=_>=0?_:_+360,q=Ua(k-y)>180?(k+y+360)/2:(k+y)/2,H=1-.17*Gt(s(q-30))+.24*Gt(s(2*q))+.32*Gt(s(3*q+6))-.2*Gt(s(4*q-63));let A=y-k;A=Ua(A)<=180?A:y<=k?A+360:A-360,A=2*Re(M*N)*Qa(s(A)/2);const I=f-c,K=N-M,D=1+.015*Z(d-50,2)/Re(20+Z(d-50,2)),U=1+.045*w,ge=1+.015*w*H,ye=30*Qf(-Z((q-275)/25,2)),fe=-(2*Re(Z(w,7)/(Z(w,7)+Z(25,7))))*Qa(2*s(ye)),qe=Re(Z(I/(r*D),2)+Z(K/(n*U),2)+Z(A/(o*ge),2)+fe*(K/(n*U))*(A/(o*ge)));return Uf(0,Wf(100,qe))}function tl(e,t,r="lab"){e=new $(e),t=new $(t);const n=e.get(r),o=t.get(r);let a=0;for(let s in n){const c=(n[s]||0)-(o[s]||0);a+=c*c}return Math.sqrt(a)}const rl=(...e)=>{try{return new $(...e),!0}catch{return!1}},nl={cool(){return jt([B.hsl(180,1,.9),B.hsl(250,.7,.4)])},hot(){return jt(["#000","#f00","#ff0","#fff"]).mode("rgb")}},Wn={OrRd:["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"],PuBu:["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"],BuPu:["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"],Oranges:["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"],BuGn:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"],YlOrBr:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"],YlGn:["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],Reds:["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"],RdPu:["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"],Greens:["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"],YlGnBu:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],Purples:["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"],GnBu:["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],Greys:["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"],YlOrRd:["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"],PuRd:["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"],Blues:["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"],PuBuGn:["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"],Viridis:["#440154","#482777","#3f4a8a","#31678e","#26838f","#1f9d8a","#6cce5a","#b6de2b","#fee825"],Spectral:["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],RdYlGn:["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],RdBu:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],PiYG:["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],PRGn:["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],RdYlBu:["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],BrBG:["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],RdGy:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],PuOr:["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],Set2:["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],Accent:["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],Set1:["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],Set3:["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],Dark2:["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],Paired:["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],Pastel2:["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],Pastel1:["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]},tc=Object.keys(Wn),rc=new Map(tc.map(e=>[e.toLowerCase(),e])),ol=typeof Proxy=="function"?new Proxy(Wn,{get(e,t){const r=t.toLowerCase();if(rc.has(r))return e[rc.get(r)]},getOwnPropertyNames(){return Object.getOwnPropertyNames(tc)}}):Wn,sl=(...e)=>{e=T(e,"cmyk");const[t,r,n,o]=e,a=e.length>4?e[4]:1;return o===1?[0,0,0,a]:[t>=1?0:255*(1-t)*(1-o),r>=1?0:255*(1-r)*(1-o),n>=1?0:255*(1-n)*(1-o),a]},{max:nc}=Math,al=(...e)=>{let[t,r,n]=T(e,"rgb");t=t/255,r=r/255,n=n/255;const o=1-nc(t,nc(r,n)),a=o<1?1/(1-o):0,s=(1-t-o)*a,c=(1-r-o)*a,i=(1-n-o)*a;return[s,c,i,o]};$.prototype.cmyk=function(){return al(this._rgb)},Object.assign(B,{cmyk:(...e)=>new $(...e,"cmyk")}),E.format.cmyk=sl,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"cmyk"),j(e)==="array"&&e.length===4)return"cmyk"}});const cl=(...e)=>{const t=T(e,"hsla");let r=Je(e)||"lsa";return t[0]=ie(t[0]||0)+"deg",t[1]=ie(t[1]*100)+"%",t[2]=ie(t[2]*100)+"%",r==="hsla"||t.length>3&&t[3]<1?(t[3]="/ "+(t.length>3?t[3]:1),r="hsla"):t.length=3,`${r.substr(0,3)}(${t.join(" ")})`},il=(...e)=>{const t=T(e,"lab");let r=Je(e)||"lab";return t[0]=ie(t[0])+"%",t[1]=ie(t[1]),t[2]=ie(t[2]),r==="laba"||t.length>3&&t[3]<1?t[3]="/ "+(t.length>3?t[3]:1):t.length=3,`lab(${t.join(" ")})`},ul=(...e)=>{const t=T(e,"lch");let r=Je(e)||"lab";return t[0]=ie(t[0])+"%",t[1]=ie(t[1]),t[2]=isNaN(t[2])?"none":ie(t[2])+"deg",r==="lcha"||t.length>3&&t[3]<1?t[3]="/ "+(t.length>3?t[3]:1):t.length=3,`lch(${t.join(" ")})`},fl=(...e)=>{const t=T(e,"lab");return t[0]=ie(t[0]*100)+"%",t[1]=Tn(t[1]),t[2]=Tn(t[2]),t.length>3&&t[3]<1?t[3]="/ "+(t.length>3?t[3]:1):t.length=3,`oklab(${t.join(" ")})`},oc=(...e)=>{const[t,r,n,...o]=T(e,"rgb"),[a,s,c]=Vn(t,r,n),[i,u,f]=ja(a,s,c);return[i,u,f,...o.length>0&&o[0]<1?[o[0]]:[]]},ll=(...e)=>{const t=T(e,"lch");return t[0]=ie(t[0]*100)+"%",t[1]=Tn(t[1]),t[2]=isNaN(t[2])?"none":ie(t[2])+"deg",t.length>3&&t[3]<1?t[3]="/ "+(t.length>3?t[3]:1):t.length=3,`oklch(${t.join(" ")})`},{round:Un}=Math,hl=(...e)=>{const t=T(e,"rgba");let r=Je(e)||"rgb";if(r.substr(0,3)==="hsl")return cl(Ga(t),r);if(r.substr(0,3)==="lab"){const n=dt();xe("d50");const o=il(Bn(t),r);return xe(n),o}if(r.substr(0,3)==="lch"){const n=dt();xe("d50");const o=ul(Fn(t),r);return xe(n),o}return r.substr(0,5)==="oklab"?fl(Vn(t)):r.substr(0,5)==="oklch"?ll(oc(t)):(t[0]=Un(t[0]),t[1]=Un(t[1]),t[2]=Un(t[2]),(r==="rgba"||t.length>3&&t[3]<1)&&(t[3]="/ "+(t.length>3?t[3]:1),r="rgba"),`${r.substr(0,3)}(${t.slice(0,r==="rgb"?3:4).join(" ")})`)},sc=(...e)=>{e=T(e,"lch");const[t,r,n,...o]=e,[a,s,c]=Pa(t,r,n),[i,u,f]=Dn(a,s,c);return[i,u,f,...o.length>0&&o[0]<1?[o[0]]:[]]},He=/((?:-?\d+)|(?:-?\d+(?:\.\d+)?)%|none)/.source,me=/((?:-?(?:\d+(?:\.\d*)?|\.\d+)%?)|none)/.source,It=/((?:-?(?:\d+(?:\.\d*)?|\.\d+)%)|none)/.source,ue=/\s*/.source,rt=/\s+/.source,Qn=/\s*,\s*/.source,zt=/((?:-?(?:\d+(?:\.\d*)?|\.\d+)(?:deg)?)|none)/.source,nt=/\s*(?:\/\s*((?:[01]|[01]?\.\d+)|\d+(?:\.\d+)?%))?/.source,ac=new RegExp("^rgba?\\("+ue+[He,He,He].join(rt)+nt+"\\)$"),cc=new RegExp("^rgb\\("+ue+[He,He,He].join(Qn)+ue+"\\)$"),ic=new RegExp("^rgba\\("+ue+[He,He,He,me].join(Qn)+ue+"\\)$"),uc=new RegExp("^hsla?\\("+ue+[zt,It,It].join(rt)+nt+"\\)$"),fc=new RegExp("^hsl?\\("+ue+[zt,It,It].join(Qn)+ue+"\\)$"),lc=/^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/,hc=new RegExp("^lab\\("+ue+[me,me,me].join(rt)+nt+"\\)$"),dc=new RegExp("^lch\\("+ue+[me,me,zt].join(rt)+nt+"\\)$"),bc=new RegExp("^oklab\\("+ue+[me,me,me].join(rt)+nt+"\\)$"),pc=new RegExp("^oklch\\("+ue+[me,me,zt].join(rt)+nt+"\\)$"),{round:mc}=Math,ot=e=>e.map((t,r)=>r<=2?Be(mc(t),0,255):t),J=(e,t=0,r=100,n=!1)=>(typeof e=="string"&&e.endsWith("%")&&(e=parseFloat(e.substring(0,e.length-1))/100,n?e=t+(e+1)*.5*(r-t):e=t+e*(r-t)),+e),oe=(e,t)=>e==="none"?t:e,eo=e=>{if(e=e.toLowerCase().trim(),e==="transparent")return[0,0,0,0];let t;if(E.format.named)try{return E.format.named(e)}catch{}if((t=e.match(ac))||(t=e.match(cc))){let r=t.slice(1,4);for(let o=0;o<3;o++)r[o]=+J(oe(r[o],0),0,255);r=ot(r);const n=t[4]!==void 0?+J(t[4],0,1):1;return r[3]=n,r}if(t=e.match(ic)){const r=t.slice(1,5);for(let n=0;n<4;n++)r[n]=+J(r[n],0,255);return r}if((t=e.match(uc))||(t=e.match(fc))){const r=t.slice(1,4);r[0]=+oe(r[0].replace("deg",""),0),r[1]=+J(oe(r[1],0),0,100)*.01,r[2]=+J(oe(r[2],0),0,100)*.01;const n=ot(Kn(r)),o=t[4]!==void 0?+J(t[4],0,1):1;return n[3]=o,n}if(t=e.match(lc)){const r=t.slice(1,4);r[1]*=.01,r[2]*=.01;const n=Kn(r);for(let o=0;o<3;o++)n[o]=mc(n[o]);return n[3]=+t[4],n}if(t=e.match(hc)){const r=t.slice(1,4);r[0]=J(oe(r[0],0),0,100),r[1]=J(oe(r[1],0),-125,125,!0),r[2]=J(oe(r[2],0),-125,125,!0);const n=dt();xe("d50");const o=ot(Pn(r));xe(n);const a=t[4]!==void 0?+J(t[4],0,1):1;return o[3]=a,o}if(t=e.match(dc)){const r=t.slice(1,4);r[0]=J(r[0],0,100),r[1]=J(oe(r[1],0),0,150,!1),r[2]=+oe(r[2].replace("deg",""),0);const n=dt();xe("d50");const o=ot(zn(r));xe(n);const a=t[4]!==void 0?+J(t[4],0,1):1;return o[3]=a,o}if(t=e.match(bc)){const r=t.slice(1,4);r[0]=J(oe(r[0],0),0,1),r[1]=J(oe(r[1],0),-.4,.4,!0),r[2]=J(oe(r[2],0),-.4,.4,!0);const n=ot(Dn(r)),o=t[4]!==void 0?+J(t[4],0,1):1;return n[3]=o,n}if(t=e.match(pc)){const r=t.slice(1,4);r[0]=J(oe(r[0],0),0,1),r[1]=J(oe(r[1],0),0,.4,!1),r[2]=+oe(r[2].replace("deg",""),0);const n=ot(sc(r)),o=t[4]!==void 0?+J(t[4],0,1):1;return n[3]=o,n}};eo.test=e=>ac.test(e)||uc.test(e)||hc.test(e)||dc.test(e)||bc.test(e)||pc.test(e)||cc.test(e)||ic.test(e)||fc.test(e)||lc.test(e)||e==="transparent",$.prototype.css=function(e){return hl(this._rgb,e)};const dl=(...e)=>new $(...e,"css");B.css=dl,E.format.css=eo,E.autodetect.push({p:5,test:(e,...t)=>{if(!t.length&&j(e)==="string"&&eo.test(e))return"css"}}),E.format.gl=(...e)=>{const t=T(e,"rgba");return t[0]*=255,t[1]*=255,t[2]*=255,t};const bl=(...e)=>new $(...e,"gl");B.gl=bl,$.prototype.gl=function(){const e=this._rgb;return[e[0]/255,e[1]/255,e[2]/255,e[3]]},$.prototype.hex=function(e){return Ea(this._rgb,e)};const pl=(...e)=>new $(...e,"hex");B.hex=pl,E.format.hex=La,E.autodetect.push({p:4,test:(e,...t)=>{if(!t.length&&j(e)==="string"&&[3,4,5,6,7,8,9].indexOf(e.length)>=0)return"hex"}});const{log:Ft}=Math,gc=e=>{const t=e/100;let r,n,o;return t<66?(r=255,n=t<6?0:-155.25485562709179-.44596950469579133*(n=t-2)+104.49216199393888*Ft(n),o=t<20?0:-254.76935184120902+.8274096064007395*(o=t-10)+115.67994401066147*Ft(o)):(r=351.97690566805693+.114206453784165*(r=t-55)-40.25366309332127*Ft(r),n=325.4494125711974+.07943456536662342*(n=t-50)-28.0852963507957*Ft(n),o=255),[r,n,o,1]},{round:ml}=Math,gl=(...e)=>{const t=T(e,"rgb"),r=t[0],n=t[2];let o=1e3,a=4e4;const s=.4;let c;for(;a-o>s;){c=(a+o)*.5;const i=gc(c);i[2]/i[0]>=n/r?a=c:o=c}return ml(c)};$.prototype.temp=$.prototype.kelvin=$.prototype.temperature=function(){return gl(this._rgb)};const to=(...e)=>new $(...e,"temp");Object.assign(B,{temp:to,kelvin:to,temperature:to}),E.format.temp=E.format.kelvin=E.format.temperature=gc,$.prototype.oklch=function(){return oc(this._rgb)},Object.assign(B,{oklch:(...e)=>new $(...e,"oklch")}),E.format.oklch=sc,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"oklch"),j(e)==="array"&&e.length===3)return"oklch"}}),Object.assign(B,{analyze:Ka,average:wf,bezier:Hf,blend:pe,brewer:ol,Color:$,colors:We,contrast:Vf,contrastAPCA:Jf,cubehelix:Bf,deltaE:el,distance:tl,input:E,interpolate:Ue,limits:Da,mix:Ue,random:Ff,scale:jt,scales:nl,valid:rl});function vl(e){return+`${Math.ceil(`${e}e+2`)}e-2`}const vc=e=>{const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return[Number.parseInt(t[1],16),Number.parseInt(t[2],16),Number.parseInt(t[3],16)]},_c=(e,t,r)=>{const n=e/255,o=t/255,a=r/255,s=Math.min(n,o,a),c=Math.max(n,o,a),i=c-s;let u=0,f=0,l=0;return i===0?u=0:c===n?u=(o-a)/i%6:c===o?u=(a-n)/i+2:u=(n-o)/i+4,u=Math.round(u*60),u<0&&(u+=360),l=(c+s)/2,f=i===0?0:i/(1-Math.abs(2*l-1)),f=+(f*100).toFixed(1),l=+(l*100).toFixed(1),[u,f,Math.round(l)]},_l=(e,t,r,n)=>{const o=r/100,a=t*Math.min(o,1-o)/100,s=d=>{const p=(d+e/30)%12,v=o-a*Math.max(Math.min(p-3,9-p,1),-1);return Math.round(255*v).toString(16).padStart(2,"0").toUpperCase()},c=s(0),i=s(8),u=s(4),l=((d,p,v)=>Math.min(Math.max(d,p),v))(n,0,1),h=Math.round(l*255).toString(16).padStart(2,"0").toUpperCase();return`#${c}${i}${u}${h}`},yl=(e,t,r=1)=>{const n=vc(e),o=vc(t==="white"?"#FFFFFF":t==="black"?"#000000":t),a=n.map((u,f)=>[(u-o[f])/(255-o[f]),(u-o[f])/(0-o[f])]),s=vl(Math.max(...a.flat().filter(u=>/^-?\d+\.?\d*$/.test(u)))),c=n.map((u,f)=>Math.round((u-o[f]+o[f]*s)/s));if(c.includes(Number.NaN)){const u=_c(n[0],n[1],n[2]);return{h:u[0],s:Math.round(u[1]*r),l:u[2],a:1}}const i=_c(c[0],c[1],c[2]);return{h:i[0],s:Math.round(i[1]*r),l:i[2],a:s}},ro={backgroundColor:"gray",colorSpace:"OKLCH",colorSmoothing:!1,formula:"wcag2",output:"HEX",colors:{gray:[X(215,20,90),X(215,8,50),X(215,6,25)],red:[X(358,100,58),X(350,100,30)],orange:[X(32,100,48),X(12,100,30)],yellow:[X(50,100,50),X(25,100,20)],lime:[X(100,68,50),X(115,86,25)],green:[X(163,87,42),X(168,100,25)],cyan:[X(185,80,45),X(200,98,35)],blue:[X(212,98,46),X(222,95,25)],purple:[X(258,94,64),X(265,100,35)],fuchsia:[X(295,56,50),X(285,80,25)],pink:[X(334,90,50),X(330,91,25)]},themes:{light:{ratios:[1.03,1.06,1.12,1.25,1.5,1.75,2.25,3.5,5.25,6.5,8,10.5,13.75,16.75],contrast:1,lightness:100,saturation:100},dark:{ratios:[1.03,1.06,1.12,1.25,1.5,1.75,2.25,3.5,5.25,6.5,8,10.5,13.75,16],contrast:1,lightness:6,saturation:97},lightHc:{ratios:[1.06,1.12,1.25,1.37,1.75,2.25,3.25,4.75,8.87,10,11.75,13.25,16,17],contrast:1,lightness:100,saturation:100},darkHc:{ratios:[1.06,1.12,1.25,1.37,1.75,2.25,3.25,4.75,8.87,10,11.75,13.25,16,17],contrast:1,lightness:6,saturation:97}}};function X(e,t,r){return B.hsl(e,t/100,r/100).hex()}function wl(e,t){const r=e.colorSpace,n=e.colorSmoothing,o=e.themes[t].ratios,a=new qa({name:"gray",colorKeys:e.colors.gray,colorspace:r,ratios:o,smooth:n}),s=new ae({name:"blue",colorKeys:e.colors.blue,colorspace:r,ratios:o,smooth:n}),c=new ae({name:"cyan",colorKeys:e.colors.cyan,colorspace:r,ratios:o,smooth:n}),i=new ae({name:"fuchsia",colorKeys:e.colors.fuchsia,colorspace:r,ratios:o,smooth:n}),u=new ae({name:"green",colorKeys:e.colors.green,colorspace:r,ratios:o,smooth:n}),f=new ae({name:"lime",colorKeys:e.colors.lime,colorspace:r,ratios:o,smooth:n}),l=new ae({name:"orange",colorKeys:e.colors.orange,colorspace:r,ratios:o,smooth:n}),h=new ae({name:"pink",colorKeys:e.colors.pink,colorspace:r,ratios:o,smooth:n}),d=new ae({name:"purple",colorKeys:e.colors.purple,colorspace:r,ratios:o,smooth:n}),p=new ae({name:"red",colorKeys:e.colors.red,colorspace:r,ratios:o,smooth:n}),v=new ae({name:"yellow",colorKeys:e.colors.yellow,colorspace:r,ratios:o,smooth:n}),m={gray:a,red:p,orange:l,yellow:v,lime:f,green:u,cyan:c,blue:s,purple:d,fuchsia:i,pink:h};return e.colors.custom&&(m.custom=new ae({name:"custom",colorKeys:e.colors.custom,colorspace:r,ratios:o,smooth:n})),new wu({colors:Object.values(m),backgroundColor:m[e.backgroundColor],contrast:e.themes[t].contrast,lightness:e.themes[t].lightness,saturation:e.themes[t].saturation,output:e.output,formula:e.formula}).contrastColors}function yc(e){const t={};for(const r of Object.keys(e.themes))t[r]=wl(e,r);return t}function kl(e){ro.colors.custom=[e];const t=yc(ro);return Object.fromEntries(Object.entries(t).map(([r,n])=>{const o=n.find(s=>s&&s.name==="custom"),a=Object.fromEntries(o.values.map(({name:s,value:c})=>[s,c]));for(const[s,c]of Object.entries(a)){const i=yl(c,n[0].background);a[`alpha${s.charAt(0).toUpperCase()+s.slice(1)}`]=_l(i.h,i.s,i.l,i.a)}return[r,a]}))}return Fe.generateCustomColors=kl,Fe.generateThemesJson=yc,Fe.hslToHex=X,Fe.leonardoConfig=ro,Object.defineProperty(Fe,Symbol.toStringTag,{value:"Module"}),Fe})({}); +var CompoundTheme=(function(Fe){"use strict";const Xe=(e,t=0,r=1)=>Zt(Jt(t,e),r),Yt=e=>{e._clipped=!1,e._unclipped=e.slice(0);for(let t=0;t<=3;t++)t<3?((e[t]<0||e[t]>255)&&(e._clipped=!0),e[t]=Xe(e[t],0,255)):t===3&&(e[t]=Xe(e[t],0,1));return e},co={};for(let e of["Boolean","Number","String","Function","Array","Date","RegExp","Undefined","Null"])co[`[object ${e}]`]=e.toLowerCase();function P(e){return co[Object.prototype.toString.call(e)]||"object"}const j=(e,t=null)=>e.length>=3?Array.prototype.slice.call(e):P(e[0])=="object"&&t?t.split("").filter(r=>e[0][r]!==void 0).map(r=>e[0][r]):e[0],pt=e=>{if(e.length<2)return null;const t=e.length-1;return P(e[t])=="string"?e[t].toLowerCase():null},{PI:mt,min:Zt,max:Jt}=Math,we=mt*2,Wt=mt/3,Ac=mt/180,Lc=180/mt,L={format:{},autodetect:[]};let $=class{constructor(...t){const r=this;if(P(t[0])==="object"&&t[0].constructor&&t[0].constructor===this.constructor)return t[0];let n=pt(t),o=!1;if(!n){o=!0,L.sorted||(L.autodetect=L.autodetect.sort((a,s)=>s.p-a.p),L.sorted=!0);for(let a of L.autodetect)if(n=a.test(...t),n)break}if(L.format[n]){const a=L.format[n].apply(null,o?t:t.slice(0,-1));r._rgb=Yt(a)}else throw new Error("unknown format: "+t);r._rgb.length===3&&r._rgb.push(1)}toString(){return P(this.hex)=="function"?this.hex():`[${this._rgb.join(",")}]`}};const Ec="2.6.0",O=(...e)=>new O.Color(...e);O.Color=$,O.version=Ec;const Tc=(...e)=>{e=j(e,"cmyk");const[t,r,n,o]=e,a=e.length>4?e[4]:1;return o===1?[0,0,0,a]:[t>=1?0:255*(1-t)*(1-o),r>=1?0:255*(1-r)*(1-o),n>=1?0:255*(1-n)*(1-o),a]},{max:io}=Math,Sc=(...e)=>{let[t,r,n]=j(e,"rgb");t=t/255,r=r/255,n=n/255;const o=1-io(t,io(r,n)),a=o<1?1/(1-o):0,s=(1-t-o)*a,c=(1-r-o)*a,i=(1-n-o)*a;return[s,c,i,o]};$.prototype.cmyk=function(){return Sc(this._rgb)},O.cmyk=(...e)=>new $(...e,"cmyk"),L.format.cmyk=Tc,L.autodetect.push({p:2,test:(...e)=>{if(e=j(e,"cmyk"),P(e)==="array"&&e.length===4)return"cmyk"}});const Ut=e=>Math.round(e*100)/100,Pc=(...e)=>{const t=j(e,"hsla");let r=pt(e)||"lsa";return t[0]=Ut(t[0]||0),t[1]=Ut(t[1]*100)+"%",t[2]=Ut(t[2]*100)+"%",r==="hsla"||t.length>3&&t[3]<1?(t[3]=t.length>3?t[3]:1,r="hsla"):t.length=3,`${r}(${t.join(",")})`},uo=(...e)=>{e=j(e,"rgba");let[t,r,n]=e;t/=255,r/=255,n/=255;const o=Zt(t,r,n),a=Jt(t,r,n),s=(a+o)/2;let c,i;return a===o?(c=0,i=Number.NaN):c=s<.5?(a-o)/(a+o):(a-o)/(2-a-o),t==a?i=(r-n)/(a-o):r==a?i=2+(n-t)/(a-o):n==a&&(i=4+(t-r)/(a-o)),i*=60,i<0&&(i+=360),e.length>3&&e[3]!==void 0?[i,c,s,e[3]]:[i,c,s]},{round:Qt}=Math,jc=(...e)=>{const t=j(e,"rgba");let r=pt(e)||"rgb";return r.substr(0,3)=="hsl"?Pc(uo(t),r):(t[0]=Qt(t[0]),t[1]=Qt(t[1]),t[2]=Qt(t[2]),(r==="rgba"||t.length>3&&t[3]<1)&&(t[3]=t.length>3?t[3]:1,r="rgba"),`${r}(${t.slice(0,r==="rgb"?3:4).join(",")})`)},{round:er}=Math,tr=(...e)=>{e=j(e,"hsl");const[t,r,n]=e;let o,a,s;if(r===0)o=a=s=n*255;else{const c=[0,0,0],i=[0,0,0],u=n<.5?n*(1+r):n+r-n*r,l=2*n-u,f=t/360;c[0]=f+1/3,c[1]=f,c[2]=f-1/3;for(let h=0;h<3;h++)c[h]<0&&(c[h]+=1),c[h]>1&&(c[h]-=1),6*c[h]<1?i[h]=l+(u-l)*6*c[h]:2*c[h]<1?i[h]=u:3*c[h]<2?i[h]=l+(u-l)*(2/3-c[h])*6:i[h]=l;[o,a,s]=[er(i[0]*255),er(i[1]*255),er(i[2]*255)]}return e.length>3?[o,a,s,e[3]]:[o,a,s,1]},fo=/^rgb\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*\)$/,lo=/^rgba\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*,\s*([01]|[01]?\.\d+)\)$/,ho=/^rgb\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/,bo=/^rgba\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/,po=/^hsl\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/,mo=/^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/,{round:go}=Math,rr=e=>{e=e.toLowerCase().trim();let t;if(L.format.named)try{return L.format.named(e)}catch{}if(t=e.match(fo)){const r=t.slice(1,4);for(let n=0;n<3;n++)r[n]=+r[n];return r[3]=1,r}if(t=e.match(lo)){const r=t.slice(1,5);for(let n=0;n<4;n++)r[n]=+r[n];return r}if(t=e.match(ho)){const r=t.slice(1,4);for(let n=0;n<3;n++)r[n]=go(r[n]*2.55);return r[3]=1,r}if(t=e.match(bo)){const r=t.slice(1,5);for(let n=0;n<3;n++)r[n]=go(r[n]*2.55);return r[3]=+r[3],r}if(t=e.match(po)){const r=t.slice(1,4);r[1]*=.01,r[2]*=.01;const n=tr(r);return n[3]=1,n}if(t=e.match(mo)){const r=t.slice(1,4);r[1]*=.01,r[2]*=.01;const n=tr(r);return n[3]=+t[4],n}};rr.test=e=>fo.test(e)||lo.test(e)||ho.test(e)||bo.test(e)||po.test(e)||mo.test(e),$.prototype.css=function(e){return jc(this._rgb,e)},O.css=(...e)=>new $(...e,"css"),L.format.css=rr,L.autodetect.push({p:5,test:(e,...t)=>{if(!t.length&&P(e)==="string"&&rr.test(e))return"css"}}),L.format.gl=(...e)=>{const t=j(e,"rgba");return t[0]*=255,t[1]*=255,t[2]*=255,t},O.gl=(...e)=>new $(...e,"gl"),$.prototype.gl=function(){const e=this._rgb;return[e[0]/255,e[1]/255,e[2]/255,e[3]]};const{floor:Bc}=Math,Gc=(...e)=>{e=j(e,"hcg");let[t,r,n]=e,o,a,s;n=n*255;const c=r*255;if(r===0)o=a=s=n;else{t===360&&(t=0),t>360&&(t-=360),t<0&&(t+=360),t/=60;const i=Bc(t),u=t-i,l=n*(1-r),f=l+c*(1-u),h=l+c*u,d=l+c;switch(i){case 0:[o,a,s]=[d,h,l];break;case 1:[o,a,s]=[f,d,l];break;case 2:[o,a,s]=[l,d,h];break;case 3:[o,a,s]=[l,f,d];break;case 4:[o,a,s]=[h,l,d];break;case 5:[o,a,s]=[d,l,f];break}}return[o,a,s,e.length>3?e[3]:1]},Ic=(...e)=>{const[t,r,n]=j(e,"rgb"),o=Zt(t,r,n),a=Jt(t,r,n),s=a-o,c=s*100/255,i=o/(255-s)*100;let u;return s===0?u=Number.NaN:(t===a&&(u=(r-n)/s),r===a&&(u=2+(n-t)/s),n===a&&(u=4+(t-r)/s),u*=60,u<0&&(u+=360)),[u,c,i]};$.prototype.hcg=function(){return Ic(this._rgb)},O.hcg=(...e)=>new $(...e,"hcg"),L.format.hcg=Gc,L.autodetect.push({p:1,test:(...e)=>{if(e=j(e,"hcg"),P(e)==="array"&&e.length===3)return"hcg"}});const zc=/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,Fc=/^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/,vo=e=>{if(e.match(zc)){(e.length===4||e.length===7)&&(e=e.substr(1)),e.length===3&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]);const t=parseInt(e,16),r=t>>16,n=t>>8&255,o=t&255;return[r,n,o,1]}if(e.match(Fc)){(e.length===5||e.length===9)&&(e=e.substr(1)),e.length===4&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]+e[3]+e[3]);const t=parseInt(e,16),r=t>>24&255,n=t>>16&255,o=t>>8&255,a=Math.round((t&255)/255*100)/100;return[r,n,o,a]}throw new Error(`unknown hex color: ${e}`)},{round:gt}=Math,_o=(...e)=>{let[t,r,n,o]=j(e,"rgba"),a=pt(e)||"auto";o===void 0&&(o=1),a==="auto"&&(a=o<1?"rgba":"rgb"),t=gt(t),r=gt(r),n=gt(n);let c="000000"+(t<<16|r<<8|n).toString(16);c=c.substr(c.length-6);let i="0"+gt(o*255).toString(16);switch(i=i.substr(i.length-2),a.toLowerCase()){case"rgba":return`#${c}${i}`;case"argb":return`#${i}${c}`;default:return`#${c}`}};$.prototype.hex=function(e){return _o(this._rgb,e)},O.hex=(...e)=>new $(...e,"hex"),L.format.hex=vo,L.autodetect.push({p:4,test:(e,...t)=>{if(!t.length&&P(e)==="string"&&[3,4,5,6,7,8,9].indexOf(e.length)>=0)return"hex"}});const{cos:Ke}=Math,Xc=(...e)=>{e=j(e,"hsi");let[t,r,n]=e,o,a,s;return isNaN(t)&&(t=0),isNaN(r)&&(r=0),t>360&&(t-=360),t<0&&(t+=360),t/=360,t<1/3?(s=(1-r)/3,o=(1+r*Ke(we*t)/Ke(Wt-we*t))/3,a=1-(s+o)):t<2/3?(t-=1/3,o=(1-r)/3,a=(1+r*Ke(we*t)/Ke(Wt-we*t))/3,s=1-(o+a)):(t-=2/3,a=(1-r)/3,s=(1+r*Ke(we*t)/Ke(Wt-we*t))/3,o=1-(a+s)),o=Xe(n*o*3),a=Xe(n*a*3),s=Xe(n*s*3),[o*255,a*255,s*255,e.length>3?e[3]:1]},{min:Kc,sqrt:Dc,acos:Vc}=Math,Yc=(...e)=>{let[t,r,n]=j(e,"rgb");t/=255,r/=255,n/=255;let o;const a=Kc(t,r,n),s=(t+r+n)/3,c=s>0?1-a/s:0;return c===0?o=NaN:(o=(t-r+(t-n))/2,o/=Dc((t-r)*(t-r)+(t-n)*(r-n)),o=Vc(o),n>r&&(o=we-o),o/=we),[o*360,c,s]};$.prototype.hsi=function(){return Yc(this._rgb)},O.hsi=(...e)=>new $(...e,"hsi"),L.format.hsi=Xc,L.autodetect.push({p:2,test:(...e)=>{if(e=j(e,"hsi"),P(e)==="array"&&e.length===3)return"hsi"}}),$.prototype.hsl=function(){return uo(this._rgb)},O.hsl=(...e)=>new $(...e,"hsl"),L.format.hsl=tr,L.autodetect.push({p:2,test:(...e)=>{if(e=j(e,"hsl"),P(e)==="array"&&e.length===3)return"hsl"}});const{floor:Zc}=Math,Jc=(...e)=>{e=j(e,"hsv");let[t,r,n]=e,o,a,s;if(n*=255,r===0)o=a=s=n;else{t===360&&(t=0),t>360&&(t-=360),t<0&&(t+=360),t/=60;const c=Zc(t),i=t-c,u=n*(1-r),l=n*(1-r*i),f=n*(1-r*(1-i));switch(c){case 0:[o,a,s]=[n,f,u];break;case 1:[o,a,s]=[l,n,u];break;case 2:[o,a,s]=[u,n,f];break;case 3:[o,a,s]=[u,l,n];break;case 4:[o,a,s]=[f,u,n];break;case 5:[o,a,s]=[n,u,l];break}}return[o,a,s,e.length>3?e[3]:1]},{min:Wc,max:Uc}=Math,Qc=(...e)=>{e=j(e,"rgb");let[t,r,n]=e;const o=Wc(t,r,n),a=Uc(t,r,n),s=a-o;let c,i,u;return u=a/255,a===0?(c=Number.NaN,i=0):(i=s/a,t===a&&(c=(r-n)/s),r===a&&(c=2+(n-t)/s),n===a&&(c=4+(t-r)/s),c*=60,c<0&&(c+=360)),[c,i,u]};$.prototype.hsv=function(){return Qc(this._rgb)},O.hsv=(...e)=>new $(...e,"hsv"),L.format.hsv=Jc,L.autodetect.push({p:2,test:(...e)=>{if(e=j(e,"hsv"),P(e)==="array"&&e.length===3)return"hsv"}});const se={Kn:18,Xn:.95047,Yn:1,Zn:1.08883,t0:.137931034,t1:.206896552,t2:.12841855,t3:.008856452},{pow:e0}=Math,yo=(...e)=>{e=j(e,"lab");const[t,r,n]=e;let o,a,s,c,i,u;return a=(t+16)/116,o=isNaN(r)?a:a+r/500,s=isNaN(n)?a:a-n/200,a=se.Yn*or(a),o=se.Xn*or(o),s=se.Zn*or(s),c=nr(3.2404542*o-1.5371385*a-.4985314*s),i=nr(-.969266*o+1.8760108*a+.041556*s),u=nr(.0556434*o-.2040259*a+1.0572252*s),[c,i,u,e.length>3?e[3]:1]},nr=e=>255*(e<=.00304?12.92*e:1.055*e0(e,1/2.4)-.055),or=e=>e>se.t1?e*e*e:se.t2*(e-se.t0),{pow:wo}=Math,ko=(...e)=>{const[t,r,n]=j(e,"rgb"),[o,a,s]=t0(t,r,n),c=116*a-16;return[c<0?0:c,500*(o-a),200*(a-s)]},sr=e=>(e/=255)<=.04045?e/12.92:wo((e+.055)/1.055,2.4),ar=e=>e>se.t3?wo(e,1/3):e/se.t2+se.t0,t0=(e,t,r)=>{e=sr(e),t=sr(t),r=sr(r);const n=ar((.4124564*e+.3575761*t+.1804375*r)/se.Xn),o=ar((.2126729*e+.7151522*t+.072175*r)/se.Yn),a=ar((.0193339*e+.119192*t+.9503041*r)/se.Zn);return[n,o,a]};$.prototype.lab=function(){return ko(this._rgb)},O.lab=(...e)=>new $(...e,"lab"),L.format.lab=yo,L.autodetect.push({p:2,test:(...e)=>{if(e=j(e,"lab"),P(e)==="array"&&e.length===3)return"lab"}});const{sin:r0,cos:n0}=Math,$o=(...e)=>{let[t,r,n]=j(e,"lch");return isNaN(n)&&(n=0),n=n*Ac,[t,n0(n)*r,r0(n)*r]},Co=(...e)=>{e=j(e,"lch");const[t,r,n]=e,[o,a,s]=$o(t,r,n),[c,i,u]=yo(o,a,s);return[c,i,u,e.length>3?e[3]:1]},o0=(...e)=>{const t=j(e,"hcl").reverse();return Co(...t)},{sqrt:s0,atan2:a0,round:c0}=Math,xo=(...e)=>{const[t,r,n]=j(e,"lab"),o=s0(r*r+n*n);let a=(a0(n,r)*Lc+360)%360;return c0(o*1e4)===0&&(a=Number.NaN),[t,o,a]},Ro=(...e)=>{const[t,r,n]=j(e,"rgb"),[o,a,s]=ko(t,r,n);return xo(o,a,s)};$.prototype.lch=function(){return Ro(this._rgb)},$.prototype.hcl=function(){return Ro(this._rgb).reverse()},O.lch=(...e)=>new $(...e,"lch"),O.hcl=(...e)=>new $(...e,"hcl"),L.format.lch=Co,L.format.hcl=o0,["lch","hcl"].forEach(e=>L.autodetect.push({p:2,test:(...t)=>{if(t=j(t,e),P(t)==="array"&&t.length===3)return e}}));const De={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",laserlemon:"#ffff54",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrod:"#fafad2",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",maroon2:"#7f0000",maroon3:"#b03060",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",purple2:"#7f007f",purple3:"#a020f0",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};$.prototype.name=function(){const e=_o(this._rgb,"rgb");for(let t of Object.keys(De))if(De[t]===e)return t.toLowerCase();return e},L.format.named=e=>{if(e=e.toLowerCase(),De[e])return vo(De[e]);throw new Error("unknown color name: "+e)},L.autodetect.push({p:5,test:(e,...t)=>{if(!t.length&&P(e)==="string"&&De[e.toLowerCase()])return"named"}});const i0=e=>{if(P(e)=="number"&&e>=0&&e<=16777215){const t=e>>16,r=e>>8&255,n=e&255;return[t,r,n,1]}throw new Error("unknown num color: "+e)},u0=(...e)=>{const[t,r,n]=j(e,"rgb");return(t<<16)+(r<<8)+n};$.prototype.num=function(){return u0(this._rgb)},O.num=(...e)=>new $(...e,"num"),L.format.num=i0,L.autodetect.push({p:5,test:(...e)=>{if(e.length===1&&P(e[0])==="number"&&e[0]>=0&&e[0]<=16777215)return"num"}});const{round:Ho}=Math;$.prototype.rgb=function(e=!0){return e===!1?this._rgb.slice(0,3):this._rgb.slice(0,3).map(Ho)},$.prototype.rgba=function(e=!0){return this._rgb.slice(0,4).map((t,r)=>r<3?e===!1?t:Ho(t):t)},O.rgb=(...e)=>new $(...e,"rgb"),L.format.rgb=(...e)=>{const t=j(e,"rgba");return t[3]===void 0&&(t[3]=1),t},L.autodetect.push({p:3,test:(...e)=>{if(e=j(e,"rgba"),P(e)==="array"&&(e.length===3||e.length===4&&P(e[3])=="number"&&e[3]>=0&&e[3]<=1))return"rgb"}});const{log:vt}=Math,qo=e=>{const t=e/100;let r,n,o;return t<66?(r=255,n=t<6?0:-155.25485562709179-.44596950469579133*(n=t-2)+104.49216199393888*vt(n),o=t<20?0:-254.76935184120902+.8274096064007395*(o=t-10)+115.67994401066147*vt(o)):(r=351.97690566805693+.114206453784165*(r=t-55)-40.25366309332127*vt(r),n=325.4494125711974+.07943456536662342*(n=t-50)-28.0852963507957*vt(n),o=255),[r,n,o,1]},{round:f0}=Math,l0=(...e)=>{const t=j(e,"rgb"),r=t[0],n=t[2];let o=1e3,a=4e4;const s=.4;let c;for(;a-o>s;){c=(a+o)*.5;const i=qo(c);i[2]/i[0]>=n/r?a=c:o=c}return f0(c)};$.prototype.temp=$.prototype.kelvin=$.prototype.temperature=function(){return l0(this._rgb)},O.temp=O.kelvin=O.temperature=(...e)=>new $(...e,"temp"),L.format.temp=L.format.kelvin=L.format.temperature=qo;const{pow:_t,sign:h0}=Math,Mo=(...e)=>{e=j(e,"lab");const[t,r,n]=e,o=_t(t+.3963377774*r+.2158037573*n,3),a=_t(t-.1055613458*r-.0638541728*n,3),s=_t(t-.0894841775*r-1.291485548*n,3);return[255*cr(4.0767416621*o-3.3077115913*a+.2309699292*s),255*cr(-1.2684380046*o+2.6097574011*a-.3413193965*s),255*cr(-.0041960863*o-.7034186147*a+1.707614701*s),e.length>3?e[3]:1]};function cr(e){const t=Math.abs(e);return t>.0031308?(h0(e)||1)*(1.055*_t(t,.4166666666666667)-.055):e*12.92}const{cbrt:ir,pow:d0,sign:b0}=Math,Oo=(...e)=>{const[t,r,n]=j(e,"rgb"),[o,a,s]=[ur(t/255),ur(r/255),ur(n/255)],c=ir(.4122214708*o+.5363325363*a+.0514459929*s),i=ir(.2119034982*o+.6806995451*a+.1073969566*s),u=ir(.0883024619*o+.2817188376*a+.6299787005*s);return[.2104542553*c+.793617785*i-.0040720468*u,1.9779984951*c-2.428592205*i+.4505937099*u,.0259040371*c+.7827717662*i-.808675766*u]};function ur(e){const t=Math.abs(e);return t<.04045?e/12.92:(b0(e)||1)*d0((t+.055)/1.055,2.4)}$.prototype.oklab=function(){return Oo(this._rgb)},O.oklab=(...e)=>new $(...e,"oklab"),L.format.oklab=Mo,L.autodetect.push({p:3,test:(...e)=>{if(e=j(e,"oklab"),P(e)==="array"&&e.length===3)return"oklab"}});const p0=(...e)=>{e=j(e,"lch");const[t,r,n]=e,[o,a,s]=$o(t,r,n),[c,i,u]=Mo(o,a,s);return[c,i,u,e.length>3?e[3]:1]},m0=(...e)=>{const[t,r,n]=j(e,"rgb"),[o,a,s]=Oo(t,r,n);return xo(o,a,s)};$.prototype.oklch=function(){return m0(this._rgb)},O.oklch=(...e)=>new $(...e,"oklch"),L.format.oklch=p0,L.autodetect.push({p:3,test:(...e)=>{if(e=j(e,"oklch"),P(e)==="array"&&e.length===3)return"oklch"}}),$.prototype.alpha=function(e,t=!1){return e!==void 0&&P(e)==="number"?t?(this._rgb[3]=e,this):new $([this._rgb[0],this._rgb[1],this._rgb[2],e],"rgb"):this._rgb[3]},$.prototype.clipped=function(){return this._rgb._clipped||!1},$.prototype.darken=function(e=1){const t=this,r=t.lab();return r[0]-=se.Kn*e,new $(r,"lab").alpha(t.alpha(),!0)},$.prototype.brighten=function(e=1){return this.darken(-e)},$.prototype.darker=$.prototype.darken,$.prototype.brighter=$.prototype.brighten,$.prototype.get=function(e){const[t,r]=e.split("."),n=this[t]();if(r){const o=t.indexOf(r)-(t.substr(0,2)==="ok"?2:0);if(o>-1)return n[o];throw new Error(`unknown channel ${r} in mode ${t}`)}else return n};const{pow:g0}=Math,v0=1e-7,_0=20;$.prototype.luminance=function(e,t="rgb"){if(e!==void 0&&P(e)==="number"){if(e===0)return new $([0,0,0,this._rgb[3]],"rgb");if(e===1)return new $([255,255,255,this._rgb[3]],"rgb");let r=this.luminance(),n=_0;const o=(s,c)=>{const i=s.interpolate(c,.5,t),u=i.luminance();return Math.abs(e-u)e?o(s,i):o(i,c)},a=(r>e?o(new $([0,0,0]),this):o(this,new $([255,255,255]))).rgb();return new $([...a,this._rgb[3]])}return y0(...this._rgb.slice(0,3))};const y0=(e,t,r)=>(e=fr(e),t=fr(t),r=fr(r),.2126*e+.7152*t+.0722*r),fr=e=>(e/=255,e<=.03928?e/12.92:g0((e+.055)/1.055,2.4)),re={},ct=(e,t,r=.5,...n)=>{let o=n[0]||"lrgb";if(!re[o]&&!n.length&&(o=Object.keys(re)[0]),!re[o])throw new Error(`interpolation mode ${o} is not defined`);return P(e)!=="object"&&(e=new $(e)),P(t)!=="object"&&(t=new $(t)),re[o](e,t,r).alpha(e.alpha()+r*(t.alpha()-e.alpha()))};$.prototype.mix=$.prototype.interpolate=function(e,t=.5,...r){return ct(this,e,t,...r)},$.prototype.premultiply=function(e=!1){const t=this._rgb,r=t[3];return e?(this._rgb=[t[0]*r,t[1]*r,t[2]*r,r],this):new $([t[0]*r,t[1]*r,t[2]*r,r],"rgb")},$.prototype.saturate=function(e=1){const t=this,r=t.lch();return r[1]+=se.Kn*e,r[1]<0&&(r[1]=0),new $(r,"lch").alpha(t.alpha(),!0)},$.prototype.desaturate=function(e=1){return this.saturate(-e)},$.prototype.set=function(e,t,r=!1){const[n,o]=e.split("."),a=this[n]();if(o){const s=n.indexOf(o)-(n.substr(0,2)==="ok"?2:0);if(s>-1){if(P(t)=="string")switch(t.charAt(0)){case"+":a[s]+=+t;break;case"-":a[s]+=+t;break;case"*":a[s]*=+t.substr(1);break;case"/":a[s]/=+t.substr(1);break;default:a[s]=+t}else if(P(t)==="number")a[s]=t;else throw new Error("unsupported value for Color.set");const c=new $(a,n);return r?(this._rgb=c._rgb,this):c}throw new Error(`unknown channel ${o} in mode ${n}`)}else return a},$.prototype.tint=function(e=.5,...t){return ct(this,"white",e,...t)},$.prototype.shade=function(e=.5,...t){return ct(this,"black",e,...t)};const w0=(e,t,r)=>{const n=e._rgb,o=t._rgb;return new $(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"rgb")};re.rgb=w0;const{sqrt:lr,pow:Ve}=Math,k0=(e,t,r)=>{const[n,o,a]=e._rgb,[s,c,i]=t._rgb;return new $(lr(Ve(n,2)*(1-r)+Ve(s,2)*r),lr(Ve(o,2)*(1-r)+Ve(c,2)*r),lr(Ve(a,2)*(1-r)+Ve(i,2)*r),"rgb")};re.lrgb=k0;const $0=(e,t,r)=>{const n=e.lab(),o=t.lab();return new $(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"lab")};re.lab=$0;const Ye=(e,t,r,n)=>{let o,a;n==="hsl"?(o=e.hsl(),a=t.hsl()):n==="hsv"?(o=e.hsv(),a=t.hsv()):n==="hcg"?(o=e.hcg(),a=t.hcg()):n==="hsi"?(o=e.hsi(),a=t.hsi()):n==="lch"||n==="hcl"?(n="hcl",o=e.hcl(),a=t.hcl()):n==="oklch"&&(o=e.oklch().reverse(),a=t.oklch().reverse());let s,c,i,u,l,f;(n.substr(0,1)==="h"||n==="oklch")&&([s,i,l]=o,[c,u,f]=a);let h,d,b,_;return!isNaN(s)&&!isNaN(c)?(c>s&&c-s>180?_=c-(s+360):c180?_=c+360-s:_=c-s,d=s+r*_):isNaN(s)?isNaN(c)?d=Number.NaN:(d=c,(l==1||l==0)&&n!="hsv"&&(h=u)):(d=s,(f==1||f==0)&&n!="hsv"&&(h=i)),h===void 0&&(h=i+r*(u-i)),b=l+r*(f-l),n==="oklch"?new $([b,h,d],n):new $([d,h,b],n)},No=(e,t,r)=>Ye(e,t,r,"lch");re.lch=No,re.hcl=No;const C0=(e,t,r)=>{const n=e.num(),o=t.num();return new $(n+r*(o-n),"num")};re.num=C0;const x0=(e,t,r)=>Ye(e,t,r,"hcg");re.hcg=x0;const R0=(e,t,r)=>Ye(e,t,r,"hsi");re.hsi=R0;const H0=(e,t,r)=>Ye(e,t,r,"hsl");re.hsl=H0;const q0=(e,t,r)=>Ye(e,t,r,"hsv");re.hsv=q0;const M0=(e,t,r)=>{const n=e.oklab(),o=t.oklab();return new $(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"oklab")};re.oklab=M0;const O0=(e,t,r)=>Ye(e,t,r,"oklch");re.oklch=O0;const{pow:hr,sqrt:dr,PI:br,cos:Ao,sin:Lo,atan2:N0}=Math,A0=(e,t="lrgb",r=null)=>{const n=e.length;r||(r=Array.from(new Array(n)).map(()=>1));const o=n/r.reduce(function(f,h){return f+h});if(r.forEach((f,h)=>{r[h]*=o}),e=e.map(f=>new $(f)),t==="lrgb")return L0(e,r);const a=e.shift(),s=a.get(t),c=[];let i=0,u=0;for(let f=0;f{const d=f.get(t);l+=f.alpha()*r[h+1];for(let b=0;b=360;)h-=360;s[f]=h}else s[f]=s[f]/c[f];return l/=n,new $(s,t).alpha(l>.99999?1:l,!0)},L0=(e,t)=>{const r=e.length,n=[0,0,0,0];for(let o=0;o.9999999&&(n[3]=1),new $(Yt(n))},{pow:E0}=Math;function yt(e){let t="rgb",r=O("#ccc"),n=0,o=[0,1],a=[],s=[0,0],c=!1,i=[],u=!1,l=0,f=1,h=!1,d={},b=!0,_=1;const g=function(m){if(m=m||["#fff","#000"],m&&P(m)==="string"&&O.brewer&&O.brewer[m.toLowerCase()]&&(m=O.brewer[m.toLowerCase()]),P(m)==="array"){m.length===1&&(m=[m[0],m[0]]),m=m.slice(0);for(let p=0;p=c[y];)y++;return y-1}return 0};let H=m=>m,x=m=>m;const N=function(m,p){let y,w;if(p==null&&(p=!1),isNaN(m)||m===null)return r;p?w=m:c&&c.length>2?w=v(m)/(c.length-2):f!==l?w=(m-l)/(f-l):w=1,w=x(w),p||(w=H(w)),_!==1&&(w=E0(w,_)),w=s[0]+w*(1-s[0]-s[1]),w=Xe(w,0,1);const C=Math.floor(w*1e4);if(b&&d[C])y=d[C];else{if(P(i)==="array")for(let q=0;q=M&&q===a.length-1){y=i[q];break}if(w>M&&wd={};g(e);const R=function(m){const p=O(N(m));return u&&p[u]?p[u]():p};return R.classes=function(m){if(m!=null){if(P(m)==="array")c=m,o=[m[0],m[m.length-1]];else{const p=O.analyze(o);m===0?c=[p.min,p.max]:c=O.limits(p,"e",m)}return R}return c},R.domain=function(m){if(!arguments.length)return o;l=m[0],f=m[m.length-1],a=[];const p=i.length;if(m.length===p&&l!==f)for(let y of Array.from(m))a.push((y-l)/(f-l));else{for(let y=0;y2){const y=m.map((C,q)=>q/(m.length-1)),w=m.map(C=>(C-l)/(f-l));w.every((C,q)=>y[q]===C)||(x=C=>{if(C<=0||C>=1)return C;let q=0;for(;C>=w[q+1];)q++;const M=(C-w[q])/(w[q+1]-w[q]);return y[q]+M*(y[q+1]-y[q])})}}return o=[l,f],R},R.mode=function(m){return arguments.length?(t=m,A(),R):t},R.range=function(m,p){return g(m),R},R.out=function(m){return u=m,R},R.spread=function(m){return arguments.length?(n=m,R):n},R.correctLightness=function(m){return m==null&&(m=!0),h=m,A(),h?H=function(p){const y=N(0,!0).lab()[0],w=N(1,!0).lab()[0],C=y>w;let q=N(p,!0).lab()[0];const M=y+(w-y)*p;let S=q-M,X=0,D=1,U=20;for(;Math.abs(S)>.01&&U-- >0;)(function(){return C&&(S*=-1),S<0?(X=p,p+=(D-p)*.5):(D=p,p+=(X-p)*.5),q=N(p,!0).lab()[0],S=q-M})();return p}:H=p=>p,R},R.padding=function(m){return m!=null?(P(m)==="number"&&(m=[m,m]),s=m,R):s},R.colors=function(m,p){arguments.length<2&&(p="hex");let y=[];if(arguments.length===0)y=i.slice(0);else if(m===1)y=[R(.5)];else if(m>1){const w=o[0],C=o[1]-w;y=T0(0,m).map(q=>R(w+q/(m-1)*C))}else{e=[];let w=[];if(c&&c.length>2)for(let C=1,q=c.length,M=1<=q;M?Cq;M?C++:C--)w.push((c[C-1]+c[C])*.5);else w=o;y=w.map(C=>R(C))}return O[p]&&(y=y.map(w=>w[p]())),y},R.cache=function(m){return m!=null?(b=m,R):b},R.gamma=function(m){return m!=null?(_=m,R):_},R.nodata=function(m){return m!=null?(r=O(m),R):r},R}function T0(e,t,r){let n=[],o=ea;o?s++:s--)n.push(s);return n}const S0=function(e){let t=[1,1];for(let r=1;rnew $(a)),e.length===2)[r,n]=e.map(a=>a.lab()),t=function(a){const s=[0,1,2].map(c=>r[c]+a*(n[c]-r[c]));return new $(s,"lab")};else if(e.length===3)[r,n,o]=e.map(a=>a.lab()),t=function(a){const s=[0,1,2].map(c=>(1-a)*(1-a)*r[c]+2*(1-a)*a*n[c]+a*a*o[c]);return new $(s,"lab")};else if(e.length===4){let a;[r,n,o,a]=e.map(s=>s.lab()),t=function(s){const c=[0,1,2].map(i=>(1-s)*(1-s)*(1-s)*r[i]+3*(1-s)*(1-s)*s*n[i]+3*(1-s)*s*s*o[i]+s*s*s*a[i]);return new $(c,"lab")}}else if(e.length>=5){let a,s,c;a=e.map(i=>i.lab()),c=e.length-1,s=S0(c),t=function(i){const u=1-i,l=[0,1,2].map(f=>a.reduce((h,d,b)=>h+s[b]*u**(c-b)*i**b*d[f],0));return new $(l,"lab")}}else throw new RangeError("No point in running bezier with only one color.");return t},j0=e=>{const t=P0(e);return t.scale=()=>yt(t),t},de=(e,t,r)=>{if(!de[r])throw new Error("unknown blend mode "+r);return de[r](e,t)},Ne=e=>(t,r)=>{const n=O(r).rgb(),o=O(t).rgb();return O.rgb(e(n,o))},Ae=e=>(t,r)=>{const n=[];return n[0]=e(t[0],r[0]),n[1]=e(t[1],r[1]),n[2]=e(t[2],r[2]),n},B0=e=>e,G0=(e,t)=>e*t/255,I0=(e,t)=>e>t?t:e,z0=(e,t)=>e>t?e:t,F0=(e,t)=>255*(1-(1-e/255)*(1-t/255)),X0=(e,t)=>t<128?2*e*t/255:255*(1-2*(1-e/255)*(1-t/255)),K0=(e,t)=>255*(1-(1-t/255)/(e/255)),D0=(e,t)=>e===255?255:(e=255*(t/255)/(1-e/255),e>255?255:e);de.normal=Ne(Ae(B0)),de.multiply=Ne(Ae(G0)),de.screen=Ne(Ae(F0)),de.overlay=Ne(Ae(X0)),de.darken=Ne(Ae(I0)),de.lighten=Ne(Ae(z0)),de.dodge=Ne(Ae(D0)),de.burn=Ne(Ae(K0));const{pow:V0,sin:Y0,cos:Z0}=Math;function J0(e=300,t=-1.5,r=1,n=1,o=[0,1]){let a=0,s;P(o)==="array"?s=o[1]-o[0]:(s=0,o=[o,o]);const c=function(i){const u=we*((e+120)/360+t*i),l=V0(o[0]+s*i,n),h=(a!==0?r[0]+i*a:r)*l*(1-l)/2,d=Z0(u),b=Y0(u),_=l+h*(-.14861*d+1.78277*b),g=l+h*(-.29227*d-.90649*b),v=l+h*(1.97294*d);return O(Yt([_*255,g*255,v*255,1]))};return c.start=function(i){return i==null?e:(e=i,c)},c.rotations=function(i){return i==null?t:(t=i,c)},c.gamma=function(i){return i==null?n:(n=i,c)},c.hue=function(i){return i==null?r:(r=i,P(r)==="array"?(a=r[1]-r[0],a===0&&(r=r[1])):a=0,c)},c.lightness=function(i){return i==null?o:(P(i)==="array"?(o=i,s=i[1]-i[0]):(o=[i,i],s=0),c)},c.scale=()=>O.scale(c),c.hue(r),c}const W0="0123456789abcdef",{floor:U0,random:Q0}=Math,ei=()=>{let e="#";for(let t=0;t<6;t++)e+=W0.charAt(U0(Q0()*16));return new $(e,"hex")},{log:Eo,pow:ti,floor:ri,abs:ni}=Math;function To(e,t=null){const r={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0};return P(e)==="object"&&(e=Object.values(e)),e.forEach(n=>{t&&P(n)==="object"&&(n=n[t]),n!=null&&!isNaN(n)&&(r.values.push(n),r.sum+=n,nr.max&&(r.max=n),r.count+=1)}),r.domain=[r.min,r.max],r.limits=(n,o)=>So(r,n,o),r}function So(e,t="equal",r=7){P(e)=="array"&&(e=To(e));const{min:n,max:o}=e,a=e.values.sort((c,i)=>c-i);if(r===1)return[n,o];const s=[];if(t.substr(0,1)==="c"&&(s.push(n),s.push(o)),t.substr(0,1)==="e"){s.push(n);for(let c=1;c 0");const c=Math.LOG10E*Eo(n),i=Math.LOG10E*Eo(o);s.push(n);for(let u=1;u200&&(f=!1)}const b={};for(let g=0;gg-v),s.push(_[0]);for(let g=1;g<_.length;g+=2){const v=_[g];!isNaN(v)&&s.indexOf(v)===-1&&s.push(v)}}return s}const oi=(e,t)=>{e=new $(e),t=new $(t);const r=e.luminance(),n=t.luminance();return r>n?(r+.05)/(n+.05):(n+.05)/(r+.05)},{sqrt:ke,pow:V,min:si,max:ai,atan2:Po,abs:jo,cos:wt,sin:Bo,exp:ci,PI:Go}=Math;function ii(e,t,r=1,n=1,o=1){var a=function(he){return 360*he/(2*Go)},s=function(he){return 2*Go*he/360};e=new $(e),t=new $(t);const[c,i,u]=Array.from(e.lab()),[l,f,h]=Array.from(t.lab()),d=(c+l)/2,b=ke(V(i,2)+V(u,2)),_=ke(V(f,2)+V(h,2)),g=(b+_)/2,v=.5*(1-ke(V(g,7)/(V(g,7)+V(25,7)))),H=i*(1+v),x=f*(1+v),N=ke(V(H,2)+V(u,2)),A=ke(V(x,2)+V(h,2)),R=(N+A)/2,m=a(Po(u,H)),p=a(Po(h,x)),y=m>=0?m:m+360,w=p>=0?p:p+360,C=jo(y-w)>180?(y+w+360)/2:(y+w)/2,q=1-.17*wt(s(C-30))+.24*wt(s(2*C))+.32*wt(s(3*C+6))-.2*wt(s(4*C-63));let M=w-y;M=jo(M)<=180?M:w<=y?M+360:M-360,M=2*ke(N*A)*Bo(s(M)/2);const S=l-c,X=A-N,D=1+.015*V(d-50,2)/ke(20+V(d-50,2)),U=1+.045*R,ce=1+.015*R*q,ye=30*ci(-V((C-275)/25,2)),le=-(2*ke(V(R,7)/(V(R,7)+V(25,7))))*Bo(2*s(ye)),qe=ke(V(S/(r*D),2)+V(X/(n*U),2)+V(M/(o*ce),2)+le*(X/(n*U))*(M/(o*ce)));return ai(0,si(100,qe))}function ui(e,t,r="lab"){e=new $(e),t=new $(t);const n=e.get(r),o=t.get(r);let a=0;for(let s in n){const c=(n[s]||0)-(o[s]||0);a+=c*c}return Math.sqrt(a)}const fi=(...e)=>{try{return new $(...e),!0}catch{return!1}},li={cool(){return yt([O.hsl(180,1,.9),O.hsl(250,.7,.4)])},hot(){return yt(["#000","#f00","#ff0","#fff"]).mode("rgb")}},kt={OrRd:["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"],PuBu:["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"],BuPu:["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"],Oranges:["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"],BuGn:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"],YlOrBr:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"],YlGn:["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],Reds:["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"],RdPu:["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"],Greens:["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"],YlGnBu:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],Purples:["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"],GnBu:["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],Greys:["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"],YlOrRd:["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"],PuRd:["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"],Blues:["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"],PuBuGn:["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"],Viridis:["#440154","#482777","#3f4a8a","#31678e","#26838f","#1f9d8a","#6cce5a","#b6de2b","#fee825"],Spectral:["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],RdYlGn:["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],RdBu:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],PiYG:["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],PRGn:["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],RdYlBu:["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],BrBG:["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],RdGy:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],PuOr:["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],Set2:["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],Accent:["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],Set1:["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],Set3:["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],Dark2:["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],Paired:["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],Pastel2:["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],Pastel1:["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]};for(let e of Object.keys(kt))kt[e.toLowerCase()]=kt[e];Object.assign(O,{average:A0,bezier:j0,blend:de,cubehelix:J0,mix:ct,interpolate:ct,random:ei,scale:yt,analyze:To,contrast:oi,deltaE:ii,distance:ui,limits:So,valid:fi,scales:li,input:L,colors:De,brewer:kt});function pr(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var mr,Io;function hi(){if(Io)return mr;Io=1;var e=e||{};e.Geometry=function(){},e.Geometry.intersectLineLine=function(r,n){var o=(r.intercept-n.intercept)/(n.slope-r.slope),a=r.slope*o+r.intercept;return{x:o,y:a}},e.Geometry.distanceFromOrigin=function(r){return Math.sqrt(Math.pow(r.x,2)+Math.pow(r.y,2))},e.Geometry.distanceLineFromOrigin=function(r){return Math.abs(r.intercept)/Math.sqrt(Math.pow(r.slope,2)+1)},e.Geometry.perpendicularThroughPoint=function(r,n){var o=-1/r.slope,a=n.y-o*n.x;return{slope:o,intercept:a}},e.Geometry.angleFromOrigin=function(r){return Math.atan2(r.y,r.x)},e.Geometry.normalizeAngle=function(r){var n=2*Math.PI;return(r%n+n)%n},e.Geometry.lengthOfRayUntilIntersect=function(r,n){return n.intercept/(Math.sin(r)-n.slope*Math.cos(r))},e.Hsluv=function(){},e.Hsluv.getBounds=function(r){for(var n=[],o=Math.pow(r+16,3)/1560896,a=o>e.Hsluv.epsilon?o:r/e.Hsluv.kappa,s=0;s<3;)for(var c=s++,i=e.Hsluv.m[c][0],u=e.Hsluv.m[c][1],l=e.Hsluv.m[c][2],f=0;f<2;){var h=f++,d=(284517*i-94839*l)*a,b=(838422*l+769860*u+731718*i)*r*a-769860*h*r,_=(632260*l-126452*u)*a+126452*h;n.push({slope:d/_,intercept:b/_})}return n},e.Hsluv.maxSafeChromaForL=function(r){for(var n=e.Hsluv.getBounds(r),o=1/0,a=0;a=0&&(s=Math.min(s,u))}return s},e.Hsluv.dotProduct=function(r,n){for(var o=0,a=0,s=r.length;a.04045?Math.pow((r+.055)/1.055,2.4):r/12.92},e.Hsluv.xyzToRgb=function(r){return[e.Hsluv.fromLinear(e.Hsluv.dotProduct(e.Hsluv.m[0],r)),e.Hsluv.fromLinear(e.Hsluv.dotProduct(e.Hsluv.m[1],r)),e.Hsluv.fromLinear(e.Hsluv.dotProduct(e.Hsluv.m[2],r))]},e.Hsluv.rgbToXyz=function(r){var n=[e.Hsluv.toLinear(r[0]),e.Hsluv.toLinear(r[1]),e.Hsluv.toLinear(r[2])];return[e.Hsluv.dotProduct(e.Hsluv.minv[0],n),e.Hsluv.dotProduct(e.Hsluv.minv[1],n),e.Hsluv.dotProduct(e.Hsluv.minv[2],n)]},e.Hsluv.yToL=function(r){return r<=e.Hsluv.epsilon?r/e.Hsluv.refY*e.Hsluv.kappa:116*Math.pow(r/e.Hsluv.refY,.3333333333333333)-16},e.Hsluv.lToY=function(r){return r<=8?e.Hsluv.refY*r/e.Hsluv.kappa:e.Hsluv.refY*Math.pow((r+16)/116,3)},e.Hsluv.xyzToLuv=function(r){var n=r[0],o=r[1],a=r[2],s=n+15*o+3*a,c=4*n,i=9*o;s!=0?(c/=s,i/=s):(c=NaN,i=NaN);var u=e.Hsluv.yToL(o);if(u==0)return[0,0,0];var l=13*u*(c-e.Hsluv.refU),f=13*u*(i-e.Hsluv.refV);return[u,l,f]},e.Hsluv.luvToXyz=function(r){var n=r[0],o=r[1],a=r[2];if(n==0)return[0,0,0];var s=o/(13*n)+e.Hsluv.refU,c=a/(13*n)+e.Hsluv.refV,i=e.Hsluv.lToY(n),u=0-9*i*s/((s-4)*c-s*c),l=(9*i-15*c*i-c*u)/(3*c);return[u,i,l]},e.Hsluv.luvToLch=function(r){var n=r[0],o=r[1],a=r[2],s=Math.sqrt(o*o+a*a),c;if(s<1e-8)c=0;else{var i=Math.atan2(a,o);c=i*180/Math.PI,c<0&&(c=360+c)}return[n,s,c]},e.Hsluv.lchToLuv=function(r){var n=r[0],o=r[1],a=r[2],s=a/360*2*Math.PI,c=Math.cos(s)*o,i=Math.sin(s)*o;return[n,c,i]},e.Hsluv.hsluvToLch=function(r){var n=r[0],o=r[1],a=r[2];if(a>99.9999999)return[100,0,n];if(a<1e-8)return[0,0,n];var s=e.Hsluv.maxChromaForLH(a,n),c=s/100*o;return[a,c,n]},e.Hsluv.lchToHsluv=function(r){var n=r[0],o=r[1],a=r[2];if(n>99.9999999)return[a,0,100];if(n<1e-8)return[a,0,0];var s=e.Hsluv.maxChromaForLH(n,a),c=o/s*100;return[a,c,n]},e.Hsluv.hpluvToLch=function(r){var n=r[0],o=r[1],a=r[2];if(a>99.9999999)return[100,0,n];if(a<1e-8)return[0,0,n];var s=e.Hsluv.maxSafeChromaForL(a),c=s/100*o;return[a,c,n]},e.Hsluv.lchToHpluv=function(r){var n=r[0],o=r[1],a=r[2];if(n>99.9999999)return[a,0,100];if(n<1e-8)return[a,0,0];var s=e.Hsluv.maxSafeChromaForL(n),c=o/s*100;return[a,c,n]},e.Hsluv.rgbToHex=function(r){for(var n="#",o=0;o<3;){var a=o++,s=r[a],c=Math.round(s*255),i=c%16,u=(c-i)/16|0;n+=e.Hsluv.hexChars.charAt(u)+e.Hsluv.hexChars.charAt(i)}return n},e.Hsluv.hexToRgb=function(r){r=r.toLowerCase();for(var n=[],o=0;o<3;){var a=o++,s=e.Hsluv.hexChars.indexOf(r.charAt(a*2+1)),c=e.Hsluv.hexChars.indexOf(r.charAt(a*2+2)),i=s*16+c;n.push(i/255)}return n},e.Hsluv.lchToRgb=function(r){return e.Hsluv.xyzToRgb(e.Hsluv.luvToXyz(e.Hsluv.lchToLuv(r)))},e.Hsluv.rgbToLch=function(r){return e.Hsluv.luvToLch(e.Hsluv.xyzToLuv(e.Hsluv.rgbToXyz(r)))},e.Hsluv.hsluvToRgb=function(r){return e.Hsluv.lchToRgb(e.Hsluv.hsluvToLch(r))},e.Hsluv.rgbToHsluv=function(r){return e.Hsluv.lchToHsluv(e.Hsluv.rgbToLch(r))},e.Hsluv.hpluvToRgb=function(r){return e.Hsluv.lchToRgb(e.Hsluv.hpluvToLch(r))},e.Hsluv.rgbToHpluv=function(r){return e.Hsluv.lchToHpluv(e.Hsluv.rgbToLch(r))},e.Hsluv.hsluvToHex=function(r){return e.Hsluv.rgbToHex(e.Hsluv.hsluvToRgb(r))},e.Hsluv.hpluvToHex=function(r){return e.Hsluv.rgbToHex(e.Hsluv.hpluvToRgb(r))},e.Hsluv.hexToHsluv=function(r){return e.Hsluv.rgbToHsluv(e.Hsluv.hexToRgb(r))},e.Hsluv.hexToHpluv=function(r){return e.Hsluv.rgbToHpluv(e.Hsluv.hexToRgb(r))},e.Hsluv.m=[[3.240969941904521,-1.537383177570093,-.498610760293],[-.96924363628087,1.87596750150772,.041555057407175],[.055630079696993,-.20397695888897,1.056971514242878]],e.Hsluv.minv=[[.41239079926595,.35758433938387,.18048078840183],[.21263900587151,.71516867876775,.072192315360733],[.019330818715591,.11919477979462,.95053215224966]],e.Hsluv.refY=1,e.Hsluv.refU=.19783000664283,e.Hsluv.refV=.46831999493879,e.Hsluv.kappa=903.2962962,e.Hsluv.epsilon=.0088564516,e.Hsluv.hexChars="0123456789abcdef";var t={hsluvToRgb:e.Hsluv.hsluvToRgb,rgbToHsluv:e.Hsluv.rgbToHsluv,hpluvToRgb:e.Hsluv.hpluvToRgb,rgbToHpluv:e.Hsluv.rgbToHpluv,hsluvToHex:e.Hsluv.hsluvToHex,hexToHsluv:e.Hsluv.hexToHsluv,hpluvToHex:e.Hsluv.hpluvToHex,hexToHpluv:e.Hsluv.hexToHpluv,lchToHpluv:e.Hsluv.lchToHpluv,hpluvToLch:e.Hsluv.hpluvToLch,lchToHsluv:e.Hsluv.lchToHsluv,hsluvToLch:e.Hsluv.hsluvToLch,lchToLuv:e.Hsluv.lchToLuv,luvToLch:e.Hsluv.luvToLch,xyzToLuv:e.Hsluv.xyzToLuv,luvToXyz:e.Hsluv.luvToXyz,xyzToRgb:e.Hsluv.xyzToRgb,rgbToXyz:e.Hsluv.rgbToXyz,lchToRgb:e.Hsluv.lchToRgb,rgbToLch:e.Hsluv.rgbToLch};return mr=t,mr}var di=hi();const gr=pr(di);var $t={exports:{}},vr,zo;function it(){if(zo)return vr;zo=1;function e(t,r){return Object.prototype.hasOwnProperty.call(t,r)}return vr=e,vr}var _r,Fo;function yr(){if(Fo)return _r;Fo=1;var e=it(),t,r;function n(){r=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],t=!0;for(var s in{toString:null})t=!1}function o(s,c,i){var u,l=0;t==null&&n();for(u in s)if(a(c,s,u,i)===!1)break;if(t)for(var f=s.constructor,h=!!f&&s===f.prototype;(u=r[l++])&&!((u!=="constructor"||!h&&e(s,u))&&s[u]!==Object.prototype[u]&&a(c,s,u,i)===!1););}function a(s,c,i,u){return s.call(u,c[i],i,c)}return _r=o,_r}var wr,Xo;function Ko(){if(Xo)return wr;Xo=1;var e=yr();function t(r){var n=[];return e(r,function(o,a){typeof o=="function"&&n.push(a)}),n.sort()}return wr=t,wr}var kr,Do;function ut(){if(Do)return kr;Do=1;function e(t,r,n){var o=t.length;r==null?r=0:r<0?r=Math.max(o+r,0):r=Math.min(r,o),n==null?n=o:n<0?n=Math.max(o+n,0):n=Math.min(n,o);for(var a=[];r1?n(arguments,1):e(a);r(c,function(i){a[i]=t(a[i],a)})}return Rr=o,Rr}var Hr,Jo;function Q(){if(Jo)return Hr;Jo=1;var e=it(),t=yr();function r(n,o,a){t(n,function(s,c){if(e(n,c))return o.call(a,n[c],c,n)})}return Hr=r,Hr}var qr,Wo;function mi(){if(Wo)return qr;Wo=1;function e(t){return t}return qr=e,qr}var Mr,Uo;function Qo(){if(Uo)return Mr;Uo=1;function e(t){return function(r){return r[t]}}return Mr=e,Mr}var Or,es;function Nr(){if(es)return Or;es=1;var e=/^\[object (.*)\]$/,t=Object.prototype.toString,r;function n(o){return o===null?"Null":o===r?"Undefined":e.exec(t.call(o))[1]}return Or=n,Or}var Ar,ts;function Lr(){if(ts)return Ar;ts=1;var e=Nr();function t(r,n){return e(r)===n}return Ar=t,Ar}var Er,rs;function gi(){if(rs)return Er;rs=1;var e=Lr(),t=Array.isArray||function(r){return e(r,"Array")};return Er=t,Er}var Tr,ns;function os(){if(ns)return Tr;ns=1;var e=Q(),t=gi();function r(s,c){for(var i=-1,u=s.length;++is&&(s=i,a=c);return a}return rn=t,rn}var nn,Ns;function on(){if(Ns)return nn;Ns=1;var e=Q();function t(r){var n=[];return e(r,function(o,a){n.push(o)}),n}return nn=t,nn}var sn,As;function Mi(){if(As)return sn;As=1;var e=qi(),t=on();function r(n,o){return e(t(n),o)}return sn=r,sn}var an,Ls;function Es(){if(Ls)return an;Ls=1;var e=Q();function t(n,o){for(var a=0,s=arguments.length,c;++a2;if(!t(n)&&!c)throw new Error("reduce of empty object with no initial value");return e(n,function(i,u,l){c?a=o.call(s,a,i,u,l):(a=i,c=!0)}),a}return yn=r,yn}var wn,Js;function Ii(){if(Js)return wn;Js=1;var e=_s(),t=Le();function r(n,o,a){return o=t(o,a),e(n,function(s,c,i){return!o(s,c,i)},a)}return wn=r,wn}var kn,Ws;function zi(){if(Ws)return kn;Ws=1;var e=Lr();function t(r){return e(r,"Function")}return kn=t,kn}var $n,Us;function Fi(){if(Us)return $n;Us=1;var e=zi();function t(r,n){var o=r[n];if(o!==void 0)return e(o)?o.call(r):o}return $n=t,$n}var Cn,Qs;function Xi(){if(Qs)return Cn;Qs=1;var e=Is();function t(r,n,o){var a=/^(.+)\.(.+)$/.exec(n);a?e(r,a[1])[a[2]]=o:r[n]=o}return Cn=t,Cn}var xn,ea;function Ki(){if(ea)return xn;ea=1;var e=xs();function t(r,n){if(e(r,n)){for(var o=n.split("."),a=o.pop();n=o.shift();)r=r[n];return delete r[a]}else return!0}return xn=t,xn}var Rn,ta;function Hn(){return ta||(ta=1,Rn={bindAll:pi(),contains:vi(),deepFillIn:_i(),deepMatches:os(),deepMixIn:yi(),equals:ki(),every:hs(),fillIn:$i(),filter:_s(),find:Ci(),flatten:xi(),forIn:yr(),forOwn:Q(),functions:Ko(),get:$s(),has:xs(),hasOwn:it(),keys:Ri(),map:qs(),matches:Hi(),max:Mi(),merge:Ai(),min:Ei(),mixIn:Es(),namespace:Is(),omit:Pi(),pick:ji(),pluck:Bi(),reduce:Gi(),reject:Ii(),result:Fi(),set:Xi(),size:Ys(),some:jr(),unset:Ki(),values:on()}),Rn}var ra;function na(){return ra||(ra=1,(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r=Hn(),n={A:{x:.44758,y:.40745},C:{x:.31006,y:.31616},D50:{x:.34567,y:.35851},D65:{x:.31272,y:.32903},D55:{x:.33243,y:.34744},D75:{x:.29903,y:.31488}},o=(0,r.map)(n,function(a){var s=100*(a.x/a.y),c=100,i=100*(1-a.x-a.y)/a.y;return[s,c,i]});t.default=o,e.exports=t.default})($t,$t.exports)),$t.exports}var Ct={exports:{}},oa;function sa(){return oa||(oa=1,(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r=Math,n=r.pow,o=r.sign,a=r.abs,s={decode:function(f){return f<=.04045?f/12.92:n((f+.055)/1.055,2.4)},encode:function(f){return f<=.0031308?12.92*f:1.055*n(f,1/2.4)-.055}},c={encode:function(f){return f<.001953125?16*f:n(f,1/1.8)},decode:function(f){return f<16*.001953125?f/16:n(f,1.8)}};function i(l){return{decode:function(h){return o(h)*n(a(h),l)},encode:function(h){return o(h)*n(a(h),1/l)}}}var u={sRGB:{r:{x:.64,y:.33},g:{x:.3,y:.6},b:{x:.15,y:.06},gamma:s},"Adobe RGB":{r:{x:.64,y:.33},g:{x:.21,y:.71},b:{x:.15,y:.06},gamma:i(2.2)},"Wide Gamut RGB":{r:{x:.7347,y:.2653},g:{x:.1152,y:.8264},b:{x:.1566,y:.0177},gamma:i(563/256)},"ProPhoto RGB":{r:{x:.7347,y:.2653},g:{x:.1596,y:.8404},b:{x:.0366,y:1e-4},gamma:c}};t.default=u,e.exports=t.default})(Ct,Ct.exports)),Ct.exports}var $e={},aa;function ca(){if(aa)return $e;aa=1,Object.defineProperty($e,"__esModule",{value:!0});function e(s){return[[s[0][0],s[1][0],s[2][0]],[s[0][1],s[1][1],s[2][1]],[s[0][2],s[1][2],s[2][2]]]}function t(s){return s[0][0]*(s[2][2]*s[1][1]-s[2][1]*s[1][2])+s[1][0]*(s[2][1]*s[0][2]-s[2][2]*s[0][1])+s[2][0]*(s[1][2]*s[0][1]-s[1][1]*s[0][2])}function r(s){var c=1/t(s);return[[(s[2][2]*s[1][1]-s[2][1]*s[1][2])*c,(s[2][1]*s[0][2]-s[2][2]*s[0][1])*c,(s[1][2]*s[0][1]-s[1][1]*s[0][2])*c],[(s[2][0]*s[1][2]-s[2][2]*s[1][0])*c,(s[2][2]*s[0][0]-s[2][0]*s[0][2])*c,(s[1][0]*s[0][2]-s[1][2]*s[0][0])*c],[(s[2][1]*s[1][0]-s[2][0]*s[1][1])*c,(s[2][0]*s[0][1]-s[2][1]*s[0][0])*c,(s[1][1]*s[0][0]-s[1][0]*s[0][1])*c]]}function n(s,c){return[s[0][0]*c[0]+s[0][1]*c[1]+s[0][2]*c[2],s[1][0]*c[0]+s[1][1]*c[1]+s[1][2]*c[2],s[2][0]*c[0]+s[2][1]*c[1]+s[2][2]*c[2]]}function o(s,c){return[[s[0][0]*c[0],s[0][1]*c[1],s[0][2]*c[2]],[s[1][0]*c[0],s[1][1]*c[1],s[1][2]*c[2]],[s[2][0]*c[0],s[2][1]*c[1],s[2][2]*c[2]]]}function a(s,c){return[[s[0][0]*c[0][0]+s[0][1]*c[1][0]+s[0][2]*c[2][0],s[0][0]*c[0][1]+s[0][1]*c[1][1]+s[0][2]*c[2][1],s[0][0]*c[0][2]+s[0][1]*c[1][2]+s[0][2]*c[2][2]],[s[1][0]*c[0][0]+s[1][1]*c[1][0]+s[1][2]*c[2][0],s[1][0]*c[0][1]+s[1][1]*c[1][1]+s[1][2]*c[2][1],s[1][0]*c[0][2]+s[1][1]*c[1][2]+s[1][2]*c[2][2]],[s[2][0]*c[0][0]+s[2][1]*c[1][0]+s[2][2]*c[2][0],s[2][0]*c[0][1]+s[2][1]*c[1][1]+s[2][2]*c[2][1],s[2][0]*c[0][2]+s[2][1]*c[1][2]+s[2][2]*c[2][2]]]}return $e.transpose=e,$e.determinant=t,$e.inverse=r,$e.multiply=n,$e.scalar=o,$e.product=a,$e}var lt={},ia;function Di(){if(ia)return lt;ia=1,Object.defineProperty(lt,"__esModule",{value:!0});var e=Math,t=e.PI;function r(o){for(var a=o*180/t;a<0;)a+=360;for(;a>360;)a-=360;return a}function n(o){for(var a=t*o/180;a<0;)a+=2*t;for(;a>2*t;)a-=2*t;return a}return lt.fromRadian=r,lt.toRadian=n,lt}var ht={},ua;function Vi(){if(ua)return ht;ua=1,Object.defineProperty(ht,"__esModule",{value:!0});var e=Math,t=e.round;function r(o){return o[0]=="#"&&(o=o.slice(1)),o.length<6&&(o=o.split("").map(function(a){return a+a}).join("")),o.match(/../g).map(function(a){return parseInt(a,16)/255})}function n(o){var a=o.map(function(s){return s=t(255*s).toString(16),s.length<2&&(s="0"+s),s}).join("");return"#"+a}return ht.fromHex=r,ht.toHex=n,ht}var xt={exports:{}},fa;function Yi(){return fa||(fa=1,(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r=ca(),n=u(r),o=na(),a=i(o),s=sa(),c=i(s);function i(f){return f&&f.__esModule?f:{default:f}}function u(f){if(f&&f.__esModule)return f;var h={};if(f!=null)for(var d in f)Object.prototype.hasOwnProperty.call(f,d)&&(h[d]=f[d]);return h.default=f,h}function l(){var f=arguments.length<=0||arguments[0]===void 0?c.default.sRGB:arguments[0],h=arguments.length<=1||arguments[1]===void 0?a.default.D65:arguments[1],d=[f.r,f.g,f.b],b=n.transpose(d.map(function(x){var N=x.x/x.y,A=1,R=(1-x.x-x.y)/x.y;return[N,A,R]})),_=f.gamma,g=n.multiply(n.inverse(b),h),v=n.scalar(b,g),H=n.inverse(v);return{fromRgb:function(N){return n.multiply(v,N.map(_.decode))},toRgb:function(N){return n.multiply(H,N).map(_.encode)}}}t.default=l,e.exports=t.default})(xt,xt.exports)),xt.exports}var qn,la;function Rt(){if(la)return qn;la=1;var e=na(),t=sa(),r=ca(),n=Di(),o=Vi(),a=Yi();return qn={illuminant:e,workspace:t,matrix:r,degree:n,rgb:o,xyz:a},qn}var Zi=Rt();const Ht=pr(Zi);var be={},ha;function qt(){if(ha)return be;ha=1,Object.defineProperty(be,"__esModule",{value:!0}),be.cfs=be.distance=be.lerp=be.corLerp=void 0;var e=Hn();function t(h,d,b){return d in h?Object.defineProperty(h,d,{value:b,enumerable:!0,configurable:!0,writable:!0}):h[d]=b,h}function r(h){if(Array.isArray(h)){for(var d=0,b=Array(h.length);dg/2&&(h>d?d+=g:h+=g)}return((1-b)*h+b*d)%(g||1/0)}function u(h,d,b){var _={};for(var g in h)_[g]=i(h[g],d[g],b,g);return _}function l(h,d){var b=0;for(var _ in h)b+=a(h[_]-d[_],2);return s(b)}function f(h){return e.merge.apply(void 0,r(h.split("").map(function(d){return t({},d,!0)})))}return be.corLerp=i,be.lerp=u,be.distance=l,be.cfs=f,be}var Mt={exports:{}},da;function Ji(){return da||(da=1,(function(e,t){var r=(function(){function s(c,i){var u=[],l=!0,f=!1,h=void 0;try{for(var d=c[Symbol.iterator](),b;!(l=(b=d.next()).done)&&(u.push(b.value),!(i&&u.length===i));l=!0);}catch(_){f=!0,h=_}finally{try{!l&&d.return&&d.return()}finally{if(f)throw h}}return u}return function(c,i){if(Array.isArray(c))return c;if(Symbol.iterator in Object(c))return s(c,i);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();Object.defineProperty(t,"__esModule",{value:!0});var n=Rt(),o=qt();function a(s,c){var i=arguments.length<=2||arguments[2]===void 0?1e-6:arguments[2],u=-i,l=1+i,f=Math,h=f.min,d=f.max,b=["000","fff"].map(function(R){return c.fromXyz(s.fromRgb(n.rgb.fromHex(R)))}),_=r(b,2),g=_[0],v=_[1];function H(R){var m=s.toRgb(c.toXyz(R)),p=m.map(function(y){return y>=u&&y<=l}).reduce(function(y,w){return y&&w},!0);return[p,m]}function x(R,m){for(var p=arguments.length<=2||arguments[2]===void 0?.001:arguments[2];(0,o.distance)(R,m)>p;){var y=(0,o.lerp)(R,m,.5),w=H(y),C=r(w,1),q=C[0];q?R=y:m=y}return R}function N(R){return(0,o.lerp)(g,v,R)}function A(R){return R.map(function(m){return d(u,h(l,m))})}return{contains:H,limit:x,spine:N,crop:A}}t.default=a,e.exports=t.default})(Mt,Mt.exports)),Mt.exports}var Ot={exports:{}},pe={},ba;function pa(){if(ba)return pe;ba=1;var e=(function(){function f(h,d){var b=[],_=!0,g=!1,v=void 0;try{for(var H=h[Symbol.iterator](),x;!(_=(x=H.next()).done)&&(b.push(x.value),!(d&&b.length===d));_=!0);}catch(N){g=!0,v=N}finally{try{!_&&H.return&&H.return()}finally{if(g)throw v}}return b}return function(h,d){if(Array.isArray(h))return h;if(Symbol.iterator in Object(h))return f(h,d);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();Object.defineProperty(pe,"__esModule",{value:!0}),pe.toNotation=pe.fromNotation=pe.toHue=pe.fromHue=void 0;var t=qt(),r=Math,n=r.floor,o=[{s:"R",h:20.14,e:.8,H:0},{s:"Y",h:90,e:.7,H:100},{s:"G",h:164.25,e:1,H:200},{s:"B",h:237.53,e:1.2,H:300},{s:"R",h:380.14,e:.8,H:400}],a=o.map(function(f){return f.s}).slice(0,-1).join("");function s(f){f50){var _=[d,h];h=_[0],d=_[1],b=100-b}return b<1?a[h]:a[h]+b.toFixed()+a[d]}return pe.fromHue=s,pe.toHue=c,pe.fromNotation=u,pe.toNotation=l,pe}var ma;function Wi(){return ma||(ma=1,(function(e,t){var r=(function(){function S(X,D){var U=[],ce=!0,ye=!1,st=void 0;try{for(var le=X[Symbol.iterator](),qe;!(ce=(qe=le.next()).done)&&(U.push(qe.value),!(D&&U.length===D));ce=!0);}catch(he){ye=!0,st=he}finally{try{!ce&&le.return&&le.return()}finally{if(ye)throw st}}return U}return function(X,D){if(Array.isArray(X))return X;if(Symbol.iterator in Object(X))return S(X,D);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})();Object.defineProperty(t,"__esModule",{value:!0});var n=Rt(),o=pa(),a=i(o),s=qt(),c=Hn();function i(S){if(S&&S.__esModule)return S;var X={};if(S!=null)for(var D in S)Object.prototype.hasOwnProperty.call(S,D)&&(X[D]=S[D]);return X.default=S,X}var u=Math,l=u.pow,f=u.sqrt,h=u.exp,d=u.abs,b=u.sign,_=Math,g=_.sin,v=_.cos,H=_.atan2,x={average:{F:1,c:.69,N_c:1},dim:{F:.9,c:.59,N_c:.9},dark:{F:.8,c:.535,N_c:.8}},N=[[.7328,.4296,-.1624],[-.7036,1.6975,.0061],[.003,.0136,.9834]],A=[[.38971,.68898,-.07868],[-.22981,1.1834,.04641],[0,0,1]],R=N,m=n.matrix.inverse(N),p=n.matrix.product(A,n.matrix.inverse(N)),y=n.matrix.product(N,n.matrix.inverse(A)),w={whitePoint:n.illuminant.D65,adaptingLuminance:40,backgroundLuminance:20,surroundType:"average",discounting:!1},C=(0,s.cfs)("QJMCshH"),q=(0,s.cfs)("JCh");function M(){var S=arguments.length<=0||arguments[0]===void 0?{}:arguments[0],X=arguments.length<=1||arguments[1]===void 0?C:arguments[1];S=(0,c.merge)(w,S);var D=S.whitePoint,U=S.adaptingLuminance,ce=S.backgroundLuminance,ye=x[S.surroundType],st=ye.F,le=ye.c,qe=ye.N_c,he=D[1],wc=1/(5*U+1),Ge=.2*l(wc,4)*5*U+.1*l(1-l(wc,4),2)*l(5*U,1/3),Xt=ce/he,no=.725*l(1/Xt,.2),kc=no,$c=1.48+f(Xt),Cc=S.discounting?1:st*(1-1/3.6*h(-(U+42)/92)),$l=n.matrix.multiply(N,D),Cl=$l.map(function(I){return Cc*he/I+1-Cc}),oo=r(Cl,3),xc=oo[0],Rc=oo[1],Hc=oo[2],xl=qc(D),Rl=Mc(xl),Kt=Oc(Rl);function qc(I){var z=n.matrix.multiply(R,I),F=r(z,3),ee=F[0],W=F[1],ie=F[2];return[xc*ee,Rc*W,Hc*ie]}function Hl(I){var z=r(I,3),F=z[0],ee=z[1],W=z[2];return n.matrix.multiply(m,[F/xc,ee/Rc,W/Hc])}function Mc(I){return n.matrix.multiply(p,I).map(function(z){var F=l(Ge*d(z)/100,.42);return b(z)*400*F/(27.13+F)+.1})}function ql(I){return n.matrix.multiply(y,I.map(function(z){var F=z-.1;return b(F)*100/Ge*l(27.13*d(F)/(400-d(F)),2.380952380952381)}))}function Oc(I){var z=r(I,3),F=z[0],ee=z[1],W=z[2];return(F*2+ee+W/20-.305)*no}function so(I){return 4/le*f(I/100)*(Kt+4)*l(Ge,.25)}function Ml(I){return 6.25*l(le*I/((Kt+4)*l(Ge,.25)),2)}function Nc(I){return I*l(Ge,.25)}function Ol(I,z){return l(I/100,2)*z/l(Ge,.25)}function Nl(I){return I/l(Ge,.25)}function Al(I,z){return 100*f(I/z)}function ao(I,z){var F=z.Q,ee=z.J,W=z.M,ie=z.C,ve=z.s,Me=z.h,Oe=z.H,te={};return I.J&&(te.J=isNaN(ee)?Ml(F):ee),I.C&&(isNaN(ie)?isNaN(W)?(F=isNaN(F)?so(ee):F,te.C=Ol(ve,F)):te.C=Nl(W):te.C=z.C),I.h&&(te.h=isNaN(Me)?a.toHue(Oe):Me),I.Q&&(te.Q=isNaN(F)?so(ee):F),I.M&&(te.M=isNaN(W)?Nc(ie):W),I.s&&(isNaN(ve)?(F=isNaN(F)?so(ee):F,W=isNaN(W)?Nc(ie):W,te.s=Al(W,F)):te.s=ve),I.H&&(te.H=isNaN(Oe)?a.fromHue(Me):Oe),te}function Ll(I){var z=qc(I),F=Mc(z),ee=r(F,3),W=ee[0],ie=ee[1],ve=ee[2],Me=W-ie*12/11+ve/11,Oe=(W+ie-2*ve)/9,te=H(Oe,Me),at=n.degree.fromRadian(te),Dt=1/4*(v(te+2)+3.8),Vt=Oc(F),bt=100*l(Vt/Kt,le*$c),Pe=5e4/13*qe*kc*Dt*f(Me*Me+Oe*Oe)/(W+ie+21/20*ve),je=l(Pe,.9)*f(bt/100)*l(1.64-l(.29,Xt),.73);return ao(X,{J:bt,C:je,h:at})}function El(I){var z=ao(q,I),F=z.J,ee=z.C,W=z.h,ie=n.degree.toRadian(W),ve=l(ee/(f(F/100)*l(1.64-l(.29,Xt),.73)),10/9),Me=1/4*(v(ie+2)+3.8),Oe=Kt*l(F/100,1/le/$c),te=5e4/13*qe*kc*Me/ve,at=Oe/no+.305,Dt=at*61/20*460/1403,Vt=61/20*220/1403,bt=21/20*6300/1403-27/1403,Pe=g(ie),je=v(ie),Ie,ze;ve===0||isNaN(ve)?Ie=ze=0:d(Pe)>=d(je)?(ze=Dt/(te/Pe+Vt*je/Pe+bt),Ie=ze*je/Pe):(Ie=Dt/(te/je+Vt+bt*Pe/je),ze=Ie*Pe/je);var Tl=[20/61*at+451/1403*Ie+288/1403*ze,20/61*at-891/1403*Ie-261/1403*ze,20/61*at-220/1403*Ie-6300/1403*ze],Sl=ql(Tl),Pl=Hl(Sl);return Pl}return{fromXyz:Ll,toXyz:El,fillOut:ao}}t.default=M,e.exports=t.default})(Ot,Ot.exports)),Ot.exports}var Nt={exports:{}},ga;function Ui(){return ga||(ga=1,(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var r=Rt(),n=Math,o=n.sqrt,a=n.pow,s=n.exp,c=n.log,i=n.cos,u=n.sin,l=n.atan2,f={LCD:{K_L:.77,c_1:.007,c_2:.0053},SCD:{K_L:1.24,c_1:.007,c_2:.0363},UCS:{K_L:1,c_1:.007,c_2:.0228}};function h(){var d=arguments.length<=0||arguments[0]===void 0?"UCS":arguments[0],b=f[d],_=b.K_L,g=b.c_1,v=b.c_2;function H(A){var R=A.J,m=A.M,p=A.h,y=r.degree.toRadian(p),w=(1+100*g)*R/(1+g*R),C=1/v*c(1+v*m),q=C*i(y),M=C*u(y);return{J_p:w,a_p:q,b_p:M}}function x(A){var R=A.J_p,m=A.a_p,p=A.b_p,y=-R/(g*R-100*g-1),w=o(a(m,2)+a(p,2)),C=(s(v*w)-1)/v,q=l(p,m),M=r.degree.fromRadian(q);return{J:y,M:C,h:M}}function N(A,R){return o(a((A.J_p-R.J_p)/_,2)+a(A.a_p-R.a_p,2)+a(A.b_p-R.b_p,2))}return{fromCam:H,toCam:x,distance:N}}t.default=h,e.exports=t.default})(Nt,Nt.exports)),Nt.exports}var Mn,va;function Qi(){if(va)return Mn;va=1;var e=qt(),t=Ji(),r=Wi(),n=Ui(),o=pa();return Mn={gamut:t,cfs:e.cfs,lerp:e.lerp,cam:r,ucs:n,hq:o},Mn}var eu=Qi();const _a=pr(eu),ya=_a.cam({whitePoint:Ht.illuminant.D65,adaptingLuminance:40,backgroundLuminance:20,surroundType:"average",discounting:!1},_a.cfs("JCh")),wa=Ht.xyz(Ht.workspace.sRGB,Ht.illuminant.D65),ka=e=>wa.toRgb(ya.toXyz({J:e[0],C:e[1],h:e[2]})),On=e=>{const t=ya.fromXyz(wa.fromRgb(e));return[t.J,t.C,t.h]},[tu,ru]=(()=>{const e={k_l:1,c1:.007,c2:.0228},t=Math.PI,r=64/t/5,n=1/(5*r+1),o=.2*n**4*(5*r)+.1*(1-n**4)**2*(5*r)**(1/3);return[a=>{const[s,c,i]=a,u=c*o**.25;let l=(1+100*e.c1)*s/(1+e.c1*s);l/=e.k_l;const f=1/e.c2*Math.log(1+e.c2*u),h=f*Math.cos(i*(t/180)),d=f*Math.sin(i*(t/180));return[l,h,d]},a=>{const[s,c,i]=a,u=Math.sqrt(c*c+i*i),l=(Math.exp(u*e.c2)-1)/e.c2,f=(180/t*Math.atan2(i,c)+360)%360,h=l/o**.25;return[s/(1+e.c1*(100-s)),h,f]}]})(),nu=e=>ka(ru(e)),$a=e=>tu(On(e)),At=console;At.color=(e,t="")=>{const n=O(e).luminance();At.log(`%c${e} ${t}`,`background-color: ${e};padding: 5px; border-radius: 5px; color: ${n>.5?"#000":"#fff"}`)},At.ramp=(e,t=1)=>{At.log("%c ",`font-size: 1px;line-height: 16px;background: ${O.getCSSGradient(e,t)};padding: 0 0 0 200px; border-radius: 2px;`)};const Ca=(e,t,r,n,o,a,s=.1)=>{if(e===r||t===n)return!0;const c=(n-t)/(r-e),i=(a+o/c-t+c*e)/(c+1/c),u=a+o/c-i/c;return(o-i)**2+(a-u)**2{const o=(t[0]+r[0])/2,a=e(o);return Ca(...t,...r,o,a,n)?null:[o,a]},Nn=(e,t,r,n=.1)=>{const o=(r-t)/10,a=[];for(let s=t;sMath.round(e*10**t)/10**t,su=(e,t=1,r=90,n=.005)=>{const o=Nn(i=>e(i).gl()[0],0,t,n),a=Nn(i=>e(i).gl()[1],0,t,n),s=Nn(i=>e(i).gl()[2],0,t,n),c=Array.from(new Set([...o.map(i=>Lt(i[0])),...a.map(i=>Lt(i[0])),...s.map(i=>Lt(i[0]))].sort((i,u)=>i-u)));return`linear-gradient(${r}deg, ${c.map(i=>`${e(i).hex()} ${Lt(i*100)}%`).join()});`},au=e=>{e.Color.prototype.jch=function(){return On(this._rgb.slice(0,3).map(o=>o/255))},e.jch=(...o)=>new e.Color(...ka(o).map(a=>Math.floor(a*255)),"rgb"),e.Color.prototype.jab=function(){return $a(this._rgb.slice(0,3).map(o=>o/255))},e.jab=(...o)=>new e.Color(...nu(o).map(a=>Math.floor(a*255)),"rgb"),e.Color.prototype.hsluv=function(){return gr.rgbToHsluv(this._rgb.slice(0,3).map(o=>o/255))},e.hsluv=(...o)=>new e.Color(...gr.hsluvToRgb(o).map(a=>Math.floor(a*255)),"rgb");const t=e.interpolate,r={jch:On,jab:$a,hsluv:gr.rgbToHsluv},n=(o,a,s)=>(Math.abs(o-a)>360/2&&(o>a?a+=360:o+=360),((1-s)*o+s*a)%360);e.interpolate=(o,a,s=.5,c="lrgb")=>{if(r[c]){typeof o!="object"&&(o=new e.Color(o)),typeof a!="object"&&(a=new e.Color(a));const i=r[c](o.gl()),u=r[c](a.gl()),l=Number.isNaN(o.hsl()[0]),f=Number.isNaN(a.hsl()[0]);let h,d,b;switch(c){case"hsluv":i[1]<1e-10&&(i[0]=u[0]),i[1]===0&&(i[1]=u[1]),u[1]<1e-10&&(u[0]=i[0]),u[1]===0&&(u[1]=i[1]),h=n(i[0],u[0],s),d=i[1]+(u[1]-i[1])*s,b=i[2]+(u[2]-i[2])*s;break;case"jch":l&&(i[2]=u[2]),f&&(u[2]=i[2]),h=i[0]+(u[0]-i[0])*s,d=i[1]+(u[1]-i[1])*s,b=n(i[2],u[2],s);break;default:h=i[0]+(u[0]-i[0])*s,d=i[1]+(u[1]-i[1])*s,b=i[2]+(u[2]-i[2])*s}return e[c](h,d,b).alpha(o.alpha()+s*(a.alpha()-o.alpha()))}return t(o,a,s,c)},e.getCSSGradient=su};const Y={mainTRC:2.4,sRco:.2126729,sGco:.7151522,sBco:.072175,normBG:.56,normTXT:.57,revTXT:.62,revBG:.65,blkThrs:.022,blkClmp:1.414,scaleBoW:1.14,scaleWoB:1.14,loBoWoffset:.027,loWoBoffset:.027,deltaYmin:5e-4,loClip:.1};function xa(e,t,r=-1){const n=[0,1.1];if(isNaN(e)||isNaN(t)||Math.min(e,t)n[1])return 0;let o=0,a=0,s="BoW";return e=e>Y.blkThrs?e:e+Math.pow(Y.blkThrs-e,Y.blkClmp),t=t>Y.blkThrs?t:t+Math.pow(Y.blkThrs-t,Y.blkClmp),Math.abs(t-e)e?(o=(Math.pow(t,Y.normBG)-Math.pow(e,Y.normTXT))*Y.scaleBoW,a=o-.1?0:o+Y.loWoBoffset),r<0?a*100:r==0?Math.round(Math.abs(a)*100)+""+s+"":Number.isInteger(r)?(a*100).toFixed(r):0)}function Et(e=[0,0,0]){function t(r){return Math.pow(r/255,Y.mainTRC)}return Y.sRco*t(e[0])+Y.sGco*t(e[1])+Y.sBco*t(e[2])}const Ra=(e,t,r,n,o,a,s,c,i)=>{const u=1-i,l=u*u,f=l*u,d=i*i*i,b=f*e+l*3*i*r+u*3*i*i*o+d*s,_=f*t+l*3*i*n+u*3*i*i*a+d*c;return{x:b,y:_}},cu=(e,t)=>{const r=[];let n={x:+e[0],y:+e[1]};for(let o=0,a=e.length;a-2*!0>o;o+=2){const s=[{x:+e[o-2],y:+e[o-1]},{x:+e[o],y:+e[o+1]},{x:+e[o+2],y:+e[o+3]},{x:+e[o+4],y:+e[o+5]}];a-4===o?s[3]=s[2]:o||(s[0]={x:+e[o],y:+e[o+1]}),r.push([n.x,n.y,(-s[0].x+6*s[1].x+s[2].x)/6,(-s[0].y+6*s[1].y+s[2].y)/6,(s[1].x+6*s[2].x-s[3].x)/6,(s[1].y+6*s[2].y-s[3].y)/6,s[2].x,s[2].y]),n=s[2]}return r},iu=(e,t,r,n,o,a,s,c)=>{let u=e,l=t,f=0;for(let h=1;h<5;h++){const{x:d,y:b}=Ra(e,t,r,n,o,a,s,c,h/5);f+=Math.hypot(d-u,b-l),u=d,l=b}return f+=Math.hypot(s-u,c-l),f},uu=(e,t,r,n,o,a,s,c)=>{const i=Math.floor(iu(e,t,r,n,o,a,s,c)*.75),u=[];let l=0;for(let f=0;f<=i;f++){const h=f/i,d=Ra(e,t,r,n,o,a,s,c,h),b=Math.round(d.x);if(u[b]=d.y,b-l>1){const _=u[l],g=u[b];for(let v=l+1;vu[Math.round(f)]||null},Ze={CAM02:"jab",CAM02p:"jch",HEX:"hex",HSL:"hsl",HSLuv:"hsluv",HSV:"hsv",LAB:"lab",LCH:"lch",RGB:"rgb",OKLAB:"oklab",OKLCH:"oklch"};function Ee(e,t=0){const r=10**t;return Math.round(e*r)/r}function fu(e,t){let r;return e>1?r=(e-1)*t+1:e<-1?r=(e+1)*t-1:r=1,Ee(r,2)}function lu(e){return O(String(e)).jch()}function hu(e){return O(String(e)).hsluv()}function du(e,t,r){const n=[[],[],[]];if(e.forEach((a,s)=>n.forEach((c,i)=>c.push(t[s],a[i]))),r==="hcl"){const a=n[1];for(let s=1;s{const s=[];for(let c=1;c{a[i]=a[c]}),s.length=0;break}if(s.length){const c=O("#ccc").jch()[2];s.forEach(i=>{a[i]=c})}s.length=0;for(let c=a.length-1;c>0;c-=2)if(Number.isNaN(a[c]))s.push(c);else{s.forEach(i=>{a[i]=a[c]});break}for(let c=1;ccu(a).map(s=>uu(...s)));return a=>{const s=o.map(c=>{for(let i=0;in*a**e+o}function An({swatches:e,colorKeys:t,colorspace:r="LAB",shift:n=1,fullScale:o=!0,smooth:a=!1,distributeLightness:s="linear",sortColor:c=!0,asFun:i=!1}={}){const u=Ze[r];if(!u)throw new Error(`Colorspace “${r}” not supported`);if(!t)throw new Error(`Colorkeys missing: returned “${t}”`);let l;if(o)l=t.map(H=>e-e*(O(H).jch()[0]/100)).sort((H,x)=>H-x).concat(e),l.unshift(0);else{let H=t.map(A=>O(A).jch()[0]/100),x=Math.min(...H),N=Math.max(...H);l=H.map(A=>A===0||isNaN((A-x)/(N-x))?0:e-(A-x)/(N-x)*e).sort((A,R)=>A-R)}let f=bu(n,[1,e],[1,e]);if(f=l.map(H=>Math.max(0,f(H))),l=f,s==="polynomial"){const H=A=>Math.sqrt(Math.sqrt((Math.pow(A,2.25)+Math.pow(A,4))/2));l=f.map(A=>A/e).map(A=>H(A)*e)}const h=t.map((H,x)=>({colorKeys:lu(H),index:x})).sort((H,x)=>x.colorKeys[0]-H.colorKeys[0]).map(H=>t[H.index]);let d=[],b;if(o){const H=u==="lch"?O.lch(...O("#fff").lch()):"#ffffff",x=u==="lch"?O.lch(...O("#000").lch()):"#000000";d=[H,...h,x]}else c?d=h:d=t;let _;if(a){const H=d;if(d=d.map(x=>O(String(x))[u]()),u==="hcl"&&d.forEach(x=>{x[1]=Number.isNaN(x[1])?0:x[1]}),u==="jch")for(let x=0;xb(N))}else b=O.scale(d.map(H=>typeof H=="object"&&H.constructor===O.Color?H:String(H))).domain(l).mode(u);return i?b:(!a||a===!1?b.colors(e):_).filter(H=>H!=null)}function pu(e,t){const r=[],n={};return Object.keys(e).forEach(s=>{n[e[s][t]]=e[s]}),Object.keys(n).forEach(s=>r.push(n[s])),r}function mu(e){return Number.isNaN(e)?0:e}function Ln(e,t,r=!1){if(!e)throw new Error(`Cannot convert color value of “${e}”`);if(!Ze[t])throw new Error(`Cannot convert to colorspace “${t}”`);const n=Ze[t],o=O(String(e))[n]();if(t==="HSL"&&o.pop(),t==="HEX"){if(r){const u=O(String(e)).rgb();return{r:u[0],g:u[1],b:u[2]}}return o}const a={};let s=o.map(mu);s=s.map((u,l)=>{let f=Ee(u),h=l;n==="hsluv"&&(h+=2);let d=n.charAt(h);return n==="jch"&&d==="c"&&(d="C"),a[d==="j"?"J":d]=f,n in{lab:1,lch:1,jab:1,jch:1}?r||((d==="l"||d==="j")&&(f+="%"),d==="h"&&(f+="deg")):n!=="hsluv"&&(d==="s"||d==="l"||d==="v"?(a[d]=Ee(u,2),r||(f=Ee(u*100),f+="%")):d==="h"&&!r&&(f+="deg")),f});const i=`${n}(${s.join(", ")})`;return r?a:i}function Ha(e,t,r){const n=[e,t,r].map(o=>(o/=255,o<=.03928?o/12.92:((o+.055)/1.055)**2.4));return n[0]*.2126+n[1]*.7152+n[2]*.0722}function gu(e,t,r,n="wcag2"){if(r===void 0){const o=O.rgb(...t).hsluv()[2];r=Ee(o/100,2)}if(n==="wcag2"){const o=Ha(e[0],e[1],e[2]),a=Ha(t[0],t[1],t[2]),s=(o+.05)/(a+.05),c=(a+.05)/(o+.05);return r<.5?s>=1?s:-c:s<1?c:s===1?s:-s}else{if(n==="wcag3")return r<.5?xa(Et(e),Et(t))*-1:xa(Et(e),Et(t));throw new Error(`Contrast calculation method ${n} unsupported; use 'wcag2' or 'wcag3'`)}}function vu(e,t){if(!e)throw new Error("Array undefined");if(!Array.isArray(e))throw new Error("Passed object is not an array");const r=t==="wcag2"?0:1;return Math.min(...e.filter(n=>n>=r))}function _u(e,t){if(!e)throw new Error("Ratios undefined");e=e.sort((c,i)=>c-i);const r=vu(e,t),n=e.indexOf(r),o=[],a=e.slice(0,n),s=e.slice(n,e.length);for(let c=0;cc-i),o}const yu=(e,t,r,n,o)=>{const s=An({swatches:3e3,colorKeys:e._modifiedKeys,colorspace:e._colorspace,shift:1,smooth:e._smooth,asFun:!0}),c={},i=f=>{if(c[f])return c[f];const h=O(s(f)).rgb(),d=gu(h,t,r,o);return c[f]=d,d},u=f=>{const h=i(0),d=i(3e3),b=h_&&x;)x--,g/=2,Hl.push(s(u(+f)))),l};let ae=class{constructor({name:t,colorKeys:r,colorspace:n="RGB",ratios:o,smooth:a=!1,output:s="HEX",saturation:c=100}){if(this._name=t,this._colorKeys=r,this._modifiedKeys=r,this._colorspace=n,this._ratios=o,this._smooth=a,this._output=s,this._saturation=c,!this._name)throw new Error("Color missing name");if(!this._colorKeys)throw new Error("Color Keys are undefined");if(!Ze[this._colorspace])throw new Error(`Colorspace “${n}” not supported`);if(!Ze[this._output])throw new Error(`Output “${n}” not supported`);for(let i=0;i{let n=O(`${r}`).oklch(),a=n[1]*(this._saturation/100),s=O.oklch(n[0],a,n[2]),c=O.rgb(s).hex();t.push(c)}),this._modifiedKeys=t,this._generateColorScale()}_generateColorScale(){this._colorScale=An({swatches:3e3,colorKeys:this._modifiedKeys,colorspace:this._colorspace,shift:1,smooth:this._smooth,asFun:!0})}};class qa extends ae{get backgroundColorScale(){return this._backgroundColorScale||this._generateColorScale(),this._backgroundColorScale}_generateColorScale(){ae.prototype._generateColorScale.call(this);const t=An({swatches:1e3,colorKeys:this._colorKeys,colorspace:this._colorspace,shift:1,smooth:this._smooth});t.push(...this.colorKeys);const r=t.map((a,s)=>({value:Math.round(hu(a)[2]),index:s})),o=pu(r,"value").map(a=>t[a.index]);return o.length>=101&&(o.length=100,o.push("#ffffff")),this._backgroundColorScale=o.map(a=>Ln(a,this._output)),this._backgroundColorScale}}class wu{constructor({colors:t,backgroundColor:r,lightness:n,contrast:o=1,saturation:a=100,output:s="HEX",formula:c="wcag2"}){if(this._output=s,this._colors=t,this._lightness=n,this._saturation=a,this._formula=c,this._setBackgroundColor(r),this._setBackgroundColorValue(),this._contrast=o,!this._colors)throw new Error("No colors are defined");if(!this._backgroundColor)throw new Error("Background color is undefined");if(t.forEach(i=>{if(!i.ratios)throw new Error(`Color ${i.name}'s ratios are undefined`)}),!Ze[this._output])throw new Error(`Output “${s}” not supported`);this._saturation<100&&this._updateColorSaturation(this._saturation),this._findContrastColors(),this._findContrastColorPairs(),this._findContrastColorValues()}set formula(t){this._formula=t,this._findContrastColors()}get formula(){return this._formula}set contrast(t){this._contrast=t,this._findContrastColors()}get contrast(){return this._contrast}set lightness(t){this._lightness=t,this._setBackgroundColor(this._backgroundColor),this._findContrastColors()}get lightness(){return this._lightness}set saturation(t){this._saturation=t,this._updateColorSaturation(t),this._findContrastColors()}get saturation(){return this._saturation}set backgroundColor(t){this._setBackgroundColor(t),this._findContrastColors()}get backgroundColorValue(){return this._backgroundColorValue}get backgroundColor(){return this._backgroundColor}set colors(t){this._colors=t,this._findContrastColors()}get colors(){return this._colors}set addColor(t){this._colors.push(t),this._findContrastColors()}set removeColor(t){const r=this._colors.filter(n=>n.name!==t.name);this._colors=r,this._findContrastColors()}set updateColor(t){if(Array.isArray(t))for(let r=0;rs.name===t[r].color);n=n[0];let o=this._colors.indexOf(n);const a=this._colors.filter(s=>s.name!==t[r].color);t[r].name&&(n.name=t[r].name),t[r].colorKeys&&(n.colorKeys=t[r].colorKeys),t[r].ratios&&(n.ratios=t[r].ratios),t[r].colorspace&&(n.colorspace=t[r].colorspace),t[r].smooth&&(n.smooth=t[r].smooth),n._generateColorScale(),a.splice(o,0,n),this._colors=a}else{let r=this._colors.filter(a=>a.name===t.color);r=r[0];let n=this._colors.indexOf(r);const o=this._colors.filter(a=>a.name!==t.color);t.name&&(r.name=t.name),t.colorKeys&&(r.colorKeys=t.colorKeys),t.ratios&&(r.ratios=t.ratios),t.colorspace&&(r.colorspace=t.colorspace),t.smooth&&(r.smooth=t.smooth),r._generateColorScale(),o.splice(n,0,r),this._colors=o}this._findContrastColors()}set output(t){this._output=t,this._colors.forEach(r=>{r.output=this._output}),this._backgroundColor.output=this._output,this._findContrastColors()}get output(){return this._output}get contrastColors(){return this._contrastColors}get contrastColorPairs(){return this._contrastColorPairs}get contrastColorValues(){return this._contrastColorValues}_setBackgroundColor(t){if(typeof t=="string"){const r=new qa({name:"background",colorKeys:[t],output:"RGB"}),n=Ee(O(String(t)).hsluv()[2]);this._backgroundColor=r,this._lightness=n,this._backgroundColorValue=r[this._lightness]}else{t.output="RGB";const r=t.backgroundColorScale[this._lightness];this._backgroundColor=t,this._backgroundColorValue=r}}_setBackgroundColorValue(){this._backgroundColorValue=this._backgroundColor.backgroundColorScale[this._lightness]}_updateColorSaturation(t){this._colors.map(r=>{r.saturation=t})}_findContrastColors(){const t=O(String(this._backgroundColorValue)).rgb(),r=this._lightness/100,o={background:Ln(this._backgroundColorValue,this._output)},a=[],s=[],c={...o};return a.push(o),this._colors.map(i=>{if(i.ratios!==void 0){let u;const l=[],f={name:i.name,values:l};let h;Array.isArray(i.ratios)?h=i.ratios:Array.isArray(i.ratios)||(u=Object.keys(i.ratios),h=Object.values(i.ratios)),h=h.map(b=>fu(+b,this._contrast));const d=yu(i,t,r,h,this._formula).map(b=>Ln(b,this._output));for(let b=0;bku($u(t,e),r),En=e=>{e._clipped=!1,e._unclipped=e.slice(0);for(let t=0;t<=3;t++)t<3?((e[t]<0||e[t]>255)&&(e._clipped=!0),e[t]=Be(e[t],0,255)):t===3&&(e[t]=Be(e[t],0,1));return e},Ma={};for(let e of["Boolean","Number","String","Function","Array","Date","RegExp","Undefined","Null"])Ma[`[object ${e}]`]=e.toLowerCase();function B(e){return Ma[Object.prototype.toString.call(e)]||"object"}const T=(e,t=null)=>e.length>=3?Array.prototype.slice.call(e):B(e[0])=="object"&&t?t.split("").filter(r=>e[0][r]!==void 0).map(r=>e[0][r]):e[0].slice(0),Je=e=>{if(e.length<2)return null;const t=e.length-1;return B(e[t])=="string"?e[t].toLowerCase():null},{PI:Tt,min:Oa,max:Na}=Math,ue=e=>Math.round(e*100)/100,Tn=e=>Math.round(e*100)/100,Ce=Tt*2,Sn=Tt/3,Cu=Tt/180,xu=180/Tt;function Aa(e){return[...e.slice(0,3).reverse(),...e.slice(3)]}const E={format:{},autodetect:[]};class k{constructor(...t){const r=this;if(B(t[0])==="object"&&t[0].constructor&&t[0].constructor===this.constructor)return t[0];let n=Je(t),o=!1;if(!n){o=!0,E.sorted||(E.autodetect=E.autodetect.sort((a,s)=>s.p-a.p),E.sorted=!0);for(let a of E.autodetect)if(n=a.test(...t),n)break}if(E.format[n]){const a=E.format[n].apply(null,o?t:t.slice(0,-1));r._rgb=En(a)}else throw new Error("unknown format: "+t);r._rgb.length===3&&r._rgb.push(1)}toString(){return B(this.hex)=="function"?this.hex():`[${this._rgb.join(",")}]`}}const Ru="3.2.0",G=(...e)=>new k(...e);G.version=Ru;const We={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",laserlemon:"#ffff54",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrod:"#fafad2",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",maroon2:"#7f0000",maroon3:"#b03060",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",purple2:"#7f007f",purple3:"#a020f0",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},Hu=/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,qu=/^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/,La=e=>{if(e.match(Hu)){(e.length===4||e.length===7)&&(e=e.substr(1)),e.length===3&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]);const t=parseInt(e,16),r=t>>16,n=t>>8&255,o=t&255;return[r,n,o,1]}if(e.match(qu)){(e.length===5||e.length===9)&&(e=e.substr(1)),e.length===4&&(e=e.split(""),e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]+e[3]+e[3]);const t=parseInt(e,16),r=t>>24&255,n=t>>16&255,o=t>>8&255,a=Math.round((t&255)/255*100)/100;return[r,n,o,a]}throw new Error(`unknown hex color: ${e}`)},{round:St}=Math,Ea=(...e)=>{let[t,r,n,o]=T(e,"rgba"),a=Je(e)||"auto";o===void 0&&(o=1),a==="auto"&&(a=o<1?"rgba":"rgb"),t=St(t),r=St(r),n=St(n);let c="000000"+(t<<16|r<<8|n).toString(16);c=c.substr(c.length-6);let i="0"+St(o*255).toString(16);switch(i=i.substr(i.length-2),a.toLowerCase()){case"rgba":return`#${c}${i}`;case"argb":return`#${i}${c}`;default:return`#${c}`}};k.prototype.name=function(){const e=Ea(this._rgb,"rgb");for(let t of Object.keys(We))if(We[t]===e)return t.toLowerCase();return e},E.format.named=e=>{if(e=e.toLowerCase(),We[e])return La(We[e]);throw new Error("unknown color name: "+e)},E.autodetect.push({p:5,test:(e,...t)=>{if(!t.length&&B(e)==="string"&&We[e.toLowerCase()])return"named"}}),k.prototype.alpha=function(e,t=!1){return e!==void 0&&B(e)==="number"?t?(this._rgb[3]=e,this):new k([this._rgb[0],this._rgb[1],this._rgb[2],e],"rgb"):this._rgb[3]},k.prototype.clipped=function(){return this._rgb._clipped||!1};const _e={Kn:18,labWhitePoint:"d65",Xn:.95047,Yn:1,Zn:1.08883,kE:216/24389,kKE:8,kK:24389/27,RefWhiteRGB:{X:.95047,Y:1,Z:1.08883},MtxRGB2XYZ:{m00:.4124564390896922,m01:.21267285140562253,m02:.0193338955823293,m10:.357576077643909,m11:.715152155287818,m12:.11919202588130297,m20:.18043748326639894,m21:.07217499330655958,m22:.9503040785363679},MtxXYZ2RGB:{m00:3.2404541621141045,m01:-.9692660305051868,m02:.055643430959114726,m10:-1.5371385127977166,m11:1.8760108454466942,m12:-.2040259135167538,m20:-.498531409556016,m21:.041556017530349834,m22:1.0572251882231791},As:.9414285350000001,Bs:1.040417467,Cs:1.089532651,MtxAdaptMa:{m00:.8951,m01:-.7502,m02:.0389,m10:.2664,m11:1.7135,m12:-.0685,m20:-.1614,m21:.0367,m22:1.0296},MtxAdaptMaI:{m00:.9869929054667123,m01:.43230526972339456,m02:-.008528664575177328,m10:-.14705425642099013,m11:.5183602715367776,m12:.04004282165408487,m20:.15996265166373125,m21:.0492912282128556,m22:.9684866957875502}},Mu=new Map([["a",[1.0985,.35585]],["b",[1.0985,.35585]],["c",[.98074,1.18232]],["d50",[.96422,.82521]],["d55",[.95682,.92149]],["d65",[.95047,1.08883]],["e",[1,1,1]],["f2",[.99186,.67393]],["f7",[.95041,1.08747]],["f11",[1.00962,.6435]],["icc",[.96422,.82521]]]);function xe(e){const t=Mu.get(String(e).toLowerCase());if(!t)throw new Error("unknown Lab illuminant "+e);_e.labWhitePoint=e,_e.Xn=t[0],_e.Zn=t[1]}function dt(){return _e.labWhitePoint}const Pn=(...e)=>{e=T(e,"lab");const[t,r,n]=e,[o,a,s]=Ou(t,r,n),[c,i,u]=Ta(o,a,s);return[c,i,u,e.length>3?e[3]:1]},Ou=(e,t,r)=>{const{kE:n,kK:o,kKE:a,Xn:s,Yn:c,Zn:i}=_e,u=(e+16)/116,l=.002*t+u,f=u-.005*r,h=l*l*l,d=f*f*f,b=h>n?h:(116*l-16)/o,_=e>a?Math.pow((e+16)/116,3):e/o,g=d>n?d:(116*f-16)/o,v=b*s,H=_*c,x=g*i;return[v,H,x]},jn=e=>{const t=Math.sign(e);return e=Math.abs(e),(e<=.0031308?e*12.92:1.055*Math.pow(e,1/2.4)-.055)*t},Ta=(e,t,r)=>{const{MtxAdaptMa:n,MtxAdaptMaI:o,MtxXYZ2RGB:a,RefWhiteRGB:s,Xn:c,Yn:i,Zn:u}=_e,l=c*n.m00+i*n.m10+u*n.m20,f=c*n.m01+i*n.m11+u*n.m21,h=c*n.m02+i*n.m12+u*n.m22,d=s.X*n.m00+s.Y*n.m10+s.Z*n.m20,b=s.X*n.m01+s.Y*n.m11+s.Z*n.m21,_=s.X*n.m02+s.Y*n.m12+s.Z*n.m22,g=(e*n.m00+t*n.m10+r*n.m20)*(d/l),v=(e*n.m01+t*n.m11+r*n.m21)*(b/f),H=(e*n.m02+t*n.m12+r*n.m22)*(_/h),x=g*o.m00+v*o.m10+H*o.m20,N=g*o.m01+v*o.m11+H*o.m21,A=g*o.m02+v*o.m12+H*o.m22,R=jn(x*a.m00+N*a.m10+A*a.m20),m=jn(x*a.m01+N*a.m11+A*a.m21),p=jn(x*a.m02+N*a.m12+A*a.m22);return[R*255,m*255,p*255]},Bn=(...e)=>{const[t,r,n,...o]=T(e,"rgb"),[a,s,c]=Sa(t,r,n),[i,u,l]=Nu(a,s,c);return[i,u,l,...o.length>0&&o[0]<1?[o[0]]:[]]};function Nu(e,t,r){const{Xn:n,Yn:o,Zn:a,kE:s,kK:c}=_e,i=e/n,u=t/o,l=r/a,f=i>s?Math.pow(i,1/3):(c*i+16)/116,h=u>s?Math.pow(u,1/3):(c*u+16)/116,d=l>s?Math.pow(l,1/3):(c*l+16)/116;return[116*h-16,500*(f-h),200*(h-d)]}function Gn(e){const t=Math.sign(e);return e=Math.abs(e),(e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4))*t}const Sa=(e,t,r)=>{e=Gn(e/255),t=Gn(t/255),r=Gn(r/255);const{MtxRGB2XYZ:n,MtxAdaptMa:o,MtxAdaptMaI:a,Xn:s,Yn:c,Zn:i,As:u,Bs:l,Cs:f}=_e;let h=e*n.m00+t*n.m10+r*n.m20,d=e*n.m01+t*n.m11+r*n.m21,b=e*n.m02+t*n.m12+r*n.m22;const _=s*o.m00+c*o.m10+i*o.m20,g=s*o.m01+c*o.m11+i*o.m21,v=s*o.m02+c*o.m12+i*o.m22;let H=h*o.m00+d*o.m10+b*o.m20,x=h*o.m01+d*o.m11+b*o.m21,N=h*o.m02+d*o.m12+b*o.m22;return H*=_/u,x*=g/l,N*=v/f,h=H*a.m00+x*a.m10+N*a.m20,d=H*a.m01+x*a.m11+N*a.m21,b=H*a.m02+x*a.m12+N*a.m22,[h,d,b]};k.prototype.lab=function(){return Bn(this._rgb)},Object.assign(G,{lab:(...e)=>new k(...e,"lab"),getLabWhitePoint:dt,setLabWhitePoint:xe}),E.format.lab=Pn,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"lab"),B(e)==="array"&&e.length===3)return"lab"}}),k.prototype.darken=function(e=1){const t=this,r=t.lab();return r[0]-=_e.Kn*e,new k(r,"lab").alpha(t.alpha(),!0)},k.prototype.brighten=function(e=1){return this.darken(-e)},k.prototype.darker=k.prototype.darken,k.prototype.brighter=k.prototype.brighten,k.prototype.get=function(e){const[t,r]=e.split("."),n=this[t]();if(r){const o=t.indexOf(r)-(t.substr(0,2)==="ok"?2:0);if(o>-1)return n[o];throw new Error(`unknown channel ${r} in mode ${t}`)}else return n};const{pow:Au}=Math,Lu=1e-7,Eu=20;k.prototype.luminance=function(e,t="rgb"){if(e!==void 0&&B(e)==="number"){if(e===0)return new k([0,0,0,this._rgb[3]],"rgb");if(e===1)return new k([255,255,255,this._rgb[3]],"rgb");let r=this.luminance(),n=Eu;const o=(s,c)=>{const i=s.interpolate(c,.5,t),u=i.luminance();return Math.abs(e-u)e?o(s,i):o(i,c)},a=(r>e?o(new k([0,0,0]),this):o(this,new k([255,255,255]))).rgb();return new k([...a,this._rgb[3]])}return Tu(...this._rgb.slice(0,3))};const Tu=(e,t,r)=>(e=In(e),t=In(t),r=In(r),.2126*e+.7152*t+.0722*r),In=e=>(e/=255,e<=.03928?e/12.92:Au((e+.055)/1.055,2.4)),ne={},Ue=(e,t,r=.5,...n)=>{let o=n[0]||"lrgb";if(!ne[o]&&!n.length&&(o=Object.keys(ne)[0]),!ne[o])throw new Error(`interpolation mode ${o} is not defined`);return B(e)!=="object"&&(e=new k(e)),B(t)!=="object"&&(t=new k(t)),ne[o](e,t,r).alpha(e.alpha()+r*(t.alpha()-e.alpha()))};k.prototype.mix=k.prototype.interpolate=function(e,t=.5,...r){return Ue(this,e,t,...r)},k.prototype.premultiply=function(e=!1){const t=this._rgb,r=t[3];return e?(this._rgb=[t[0]*r,t[1]*r,t[2]*r,r],this):new k([t[0]*r,t[1]*r,t[2]*r,r],"rgb")};const{sin:Su,cos:Pu}=Math,Pa=(...e)=>{let[t,r,n]=T(e,"lch");return isNaN(n)&&(n=0),n=n*Cu,[t,Pu(n)*r,Su(n)*r]},zn=(...e)=>{e=T(e,"lch");const[t,r,n]=e,[o,a,s]=Pa(t,r,n),[c,i,u]=Pn(o,a,s);return[c,i,u,e.length>3?e[3]:1]},ju=(...e)=>{const t=Aa(T(e,"hcl"));return zn(...t)},{sqrt:Bu,atan2:Gu,round:Iu}=Math,ja=(...e)=>{const[t,r,n]=T(e,"lab"),o=Bu(r*r+n*n);let a=(Gu(n,r)*xu+360)%360;return Iu(o*1e4)===0&&(a=Number.NaN),[t,o,a]},Fn=(...e)=>{const[t,r,n,...o]=T(e,"rgb"),[a,s,c]=Bn(t,r,n),[i,u,l]=ja(a,s,c);return[i,u,l,...o.length>0&&o[0]<1?[o[0]]:[]]};k.prototype.lch=function(){return Fn(this._rgb)},k.prototype.hcl=function(){return Aa(Fn(this._rgb))},Object.assign(G,{lch:(...e)=>new k(...e,"lch"),hcl:(...e)=>new k(...e,"hcl")}),E.format.lch=zn,E.format.hcl=ju,["lch","hcl"].forEach(e=>E.autodetect.push({p:2,test:(...t)=>{if(t=T(t,e),B(t)==="array"&&t.length===3)return e}})),k.prototype.saturate=function(e=1){const t=this,r=t.lch();return r[1]+=_e.Kn*e,r[1]<0&&(r[1]=0),new k(r,"lch").alpha(t.alpha(),!0)},k.prototype.desaturate=function(e=1){return this.saturate(-e)},k.prototype.set=function(e,t,r=!1){const[n,o]=e.split("."),a=this[n]();if(o){const s=n.indexOf(o)-(n.substr(0,2)==="ok"?2:0);if(s>-1){if(B(t)=="string")switch(t.charAt(0)){case"+":a[s]+=+t;break;case"-":a[s]+=+t;break;case"*":a[s]*=+t.substr(1);break;case"/":a[s]/=+t.substr(1);break;default:a[s]=+t}else if(B(t)==="number")a[s]=t;else throw new Error("unsupported value for Color.set");const c=new k(a,n);return r?(this._rgb=c._rgb,this):c}throw new Error(`unknown channel ${o} in mode ${n}`)}else return a},k.prototype.tint=function(e=.5,...t){return Ue(this,"white",e,...t)},k.prototype.shade=function(e=.5,...t){return Ue(this,"black",e,...t)};const zu=(e,t,r)=>{const n=e._rgb,o=t._rgb;return new k(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"rgb")};ne.rgb=zu;const{sqrt:Xn,pow:Qe}=Math,Fu=(e,t,r)=>{const[n,o,a]=e._rgb,[s,c,i]=t._rgb;return new k(Xn(Qe(n,2)*(1-r)+Qe(s,2)*r),Xn(Qe(o,2)*(1-r)+Qe(c,2)*r),Xn(Qe(a,2)*(1-r)+Qe(i,2)*r),"rgb")};ne.lrgb=Fu;const Xu=(e,t,r)=>{const n=e.lab(),o=t.lab();return new k(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"lab")};ne.lab=Xu;const et=(e,t,r,n)=>{let o,a;n==="hsl"?(o=e.hsl(),a=t.hsl()):n==="hsv"?(o=e.hsv(),a=t.hsv()):n==="hcg"?(o=e.hcg(),a=t.hcg()):n==="hsi"?(o=e.hsi(),a=t.hsi()):n==="lch"||n==="hcl"?(n="hcl",o=e.hcl(),a=t.hcl()):n==="oklch"&&(o=e.oklch().reverse(),a=t.oklch().reverse());let s,c,i,u,l,f;(n.substr(0,1)==="h"||n==="oklch")&&([s,i,l]=o,[c,u,f]=a);let h,d,b,_;return!isNaN(s)&&!isNaN(c)?(c>s&&c-s>180?_=c-(s+360):c180?_=c+360-s:_=c-s,d=s+r*_):isNaN(s)?isNaN(c)?d=Number.NaN:(d=c,(l==1||l==0)&&n!="hsv"&&(h=u)):(d=s,(f==1||f==0)&&n!="hsv"&&(h=i)),h===void 0&&(h=i+r*(u-i)),b=l+r*(f-l),n==="oklch"?new k([b,h,d],n):new k([d,h,b],n)},Ba=(e,t,r)=>et(e,t,r,"lch");ne.lch=Ba,ne.hcl=Ba;const Ku=e=>{if(B(e)=="number"&&e>=0&&e<=16777215){const t=e>>16,r=e>>8&255,n=e&255;return[t,r,n,1]}throw new Error("unknown num color: "+e)},Du=(...e)=>{const[t,r,n]=T(e,"rgb");return(t<<16)+(r<<8)+n};k.prototype.num=function(){return Du(this._rgb)},Object.assign(G,{num:(...e)=>new k(...e,"num")}),E.format.num=Ku,E.autodetect.push({p:5,test:(...e)=>{if(e.length===1&&B(e[0])==="number"&&e[0]>=0&&e[0]<=16777215)return"num"}});const Vu=(e,t,r)=>{const n=e.num(),o=t.num();return new k(n+r*(o-n),"num")};ne.num=Vu;const{floor:Yu}=Math,Zu=(...e)=>{e=T(e,"hcg");let[t,r,n]=e,o,a,s;n=n*255;const c=r*255;if(r===0)o=a=s=n;else{t===360&&(t=0),t>360&&(t-=360),t<0&&(t+=360),t/=60;const i=Yu(t),u=t-i,l=n*(1-r),f=l+c*(1-u),h=l+c*u,d=l+c;switch(i){case 0:[o,a,s]=[d,h,l];break;case 1:[o,a,s]=[f,d,l];break;case 2:[o,a,s]=[l,d,h];break;case 3:[o,a,s]=[l,f,d];break;case 4:[o,a,s]=[h,l,d];break;case 5:[o,a,s]=[d,l,f];break}}return[o,a,s,e.length>3?e[3]:1]},Ju=(...e)=>{const[t,r,n]=T(e,"rgb"),o=Oa(t,r,n),a=Na(t,r,n),s=a-o,c=s*100/255,i=o/(255-s)*100;let u;return s===0?u=Number.NaN:(t===a&&(u=(r-n)/s),r===a&&(u=2+(n-t)/s),n===a&&(u=4+(t-r)/s),u*=60,u<0&&(u+=360)),[u,c,i]};k.prototype.hcg=function(){return Ju(this._rgb)};const Wu=(...e)=>new k(...e,"hcg");G.hcg=Wu,E.format.hcg=Zu,E.autodetect.push({p:1,test:(...e)=>{if(e=T(e,"hcg"),B(e)==="array"&&e.length===3)return"hcg"}});const Uu=(e,t,r)=>et(e,t,r,"hcg");ne.hcg=Uu;const{cos:tt}=Math,Qu=(...e)=>{e=T(e,"hsi");let[t,r,n]=e,o,a,s;return isNaN(t)&&(t=0),isNaN(r)&&(r=0),t>360&&(t-=360),t<0&&(t+=360),t/=360,t<1/3?(s=(1-r)/3,o=(1+r*tt(Ce*t)/tt(Sn-Ce*t))/3,a=1-(s+o)):t<2/3?(t-=1/3,o=(1-r)/3,a=(1+r*tt(Ce*t)/tt(Sn-Ce*t))/3,s=1-(o+a)):(t-=2/3,a=(1-r)/3,s=(1+r*tt(Ce*t)/tt(Sn-Ce*t))/3,o=1-(a+s)),o=Be(n*o*3),a=Be(n*a*3),s=Be(n*s*3),[o*255,a*255,s*255,e.length>3?e[3]:1]},{min:ef,sqrt:tf,acos:rf}=Math,nf=(...e)=>{let[t,r,n]=T(e,"rgb");t/=255,r/=255,n/=255;let o;const a=ef(t,r,n),s=(t+r+n)/3,c=s>0?1-a/s:0;return c===0?o=NaN:(o=(t-r+(t-n))/2,o/=tf((t-r)*(t-r)+(t-n)*(r-n)),o=rf(o),n>r&&(o=Ce-o),o/=Ce),[o*360,c,s]};k.prototype.hsi=function(){return nf(this._rgb)};const of=(...e)=>new k(...e,"hsi");G.hsi=of,E.format.hsi=Qu,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"hsi"),B(e)==="array"&&e.length===3)return"hsi"}});const sf=(e,t,r)=>et(e,t,r,"hsi");ne.hsi=sf;const Kn=(...e)=>{e=T(e,"hsl");const[t,r,n]=e;let o,a,s;if(r===0)o=a=s=n*255;else{const c=[0,0,0],i=[0,0,0],u=n<.5?n*(1+r):n+r-n*r,l=2*n-u,f=t/360;c[0]=f+1/3,c[1]=f,c[2]=f-1/3;for(let h=0;h<3;h++)c[h]<0&&(c[h]+=1),c[h]>1&&(c[h]-=1),6*c[h]<1?i[h]=l+(u-l)*6*c[h]:2*c[h]<1?i[h]=u:3*c[h]<2?i[h]=l+(u-l)*(2/3-c[h])*6:i[h]=l;[o,a,s]=[i[0]*255,i[1]*255,i[2]*255]}return e.length>3?[o,a,s,e[3]]:[o,a,s,1]},Ga=(...e)=>{e=T(e,"rgba");let[t,r,n]=e;t/=255,r/=255,n/=255;const o=Oa(t,r,n),a=Na(t,r,n),s=(a+o)/2;let c,i;return a===o?(c=0,i=Number.NaN):c=s<.5?(a-o)/(a+o):(a-o)/(2-a-o),t==a?i=(r-n)/(a-o):r==a?i=2+(n-t)/(a-o):n==a&&(i=4+(t-r)/(a-o)),i*=60,i<0&&(i+=360),e.length>3&&e[3]!==void 0?[i,c,s,e[3]]:[i,c,s]};k.prototype.hsl=function(){return Ga(this._rgb)};const af=(...e)=>new k(...e,"hsl");G.hsl=af,E.format.hsl=Kn,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"hsl"),B(e)==="array"&&e.length===3)return"hsl"}});const cf=(e,t,r)=>et(e,t,r,"hsl");ne.hsl=cf;const{floor:uf}=Math,ff=(...e)=>{e=T(e,"hsv");let[t,r,n]=e,o,a,s;if(n*=255,r===0)o=a=s=n;else{t===360&&(t=0),t>360&&(t-=360),t<0&&(t+=360),t/=60;const c=uf(t),i=t-c,u=n*(1-r),l=n*(1-r*i),f=n*(1-r*(1-i));switch(c){case 0:[o,a,s]=[n,f,u];break;case 1:[o,a,s]=[l,n,u];break;case 2:[o,a,s]=[u,n,f];break;case 3:[o,a,s]=[u,l,n];break;case 4:[o,a,s]=[f,u,n];break;case 5:[o,a,s]=[n,u,l];break}}return[o,a,s,e.length>3?e[3]:1]},{min:lf,max:hf}=Math,df=(...e)=>{e=T(e,"rgb");let[t,r,n]=e;const o=lf(t,r,n),a=hf(t,r,n),s=a-o;let c,i,u;return u=a/255,a===0?(c=Number.NaN,i=0):(i=s/a,t===a&&(c=(r-n)/s),r===a&&(c=2+(n-t)/s),n===a&&(c=4+(t-r)/s),c*=60,c<0&&(c+=360)),[c,i,u]};k.prototype.hsv=function(){return df(this._rgb)};const bf=(...e)=>new k(...e,"hsv");G.hsv=bf,E.format.hsv=ff,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"hsv"),B(e)==="array"&&e.length===3)return"hsv"}});const pf=(e,t,r)=>et(e,t,r,"hsv");ne.hsv=pf;function Pt(e,t){let r=e.length;Array.isArray(e[0])||(e=[e]),Array.isArray(t[0])||(t=t.map(s=>[s]));let n=t[0].length,o=t[0].map((s,c)=>t.map(i=>i[c])),a=e.map(s=>o.map(c=>Array.isArray(s)?s.reduce((i,u,l)=>i+u*(c[l]||0),0):c.reduce((i,u)=>i+u*s,0)));return r===1&&(a=a[0]),n===1?a.map(s=>s[0]):a}const Dn=(...e)=>{e=T(e,"lab");const[t,r,n,...o]=e,[a,s,c]=mf([t,r,n]),[i,u,l]=Ta(a,s,c);return[i,u,l,...o.length>0&&o[0]<1?[o[0]]:[]]};function mf(e){var t=[[1.2268798758459243,-.5578149944602171,.2813910456659647],[-.0405757452148008,1.112286803280317,-.0717110580655164],[-.0763729366746601,-.4214933324022432,1.5869240198367816]],r=[[1,.3963377773761749,.2158037573099136],[1,-.1055613458156586,-.0638541728258133],[1,-.0894841775298119,-1.2914855480194092]],n=Pt(r,e);return Pt(t,n.map(o=>o**3))}const Vn=(...e)=>{const[t,r,n,...o]=T(e,"rgb"),a=Sa(t,r,n);return[...gf(a),...o.length>0&&o[0]<1?[o[0]]:[]]};function gf(e){const t=[[.819022437996703,.3619062600528904,-.1288737815209879],[.0329836539323885,.9292868615863434,.0361446663506424],[.0481771893596242,.2642395317527308,.6335478284694309]],r=[[.210454268309314,.7936177747023054,-.0040720430116193],[1.9779985324311684,-2.42859224204858,.450593709617411],[.0259040424655478,.7827717124575296,-.8086757549230774]],n=Pt(t,e);return Pt(r,n.map(o=>Math.cbrt(o)))}k.prototype.oklab=function(){return Vn(this._rgb)},Object.assign(G,{oklab:(...e)=>new k(...e,"oklab")}),E.format.oklab=Dn,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"oklab"),B(e)==="array"&&e.length===3)return"oklab"}});const vf=(e,t,r)=>{const n=e.oklab(),o=t.oklab();return new k(n[0]+r*(o[0]-n[0]),n[1]+r*(o[1]-n[1]),n[2]+r*(o[2]-n[2]),"oklab")};ne.oklab=vf;const _f=(e,t,r)=>et(e,t,r,"oklch");ne.oklch=_f;const{pow:Yn,sqrt:Zn,PI:Jn,cos:Ia,sin:za,atan2:yf}=Math,wf=(e,t="lrgb",r=null)=>{const n=e.length;r||(r=Array.from(new Array(n)).map(()=>1));const o=n/r.reduce(function(f,h){return f+h});if(r.forEach((f,h)=>{r[h]*=o}),e=e.map(f=>new k(f)),t==="lrgb")return kf(e,r);const a=e.shift(),s=a.get(t),c=[];let i=0,u=0;for(let f=0;f{const d=f.get(t);l+=f.alpha()*r[h+1];for(let b=0;b=360;)h-=360;s[f]=h}else s[f]=s[f]/c[f];return l/=n,new k(s,t).alpha(l>.99999?1:l,!0)},kf=(e,t)=>{const r=e.length,n=[0,0,0,0];for(let o=0;o.9999999&&(n[3]=1),new k(En(n))},{pow:$f}=Math;function jt(e){let t="rgb",r=G("#ccc"),n=0,o=[0,1],a=[0,1],s=[],c=[0,0],i=!1,u=[],l=!1,f=0,h=1,d=!1,b={},_=!0,g=1;const v=function(p){if(p=p||["#fff","#000"],p&&B(p)==="string"&&G.brewer&&G.brewer[p.toLowerCase()]&&(p=G.brewer[p.toLowerCase()]),B(p)==="array"){p.length===1&&(p=[p[0],p[0]]),p=p.slice(0);for(let y=0;y=i[w];)w++;return w-1}return 0};let x=p=>p,N=p=>p;const A=function(p,y){let w,C;if(y==null&&(y=!1),isNaN(p)||p===null)return r;y?C=p:i&&i.length>2?C=H(p)/(i.length-2):h!==f?C=(p-f)/(h-f):C=1,C=N(C),y||(C=x(C)),g!==1&&(C=$f(C,g)),C=c[0]+C*(1-c[0]-c[1]),C=Be(C,0,1);const q=Math.floor(C*1e4);if(_&&b[q])w=b[q];else{if(B(u)==="array")for(let M=0;M=S&&M===s.length-1){w=u[M];break}if(C>S&&Cb={};v(e);const m=function(p){const y=G(A(p));return l&&y[l]?y[l]():y};return m.classes=function(p){if(p!=null){if(B(p)==="array")i=p,o=[p[0],p[p.length-1]];else{const y=G.analyze(o);p===0?i=[y.min,y.max]:i=G.limits(y,"e",p)}return m}return i},m.domain=function(p){if(!arguments.length)return a;a=p.slice(0),f=p[0],h=p[p.length-1],s=[];const y=u.length;if(p.length===y&&f!==h)for(let w of Array.from(p))s.push((w-f)/(h-f));else{for(let w=0;w2){const w=p.map((q,M)=>M/(p.length-1)),C=p.map(q=>(q-f)/(h-f));C.every((q,M)=>w[M]===q)||(N=q=>{if(q<=0||q>=1)return q;let M=0;for(;q>=C[M+1];)M++;const S=(q-C[M])/(C[M+1]-C[M]);return w[M]+S*(w[M+1]-w[M])})}}return o=[f,h],m},m.mode=function(p){return arguments.length?(t=p,R(),m):t},m.range=function(p,y){return v(p),m},m.out=function(p){return l=p,m},m.spread=function(p){return arguments.length?(n=p,m):n},m.correctLightness=function(p){return p==null&&(p=!0),d=p,R(),d?x=function(y){const w=A(0,!0).lab()[0],C=A(1,!0).lab()[0],q=w>C;let M=A(y,!0).lab()[0];const S=w+(C-w)*y;let X=M-S,D=0,U=1,ce=20;for(;Math.abs(X)>.01&&ce-- >0;)(function(){return q&&(X*=-1),X<0?(D=y,y+=(U-y)*.5):(U=y,y+=(D-y)*.5),M=A(y,!0).lab()[0],X=M-S})();return y}:x=y=>y,m},m.padding=function(p){return p!=null?(B(p)==="number"&&(p=[p,p]),c=p,m):c},m.colors=function(p,y){arguments.length<2&&(y="hex");let w=[];if(arguments.length===0)w=u.slice(0);else if(p===1)w=[m(.5)];else if(p>1){const C=o[0],q=o[1]-C;w=Cf(0,p).map(M=>m(C+M/(p-1)*q))}else{e=[];let C=[];if(i&&i.length>2)for(let q=1,M=i.length,S=1<=M;S?qM;S?q++:q--)C.push((i[q-1]+i[q])*.5);else C=o;w=C.map(q=>m(q))}return G[y]&&(w=w.map(C=>C[y]())),w},m.cache=function(p){return p!=null?(_=p,m):_},m.gamma=function(p){return p!=null?(g=p,m):g},m.nodata=function(p){return p!=null?(r=G(p),m):r},m}function Cf(e,t,r){let n=[],o=ea;o?s++:s--)n.push(s);return n}const xf=function(e){let t=[1,1];for(let r=1;rnew k(a)),e.length===2)[r,n]=e.map(a=>a.lab()),t=function(a){const s=[0,1,2].map(c=>r[c]+a*(n[c]-r[c]));return new k(s,"lab")};else if(e.length===3)[r,n,o]=e.map(a=>a.lab()),t=function(a){const s=[0,1,2].map(c=>(1-a)*(1-a)*r[c]+2*(1-a)*a*n[c]+a*a*o[c]);return new k(s,"lab")};else if(e.length===4){let a;[r,n,o,a]=e.map(s=>s.lab()),t=function(s){const c=[0,1,2].map(i=>(1-s)*(1-s)*(1-s)*r[i]+3*(1-s)*(1-s)*s*n[i]+3*(1-s)*s*s*o[i]+s*s*s*a[i]);return new k(c,"lab")}}else if(e.length>=5){let a,s,c;a=e.map(i=>i.lab()),c=e.length-1,s=xf(c),t=function(i){const u=1-i,l=[0,1,2].map(f=>a.reduce((h,d,b)=>h+s[b]*u**(c-b)*i**b*d[f],0));return new k(l,"lab")}}else throw new RangeError("No point in running bezier with only one color.");return t},Hf=e=>{const t=Rf(e);return t.scale=()=>jt(t),t},{round:Fa}=Math;k.prototype.rgb=function(e=!0){return e===!1?this._rgb.slice(0,3):this._rgb.slice(0,3).map(Fa)},k.prototype.rgba=function(e=!0){return this._rgb.slice(0,4).map((t,r)=>r<3?e===!1?t:Fa(t):t)},Object.assign(G,{rgb:(...e)=>new k(...e,"rgb")}),E.format.rgb=(...e)=>{const t=T(e,"rgba");return t[3]===void 0&&(t[3]=1),t},E.autodetect.push({p:3,test:(...e)=>{if(e=T(e,"rgba"),B(e)==="array"&&(e.length===3||e.length===4&&B(e[3])=="number"&&e[3]>=0&&e[3]<=1))return"rgb"}});const me=(e,t,r)=>{if(!me[r])throw new Error("unknown blend mode "+r);return me[r](e,t)},Te=e=>(t,r)=>{const n=G(r).rgb(),o=G(t).rgb();return G.rgb(e(n,o))},Se=e=>(t,r)=>{const n=[];return n[0]=e(t[0],r[0]),n[1]=e(t[1],r[1]),n[2]=e(t[2],r[2]),n},qf=e=>e,Mf=(e,t)=>e*t/255,Of=(e,t)=>e>t?t:e,Nf=(e,t)=>e>t?e:t,Af=(e,t)=>255*(1-(1-e/255)*(1-t/255)),Lf=(e,t)=>t<128?2*e*t/255:255*(1-2*(1-e/255)*(1-t/255)),Ef=(e,t)=>255*(1-(1-t/255)/(e/255)),Tf=(e,t)=>e===255?255:(e=255*(t/255)/(1-e/255),e>255?255:e);me.normal=Te(Se(qf)),me.multiply=Te(Se(Mf)),me.screen=Te(Se(Af)),me.overlay=Te(Se(Lf)),me.darken=Te(Se(Of)),me.lighten=Te(Se(Nf)),me.dodge=Te(Se(Tf)),me.burn=Te(Se(Ef));const{pow:Sf,sin:Pf,cos:jf}=Math;function Bf(e=300,t=-1.5,r=1,n=1,o=[0,1]){let a=0,s;B(o)==="array"?s=o[1]-o[0]:(s=0,o=[o,o]);const c=function(i){const u=Ce*((e+120)/360+t*i),l=Sf(o[0]+s*i,n),h=(a!==0?r[0]+i*a:r)*l*(1-l)/2,d=jf(u),b=Pf(u),_=l+h*(-.14861*d+1.78277*b),g=l+h*(-.29227*d-.90649*b),v=l+h*(1.97294*d);return G(En([_*255,g*255,v*255,1]))};return c.start=function(i){return i==null?e:(e=i,c)},c.rotations=function(i){return i==null?t:(t=i,c)},c.gamma=function(i){return i==null?n:(n=i,c)},c.hue=function(i){return i==null?r:(r=i,B(r)==="array"?(a=r[1]-r[0],a===0&&(r=r[1])):a=0,c)},c.lightness=function(i){return i==null?o:(B(i)==="array"?(o=i,s=i[1]-i[0]):(o=[i,i],s=0),c)},c.scale=()=>G.scale(c),c.hue(r),c}const Gf="0123456789abcdef",{floor:If,random:zf}=Math,Ff=(e=zf)=>{let t="#";for(let r=0;r<6;r++)t+=Gf.charAt(If(e()*16));return new k(t,"hex")},{log:Xa,pow:Xf,floor:Kf,abs:Df}=Math;function Ka(e,t=null){const r={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0};return B(e)==="object"&&(e=Object.values(e)),e.forEach(n=>{t&&B(n)==="object"&&(n=n[t]),n!=null&&!isNaN(n)&&(r.values.push(n),r.sum+=n,nr.max&&(r.max=n),r.count+=1)}),r.domain=[r.min,r.max],r.limits=(n,o)=>Da(r,n,o),r}function Da(e,t="equal",r=7){B(e)=="array"&&(e=Ka(e));const{min:n,max:o}=e,a=e.values.sort((c,i)=>c-i);if(r===1)return[n,o];const s=[];if(t.substr(0,1)==="c"&&(s.push(n),s.push(o)),t.substr(0,1)==="e"){s.push(n);for(let c=1;c 0");const c=Math.LOG10E*Xa(n),i=Math.LOG10E*Xa(o);s.push(n);for(let u=1;u200&&(f=!1)}const b={};for(let g=0;gg-v),s.push(_[0]);for(let g=1;g<_.length;g+=2){const v=_[g];!isNaN(v)&&s.indexOf(v)===-1&&s.push(v)}}return s}const Vf=(e,t)=>{e=new k(e),t=new k(t);const r=e.luminance(),n=t.luminance();return r>n?(r+.05)/(n+.05):(n+.05)/(r+.05)};const Va=.027,Yf=5e-4,Zf=.1,Ya=1.14,Bt=.022,Za=1.414,Jf=(e,t)=>{e=new k(e),t=new k(t),e.alpha()<1&&(e=Ue(t,e,e.alpha(),"rgb"));const r=Ja(...e.rgb()),n=Ja(...t.rgb()),o=r>=Bt?r:r+Math.pow(Bt-r,Za),a=n>=Bt?n:n+Math.pow(Bt-n,Za),s=Math.pow(a,.56)-Math.pow(o,.57),c=Math.pow(a,.65)-Math.pow(o,.62),i=Math.abs(a-o)0?i-Va:i+Va)*100};function Ja(e,t,r){return .2126729*Math.pow(e/255,2.4)+.7151522*Math.pow(t/255,2.4)+.072175*Math.pow(r/255,2.4)}const{sqrt:Re,pow:Z,min:Wf,max:Uf,atan2:Wa,abs:Ua,cos:Gt,sin:Qa,exp:Qf,PI:ec}=Math;function el(e,t,r=1,n=1,o=1){var a=function(he){return 360*he/(2*ec)},s=function(he){return 2*ec*he/360};e=new k(e),t=new k(t);const[c,i,u]=Array.from(e.lab()),[l,f,h]=Array.from(t.lab()),d=(c+l)/2,b=Re(Z(i,2)+Z(u,2)),_=Re(Z(f,2)+Z(h,2)),g=(b+_)/2,v=.5*(1-Re(Z(g,7)/(Z(g,7)+Z(25,7)))),H=i*(1+v),x=f*(1+v),N=Re(Z(H,2)+Z(u,2)),A=Re(Z(x,2)+Z(h,2)),R=(N+A)/2,m=a(Wa(u,H)),p=a(Wa(h,x)),y=m>=0?m:m+360,w=p>=0?p:p+360,C=Ua(y-w)>180?(y+w+360)/2:(y+w)/2,q=1-.17*Gt(s(C-30))+.24*Gt(s(2*C))+.32*Gt(s(3*C+6))-.2*Gt(s(4*C-63));let M=w-y;M=Ua(M)<=180?M:w<=y?M+360:M-360,M=2*Re(N*A)*Qa(s(M)/2);const S=l-c,X=A-N,D=1+.015*Z(d-50,2)/Re(20+Z(d-50,2)),U=1+.045*R,ce=1+.015*R*q,ye=30*Qf(-Z((C-275)/25,2)),le=-(2*Re(Z(R,7)/(Z(R,7)+Z(25,7))))*Qa(2*s(ye)),qe=Re(Z(S/(r*D),2)+Z(X/(n*U),2)+Z(M/(o*ce),2)+le*(X/(n*U))*(M/(o*ce)));return Uf(0,Wf(100,qe))}function tl(e,t,r="lab"){e=new k(e),t=new k(t);const n=e.get(r),o=t.get(r);let a=0;for(let s in n){const c=(n[s]||0)-(o[s]||0);a+=c*c}return Math.sqrt(a)}const rl=(...e)=>{try{return new k(...e),!0}catch{return!1}},nl={cool(){return jt([G.hsl(180,1,.9),G.hsl(250,.7,.4)])},hot(){return jt(["#000","#f00","#ff0","#fff"]).mode("rgb")}},Wn={OrRd:["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"],PuBu:["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"],BuPu:["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"],Oranges:["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"],BuGn:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"],YlOrBr:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"],YlGn:["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],Reds:["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"],RdPu:["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"],Greens:["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"],YlGnBu:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],Purples:["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"],GnBu:["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],Greys:["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"],YlOrRd:["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"],PuRd:["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"],Blues:["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"],PuBuGn:["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"],Viridis:["#440154","#482777","#3f4a8a","#31678e","#26838f","#1f9d8a","#6cce5a","#b6de2b","#fee825"],Spectral:["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],RdYlGn:["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],RdBu:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],PiYG:["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],PRGn:["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],RdYlBu:["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],BrBG:["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],RdGy:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],PuOr:["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],Set2:["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],Accent:["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],Set1:["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],Set3:["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],Dark2:["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],Paired:["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],Pastel2:["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],Pastel1:["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]},tc=Object.keys(Wn),rc=new Map(tc.map(e=>[e.toLowerCase(),e])),ol=typeof Proxy=="function"?new Proxy(Wn,{get(e,t){const r=t.toLowerCase();if(rc.has(r))return e[rc.get(r)]},getOwnPropertyNames(){return Object.getOwnPropertyNames(tc)}}):Wn,sl=(...e)=>{e=T(e,"cmyk");const[t,r,n,o]=e,a=e.length>4?e[4]:1;return o===1?[0,0,0,a]:[t>=1?0:255*(1-t)*(1-o),r>=1?0:255*(1-r)*(1-o),n>=1?0:255*(1-n)*(1-o),a]},{max:nc}=Math,al=(...e)=>{let[t,r,n]=T(e,"rgb");t=t/255,r=r/255,n=n/255;const o=1-nc(t,nc(r,n)),a=o<1?1/(1-o):0,s=(1-t-o)*a,c=(1-r-o)*a,i=(1-n-o)*a;return[s,c,i,o]};k.prototype.cmyk=function(){return al(this._rgb)},Object.assign(G,{cmyk:(...e)=>new k(...e,"cmyk")}),E.format.cmyk=sl,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"cmyk"),B(e)==="array"&&e.length===4)return"cmyk"}});const cl=(...e)=>{const t=T(e,"hsla");let r=Je(e)||"lsa";return t[0]=ue(t[0]||0)+"deg",t[1]=ue(t[1]*100)+"%",t[2]=ue(t[2]*100)+"%",r==="hsla"||t.length>3&&t[3]<1?(t[3]="/ "+(t.length>3?t[3]:1),r="hsla"):t.length=3,`${r.substr(0,3)}(${t.join(" ")})`},il=(...e)=>{const t=T(e,"lab");let r=Je(e)||"lab";return t[0]=ue(t[0])+"%",t[1]=ue(t[1]),t[2]=ue(t[2]),r==="laba"||t.length>3&&t[3]<1?t[3]="/ "+(t.length>3?t[3]:1):t.length=3,`lab(${t.join(" ")})`},ul=(...e)=>{const t=T(e,"lch");let r=Je(e)||"lab";return t[0]=ue(t[0])+"%",t[1]=ue(t[1]),t[2]=isNaN(t[2])?"none":ue(t[2])+"deg",r==="lcha"||t.length>3&&t[3]<1?t[3]="/ "+(t.length>3?t[3]:1):t.length=3,`lch(${t.join(" ")})`},fl=(...e)=>{const t=T(e,"lab");return t[0]=ue(t[0]*100)+"%",t[1]=Tn(t[1]),t[2]=Tn(t[2]),t.length>3&&t[3]<1?t[3]="/ "+(t.length>3?t[3]:1):t.length=3,`oklab(${t.join(" ")})`},oc=(...e)=>{const[t,r,n,...o]=T(e,"rgb"),[a,s,c]=Vn(t,r,n),[i,u,l]=ja(a,s,c);return[i,u,l,...o.length>0&&o[0]<1?[o[0]]:[]]},ll=(...e)=>{const t=T(e,"lch");return t[0]=ue(t[0]*100)+"%",t[1]=Tn(t[1]),t[2]=isNaN(t[2])?"none":ue(t[2])+"deg",t.length>3&&t[3]<1?t[3]="/ "+(t.length>3?t[3]:1):t.length=3,`oklch(${t.join(" ")})`},{round:Un}=Math,hl=(...e)=>{const t=T(e,"rgba");let r=Je(e)||"rgb";if(r.substr(0,3)==="hsl")return cl(Ga(t),r);if(r.substr(0,3)==="lab"){const n=dt();xe("d50");const o=il(Bn(t),r);return xe(n),o}if(r.substr(0,3)==="lch"){const n=dt();xe("d50");const o=ul(Fn(t),r);return xe(n),o}return r.substr(0,5)==="oklab"?fl(Vn(t)):r.substr(0,5)==="oklch"?ll(oc(t)):(t[0]=Un(t[0]),t[1]=Un(t[1]),t[2]=Un(t[2]),(r==="rgba"||t.length>3&&t[3]<1)&&(t[3]="/ "+(t.length>3?t[3]:1),r="rgba"),`${r.substr(0,3)}(${t.slice(0,r==="rgb"?3:4).join(" ")})`)},sc=(...e)=>{e=T(e,"lch");const[t,r,n,...o]=e,[a,s,c]=Pa(t,r,n),[i,u,l]=Dn(a,s,c);return[i,u,l,...o.length>0&&o[0]<1?[o[0]]:[]]},He=/((?:-?\d+)|(?:-?\d+(?:\.\d+)?)%|none)/.source,ge=/((?:-?(?:\d+(?:\.\d*)?|\.\d+)%?)|none)/.source,It=/((?:-?(?:\d+(?:\.\d*)?|\.\d+)%)|none)/.source,fe=/\s*/.source,rt=/\s+/.source,Qn=/\s*,\s*/.source,zt=/((?:-?(?:\d+(?:\.\d*)?|\.\d+)(?:deg)?)|none)/.source,nt=/\s*(?:\/\s*((?:[01]|[01]?\.\d+)|\d+(?:\.\d+)?%))?/.source,ac=new RegExp("^rgba?\\("+fe+[He,He,He].join(rt)+nt+"\\)$"),cc=new RegExp("^rgb\\("+fe+[He,He,He].join(Qn)+fe+"\\)$"),ic=new RegExp("^rgba\\("+fe+[He,He,He,ge].join(Qn)+fe+"\\)$"),uc=new RegExp("^hsla?\\("+fe+[zt,It,It].join(rt)+nt+"\\)$"),fc=new RegExp("^hsl?\\("+fe+[zt,It,It].join(Qn)+fe+"\\)$"),lc=/^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/,hc=new RegExp("^lab\\("+fe+[ge,ge,ge].join(rt)+nt+"\\)$"),dc=new RegExp("^lch\\("+fe+[ge,ge,zt].join(rt)+nt+"\\)$"),bc=new RegExp("^oklab\\("+fe+[ge,ge,ge].join(rt)+nt+"\\)$"),pc=new RegExp("^oklch\\("+fe+[ge,ge,zt].join(rt)+nt+"\\)$"),{round:mc}=Math,ot=e=>e.map((t,r)=>r<=2?Be(mc(t),0,255):t),J=(e,t=0,r=100,n=!1)=>(typeof e=="string"&&e.endsWith("%")&&(e=parseFloat(e.substring(0,e.length-1))/100,n?e=t+(e+1)*.5*(r-t):e=t+e*(r-t)),+e),oe=(e,t)=>e==="none"?t:e,eo=e=>{if(e=e.toLowerCase().trim(),e==="transparent")return[0,0,0,0];let t;if(E.format.named)try{return E.format.named(e)}catch{}if((t=e.match(ac))||(t=e.match(cc))){let r=t.slice(1,4);for(let o=0;o<3;o++)r[o]=+J(oe(r[o],0),0,255);r=ot(r);const n=t[4]!==void 0?+J(t[4],0,1):1;return r[3]=n,r}if(t=e.match(ic)){const r=t.slice(1,5);for(let n=0;n<4;n++)r[n]=+J(r[n],0,255);return r}if((t=e.match(uc))||(t=e.match(fc))){const r=t.slice(1,4);r[0]=+oe(r[0].replace("deg",""),0),r[1]=+J(oe(r[1],0),0,100)*.01,r[2]=+J(oe(r[2],0),0,100)*.01;const n=ot(Kn(r)),o=t[4]!==void 0?+J(t[4],0,1):1;return n[3]=o,n}if(t=e.match(lc)){const r=t.slice(1,4);r[1]*=.01,r[2]*=.01;const n=Kn(r);for(let o=0;o<3;o++)n[o]=mc(n[o]);return n[3]=+t[4],n}if(t=e.match(hc)){const r=t.slice(1,4);r[0]=J(oe(r[0],0),0,100),r[1]=J(oe(r[1],0),-125,125,!0),r[2]=J(oe(r[2],0),-125,125,!0);const n=dt();xe("d50");const o=ot(Pn(r));xe(n);const a=t[4]!==void 0?+J(t[4],0,1):1;return o[3]=a,o}if(t=e.match(dc)){const r=t.slice(1,4);r[0]=J(r[0],0,100),r[1]=J(oe(r[1],0),0,150,!1),r[2]=+oe(r[2].replace("deg",""),0);const n=dt();xe("d50");const o=ot(zn(r));xe(n);const a=t[4]!==void 0?+J(t[4],0,1):1;return o[3]=a,o}if(t=e.match(bc)){const r=t.slice(1,4);r[0]=J(oe(r[0],0),0,1),r[1]=J(oe(r[1],0),-.4,.4,!0),r[2]=J(oe(r[2],0),-.4,.4,!0);const n=ot(Dn(r)),o=t[4]!==void 0?+J(t[4],0,1):1;return n[3]=o,n}if(t=e.match(pc)){const r=t.slice(1,4);r[0]=J(oe(r[0],0),0,1),r[1]=J(oe(r[1],0),0,.4,!1),r[2]=+oe(r[2].replace("deg",""),0);const n=ot(sc(r)),o=t[4]!==void 0?+J(t[4],0,1):1;return n[3]=o,n}};eo.test=e=>ac.test(e)||uc.test(e)||hc.test(e)||dc.test(e)||bc.test(e)||pc.test(e)||cc.test(e)||ic.test(e)||fc.test(e)||lc.test(e)||e==="transparent",k.prototype.css=function(e){return hl(this._rgb,e)};const dl=(...e)=>new k(...e,"css");G.css=dl,E.format.css=eo,E.autodetect.push({p:5,test:(e,...t)=>{if(!t.length&&B(e)==="string"&&eo.test(e))return"css"}}),E.format.gl=(...e)=>{const t=T(e,"rgba");return t[0]*=255,t[1]*=255,t[2]*=255,t};const bl=(...e)=>new k(...e,"gl");G.gl=bl,k.prototype.gl=function(){const e=this._rgb;return[e[0]/255,e[1]/255,e[2]/255,e[3]]},k.prototype.hex=function(e){return Ea(this._rgb,e)};const pl=(...e)=>new k(...e,"hex");G.hex=pl,E.format.hex=La,E.autodetect.push({p:4,test:(e,...t)=>{if(!t.length&&B(e)==="string"&&[3,4,5,6,7,8,9].indexOf(e.length)>=0)return"hex"}});const{log:Ft}=Math,gc=e=>{const t=e/100;let r,n,o;return t<66?(r=255,n=t<6?0:-155.25485562709179-.44596950469579133*(n=t-2)+104.49216199393888*Ft(n),o=t<20?0:-254.76935184120902+.8274096064007395*(o=t-10)+115.67994401066147*Ft(o)):(r=351.97690566805693+.114206453784165*(r=t-55)-40.25366309332127*Ft(r),n=325.4494125711974+.07943456536662342*(n=t-50)-28.0852963507957*Ft(n),o=255),[r,n,o,1]},{round:ml}=Math,gl=(...e)=>{const t=T(e,"rgb"),r=t[0],n=t[2];let o=1e3,a=4e4;const s=.4;let c;for(;a-o>s;){c=(a+o)*.5;const i=gc(c);i[2]/i[0]>=n/r?a=c:o=c}return ml(c)};k.prototype.temp=k.prototype.kelvin=k.prototype.temperature=function(){return gl(this._rgb)};const to=(...e)=>new k(...e,"temp");Object.assign(G,{temp:to,kelvin:to,temperature:to}),E.format.temp=E.format.kelvin=E.format.temperature=gc,k.prototype.oklch=function(){return oc(this._rgb)},Object.assign(G,{oklch:(...e)=>new k(...e,"oklch")}),E.format.oklch=sc,E.autodetect.push({p:2,test:(...e)=>{if(e=T(e,"oklch"),B(e)==="array"&&e.length===3)return"oklch"}}),Object.assign(G,{analyze:Ka,average:wf,bezier:Hf,blend:me,brewer:ol,Color:k,colors:We,contrast:Vf,contrastAPCA:Jf,cubehelix:Bf,deltaE:el,distance:tl,input:E,interpolate:Ue,limits:Da,mix:Ue,random:Ff,scale:jt,scales:nl,valid:rl});function vl(e){return+`${Math.ceil(`${e}e+2`)}e-2`}const vc=e=>{const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return[Number.parseInt(t[1],16),Number.parseInt(t[2],16),Number.parseInt(t[3],16)]},_c=(e,t,r)=>{const n=e/255,o=t/255,a=r/255,s=Math.min(n,o,a),c=Math.max(n,o,a),i=c-s;let u=0,l=0,f=0;return i===0?u=0:c===n?u=(o-a)/i%6:c===o?u=(a-n)/i+2:u=(n-o)/i+4,u=Math.round(u*60),u<0&&(u+=360),f=(c+s)/2,l=i===0?0:i/(1-Math.abs(2*f-1)),l=+(l*100).toFixed(1),f=+(f*100).toFixed(1),[u,l,Math.round(f)]},_l=(e,t,r,n)=>{const o=r/100,a=t*Math.min(o,1-o)/100,s=d=>{const b=(d+e/30)%12,_=o-a*Math.max(Math.min(b-3,9-b,1),-1);return Math.round(255*_).toString(16).padStart(2,"0").toUpperCase()},c=s(0),i=s(8),u=s(4),f=((d,b,_)=>Math.min(Math.max(d,b),_))(n,0,1),h=Math.round(f*255).toString(16).padStart(2,"0").toUpperCase();return`#${c}${i}${u}${h}`},yl=(e,t,r=1)=>{const n=vc(e),o=vc(t==="white"?"#FFFFFF":t==="black"?"#000000":t),a=n.map((u,l)=>[(u-o[l])/(255-o[l]),(u-o[l])/(0-o[l])]),s=vl(Math.max(...a.flat().filter(u=>/^-?\d+\.?\d*$/.test(u)))),c=n.map((u,l)=>Math.round((u-o[l]+o[l]*s)/s));if(c.includes(Number.NaN)){const u=_c(n[0],n[1],n[2]);return{h:u[0],s:Math.round(u[1]*r),l:u[2],a:1}}const i=_c(c[0],c[1],c[2]);return{h:i[0],s:Math.round(i[1]*r),l:i[2],a:s}},ro={backgroundColor:"gray",colorSpace:"OKLCH",colorSmoothing:!1,formula:"wcag2",output:"HEX",colors:{gray:[K(215,20,90),K(215,8,50),K(215,6,25)],red:[K(358,100,58),K(350,100,30)],orange:[K(32,100,48),K(12,100,30)],yellow:[K(50,100,50),K(25,100,20)],lime:[K(100,68,50),K(115,86,25)],green:[K(163,87,42),K(168,100,25)],cyan:[K(185,80,45),K(200,98,35)],blue:[K(212,98,46),K(222,95,25)],purple:[K(258,94,64),K(265,100,35)],fuchsia:[K(295,56,50),K(285,80,25)],pink:[K(334,90,50),K(330,91,25)]},themes:{light:{ratios:[1.03,1.06,1.12,1.25,1.5,1.75,2.25,3.5,5.25,6.5,8,10.5,13.75,16.75],contrast:1,lightness:100,saturation:100},dark:{ratios:[1.03,1.06,1.12,1.25,1.5,1.75,2.25,3.5,5.25,6.5,8,10.5,13.75,16],contrast:1,lightness:6,saturation:97},lightHc:{ratios:[1.06,1.12,1.25,1.37,1.75,2.25,3.25,4.75,8.87,10,11.75,13.25,16,17],contrast:1,lightness:100,saturation:100},darkHc:{ratios:[1.06,1.12,1.25,1.37,1.75,2.25,3.25,4.75,8.87,10,11.75,13.25,16,17],contrast:1,lightness:6,saturation:97}}};function K(e,t,r){return G.hsl(e,t/100,r/100).hex()}function wl(e,t){const r=e.colorSpace,n=e.colorSmoothing,o=e.themes[t].ratios,a=new qa({name:"gray",colorKeys:e.colors.gray,colorspace:r,ratios:o,smooth:n}),s=new ae({name:"blue",colorKeys:e.colors.blue,colorspace:r,ratios:o,smooth:n}),c=new ae({name:"cyan",colorKeys:e.colors.cyan,colorspace:r,ratios:o,smooth:n}),i=new ae({name:"fuchsia",colorKeys:e.colors.fuchsia,colorspace:r,ratios:o,smooth:n}),u=new ae({name:"green",colorKeys:e.colors.green,colorspace:r,ratios:o,smooth:n}),l=new ae({name:"lime",colorKeys:e.colors.lime,colorspace:r,ratios:o,smooth:n}),f=new ae({name:"orange",colorKeys:e.colors.orange,colorspace:r,ratios:o,smooth:n}),h=new ae({name:"pink",colorKeys:e.colors.pink,colorspace:r,ratios:o,smooth:n}),d=new ae({name:"purple",colorKeys:e.colors.purple,colorspace:r,ratios:o,smooth:n}),b=new ae({name:"red",colorKeys:e.colors.red,colorspace:r,ratios:o,smooth:n}),_=new ae({name:"yellow",colorKeys:e.colors.yellow,colorspace:r,ratios:o,smooth:n}),g={gray:a,red:b,orange:f,yellow:_,lime:l,green:u,cyan:c,blue:s,purple:d,fuchsia:i,pink:h};return e.colors.custom&&(g.custom=new ae({name:"custom",colorKeys:e.colors.custom,colorspace:r,ratios:o,smooth:n})),new wu({colors:Object.values(g),backgroundColor:g[e.backgroundColor],contrast:e.themes[t].contrast,lightness:e.themes[t].lightness,saturation:e.themes[t].saturation,output:e.output,formula:e.formula}).contrastColors}function yc(e){const t={};for(const r of Object.keys(e.themes))t[r]=wl(e,r);return t}function kl(e){ro.colors.custom=[e];const t=yc(ro);return Object.fromEntries(Object.entries(t).map(([r,n])=>{const o=n.find(s=>s&&s.name==="custom"),a=Object.fromEntries(o.values.map(({name:s,value:c})=>[s,c]));for(const[s,c]of Object.entries(a)){const i=yl(c,n[0].background);a[`alpha${s.charAt(0).toUpperCase()+s.slice(1)}`]=_l(i.h,i.s,i.l,i.a)}return[r,a]}))}return Fe.generateCustomColors=kl,Fe.generateThemesJson=yc,Fe.hslToHex=K,Fe.leonardoConfig=ro,Object.defineProperty(Fe,Symbol.toStringTag,{value:"Module"}),Fe})({}); 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 a8ae1cf8f4..2f634b529e 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 @@ -1,12 +1,10 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. */ - /** * !!! WARNING !!! * @@ -14,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated @@ -185,6 +181,9 @@ object CompoundIcons { @Composable fun ErrorSolid(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_error_solid) } + @Composable fun ExitFullScreen(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_exit_full_screen) + } @Composable fun Expand(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_expand) } @@ -218,6 +217,9 @@ object CompoundIcons { @Composable fun Forward(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_forward) } + @Composable fun FullScreen(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_full_screen) + } @Composable fun Grid(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_grid) } @@ -296,6 +298,9 @@ object CompoundIcons { @Composable fun Leave(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_leave) } + @Composable fun LeftPanelClose(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_left_panel_close) + } @Composable fun Link(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_link) } @@ -503,6 +508,12 @@ object CompoundIcons { @Composable fun SignOut(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_sign_out) } + @Composable fun Space(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_space) + } + @Composable fun SpaceSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_space_solid) + } @Composable fun Spinner(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_spinner) } @@ -620,12 +631,6 @@ object CompoundIcons { @Composable fun Windows(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_windows) } - @Composable fun Workspace(): ImageVector { - return ImageVector.vectorResource(R.drawable.ic_compound_workspace) - } - @Composable fun WorkspaceSolid(): ImageVector { - return ImageVector.vectorResource(R.drawable.ic_compound_workspace_solid) - } val all @Composable get() = persistentListOf( Admin(), @@ -681,6 +686,7 @@ object CompoundIcons { EndCall(), Error(), ErrorSolid(), + ExitFullScreen(), Expand(), Explore(), ExportArchive(), @@ -692,6 +698,7 @@ object CompoundIcons { Files(), Filter(), Forward(), + FullScreen(), Grid(), Group(), Guest(), @@ -718,6 +725,7 @@ object CompoundIcons { Keyboard(), Labs(), Leave(), + LeftPanelClose(), Link(), Linux(), ListBulleted(), @@ -787,6 +795,8 @@ object CompoundIcons { Shield(), Sidebar(), SignOut(), + Space(), + SpaceSolid(), Spinner(), Spotlight(), SpotlightView(), @@ -826,8 +836,6 @@ object CompoundIcons { Warning(), WebBrowser(), Windows(), - Workspace(), - WorkspaceSolid(), ) val allResIds get() = persistentListOf( @@ -884,6 +892,7 @@ object CompoundIcons { R.drawable.ic_compound_end_call, R.drawable.ic_compound_error, R.drawable.ic_compound_error_solid, + R.drawable.ic_compound_exit_full_screen, R.drawable.ic_compound_expand, R.drawable.ic_compound_explore, R.drawable.ic_compound_export_archive, @@ -895,6 +904,7 @@ object CompoundIcons { R.drawable.ic_compound_files, R.drawable.ic_compound_filter, R.drawable.ic_compound_forward, + R.drawable.ic_compound_full_screen, R.drawable.ic_compound_grid, R.drawable.ic_compound_group, R.drawable.ic_compound_guest, @@ -921,6 +931,7 @@ object CompoundIcons { R.drawable.ic_compound_keyboard, R.drawable.ic_compound_labs, R.drawable.ic_compound_leave, + R.drawable.ic_compound_left_panel_close, R.drawable.ic_compound_link, R.drawable.ic_compound_linux, R.drawable.ic_compound_list_bulleted, @@ -990,6 +1001,8 @@ object CompoundIcons { R.drawable.ic_compound_shield, R.drawable.ic_compound_sidebar, R.drawable.ic_compound_sign_out, + R.drawable.ic_compound_space, + R.drawable.ic_compound_space_solid, R.drawable.ic_compound_spinner, R.drawable.ic_compound_spotlight, R.drawable.ic_compound_spotlight_view, @@ -1029,7 +1042,5 @@ object CompoundIcons { R.drawable.ic_compound_warning, R.drawable.ic_compound_web_browser, R.drawable.ic_compound_windows, - R.drawable.ic_compound_workspace, - R.drawable.ic_compound_workspace_solid, ) } diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColors.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/SemanticColors.kt index fe04e212cc..6136b04d4b 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 @@ -1,19 +1,10 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. */ - -@file:Suppress("all") -package io.element.android.compound.tokens.generated - -import androidx.compose.runtime.Immutable -import androidx.compose.ui.graphics.Color - - /** * !!! WARNING !!! * @@ -21,12 +12,14 @@ import androidx.compose.ui.graphics.Color * DO NOT EDIT MANUALLY. */ +@file:Suppress("all") +package io.element.android.compound.tokens.generated - +import androidx.compose.ui.graphics.Color /** - * This class holds all the semantic tokens of the Compound theme. - */ + * This class holds all the semantic tokens of the Compound theme. + */ data class SemanticColors( /** Background colour for accent or brand actions. State: Hover */ val bgAccentHovered: Color, @@ -50,17 +43,21 @@ data class SemanticColors( val bgActionSecondaryPressed: Color, /** Background colour for secondary actions. State: Rest. */ val bgActionSecondaryRest: Color, + /** Background colour for tertiary actions. State: Hover */ + val bgActionTertiaryHovered: Color, + /** Background colour for tertiary actions. State: Rest */ + 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 bgBadgeDefault: Color, /** Badge info background colour */ val bgBadgeInfo: Color, - /** Default global background for the user interface. -Elevation: Default (Level 0) */ + /** Default global background for the user interface. Elevation: Default (Level 0) */ val bgCanvasDefault: Color, - /** Default global background for the user interface. -Elevation: Level 1. */ + /** Default global background for the user interface. Elevation: Level 1. */ val bgCanvasDefaultLevel1: Color, /** Default background for disabled elements. There's no minimum contrast requirement. */ val bgCanvasDisabled: Color, @@ -86,14 +83,11 @@ Elevation: Level 1. */ val bgDecorative6: Color, /** Subtle background colour for informational elements. State: Rest. */ val bgInfoSubtle: Color, - /** Medium contrast surfaces. -Elevation: Default (Level 2). */ + /** Medium contrast surfaces. Elevation: Default (Level 2). */ val bgSubtlePrimary: Color, - /** Low contrast surfaces. -Elevation: Default (Level 1). */ + /** Low contrast surfaces. Elevation: Default (Level 1). */ val bgSubtleSecondary: Color, - /** Lower contrast surfaces. -Elevation: Level 0. */ + /** Lower contrast surfaces. Elevation: Level 0. */ val bgSubtleSecondaryLevel0: Color, /** Subtle background colour for success state elements. State: Rest. */ val bgSuccessSubtle: Color, 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 6cbfd5f1fc..60afe79ae2 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 @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -13,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated @@ -37,9 +34,12 @@ val compoundColorsDark = SemanticColors( bgActionSecondaryHovered = DarkColorTokens.colorAlphaGray200, bgActionSecondaryPressed = DarkColorTokens.colorAlphaGray300, bgActionSecondaryRest = DarkColorTokens.colorThemeBg, - bgBadgeAccent = DarkColorTokens.colorAlphaGreen300, - bgBadgeDefault = DarkColorTokens.colorAlphaGray300, - bgBadgeInfo = DarkColorTokens.colorAlphaBlue300, + bgActionTertiaryHovered = DarkColorTokens.colorGray300, + bgActionTertiaryRest = DarkColorTokens.colorThemeBg, + bgActionTertiarySelected = DarkColorTokens.colorGray400, + bgBadgeAccent = DarkColorTokens.colorAlphaGreen500, + bgBadgeDefault = DarkColorTokens.colorAlphaGray500, + bgBadgeInfo = DarkColorTokens.colorAlphaBlue500, bgCanvasDefault = DarkColorTokens.colorThemeBg, bgCanvasDefaultLevel1 = DarkColorTokens.colorGray300, bgCanvasDisabled = DarkColorTokens.colorGray200, @@ -89,7 +89,7 @@ val compoundColorsDark = SemanticColors( iconAccentTertiary = DarkColorTokens.colorGreen800, iconCriticalPrimary = DarkColorTokens.colorRed900, iconDisabled = DarkColorTokens.colorGray700, - iconInfoPrimary = DarkColorTokens.colorBlue900, + iconInfoPrimary = DarkColorTokens.colorBlue1100, iconOnSolidPrimary = DarkColorTokens.colorThemeBg, iconPrimary = DarkColorTokens.colorGray1400, iconPrimaryAlpha = DarkColorTokens.colorAlphaGray1400, @@ -112,8 +112,8 @@ val compoundColorsDark = SemanticColors( textDecorative5 = DarkColorTokens.colorPink1100, textDecorative6 = DarkColorTokens.colorOrange1100, textDisabled = DarkColorTokens.colorGray800, - textInfoPrimary = DarkColorTokens.colorBlue900, - textLinkExternal = DarkColorTokens.colorBlue900, + textInfoPrimary = DarkColorTokens.colorBlue1100, + textLinkExternal = DarkColorTokens.colorBlue1100, textOnSolidPrimary = DarkColorTokens.colorThemeBg, textPrimary = DarkColorTokens.colorGray1400, textSecondary = DarkColorTokens.colorGray900, 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 94bcdabeae..c718caeeeb 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 @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -13,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated @@ -37,9 +34,12 @@ val compoundColorsHcDark = SemanticColors( bgActionSecondaryHovered = DarkHcColorTokens.colorAlphaGray200, bgActionSecondaryPressed = DarkHcColorTokens.colorAlphaGray300, bgActionSecondaryRest = DarkHcColorTokens.colorThemeBg, - bgBadgeAccent = DarkHcColorTokens.colorAlphaGreen300, - bgBadgeDefault = DarkHcColorTokens.colorAlphaGray300, - bgBadgeInfo = DarkHcColorTokens.colorAlphaBlue300, + bgActionTertiaryHovered = DarkHcColorTokens.colorGray300, + bgActionTertiaryRest = DarkHcColorTokens.colorThemeBg, + bgActionTertiarySelected = DarkHcColorTokens.colorGray400, + bgBadgeAccent = DarkHcColorTokens.colorAlphaGreen500, + bgBadgeDefault = DarkHcColorTokens.colorAlphaGray500, + bgBadgeInfo = DarkHcColorTokens.colorAlphaBlue500, bgCanvasDefault = DarkHcColorTokens.colorThemeBg, bgCanvasDefaultLevel1 = DarkHcColorTokens.colorGray300, bgCanvasDisabled = DarkHcColorTokens.colorGray200, @@ -89,7 +89,7 @@ val compoundColorsHcDark = SemanticColors( iconAccentTertiary = DarkHcColorTokens.colorGreen800, iconCriticalPrimary = DarkHcColorTokens.colorRed900, iconDisabled = DarkHcColorTokens.colorGray700, - iconInfoPrimary = DarkHcColorTokens.colorBlue900, + iconInfoPrimary = DarkHcColorTokens.colorBlue1100, iconOnSolidPrimary = DarkHcColorTokens.colorThemeBg, iconPrimary = DarkHcColorTokens.colorGray1400, iconPrimaryAlpha = DarkHcColorTokens.colorAlphaGray1400, @@ -112,8 +112,8 @@ val compoundColorsHcDark = SemanticColors( textDecorative5 = DarkHcColorTokens.colorPink1100, textDecorative6 = DarkHcColorTokens.colorOrange1100, textDisabled = DarkHcColorTokens.colorGray800, - textInfoPrimary = DarkHcColorTokens.colorBlue900, - textLinkExternal = DarkHcColorTokens.colorBlue900, + textInfoPrimary = DarkHcColorTokens.colorBlue1100, + textLinkExternal = DarkHcColorTokens.colorBlue1100, textOnSolidPrimary = DarkHcColorTokens.colorThemeBg, textPrimary = DarkHcColorTokens.colorGray1400, textSecondary = DarkHcColorTokens.colorGray900, 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 cc779758df..377997ec79 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 @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -13,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated @@ -37,9 +34,12 @@ val compoundColorsLight = SemanticColors( bgActionSecondaryHovered = LightColorTokens.colorAlphaGray200, bgActionSecondaryPressed = LightColorTokens.colorAlphaGray300, bgActionSecondaryRest = LightColorTokens.colorThemeBg, - bgBadgeAccent = LightColorTokens.colorAlphaGreen300, - bgBadgeDefault = LightColorTokens.colorAlphaGray300, - bgBadgeInfo = LightColorTokens.colorAlphaBlue300, + bgActionTertiaryHovered = LightColorTokens.colorGray300, + bgActionTertiaryRest = LightColorTokens.colorThemeBg, + bgActionTertiarySelected = LightColorTokens.colorGray400, + bgBadgeAccent = LightColorTokens.colorAlphaGreen400, + bgBadgeDefault = LightColorTokens.colorAlphaGray400, + bgBadgeInfo = LightColorTokens.colorAlphaBlue400, bgCanvasDefault = LightColorTokens.colorThemeBg, bgCanvasDefaultLevel1 = LightColorTokens.colorThemeBg, bgCanvasDisabled = LightColorTokens.colorGray200, @@ -89,7 +89,7 @@ val compoundColorsLight = SemanticColors( iconAccentTertiary = LightColorTokens.colorGreen800, iconCriticalPrimary = LightColorTokens.colorRed900, iconDisabled = LightColorTokens.colorGray700, - iconInfoPrimary = LightColorTokens.colorBlue900, + iconInfoPrimary = LightColorTokens.colorBlue1100, iconOnSolidPrimary = LightColorTokens.colorThemeBg, iconPrimary = LightColorTokens.colorGray1400, iconPrimaryAlpha = LightColorTokens.colorAlphaGray1400, @@ -112,8 +112,8 @@ val compoundColorsLight = SemanticColors( textDecorative5 = LightColorTokens.colorPink1100, textDecorative6 = LightColorTokens.colorOrange1100, textDisabled = LightColorTokens.colorGray800, - textInfoPrimary = LightColorTokens.colorBlue900, - textLinkExternal = LightColorTokens.colorBlue900, + textInfoPrimary = LightColorTokens.colorBlue1100, + textLinkExternal = LightColorTokens.colorBlue1100, textOnSolidPrimary = LightColorTokens.colorThemeBg, textPrimary = LightColorTokens.colorGray1400, textSecondary = LightColorTokens.colorGray900, 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 5956b80195..b32a0dd9f0 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 @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -13,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated @@ -37,9 +34,12 @@ val compoundColorsHcLight = SemanticColors( bgActionSecondaryHovered = LightHcColorTokens.colorAlphaGray200, bgActionSecondaryPressed = LightHcColorTokens.colorAlphaGray300, bgActionSecondaryRest = LightHcColorTokens.colorThemeBg, - bgBadgeAccent = LightHcColorTokens.colorAlphaGreen300, - bgBadgeDefault = LightHcColorTokens.colorAlphaGray300, - bgBadgeInfo = LightHcColorTokens.colorAlphaBlue300, + bgActionTertiaryHovered = LightHcColorTokens.colorGray300, + bgActionTertiaryRest = LightHcColorTokens.colorThemeBg, + bgActionTertiarySelected = LightHcColorTokens.colorGray400, + bgBadgeAccent = LightHcColorTokens.colorAlphaGreen400, + bgBadgeDefault = LightHcColorTokens.colorAlphaGray400, + bgBadgeInfo = LightHcColorTokens.colorAlphaBlue400, bgCanvasDefault = LightHcColorTokens.colorThemeBg, bgCanvasDefaultLevel1 = LightHcColorTokens.colorThemeBg, bgCanvasDisabled = LightHcColorTokens.colorGray200, @@ -89,7 +89,7 @@ val compoundColorsHcLight = SemanticColors( iconAccentTertiary = LightHcColorTokens.colorGreen800, iconCriticalPrimary = LightHcColorTokens.colorRed900, iconDisabled = LightHcColorTokens.colorGray700, - iconInfoPrimary = LightHcColorTokens.colorBlue900, + iconInfoPrimary = LightHcColorTokens.colorBlue1100, iconOnSolidPrimary = LightHcColorTokens.colorThemeBg, iconPrimary = LightHcColorTokens.colorGray1400, iconPrimaryAlpha = LightHcColorTokens.colorAlphaGray1400, @@ -112,8 +112,8 @@ val compoundColorsHcLight = SemanticColors( textDecorative5 = LightHcColorTokens.colorPink1100, textDecorative6 = LightHcColorTokens.colorOrange1100, textDisabled = LightHcColorTokens.colorGray800, - textInfoPrimary = LightHcColorTokens.colorBlue900, - textLinkExternal = LightHcColorTokens.colorBlue900, + textInfoPrimary = LightHcColorTokens.colorBlue1100, + textLinkExternal = LightHcColorTokens.colorBlue1100, textOnSolidPrimary = LightHcColorTokens.colorThemeBg, textPrimary = LightHcColorTokens.colorGray1400, textSecondary = LightHcColorTokens.colorGray900, diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/TypographyTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/TypographyTokens.kt index 27ab3e918c..0f450776ef 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/TypographyTokens.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/TypographyTokens.kt @@ -1,12 +1,10 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. */ - /** * !!! WARNING !!! * @@ -14,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkColorTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkColorTokens.kt index 10b31b5716..04dbf6b9f2 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkColorTokens.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkColorTokens.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -13,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated.internal diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkHcColorTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkHcColorTokens.kt index fa55eaf64f..8b2c04a93a 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkHcColorTokens.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/DarkHcColorTokens.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -13,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated.internal diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightColorTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightColorTokens.kt index dd42c82d59..c7561c7ce9 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightColorTokens.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightColorTokens.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -13,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated.internal diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightHcColorTokens.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightHcColorTokens.kt index 0a6801850d..40c91c5b53 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightHcColorTokens.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/tokens/generated/internal/LightHcColorTokens.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -13,8 +12,6 @@ * DO NOT EDIT MANUALLY. */ - - @file:Suppress("all") package io.element.android.compound.tokens.generated.internal diff --git a/libraries/compound/src/main/res/drawable/ic_compound_exit_full_screen.xml b/libraries/compound/src/main/res/drawable/ic_compound_exit_full_screen.xml new file mode 100644 index 0000000000..2b806f8992 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_exit_full_screen.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_full_screen.xml b/libraries/compound/src/main/res/drawable/ic_compound_full_screen.xml new file mode 100644 index 0000000000..8042ed32c9 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_full_screen.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_left_panel_close.xml b/libraries/compound/src/main/res/drawable/ic_compound_left_panel_close.xml new file mode 100644 index 0000000000..60e11c6f4f --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_left_panel_close.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_space.xml b/libraries/compound/src/main/res/drawable/ic_compound_space.xml new file mode 100644 index 0000000000..53a069c640 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_space.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_space_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_space_solid.xml new file mode 100644 index 0000000000..34730e87ff --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_space_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_threads.xml b/libraries/compound/src/main/res/drawable/ic_compound_threads.xml index 4fa1e877d1..6d3fd0c853 100644 --- a/libraries/compound/src/main/res/drawable/ic_compound_threads.xml +++ b/libraries/compound/src/main/res/drawable/ic_compound_threads.xml @@ -4,10 +4,10 @@ android:autoMirrored="true" android:viewportWidth="24" android:viewportHeight="24"> - - + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_threads_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_threads_solid.xml index 4db292231d..b06b67c27e 100644 --- a/libraries/compound/src/main/res/drawable/ic_compound_threads_solid.xml +++ b/libraries/compound/src/main/res/drawable/ic_compound_threads_solid.xml @@ -4,7 +4,7 @@ android:autoMirrored="true" android:viewportWidth="24" android:viewportHeight="24"> - + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_workspace.xml b/libraries/compound/src/main/res/drawable/ic_compound_workspace.xml deleted file mode 100644 index e5629d881a..0000000000 --- a/libraries/compound/src/main/res/drawable/ic_compound_workspace.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/libraries/compound/src/main/res/drawable/ic_compound_workspace_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_workspace_solid.xml deleted file mode 100644 index 12c582ebb3..0000000000 --- a/libraries/compound/src/main/res/drawable/ic_compound_workspace_solid.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - From 4e043bfa406ca60406f3195c13a52a44197fbabb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 12 Dec 2025 12:21:41 +0100 Subject: [PATCH 120/347] Fix compilation issue. --- .../features/announcement/impl/spaces/SpaceAnnouncementView.kt | 2 +- .../element/android/features/home/impl/HomeNavigationBarItem.kt | 2 +- .../securityandprivacy/impl/root/SecurityAndPrivacyView.kt | 2 +- .../libraries/matrix/ui/components/SpaceHeaderRootView.kt | 2 +- .../android/libraries/matrix/ui/components/SpaceInfoRow.kt | 2 +- .../element/android/libraries/matrix/ui/model/SpaceExtension.kt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt index e0759bc490..3fe6ec4456 100644 --- a/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt +++ b/features/announcement/impl/src/main/kotlin/io/element/android/features/announcement/impl/spaces/SpaceAnnouncementView.kt @@ -81,7 +81,7 @@ private fun SpaceAnnouncementHeader( showBetaLabel = true, subTitle = stringResource(id = R.string.screen_space_announcement_subtitle), iconStyle = BigIcon.Style.Default( - vectorIcon = CompoundIcons.WorkspaceSolid(), + vectorIcon = CompoundIcons.SpaceSolid(), usePrimaryTint = true, ), ) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeNavigationBarItem.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeNavigationBarItem.kt index 6a4a5e1688..035e953b23 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeNavigationBarItem.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeNavigationBarItem.kt @@ -28,7 +28,7 @@ enum class HomeNavigationBarItem( isSelected: Boolean, ) = when (this) { Chats -> if (isSelected) CompoundIcons.ChatSolid() else CompoundIcons.Chat() - Spaces -> if (isSelected) CompoundIcons.WorkspaceSolid() else CompoundIcons.Workspace() + Spaces -> if (isSelected) CompoundIcons.SpaceSolid() else CompoundIcons.Space() } companion object { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index add719153a..125d84c84d 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -218,7 +218,7 @@ private fun RoomAccessSection( Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_unavailable_description)) }, trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.SpaceMember, enabled = false), - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Workspace())), + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Space())), enabled = false, ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderRootView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderRootView.kt index f80cf2d65c..1e8fb864a7 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderRootView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderRootView.kt @@ -42,7 +42,7 @@ fun SpaceHeaderRootView( verticalArrangement = Arrangement.spacedBy(16.dp) ) { BigIcon( - style = BigIcon.Style.Default(CompoundIcons.WorkspaceSolid()) + style = BigIcon.Style.Default(CompoundIcons.SpaceSolid()) ) Text( text = stringResource(CommonStrings.screen_space_list_title), 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 9709e0e3c6..052d9862a6 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 @@ -108,7 +108,7 @@ internal fun SpaceInfoRowPreview() = ElementPreview { SpaceInfoRow( leftText = "Element space", rightText = numberOfRooms(16), - iconVector = CompoundIcons.Workspace(), + iconVector = CompoundIcons.Space(), ) SpaceInfoRow( visibility = SpaceRoomVisibility.Private, diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SpaceExtension.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SpaceExtension.kt index f9d4063601..195dfdb40e 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SpaceExtension.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SpaceExtension.kt @@ -32,7 +32,7 @@ val SpaceRoomVisibility.icon: ImageVector return when (this) { SpaceRoomVisibility.Private -> CompoundIcons.LockSolid() SpaceRoomVisibility.Public -> CompoundIcons.Public() - SpaceRoomVisibility.Restricted -> CompoundIcons.Workspace() + SpaceRoomVisibility.Restricted -> CompoundIcons.Space() } } From 23f3195b2a08b4359c35c526dc2e7d4a111aeeae Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 12 Dec 2025 11:36:01 +0000 Subject: [PATCH 121/347] 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 ++-- ...nnouncement.impl.spaces_SpaceAnnouncementView_Day_0_en.png | 4 ++-- ...ouncement.impl.spaces_SpaceAnnouncementView_Night_0_en.png | 4 ++-- ...crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png | 4 ++-- ...crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png | 3 --- ...ypto.historyvisible_HistoryVisibleStateView_Night_0_en.png | 4 ++-- ...ypto.historyvisible_HistoryVisibleStateView_Night_1_en.png | 3 --- ...historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png | 4 ++-- ...historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png | 3 --- ...storyvisible_MessagesViewWithHistoryVisible_Night_0_en.png | 4 ++-- ...storyvisible_MessagesViewWithHistoryVisible_Night_1_en.png | 3 --- ...ineItemTextViewWithLinkifiedUrlAndNestedParenthesis_en.png | 4 ++-- ...mponents.event_TimelineItemTextViewWithLinkifiedUrl_en.png | 4 ++-- ...es.impl.timeline.components_ThreadSummaryView_Day_0_en.png | 4 ++-- ....impl.timeline.components_ThreadSummaryView_Night_0_en.png | 2 +- ....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 | 2 +- ...ne.components_TimelineItemEventRowWithReply_Night_3_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_4_en.png | 2 +- ...ne.components_TimelineItemEventRowWithReply_Night_5_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_6_en.png | 2 +- ...ne.components_TimelineItemEventRowWithReply_Night_7_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_8_en.png | 4 ++-- ...ne.components_TimelineItemEventRowWithReply_Night_9_en.png | 4 ++-- ...ponents_TimelineItemEventRowWithThreadSummary_Day_0_en.png | 4 ++-- ...nents_TimelineItemEventRowWithThreadSummary_Night_0_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_11_en.png | 4 ++-- .../features.messages.impl_MessagesView_Night_11_en.png | 4 ++-- .../features.preferences.impl.labs_LabsView_Day_0_en.png | 4 ++-- .../features.preferences.impl.labs_LabsView_Day_1_en.png | 4 ++-- .../features.preferences.impl.labs_LabsView_Night_0_en.png | 4 ++-- .../features.preferences.impl.labs_LabsView_Night_1_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 ++-- .../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 | 4 ++-- .../images/features.roomdetails.impl_RoomDetails_1_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 | 4 ++-- .../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 ++-- ...libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png | 4 ++-- ...braries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png | 4 ++-- ...designsystem.atomic.atoms_MatrixBadgeAtomInfo_Day_0_en.png | 4 ++-- ...signsystem.atomic.atoms_MatrixBadgeAtomInfo_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 ++-- ...system.atomic.molecules_ComposerAlertMolecule_Day_3_en.png | 4 ++-- ...system.atomic.molecules_ComposerAlertMolecule_Day_4_en.png | 4 ++-- ...system.atomic.molecules_ComposerAlertMolecule_Day_5_en.png | 4 ++-- ...stem.atomic.molecules_ComposerAlertMolecule_Night_3_en.png | 4 ++-- ...stem.atomic.molecules_ComposerAlertMolecule_Night_4_en.png | 4 ++-- ...stem.atomic.molecules_ComposerAlertMolecule_Night_5_en.png | 4 ++-- ...mponents.preferences_PreferenceCategory_Preferences_en.png | 4 ++-- ...mponents.preferences_PreferenceCheckbox_Preferences_en.png | 4 ++-- ...mponents.preferences_PreferenceDropdown_Preferences_en.png | 4 ++-- ...nsystem.components.preferences_PreferencePage_Day_0_en.png | 4 ++-- ...ystem.components.preferences_PreferencePage_Night_0_en.png | 4 ++-- ...components.preferences_PreferenceSwitch_Preferences_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 ++-- ...ies.textcomposer_TextComposerEditNotEncrypted_Day_0_en.png | 4 ++-- ...s.textcomposer_TextComposerEditNotEncrypted_Night_0_en.png | 4 ++-- ...xtcomposer_TextComposerFormattingNotEncrypted_Day_0_en.png | 4 ++-- ...composer_TextComposerFormattingNotEncrypted_Night_0_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 ++-- ...s.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en.png | 4 ++-- ...textcomposer_TextComposerSimpleNotEncrypted_Night_0_en.png | 4 ++-- ...es.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png | 4 ++-- ....textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png | 4 ++-- 168 files changed, 324 insertions(+), 336 deletions(-) delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png diff --git a/libraries/compound/screenshots/Compound Icons - Dark.png b/libraries/compound/screenshots/Compound Icons - Dark.png index 52e6ba23ab..d3fb6dc294 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:4c0f668bcd8d511bc80daa1320bdcc1fe6a8f82cd53d91dbab9ffd0d09d72934 -size 210897 +oid sha256:fc758c149db501d0ac5eb235cca1d63b67230aae40356e7ccca4c9d481a9ce17 +size 216981 diff --git a/libraries/compound/screenshots/Compound Icons - Light.png b/libraries/compound/screenshots/Compound Icons - Light.png index 189864a54d..a6728d0947 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:85eb26db4406a921c45f143c8ccb59214b2b70cb19359fe9e7eeeecfb733ca74 -size 222592 +oid sha256:db230bfe3d51527959d2a4f7c64a8cc79209dcfb752f077f84c0f5058d94f0bd +size 228829 diff --git a/libraries/compound/screenshots/Compound Icons - Rtl.png b/libraries/compound/screenshots/Compound Icons - Rtl.png index aa1bdac4f5..c3f0b5fb8c 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:9acd4fdec8deddbf723184ce5f373ed54e64a68d5b572419059e3feab3a508be -size 223915 +oid sha256:4c6cd3ad1978c6f4e07d62b1edd08c5f32b3c498934d25af43932c50ef309fe0 +size 230519 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png b/libraries/compound/screenshots/Compound Semantic Colors - Dark HC.png index 4890b91886..b66b386ed8 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:578e9b5a38791e2686a7b9ba5c461eb1d1fb29dfbe950bf46c113ad75ceac175 -size 327758 +oid sha256:c846cd10b83361c368bdbb31ed6220cc22693c3cbf52791fb369841af1e9ea48 +size 327701 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Dark.png b/libraries/compound/screenshots/Compound Semantic Colors - Dark.png index 4cc125b4c8..35d684d39b 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:4cab40fc0506c8f2a2efafb1199e85f1da3ebacb49b176e9105e3f95175f85ee -size 325565 +oid sha256:05b35fedbd53dec2cc5c4c211a8db1a56055963de69425ddae2cab5aff7e3e75 +size 325750 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Light HC.png b/libraries/compound/screenshots/Compound Semantic Colors - Light HC.png index 5a8f5a6b32..9061d2b894 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:174f9d4ee70a29c0c8c2a01a15daeb14281530678ff7d7fb19a208bfd789533a -size 309210 +oid sha256:8d98e64eda5d6333067ccc599e99636f618331397207bb7534595e2756edb75e +size 309312 diff --git a/libraries/compound/screenshots/Compound Semantic Colors - Light.png b/libraries/compound/screenshots/Compound Semantic Colors - Light.png index f010626dda..83c00ab51c 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:7598b98462c015f2bf74b3ea3ad95fc0220b2efb9bb81ac56025cf6a158e3f8a -size 308976 +oid sha256:5ccbf1234065b182939f001eb65eca0a62adae41a2d91ef0307d27b059407178 +size 309084 diff --git a/libraries/compound/screenshots/Compound Vector Icons - Dark.png b/libraries/compound/screenshots/Compound Vector Icons - Dark.png index 30eac13a58..290f09480a 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:9f2584ffd8e3a4746937cdc3e0baf04a89839061f15d00342e6150c21bf13228 -size 83228 +oid sha256:1d4f46c82f1504a983885a7d177900cd6d6f7729dce6851520cd7e471870ad2d +size 84955 diff --git a/libraries/compound/screenshots/Compound Vector Icons - Light.png b/libraries/compound/screenshots/Compound Vector Icons - Light.png index 41fac03927..01cee66ad7 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:fb1854bf504fcab7752c4d51f5fc6cae65511581fb64a1adcdcf6f912d4aa15a -size 89148 +oid sha256:e2c1a78a88fad99c1fd9bc29d802ee8c2bdefec89626cd700c73f4909738aeb5 +size 91022 diff --git a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png index ec148b5c75..e68a69090d 100644 --- a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48f54197f74cf0675e04a83efbb278728568024bcec38a8553b623cdba384e50 -size 60460 +oid sha256:8397ea9df5871ea2c71183f59030c73ef7ba102aa75e5609459bae06b662847a +size 60474 diff --git a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png index 870bdf0bca..ff9a4d740e 100644 --- a/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2e2356a3f8521649d6ad2c10f654142f87141e3f747db5a6f6ba25483c8171a -size 59516 +oid sha256:87029fb2522ab31001a5b1efb12b8f99d0a5217d838d7531894875c44aaced76 +size 59531 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png index d19a140456..0e62152f25 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96bc0c555188cee4b3f3e3e0f28f944a4225e27b9a1069edf2b10a2993ee3080 -size 26078 +oid sha256:5503fe0529183e4235336b86b2566a7780c0acb42a0555259fdc5c2d83af923c +size 26362 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png deleted file mode 100644 index d19a140456..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:96bc0c555188cee4b3f3e3e0f28f944a4225e27b9a1069edf2b10a2993ee3080 -size 26078 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png index d21a12dd64..cf08addacb 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a103daf8447cb571a0c5010d062a7790aaa0f3dce30f052bf86884708f4881a5 -size 28769 +oid sha256:25f79679d8b15bbd4cd27b79aec1d5a33f7784d73a0b6fcb5d80a3da83b28188 +size 29073 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png deleted file mode 100644 index d21a12dd64..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a103daf8447cb571a0c5010d062a7790aaa0f3dce30f052bf86884708f4881a5 -size 28769 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png index 22d05e61fa..31ddd63f80 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9682cdd7e08e32591fa47f56da5e6ef4cc3a777700931c2c86e9b802a9cf25cb -size 67342 +oid sha256:3a591fbf79b2b97bec5028b4b32b4a28ded3023355dbb446be793cd59701c284 +size 67642 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png deleted file mode 100644 index 22d05e61fa..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9682cdd7e08e32591fa47f56da5e6ef4cc3a777700931c2c86e9b802a9cf25cb -size 67342 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png index b2bb8ac3fc..3dd62262e8 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d20c04c6385e675bd71d93d2d5d832509b1300a27708245755f263392b33bc8a -size 69457 +oid sha256:220888172844b7a99bed005197f78c6fe1658d8905de5e524d3e0c58b174c150 +size 69851 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png deleted file mode 100644 index b2bb8ac3fc..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d20c04c6385e675bd71d93d2d5d832509b1300a27708245755f263392b33bc8a -size 69457 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemTextViewWithLinkifiedUrlAndNestedParenthesis_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemTextViewWithLinkifiedUrlAndNestedParenthesis_en.png index 6bd15db678..12e583aac4 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemTextViewWithLinkifiedUrlAndNestedParenthesis_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemTextViewWithLinkifiedUrlAndNestedParenthesis_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa94348d573952caea928cef169e6dab0b2e46c8d7328ffd31b385fbf575fd39 -size 20313 +oid sha256:82210d42de0cf0fd4fef8d23a3c3971b8778a916a2af27b3e8e3320de96d5c3f +size 20475 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemTextViewWithLinkifiedUrl_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemTextViewWithLinkifiedUrl_en.png index 551c04dedd..0b13dd05c6 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemTextViewWithLinkifiedUrl_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemTextViewWithLinkifiedUrl_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6678b4bfada4177341a7af5a892726522b1771e7a13f421a74b33a474f7b0a8b -size 19552 +oid sha256:50f6dbb2770fc8184c9a410b6a3a1182f26e063075e66a657e81eba8496a3489 +size 19729 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en.png index 32733b09b6..8a2324db79 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2cb3989055cf63e3ee14d8e2d8b2cdcd67b3af1addae78b38ab13ddcf93a232d -size 9740 +oid sha256:2ae7f9c33c329fad507868f5e36a122045fb79e401a2215b487bf3f41f8cc977 +size 9739 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en.png index 9b9901528b..120ca41bbc 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e206a2485736baa2ac8c6dae6847ef381bfa1f36a5b7bda14a7f93a55069f41 +oid sha256:7a0e23b9af1963b9c500c39e6d5ac1fa72623db436c9e21596b69b4cae5dc6bb size 9666 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 4850eca991..fe900dffc8 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:2e469e1d16e26b6615191bd26e1ada64c98292572b7d8ab98a423ec3ae355c16 -size 379478 +oid sha256:e516218540c579c2dd9b322b498afc502fd9473b087b416efa43dd8260d056bb +size 379469 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 05caec2562..f2ae031f5f 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:2ac5f753b3d3973878b9244d3f59ee3171864506f8a8765a4caad5424512f5e1 -size 377817 +oid sha256:8cf6dd8fbd5f7c7cc66ed09fe29fb6760ba0c2a2d664b129dac9acb80e3c95d9 +size 377818 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 4dcd174908..ae5230de8f 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:0dfc5205d51fe54d92f1586da5b084789639908ffba9cab9f4a9a527441b4de2 -size 364950 +oid sha256:15ef0b45a784088e223a0c9996da6b6299277c02d7934f69bf1148f764390aa8 +size 364949 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 8128a86192..81056bda38 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:8ed58942c843877fbc757a37489fe538a504410382c87cde2bdf8f3b54d3b417 -size 370053 +oid sha256:5bbfe429c79f1a34534041928d5e87efb748d02e1000e759ce1a0ad58efb40db +size 370052 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 a40fcca299..2cf4424886 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:7e866c721980fe3f6c3ffb740e6f2262f68c80a76f7f4ab648d54d0e81dc603a -size 363008 +oid sha256:a07e7bd9dd62fe64a558e583f3ad98980d09c7585509efa436e4df5a9d3dcadd +size 363006 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 22af9825a8..6aa48c10a8 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:74eb06d02b477a325f50f1618ae549e43d2b72444072b28c0287bd551410e080 -size 368151 +oid sha256:c68ffdebaa08c9277eacad0a16eee158e72ae28d3ce14592174091068f0ea6ea +size 368149 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 c125d9b881..cb11591308 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:7a3ac104355ef6ad83d6c4271fb1c666a4c625264144d8ebb577a625e0f5f730 -size 353133 +oid sha256:273d926ab913ac5e44ed986cad5484f14b6c78e3bab3ae6169e97521cc734eeb +size 353127 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 3a90e26ac1..b7c6d2ff79 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:73cfddbb371d681801710788b443d6b3de733b026bc9421d994435e9191cc2e7 -size 363534 +oid sha256:a534bd9c790747f983831badb8dda126a776d9639ec7f9454e798e96d1be4954 +size 363533 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 8fcc1ba614..a1ea6130e0 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:52c4271018f6ef8dde2f4704c875b50b013c91e3fc9a6821bb22c1778a833ff0 -size 351724 +oid sha256:1848d32a74c570671557ac50dae5e43679a4f79ae20e69489a5140d5508f4ab1 +size 351731 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 0430452b23..a936428bd5 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:651e870ef260bfce2671d8179d4c2711cde8216fd933df14d55b49b1338defac -size 361233 +oid sha256:5f0a52fb45860dd2ceef51a84a1b3ade90158f4ad9412c8ab5209e484d025022 +size 361217 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 fbfc33a745..75dd71ad5e 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:ed7ab7efe006792017dfebb212f4169afa51b121f0acc32f594cbf56fc13bf5b -size 369628 +oid sha256:cd9f85eb61c206e7237f148afdafce0df78246916bf1e149dc14cfa7dcf9ad75 +size 369622 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 b07ca33c78..44b50ff770 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:f9ae07748ec931966b8be1aefd7dbecf533955d691dc5d2b75ead73b31ff0454 -size 354533 +oid sha256:523655ecb0dcc790c3f5488684f8818e66d67307c0fceb7321793ecbf8d6b5b1 +size 354543 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 d3a1958dfe..dc49264f75 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:824bb76f7f23573a9bf429a7c46336a5066c9c80c39203be09de17036cf901a1 -size 367900 +oid sha256:06054cadaae544104b0a7ffe7c5c712a68dd1075044b6a6558b732465e74af69 +size 367897 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 6d69b0ec43..09d9ab87f2 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:060e4a97bd87ff79d5464081684245d37af2733a1440b03f76ced429f0137d05 -size 345006 +oid sha256:ec07a302a034abc4058098981a884a2812b6fbaaefe43910f954efc2becab3fc +size 345007 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 54be2d70d9..577a6744e2 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:eca32f762418e4b7e3828f5dd0cb839d7020d6cfab308b0727885195b00c3c01 -size 357521 +oid sha256:b6364afd08f2a1f744143bf8e1aa0a77585cfa8ff2c8b5b0a0eb2e01afbef0e3 +size 357517 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 5f3af564d5..d78ec33087 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:ed1e765f4ba4078e931572fc5df68655cdee951d021762ea41c4d6e867fc960b -size 356674 +oid sha256:af1605ff52a6a6e92154312b00706401889d478c41ebfc7aa75e680412b8f65c +size 356672 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 46926bcb25..14b4638e34 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:80b986470b115a047156c2d63c026ed5f887cfa4af0488cbb477722a43b57980 -size 364488 +oid sha256:26cbb8ad35bb3746b931aabee1a568c37ec0f59052a36752af482149996fd207 +size 364483 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 255ea7812f..a58a3b697e 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:75c8fd9c2cb9fd654e9593d4763dc6d04184e1ea2f814e79fb6cbec7f231b47f -size 397016 +oid sha256:cac3aea0874bd1c8e3c26bbfe7e6353042d248533e630b69644a02261fb2d7b3 +size 397020 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 f88757a9c2..ef4fe7217f 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:dce75ec016354e7e3243fde61f1bdd3520bad5a84bca84a160ec0f4dea857dfc -size 355897 +oid sha256:a63ce064aad609786d444e55379fdab29253310b77012387e168ddfdaa583f55 +size 355891 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 a2c24e47cd..8a0c80710d 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:11ae7ffda287e87638c639f6357615e25978d663a5c6e66e699323f352a003ec -size 357733 +oid sha256:9b7bd7fa60c549e0f03d73cd67db352285ce02d050d465505ecee6b3dc535e96 +size 357735 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 1283ec7e67..3fc491378c 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:62ca94e55d4907b37afc1865955f4cab2f3e595827b361bb0612ae020ef3380e -size 364820 +oid sha256:fa0b9eea253b1eb6c855dedc6dc444b482254e4b4d96a895d3e82ee10a9a38c1 +size 364811 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 2b66e7a119..bb6eb5eed9 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:04293e07b3ba253facde1fd495fb1fc5700d9fa91d55e6fc26407bbe80710c9d -size 355148 +oid sha256:e7d978590295705191b23fef236aced625dc85165c23ae703bb9faa7ce2efa6b +size 355139 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 23c44e4e2b..e0be8f49d5 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:e497584801b9aedaf49483e718baf913d9de4784a7785d4b1dbc931af15ca2c5 -size 367618 +oid sha256:9d0997895e84028a7433a3e49503e1bb79f675fa9ba5d80735fdff0a1a4a126d +size 367615 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 5502b438e6..7e2202e70d 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:0c07b6043cac6215e0f1adb1f341fab2657f5989fc6f775c44103d767cdaa654 -size 352618 +oid sha256:691b5b8844c37c0a70bff7e2edb489c6444e6a3dcdbcd1fb1364d3f429b0ec8a +size 352620 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 a333a03c2f..7c53094f41 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:8b26ac3162c11d5ec150548b8e57c60c8be81da5e3360b06fce254a41d6bd46f -size 366046 +oid sha256:a0138339ed9132c2ea93f27bcc163f838e24a94ab4e731d6a7baa3fe1e2c7e3c +size 366045 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 7e86609428..60afd00b14 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:d7bf88755dc4eb1e9750f9556fce89ec3be77a51f608734e5ea535012221632c -size 342592 +oid sha256:7876a6125d45647beb8cc5b5b125556b16560dab6599ed4eba9fd746fd4b17f2 +size 342595 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 74f6213244..5cb708dad7 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:9896599ce680aedd483223ce1a83736545b792e61bdf2b8d231eaf76cb3f23d5 +oid sha256:2eb5334bd16dab1bd9ba111967aac6e29fd6eb3d325fdec6f6ff6b7b3dceaf06 size 355727 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 1bd2b6d19e..cf56ea41d7 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:2ab6a4c7fdc6c3701c0a2fbd1ff2ac5b023d904bcd61604be63fc74db8809c74 -size 354859 +oid sha256:2f4fbc0a4be27e1f6b42f0f7d447e95662a9acffe079b5ca27b8f38971c67b7d +size 354860 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 1b17e5f9a2..650725b8a5 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:ef2b2583e788c1d802d81ead131f67f17d83b5a7e8f8d44f7c5bc9a042b76722 +oid sha256:ce5ef1cdb3b466af1b445020cdf6b5037c0222430a37a6cf2bab42738c75dd83 size 362581 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 8743d61fd4..1db9c6d9e9 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:7cbbaadca7fb46fa4f6483eb9760fab96611a2115f98ea6d9f6f62411fc5b4fb -size 395148 +oid sha256:e801e2540bbcc28afccfcc9d57fbc6945b0b1a069dc7b7c9f31790134dc498ac +size 395151 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 e4a4be9cd6..57b7b4070d 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:45d46f34b9fb4fb8260bf2154b8bee5112b94524800870ffed2488252ea0ecf9 +oid sha256:284c445b4cf37c26c9dab6b9a00d23fc1fcde5eca3b02bf7149ef50c77f07980 size 353920 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 3485c722e6..a3f63b3e46 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:091ea9b69b86dbd001ef78d018fc4f273db1323b999aa3c591c38f8d214812ad -size 356033 +oid sha256:22df78bb78f17d4c87ba31db8d335f6428d85c5ff80c9bd563f5dd6a6f1b762e +size 356037 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 342b7415f7..c1c1318e73 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:66a0b023dfad07f7026219325d966375bf3f25fa0b3f8192f101828e8b4df2bd -size 363005 +oid sha256:2791382f305e4acda3dc503b9c26f9fbcc2a5f587907cd440aaef0c37e37644f +size 363006 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 ebb207c6c5..ff67beb656 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:616c6ed62e974a649145ffd0f540e45701f302f4881f6503b240746f1084633f -size 353268 +oid sha256:21b77a16dd2e7d68c4f4cd8f2df9d0ea9cd55edb54dd48131bdedcee9c4e7395 +size 353264 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en.png index 6b04b74ff7..1e545b50a8 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f37fa6b14e11126a7cee60f333b2cfabd4b540b548d13467115533f58b7b333 -size 68208 +oid sha256:6ac7ccc7a75706f50fb4af5cd3149665b9aa52ea3a69b23b6e71a9f802cb8699 +size 68204 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en.png index 690f541b9a..d636453a96 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c3b4dc78e6ac7b6296d7b24c0a0f28faf90b4dfb983cf0c970f41157b7ca469b -size 66907 +oid sha256:5f64cfe1b26fc3c5f294e68b91f0f0f785a945cb1cadad57152d3a72b713a9ac +size 66906 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png index ca2c69a01b..672d60c299 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97065ad20dc15bad0e6be815df8a5bd8b0411d11e7189e50a7abd13438f60f4b -size 69292 +oid sha256:d4e22dc6079daafbda97305b48143936228bc16e8c1dd84d46886b2d9f437dca +size 69579 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png index 34738a39fb..75c49364fe 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f65782549d9ae258584413de54a016705b705f05fd653b48c302b62dc3cd0c71 -size 70718 +oid sha256:0b6050f9ca4c5f714f6061c31a1a77147d06ff4b500144cb100fa10e05cc13f3 +size 71108 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png index d131a922fd..0273b0949c 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f717db20299c7a563304a00e812810d30edf3a92090bdfd478b044689be90c3e -size 43422 +oid sha256:e4f5154e5b0cc46dedb451a5201377bd6a5f9d00eedead80faac2e42077e69aa +size 43421 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png index adeaf23582..35bec7f802 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:219df263627e37e386f32a5516e94f812a9a49e8094a5da7ed8787e845b00ae6 -size 37457 +oid sha256:622765f7acfe732a8ad0a6b4a802c26ac92926beec5cbb213e16c8c152afa410 +size 37463 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png index 55a3c08314..79f87ba1c8 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a31f6f5ebfff32d770502a1469da23aea728693b4b03821f0747ced891307fcd -size 42188 +oid sha256:7e722c3f569138d1ca1e618c4bdd78e79e78a599effcf062cada98ad96c4dea4 +size 42197 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png index 58f05833c3..5cf3b1e3d6 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1aec8ef33c5f19e1de94a047b03f74ea98427e27f67c0425e87fc79384daaa5 -size 35121 +oid sha256:3cf7db826d0de2e45632e9e7828b5474f9588e07b3344ed75a254687c8758905 +size 35120 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 4afce772f4..07d4c6fe34 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:563c1fb871dd46823c24f4372c88e15e92e446b9cf14667f910e19d8cc26adc3 -size 43014 +oid sha256:a7d094485bb16c1e6bec8376cb788aff4c67e73aa103c91e9c588ee7d239b011 +size 43004 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 ab862d3e1b..28173d1125 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:d0650642de63c69978d9665a78fa12095d4bb4c4d6cb226dd8de00e1f60376b6 -size 41965 +oid sha256:807fdac63cf66d0e22c3be3bb912fb813dae735ad80cead01a41226063476131 +size 41950 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 ba95ff1e8a..ce2c6b58bc 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:0a6f32c806782b4766acd278fa7c7c6b80f3a2f31d6ccff49c01dec6a4463120 -size 40796 +oid sha256:19cad5807c22bb3b5137b94833b9355edd2a4e2dc3bd4e2fec6de47ecd91b2ff +size 40845 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 74998495a1..fbce4844b4 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:e63194ac849e271a3df7994f6b2ad11baa95f071b319b21bb37e2875b99201cd -size 42305 +oid sha256:ea37a3e4130be70df81abd1d91603630852eafa888588441c8caf0c6ffeff6bc +size 42296 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 f79dda0606..9b6ab6166c 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:b84c9b52ed4d1845af6fd73a5a965fe872a898e097c45db17656021c00b47f2a -size 42210 +oid sha256:20574055fdf6970508234b241e2ea0af5ebe94b4e408d652591e5a1651d3f152 +size 42203 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 5deb2e11c5..e8fea24d29 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:7374624c5ee056dd1a5ae4078f883dd844ceeb03715075d0edaa577eadca1a21 -size 42737 +oid sha256:9a3de10ccfb402fcadb87903c9c81aafcee0836eca4aa8d5c19093f8992addcb +size 42727 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 2080442169..d7d584fa5b 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:86e732f7d44146add5b8a74c62942a1d67794a617115357326bcfd63fbef8a9c -size 43270 +oid sha256:2ba333f2b5d8f8d2483ab2e1d42b1bbc73341bf8777bb2fdae558bb9d5567684 +size 43259 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 f0352b8831..9b8bde44da 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:9d1c6c551215f28d3fea257bd8bf696958d2ce9cd165834c451c856b7ede7103 -size 42540 +oid sha256:c6158753a141ac5759592eb50da522ca65cdef9749019ae63a58ff56e34022c8 +size 42530 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 24b1842b43..a6565094ab 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:bffb85f5e586cf33e0ff91592e52595ea534771d41ae9ed44cdf37dc8982b749 -size 41812 +oid sha256:d2ed86adef0287ec1ecf024743ce53fdd04df8df6fc3519beef1fac6514a368b +size 41806 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 b2ea0e926c..c955529169 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:577e76d3079fcf609615983a2925506d8b19618d8cc19f9018f0a693ea9a7f4d -size 38944 +oid sha256:2b41b96a24c27b4b4996b9c12f8c9947c72f6ce80a9298a9ca0fbdb34b659862 +size 38998 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 109f7191c8..bfd9888358 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:cdd0f9ba41246283eea26da43d55363e20e7ac341d4579c7ba5f99f50674b820 -size 38901 +oid sha256:4f07e230e571042b96a6747357b90c692276e5817a784f1bd1fc8a13f7bdc05a +size 38955 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 03faf49046..aeda6a9e8a 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:a27a7a44360c29a54875e0c9bad4090802eab311adfe92b454537bec1c63c33d -size 38145 +oid sha256:656740357bfe51573ba3f6faa5387d64076897bf4874671889e5c9e2b4c51e90 +size 38139 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 4c500d4520..ac5031e91f 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:ce59a6f27ae108aefaeac5f174ecaca7f45f47578d67b06ec90f19ae5f0857c4 -size 36663 +oid sha256:9673aa3cacb1b04e09f94f265a7c3a0128c205026729cc618fb7552bed9a4bcf +size 36670 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 71e939e51d..7920b86025 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:45078434e33023bb2f7fc5e5632c39f6f289e14a74a922bafbb5be5d69c59662 -size 42578 +oid sha256:abb3ac4c9ebc66d3f1b6457695147a59965026eb7beda75e2eba22a84449e0c7 +size 42485 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 09a3661a75..13ddf88701 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:43c9bb289d3649f3fb645a6ba148714745ae360fdca19547db26c6a856c3e0be -size 41471 +oid sha256:3315b18fdd823f1e30bd5bdff6c8c32e076f6eb1e7d45d2014dc012fd9bed95a +size 41475 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 178191874d..1f2df272ef 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:726292bbf99af55d7b8f3c9ee64a5ce5a263ff51112cb12e6bf15834d8c7cb97 -size 38592 +oid sha256:f25d76ec7ae901cea990606f98ce8bfdc4e9d35830ea00bdcda4be39d8ec12b2 +size 38644 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 d8a3991f39..6e978a0b86 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:0756ec085e3d48d62d9bf5a65ffa88608bfadc7a085032e8371a5c628956eeb6 -size 42036 +oid sha256:69384dc3fe2b0343762a7f26b6a88f6557043061d1c52ee6662df7b11965fc64 +size 41973 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 3efcf95bc6..d2df6658f0 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:23a551837f3170f0f788c6def95c3cc25788d523b5bd0c5065d7e667fc222717 -size 43203 +oid sha256:0d42f0d35ed1d39ce248466da8e78e334b8af321ae46d2f556cc438b72a5a598 +size 43201 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 63478b34f4..3e17b67de8 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:6cb318d9310aca5ac9909e61407091d6d19719702eb90134e69f95a7f888f0b8 -size 42251 +oid sha256:eb28bb52f2525e56a9878a15f4ead5082552f34c949478e9007daa99b11672bd +size 42242 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 b9a5cfd98b..7fc97a68c7 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:2d0db82cf51a6c11a4076b0b059cab83fb3972f1f2fd198fc7d88473f3d71468 -size 42322 +oid sha256:1a6a449f71ad2b13548c98239197e9b41ff69dd61883165436c2536328f080ce +size 42317 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 10d904c88f..27e877354d 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:d0e5449db01008ac93de2622c74ce928398c4b5b72955f6accb8be6227eff10b -size 44019 +oid sha256:7f747dfcc1231f58c0ddf1bbd65a371260ddc235c5154b813b9c160d48adf2fe +size 44008 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 41658f0d04..dd7a9d62d4 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:b807776a9fc45a7e3e0269e3c49e3d254a0c352ad2fe5cc4a992eabc003bc009 -size 42957 +oid sha256:85de1a31b77b063d45e3bd8a3d9295258d7aeae1c718110616f3b0d070866115 +size 42941 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 6fb32137ed..1028b93a14 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:bb10e358f851007b69049cb402f1bcb96187ace186d0388ceca159df470c98aa -size 41745 +oid sha256:4da08f2a8b9028b010f5aa6f6723f62b9628e2934ca5f63b006dd4f95aa42c26 +size 41775 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 e50e4828d6..09265aa6a8 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:84903a3f98030ff665fadfc33f652f90f7f7218b0cfed1d2aeda28a841d8eae9 -size 43286 +oid sha256:004d09f28f9557dc4777ba570519953617a234ee8e81829da6a9e6c1c859e34a +size 43271 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 facd9bf8ce..aecd669aa9 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:df98b09223ecccf3f31916e206542e1dd4cabd17164afbaf5146308a35191c98 -size 43176 +oid sha256:4fefa1e43c387aff8b21898d7431683710678d23f75ae66fbd5a9674b6dc6aa9 +size 43166 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 6e91a419fe..27ecce85f9 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:6fe0960d489628e9de6d456ef1fb87f7e84612ecc017175e0064f9ca2a3f0ef5 -size 43677 +oid sha256:1545f2842633d9257ac4d04e156136054d83117051836690c769c8c140df4aa7 +size 43668 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 4404a8104b..6099e3dfea 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:3bd079d0f8c7a9f6f51ab19eff354e160bdd595afa35a2b0fa4f850ed324fc83 -size 44285 +oid sha256:750e5212166a2037d7c8781bf3cbc26f43e458045e0adf4bff0556d4c1b0fe35 +size 44271 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 8944270170..c37acd6257 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:6e01dc9e4f2bbe0e828fc989316c4c1273de8ddd63c51597d14b9d82d4eeb37e -size 43526 +oid sha256:745513bbfe1ec194c8245c3dcfaeb622e2035ffb901c221e4417ee68dc562926 +size 43516 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 71cc58dc7a..1dfe867624 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:20dcb59412950d80583dff0d5bac8fa1380a5cad9dac8e6ed32272fc7be39e8c -size 43033 +oid sha256:fdbaa5a809e49505bd65b3a80d58d34c86349bbd232b19670737cfe71a341626 +size 43009 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 abafac6652..49c174bf4c 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:4423c2b99ca7270ea2a9496c71742117a6b5a63f4d053810cde5b724cf309827 -size 39819 +oid sha256:09b3d8e59d77fb1a56d2e3fe65ca4653f1ce0e83e2d1ae66af5b2fae894bc2fe +size 39844 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 eec52148c1..ff1e4c85eb 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:630106a8a6373edb3ea61ebe9004d1e842185e16fa67c5103e9207f12388197d -size 39702 +oid sha256:7fa29b5231b97749c6768d36f278a53fcf7dff7d3f19d7800a1ec3fd785940dc +size 39727 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 af4b7e3e4b..3ae4895e73 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:666d69adf97dc13817ec64204ba36f77837bc58593233c6988a9410737e17f0d -size 39243 +oid sha256:de557bc7ff39c13540f6caa70807065a5506f67d983661a247d8da7bee0e8437 +size 39241 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 898001307a..50bb5ae415 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:a782c4d02d209fcd9625f24dc7008c9d0bd0862646ed518cd5855e015d444cb1 -size 37680 +oid sha256:f1dd2be009cf074cd5192630e69f94fc75ffed71c5da5f6fa41a49dcee5b33d0 +size 37669 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 4b5827b560..526d814126 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:f6bb45bd7efc53d3f7db74f5ed5801a4448d39cb231404c4655b0c9e91f246d4 -size 43446 +oid sha256:02805cb9b7642e8d227b88dd5384efe5e95ea58c5049cae8f60cd6af11fdc19c +size 43388 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 e47ac6ab05..20e2d596cc 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:eac86b6ff6d16de49e2cd063983e06bf144d796e86ef00e992cd3f1f0d248b47 -size 42371 +oid sha256:9d85ab1c7243b178d24b2716320d6a005f3f56f1f2953e1ca29879af2d923311 +size 42369 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 546f29bed7..2a4e8a2789 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:b4e5f3b38e510ebb3bf3e72a3eb28597933b438eb466fd4a5405f61b7d8c199c -size 39363 +oid sha256:51b8a65fa1ea90f0f3227d11dab9e02b6821e159eef5288ed2cfd4d04ba52fb9 +size 39390 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 30dd8c4ed6..9420f03ae5 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:bb1c8acabcb77021ed8dec07dc0bcf8537342da4b99030ad6bcb07f97d48c30b -size 42948 +oid sha256:5ef4eeee1c2d48fd0b4bc2db2b5e63a1669a7b1347340c70bd08f82bfa476a99 +size 42943 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 239eeea47d..733da0d460 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:07c72b2af77dd3d9b096b800c035ebc9e5e256dafb351232b67aba1cbe8e6d2b -size 44390 +oid sha256:f276d3cc7714d47086eff53cb564d8a9b604cfd0b6dbbcd4eb906326f5b03110 +size 44373 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 44be14ec52..7088632f7a 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:aab42df4fed8f0dc7696f7b871a7d24db2db0d07014131f682c18b3a25a65f45 -size 43295 +oid sha256:4deed8665be752e542a35fa10fbfe52912c439989ae021ac8234f5641a6e952b +size 43284 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 2c12e4ece6..cd5e1b9bd4 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:5b4ef80cebe6c2edd5c7a66fc77e7360ffd845936a1984a917dc8f50c66ef89e -size 43307 +oid sha256:494e81f1ca9e65950f3f7811d420154f3df9cb39749341b845ae873fdc0c34b3 +size 43300 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 168f2c58b9..1a480242fd 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:70699c27896e4f718fa9266da6309f15760d555ccab3e70cb4ff784d200ff548 -size 15947 +oid sha256:a003185cde12085777ea4d8e9644340e6c33d5cfd5f28a334505ddcfb2ff086f +size 15988 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 8ffedb6083..0bec1fd952 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:116674e61bc1713dcaebf771f24259943564a72038ee5f44e4f1725a3f4ad264 -size 15297 +oid sha256:dbe0459f90845db50c49a75d93b557242cde82fbc5563d1ba971f307efe6310b +size 15353 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 e878beb841..5adea69646 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:5a8932b7cda9041d40739fcfdbf9d41ef949c22ecd81394d5ec5d68bbeca7ba2 -size 24248 +oid sha256:570e2d342a5783c6262ec635ca77a4c9b9dbc350630c20ab6c12b18b2a4a4629 +size 24283 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 cdf5fb5cab..2b32d0dddf 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:fabeea3e8fe50ed61c3ed73e8bc9c16feea9db9e96a30c62e2643c7fd61898c0 -size 23366 +oid sha256:0115719e51a0f718c7071bd01798ee0212c73c04d423e0893a6abbff816a879c +size 23420 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png index 9957d3f2a8..3cdd56a15a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6453b165bca4b509d7a2e1749e0534f5f12465de3b32bb0513cf377021a57a5 -size 5080 +oid sha256:6ac466625bd9985cc0c820a99b30fe6e9c0e3ef738cb47d5eec9a92a5ed1cda4 +size 5100 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png index abea5053c1..ec803d2726 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2431e2c666af3353ae85d9a101d8dde1378b4fa3d1828ff23a7f4753f6fb2725 -size 5112 +oid sha256:40894153477d0d133746def9003533095c1cf18f5284974bfb268790eaef4e4d +size 5122 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 c841a032ed..f255f6b584 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:ae006adc82d337fe478f01233e7890f583b93470987b69227666aad4c7749a51 -size 7037 +oid sha256:80949f82856fae9017643fb91a9247fbff10360e738e5c1e1c8cb20964319a53 +size 7054 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 a81dfe7f9e..d14e225325 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:24267c25c8b258355b9651f71f1446ef2dadc5c868f56d23f63957e9a2db88b5 -size 7134 +oid sha256:b7ee25f4b4fd3faf4b5d50211aa7bbb029c658d329acb51093b39a603a5d9037 +size 7077 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 73e03f01ff..cbb16b65d3 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:7739f13ad8e137ee805e7b105c0ef2caac23f6cb57786f9259eae65ea45d8a5e -size 6524 +oid sha256:da8c84bce2caba0a96f884e09b6c272a6a05b3676ca35c85e4d384e983440608 +size 6654 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 53d3273210..8b1995db1c 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:4afdd017461f6fbc84d6833401bb929180c858c1ba256167f7fd951cc2244c31 -size 6546 +oid sha256:944fb28c55313433e7ea435c9c5041825814c1209ab1a50067fe56f85386aebb +size 6574 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 06e37b48fd..a38c890d57 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:43d5485f54806c93c3801c9fdf430bce0786fb0f17a11f17b1f7b4f14fbf1021 -size 6087 +oid sha256:4937e2e3776d515f9a1d661da96c0131229772f3965639e1f79d84cb4a7645ea +size 6132 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 2fa9e9f05b..e96ca6adf3 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:b7b729ccbd27f32162efe06f1f806d0483cf98b3d47175a0fbb7a88b2fb5e1c4 -size 5892 +oid sha256:86c742e833d91d47bdf3410b7c24a369225bc43f222adb578c7abb3babfe9e1e +size 5986 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en.png index d7f6563f39..6985721c59 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f6d00c045200e5f98d31b06afd5517ee2da41080281c6d8601ea0169a8b32f1 -size 17187 +oid sha256:b876487f0e69c5a52679254306610ac11cbc094e23ca9919cc67c073ce8d02d8 +size 17395 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en.png index 9b74cddfa1..b3e49c2d38 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee64a1ca25439b8dec91e873238f52d62fcd4683c7d4d619b8a053fa0b6040ab -size 19185 +oid sha256:7c58cc25cbc6cd4375aaf010b97c016a17887da201ee9e00e5a28777a938e825 +size 19374 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en.png index fd1e0d7ac3..c0cde40f12 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dfece8ca4d27aa8bb0a96711f4492a7661dd9c1a00a483f120c7fd25a2abd524 -size 19146 +oid sha256:6867123a35845631c71a206f6711d19f98949b627fe08a56edca906d0cf39d65 +size 19357 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en.png index 14f3d254a0..f4282a639e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e410c37f7044dd47d56f965c1c65294d639c2c7d614e67acaaa90df4121f6e48 -size 20253 +oid sha256:d2cfb17927107faff4eed8544f0673d806e7bf93c84ba0cf536bd3108d510739 +size 20592 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en.png index 16e14a6ce9..b1a3f054bd 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a03040b73e680faf99faa8c4cf92d0ba64353346e3c80a00934e0986bbf570ac -size 22509 +oid sha256:406041edf077219d0006397adb4135a0b0ff5cf012982225f8a8d65e5b538214 +size 22886 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en.png index 16eef7e0a7..f6b4b1cf78 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b080c7768f8f954afad03d5c334207692fcf1f4e8af7d41fe0d2fced384fe9b9 -size 22130 +oid sha256:3f6bcebbcdba8ef2e472d8d76549631508d3c36a4a9ff3fe0a8a6fae41f06a26 +size 22518 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceCategory_Preferences_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceCategory_Preferences_en.png index f5694840fe..104fca8396 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceCategory_Preferences_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceCategory_Preferences_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1b41f7235c9aa037dea64a67f87ff688d4b229f1b5a46bd563f57a7b6c690d9f -size 24926 +oid sha256:321c0b750862d017100c61f7c4e5656fcc6d8566e0cebd81586dc6891d971b76 +size 24932 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceCheckbox_Preferences_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceCheckbox_Preferences_en.png index 1b4ee926d1..97c8f9a589 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceCheckbox_Preferences_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceCheckbox_Preferences_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20a85881942bff954dbf326116eca8c2c1d9b2dae3c7a8adde7f17de01c6051b -size 65875 +oid sha256:cf70f35d11eb71737f0d33bbdad1073a3ce15bbb6534f4cda3a8c8b8a21f3da8 +size 65858 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png index 99527960b1..1d7613430e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73749a1655e26374776fa7e8aa83582b969cd40259a5ff580710a2b19acdddb6 -size 32072 +oid sha256:00eb9c6756c353ac82144c391617a515d871940c32d0604d86203f8568e9e5e2 +size 32077 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferencePage_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferencePage_Day_0_en.png index 1d6a5b52a9..b145a008b0 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferencePage_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferencePage_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf28d2f2f6881f4abf14fe8228b05cbb9194685be7a1bbb14832932b302bdf89 -size 22324 +oid sha256:f44fa660c80894392dffe711573d536ab8e71b82411f339b45bd29b1823d4919 +size 22325 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferencePage_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferencePage_Night_0_en.png index 5b56b809ed..a3ffd3de6b 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferencePage_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferencePage_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b56433b754cdc8bb335acc1ca97acfe7c55474976f657b984f4f34477e2f9dbd -size 21555 +oid sha256:442c03aa8abe7e43ccbb1c736349d606353833c3b33535797b3b2840d46b7a6d +size 21554 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en.png index ae07f25c42..f3671582ac 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ebc0ab69be80185ce7987b412d47bf01c8df140a346bd64a983b6c51fdb0b23f -size 35700 +oid sha256:fd6ac8137997251a9f8800a9988d0fbca7d8adfb1e7a862513e09dd02faa931f +size 35693 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 dfbf9ff253..0e350840c4 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:6b0f8614dde547fb8e3ae607840e97dbd33f9d0ba179174a3b22dca715ee18a1 -size 6025 +oid sha256:0a81766956178672485c43d1a904e7d3e14ae767c0e0d26ac2b4bdce13c0559e +size 6090 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 1009cfd194..3ea800f130 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:b7382ba4a96f23194e5ba732e600b9f8571f014085b98ad5e450f020f07959fe -size 5854 +oid sha256:37f1b0274f4f011736797196e268d5c07c19449001faeb1ee4e9950c2f956c6f +size 5954 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 d91c25f8b6..f6d53a9aaa 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:5a9147ee3d19edc25ca2723ce63fe0ceea0d071a2c2aec27f0035c862ff216ec -size 102540 +oid sha256:22f7a2f98e8a7deaacaaeb75233cf1cb006c79c8e108b3c000190ac7ab006083 +size 103743 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 bfe5178d57..2bbe3e0435 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:6434eccd77ea3b9caa1368499c08d4f7f796132c217c90df335004547d42103d -size 35663 +oid sha256:194e43d76e485ce80195018876ff9f1baeb1770c13c88388cc8adaeb192b9367 +size 35904 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 a0a19059c8..25f1737a6d 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:bc6ae5ce0f90c7bfaa76aa0d10e23fabade20a2a23c112f5bceeb66aff585dd1 -size 34552 +oid sha256:4e40c4eba4117cfbc37f2a7dbebfa2cb3f6a81b12507fd3c2deb9df2d40b4754 +size 34349 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 fa55a464bb..a684be36f4 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:e956a7bd54ffee6dea722ff5c8e5a602f797ed82f0f4010cbd721cfed015f002 -size 51477 +oid sha256:94672cc5b4e0a4fbce2fe3053636605a7984b6cab3bef41cdc1f6b174a35252e +size 51851 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 6400d5d479..9efb85ed8f 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:65d838a4214cb8f5f05bdf8d45b3641c283c9abf9ba4490df2ac08812ccfa0af -size 49793 +oid sha256:ca6f44470098e77a72f5b171d36d793b63234dfade5cb6e688832e6ca3308275 +size 49451 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en.png index 0210d92d65..7e5c3f7c9f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07dde3fb17519070b77161696e914b84fc22aae9ba3f0450ee90f2d97f958856 -size 63523 +oid sha256:49f2eddd77c7a5e7a9307c79068962432a06542c327ad984e931c3de9dbf93f8 +size 63577 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en.png index 50cb131812..05e2660879 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37a468d82a264f1daf018045d39def3159b7109c0ad658494fb545fd545c2cb4 -size 60915 +oid sha256:6507cecb7cb8234523c458ede4aa86d6efe818ce59917d9880e13e899118d343 +size 60992 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en.png index d4b2df8fe4..4698ec2b86 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58d71f16891297f6edd291d20860fea05bd6ffc1ed53082337b4b0106f20a334 -size 64466 +oid sha256:fd0cc87122d0a95938e3a345d256897dcd4a6f76d0fc3f025b5dff62799e9aec +size 64538 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en.png index 84f226777b..374c8d58d8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9fc8659a0e124f417a15b4be2e1871c41acdb593b2584a86eefb2b75073da61d -size 61481 +oid sha256:feb109a35370f31716f4209dba88ae2b10c31cb612cd5045fcf8fe61a519d258 +size 61541 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 630f6fa3a0..a9768e6f92 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:1d36612b8e2ca7f59ab05b4b4118012c2725da9ebbc7df63352c70375451bd13 -size 73958 +oid sha256:184eec76d1b81bbcb0da05f190df652e0acc99b511f39b6efd64848ac0265333 +size 74011 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 d95da7f0c6..4d9e3852b7 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:9672fa099af849fd75e4c6a8a5d01682e1e5a0283958c6abe2adc122ad5e2763 -size 60519 +oid sha256:8b58254ab6455b9cb669f585e55d63b3ea2d0d1863dc9cc33cfcf7efeb9c9aeb +size 60569 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 d7ffa82c24..e1f56a9a7b 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:fedd88e24489233b32e215b671f238467816f6ccc5bf634925ec845d32ffed90 -size 73376 +oid sha256:de0965032145efc6dd7a2eeb62cf61a38f7c178a8b8da9aa3ff38f8408698241 +size 73436 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 075a41d8ad..1f689785c4 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:37e4dda90892ae77976eeb7c78c58e236c96970f46e305a2a9e5814841990a5b -size 82106 +oid sha256:096674378b59fff410c6788ba29914bc4711d0f78f6bd82caf63b1e4494c97bd +size 82156 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 289a88628c..a63e418a77 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:992291c170b880009c4efd872a92d19d06476f506bb748b5d5bfe4018c87d01b -size 63075 +oid sha256:4d35305c3c04c597092b1d7cd35718cc6e8b3ccf262f36a5e309321d2575a1c8 +size 63135 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 42e2287129..79e9391ba7 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:bd1d0f3a07d29610650691389071444fdd2117fc62ccf52619ea43edc65e9169 -size 61984 +oid sha256:1dec29ccf1d615eeea8527a9faac5547b4f41bf7bd0e43708f549f0ef9e3f128 +size 62034 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 1219e15937..f547f8a6b2 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:ca4142324fe63d5a0c3b06a9af710ba3484209a2b938115a68e35d7785cd28dc -size 68983 +oid sha256:a55fd94dff2318b2dde74c7db1df8dbdbcfead6d897ff60fbdcbc1e016588bf7 +size 69042 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 643df1809a..d9c304aef6 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:c672e86ebd42326d6373a55b9fd5b3dab8d5845af76d0b15ff0cc478a7f68be6 -size 90870 +oid sha256:30919bba4348eedd2491874053ae23d9ac27a9aefdea56611564b4a4df8aac8a +size 90920 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 2eb532fa42..eb8c2523d5 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:83d739bb6b0840e44142b986f04bae377761c59b1093f329c5392caa8f6e1a03 -size 61413 +oid sha256:30b2ec608ba0da25348d72ed3e5cb8bf939b4b17969e1bc8d0afe2a36a107b83 +size 61464 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 d2f52adc69..ef397e5d6b 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:592397176013d373cc1e10b200a804edc1bd9298ee8d6deb28a78a44e1e4787a -size 62569 +oid sha256:407dc99e70a309c124964570a1b5f0c272c6b44f6f099d06a87d4e5aafc3d925 +size 62615 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 ec4f1a0002..7926c0c712 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:b50323e3ff9f7b0ec0d8eae7ca0ed889c1beb274934a31e6f6f97d8fda2a15bb -size 68751 +oid sha256:523ccef98d598f6c92b95fe1682eecfc7e68e76d34a34c64f6be92ce94bf650c +size 68802 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 06c15ea1e1..8f22c38553 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:9c98826a30218349b4fe2f12cb60c25f27eb9852153a58a5638f76ad5a036e00 -size 60929 +oid sha256:140983f21a45088f5ae2c9616f4b66533c79b26029dd7f589683106e6aa0931b +size 60980 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 1306534870..6db788f931 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:35b2efddf5636cde7c38237f4021554e7d97dbc533ec319bd3b8cfe87eabf42d -size 71784 +oid sha256:8acf2059f390b026e192c4e30ac2e374197b88011c7d0c0886270f7d41285e18 +size 71843 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 f7a80fd218..4b599055d9 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:b2e81ef71f7329b67791f9bcc8faea5ea57f1a65106fc24dd1daf059c7beb7af -size 58663 +oid sha256:9edaf14c0b0db2d9e809ee49e1a3735ade58a72e662e04feb39204b7fcf5b382 +size 58693 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 d8d8daf3d6..f6c1f38e3f 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:f0f17910535315498aefbea2bb6ab090a7d86896558ce9fc360bcb065502acb6 -size 71231 +oid sha256:95895c181425f9569e6c18414667130a2c272e6fdffa45486b2e56f68d8a2bed +size 71289 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 3ea53f7f2c..d3cb1edec3 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:178c5a54819558973cac3b0a581c42278bdf0f86b21d21187a64fbf6dc0184a7 -size 79661 +oid sha256:9405692b572aca986d5bdf4c70182789776a6a99eb6c72bdbb32446ad03f3cfd +size 79714 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 a4f31dc1db..3eb9e16d55 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:a8bbe99e3f3686d38176ac7a3833ced49e05023025aa287c1cb4c8d0f7ae992b -size 61150 +oid sha256:024388bfae5dcd6ff96b8bbcf37037f9c339d4d7a514ad3d096a89330fcade6b +size 61206 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 a772709fc1..38c13a155e 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:4da6aa4ff5b063a0eb0bec7550a4306f22427f0a10dd65b7a3a03419dac43d47 -size 60118 +oid sha256:d6c45be7f090c67756caad58816d22a44182407b9b6fd22d594711d61d194baf +size 60166 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 3e06d26688..86c24fe574 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:a01f535e55351ea42980bb7afa918bbd58bc41bede32ff73bb402eb5c4db7b58 -size 66848 +oid sha256:8d96404fceabc8945bef767daf670470f073b3bd214003990a38baa29ff5fd5b +size 66897 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 a6685f1f13..ab5e7d6ce0 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:a8896aaf421365ce42a2f7b83dfa71fe7c541a99053dc47649140881698613fc -size 87845 +oid sha256:34512dd365f1e270c269a6e1ed85394ad34a07de124d770896b752ab993276bd +size 87890 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 017eea5ad2..52209b5ca6 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:63dc10fed81ee563b5779f552419035af304663e5475abf16f390e9cb50715a5 -size 59524 +oid sha256:c0270681b59abdb38682a9ac5aad7919392c5444fdda6fc86d75c8115ba1c4dd +size 59573 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 9dbfe5d5a2..619c713d14 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:25f1e03b14fc39ea069bcb1fda30d49e839dca025523ead7590990831a0b9188 -size 60651 +oid sha256:b43b7277eeaee8243ba47ccd9e88b89e1e1f8500cd2399b9f8e61bdb20e04033 +size 60695 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 df2cda9dde..326b358f51 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:5bb9258874c2cbea357264ac2044a44a2742671319d19300c648e84809442f4a -size 66517 +oid sha256:e9ed04cda8b0a500d4d8d2bfe4d34edcb8ffd9e70ef0d0b4f381ef4af0432d55 +size 66563 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 a374e89168..63f4a611c9 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:c546ed7f7120d1de974507fc28e3b7e7a479c71958b739180699947c60f69d2d -size 59132 +oid sha256:db0017e0d9005c8c419461dcbd8821f4559b6ff1a5e3c8fe5cf6701cc0821da8 +size 59178 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en.png index 8f6cf01450..dd72a06454 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:efc225d678533e384bb0faf6daeb385f35b72b27ef2e6c7420d5794966920c3b -size 56765 +oid sha256:3467181fd666dd8200c25366392f43a4d80ea051a18d3b525bb7e78dee6757bd +size 56785 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en.png index 2f51e7b55a..e637616fa7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c76814aa7953eb75dcb0a1fddcb4b9dc755c863003dc8acfc0e41701f9db95f2 -size 54185 +oid sha256:bb37d793986aabf523d90cbf90d3873d51deda4117d340d3a931cc6a5b5aca80 +size 54246 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png index 186753469b..8301d09a79 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98dbb0ac81d2079ac41f107b78e6fb7ccbf1f53fcd9e95e8716fb05ca1b14ea3 -size 36091 +oid sha256:09faeef5f5864f93d81f271a67826acf417b228987c6f918b95b31f91a468cb1 +size 36097 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png index bb102c7bcb..943d0abc8e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c454bf724b6875610870eec156f0c544e84baf9c6e9a755b965f692f498a1b1e -size 34222 +oid sha256:246d4bf81c16bbbcfc82dd23b23bb1471e3d5e078bc7ecaba3c68d2ab3bb75c2 +size 34307 From e7cfe1d456eb4bb9fe863521316d0f1aa146b6bc Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 12 Dec 2025 17:44:21 +0100 Subject: [PATCH 122/347] design: CheckableUserRow uses Checkbox --- .../libraries/matrix/ui/components/CheckableUserRow.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableUserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableUserRow.kt index fbaa827ea9..917b03f309 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableUserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableUserRow.kt @@ -11,8 +11,9 @@ package io.element.android.libraries.matrix.ui.components import androidx.compose.foundation.clickable 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.width import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.ui.Alignment @@ -20,10 +21,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.Role import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import io.element.android.libraries.designsystem.atomic.atoms.SelectedIndicatorAtom 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.ElementThemedPreview +import io.element.android.libraries.designsystem.theme.components.Checkbox import io.element.android.libraries.designsystem.theme.components.HorizontalDivider import io.element.android.libraries.matrix.ui.model.getAvatarData @@ -63,11 +64,12 @@ fun CheckableUserRow( ) } } - SelectedIndicatorAtom( - modifier = Modifier.padding(end = 24.dp), + Checkbox( + onCheckedChange = onCheckedChange, checked = checked, enabled = enabled, ) + Spacer(modifier = Modifier.width(4.dp)) } } From fc0f1af52ef4f07581e8c264fc95fd5a1b7bb3f2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 12 Dec 2025 17:44:42 +0100 Subject: [PATCH 123/347] design: update vertical padding of the UserRow --- .../libraries/matrix/ui/components/UnresolvedUserRow.kt | 4 +--- .../element/android/libraries/matrix/ui/components/UserRow.kt | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt index 56e88bf3a3..32fa641a63 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt @@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable @@ -45,8 +44,7 @@ fun UnresolvedUserRow( Row( modifier = modifier .fillMaxWidth() - .heightIn(min = 56.dp) - .padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 8.dp), + .padding(start = 16.dp, top = 12.dp, end = 16.dp, bottom = 12.dp), verticalAlignment = Alignment.CenterVertically ) { Avatar( diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UserRow.kt index 932cab9a49..9bcf0b323f 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UserRow.kt @@ -11,7 +11,6 @@ package io.element.android.libraries.matrix.ui.components import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row 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.Alignment @@ -37,8 +36,7 @@ internal fun UserRow( Row( modifier = modifier .fillMaxWidth() - .heightIn(min = 56.dp) - .padding(start = 16.dp, top = 4.dp, end = 16.dp, bottom = 4.dp), + .padding(start = 16.dp, top = 12.dp, end = 16.dp, bottom = 12.dp), verticalAlignment = Alignment.CenterVertically ) { Avatar( From 7fd8ae5c517dd02a3e258298bc8f09dc275234e8 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 12 Dec 2025 17:05:45 +0000 Subject: [PATCH 124/347] Update screenshots --- .../features.invitepeople.impl_InvitePeopleView_Day_5_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_6_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_7_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_5_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_6_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_7_en.png | 4 ++-- ...crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png | 3 --- ...ypto.historyvisible_HistoryVisibleStateView_Night_1_en.png | 3 --- ...historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png | 3 --- ...storyvisible_MessagesViewWithHistoryVisible_Night_1_en.png | 3 --- ...ts.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en.png | 4 ++-- ...ts.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en.png | 4 ++-- ...ts.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en.png | 4 ++-- ...ts.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en.png | 4 ++-- ...ts.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en.png | 4 ++-- ....receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en.png | 4 ++-- ....receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en.png | 4 ++-- ....receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en.png | 4 ++-- ....receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en.png | 4 ++-- ....receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en.png | 4 ++-- ...references.impl.blockedusers_BlockedUsersView_Day_0_en.png | 4 ++-- ...references.impl.blockedusers_BlockedUsersView_Day_1_en.png | 4 ++-- ...references.impl.blockedusers_BlockedUsersView_Day_3_en.png | 4 ++-- ...references.impl.blockedusers_BlockedUsersView_Day_4_en.png | 4 ++-- ...references.impl.blockedusers_BlockedUsersView_Day_5_en.png | 4 ++-- ...references.impl.blockedusers_BlockedUsersView_Day_6_en.png | 4 ++-- ...ferences.impl.blockedusers_BlockedUsersView_Night_0_en.png | 4 ++-- ...ferences.impl.blockedusers_BlockedUsersView_Night_1_en.png | 4 ++-- ...ferences.impl.blockedusers_BlockedUsersView_Night_3_en.png | 4 ++-- ...ferences.impl.blockedusers_BlockedUsersView_Night_4_en.png | 4 ++-- ...ferences.impl.blockedusers_BlockedUsersView_Night_5_en.png | 4 ++-- ...ferences.impl.blockedusers_BlockedUsersView_Night_6_en.png | 4 ++-- ...res.preferences.impl.root_MultiAccountSection_Day_0_en.png | 4 ++-- ...s.preferences.impl.root_MultiAccountSection_Night_0_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_2_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_3_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_4_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_5_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_2_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_3_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_4_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_5_en.png | 4 ++-- ...tchat.impl.components_SearchMultipleUsersResultItem_en.png | 4 ++-- ...tartchat.impl.components_SearchSingleUserResultItem_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_5_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_6_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_9_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_5_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_6_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_9_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Day_1_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Day_2_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Day_3_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Night_1_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Night_2_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Night_3_en.png | 4 ++-- ...ibraries.accountselect.impl_AccountSelectView_Day_1_en.png | 4 ++-- ...raries.accountselect.impl_AccountSelectView_Night_1_en.png | 4 ++-- ...aries.matrix.ui.components_CheckableResolvedUserRow_en.png | 4 ++-- ...ies.matrix.ui.components_CheckableUnresolvedUserRow_en.png | 4 ++-- .../libraries.matrix.ui.components_MatrixUserRow_Day_0_en.png | 4 ++-- .../libraries.matrix.ui.components_MatrixUserRow_Day_1_en.png | 4 ++-- ...ibraries.matrix.ui.components_MatrixUserRow_Night_0_en.png | 4 ++-- ...ibraries.matrix.ui.components_MatrixUserRow_Night_1_en.png | 4 ++-- .../libraries.matrix.ui.components_UnresolvedUserRow_en.png | 4 ++-- 65 files changed, 122 insertions(+), 134 deletions(-) delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_5_en.png index e08a8add02..26cdab67d4 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ce85ac67e6ff108ba0d333e43d5ee0f8017602b7c271945de779b15d39f4884 -size 38233 +oid sha256:639cb5bcb5a74d1cdb94703c42189d1a5d9fd2b9d9f49c23cd47bb340a830710 +size 37829 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_6_en.png index b06373ab5c..91e9bcc3dc 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04086fce6b3b8b17a8736903c1975e3b08fb2273ca6c41fe71000b61ce7f0950 -size 32559 +oid sha256:651042b5628da42cdb4d7d8fb465ba279a12d78d8f51a688eeee90bc413002d0 +size 32992 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_7_en.png index e4c273afd6..09e1bb63ae 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b796eb0b26e073beeff1ac1f87e8e403e39c6030d092fc3f18b29d26e34d57af -size 25476 +oid sha256:b2e674fec4e26de21c82e020f9c9a7b693599ff98c1aa4d5c846c0179db3e1bf +size 25727 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_5_en.png index 5649bb84ae..0fca502f1c 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3497c9641b660ff1de9a54e1051f9ee6fcebc31a631f681082d28834c1273df -size 38989 +oid sha256:e3a65959829bbf2c2e2f2842b78f620e417a0edaa5996f7a53f24b6cc997f9ab +size 38491 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_6_en.png index 40e5dce4ed..c6fc626fa3 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49c325c609a49cc5a843c257a0cf7977d2fac8916404d0e1f94b58274546ef73 -size 32660 +oid sha256:ca72547eaa183851897287859b5be5fe8dad13f2d69a374d7e62477de171f37b +size 33060 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_7_en.png index e9b761b471..df9f13f8b4 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66220acd53b2e0e60c710605d79f316c961dc10d281be650bdf50114c04be758 -size 25030 +oid sha256:8d49358838af8128be8b8a1e06712a5656460e247db0ed496186cc5017a31ac4 +size 25307 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png deleted file mode 100644 index d19a140456..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:96bc0c555188cee4b3f3e3e0f28f944a4225e27b9a1069edf2b10a2993ee3080 -size 26078 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png deleted file mode 100644 index d21a12dd64..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a103daf8447cb571a0c5010d062a7790aaa0f3dce30f052bf86884708f4881a5 -size 28769 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png deleted file mode 100644 index 22d05e61fa..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9682cdd7e08e32591fa47f56da5e6ef4cc3a777700931c2c86e9b802a9cf25cb -size 67342 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png deleted file mode 100644 index b2bb8ac3fc..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d20c04c6385e675bd71d93d2d5d832509b1300a27708245755f263392b33bc8a -size 69457 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en.png index d99f4f4bf2..24cd69292a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e10ab8535d37d714ce4ec7392fed1e3ecaab3f459c1bcc872601bed6d57fc69 -size 11417 +oid sha256:64b472e04eca6203aa2563e65b0f54af3b4baa9da1706a4ecf4a0609697d48d9 +size 11403 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en.png index ea1c9353b8..517f2db0e7 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e97d19ae75ab72b57ec48bf6c39bf1f742e25ef5acbb20a7583ba697ae4d745 -size 16881 +oid sha256:fdc697787133723238c5b228b53c76b94e8a159b63df9068189398439d179353 +size 16904 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en.png index 4243e92aaf..35ea429edc 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f58353935619cb6551f737a95381bdb4a1736fd77054886cd908044110c6dd03 -size 21967 +oid sha256:f4a48c30efc2dc278c5c9aa6274899f0c669fc7d5433fafd737681bc3486bdd2 +size 22025 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en.png index 1b2abb045c..eb3bb61a96 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6ae65c60453959b99624c3b51c6b84b721ef9999bd0313e6c785c9d5bb82c00 -size 26218 +oid sha256:ddd99012579e28dc0d52dedcfa097825d3ada4548c4a3d3595a6fa9347168bf4 +size 26295 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en.png index 0401898572..f9e54b9351 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a00ac9b95359013527bafc8f244b55ed02a75cde8a81a16815e121575a4b6ae -size 31544 +oid sha256:1a086cf3f75b8e525e41684e5366a5d416ae04cd43a093c8f2f09f6d1509b3f2 +size 31717 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en.png index ef64f0eff5..fca1afde50 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1efb80a24b556fdeea528de1b5afb004100616bf3163c7b5c5b184a2ff82a84e -size 11080 +oid sha256:f4891d5825449f0362bad22f16cb8ffd9c9332312f9528d0acf23a8db146f37b +size 11055 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en.png index d468d2491a..56d6e2edb9 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70b76a4cab9419ac6e49352982c203a87db6f7cb44091f29a8abf24584db2292 -size 16208 +oid sha256:d2d1dcdd63d79289f6d56ecf3b108e147791e218cef96c598bdfcf0e51f15ddd +size 16273 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en.png index 009bda75c5..082b848111 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00fce403745ec69a35aa00ca423cd42633e2870504806857d13ffc7d920846fc -size 21474 +oid sha256:17ca7249652b4fd0263cedd75782e8f57277feecb0d77976b8d428d1621506b0 +size 21525 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en.png index e1f610cad0..6d88f73cc6 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cba66ab8e687a3f7fd904fda4001bb5bee26d8825d5d19cf700aefad98637d6e -size 26307 +oid sha256:87501fc77eb9026ff8b4a703eb85c93b31fcf7c0d0cbfde7afe9b6dd0110d068 +size 26460 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en.png index b9a11d8f1c..037728612a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:417f719ea18b93aa1ced2c2fe0cd73c2558170a16df8370edf2c66491337b607 -size 31734 +oid sha256:9cf2adb5e8ac9f8bca87e6b5e1a8b5f59dacd6ee470d8a3b5bb5c2e6233e1709 +size 31937 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en.png index 076b23e094..cbe9ac4af5 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c9e3e250938e4dec52652a16f5457c005d9a112ee4ca169d6dcdcb0d8682987f -size 58911 +oid sha256:9f6981c35088873ccc506975aec10c62ecd706ae4fa73f11a3fbb7a786e8ca5d +size 53394 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en.png index 7ad29e0567..ed83508084 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f74e0fd4c913c895b3edfb6ee8b75f5034230d2462947e7cedcf13aa749ecd1 -size 58628 +oid sha256:44935e8bb95a3c4967cbe23de7e067519e9123edff1129276da7cc73067d83a4 +size 57956 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en.png index a9dde01586..7703f26bb4 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4084d378d7972223d258df063df13998b2fafae02bfc6f585472808dbf66955a -size 55264 +oid sha256:ad5a2a0849cd17e90124a20fa99e79e05182a518d6f9789f16e0a83e1c06bf1a +size 50695 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en.png index 1b61c9177b..74796eabbf 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c57c0986de2480dee08b62b48ccbb8eab5fd3271d0d0c0b9e3d3d7b9cebd678 -size 61750 +oid sha256:3b04ccd9f43fa8283e62d43de910bcf68ceba81cec88fc1e20710252e0828c85 +size 56290 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en.png index f12c58ca40..062db915ca 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:912a4cc70e1385a661738ad8a44f6ef684079754b704b259ac2122f1d1370ed7 -size 61266 +oid sha256:19b57b52597b1663725a6681facb0e98351b4bcc482b21722539762ef4e26e21 +size 55782 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en.png index 076b23e094..cbe9ac4af5 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c9e3e250938e4dec52652a16f5457c005d9a112ee4ca169d6dcdcb0d8682987f -size 58911 +oid sha256:9f6981c35088873ccc506975aec10c62ecd706ae4fa73f11a3fbb7a786e8ca5d +size 53394 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en.png index 1aebfc1e25..ae2d011dc0 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08596a989d560562dcaf95bf822d437b54273c8b05e194bd876e41db8278960c -size 60062 +oid sha256:26da644c71f1fed42bffedc56d1bf23c5454aaa8bb8679fe705567670f9c0e69 +size 54576 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en.png index 1db31f192d..96b3bfc0c5 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b6b52039677271c7b20709734393061fe8ce2e3df07683cefb98d28f6f74aef -size 59297 +oid sha256:8838ca5825b2f21eff9332f2b9a21d04f5cc8ef22bb809116a19b5e47863f0f6 +size 59050 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en.png index 4df9e1a5de..3a3cc98686 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59758683e591affc670a7f738aea5e8e41a8743d32154611da0558e9c9290c35 -size 53072 +oid sha256:baebdfc57e32a6cb4e7a9dc96123056428a9304fd70d3b121c9f463d287a5ee8 +size 48584 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en.png index b960fb2898..a81ef5cd17 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71c6926e36b400cc8842fae1029bf5240339ead2f49b31e06adcbc7cc43e1d96 -size 61757 +oid sha256:2d7121455aa0fe2cfb095d3c0a649813473752a0cf9c588059792f97badd1a3e +size 56285 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en.png index 322b173f32..db65f781ce 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:22c9d278e5b933512a72b9af164e5e4b0385821d64d2b597d7e8655184c8ead0 -size 61501 +oid sha256:8fe4eb205597b6e39a99e78c4eaf8fc7805509ffea6176b02881e179f5269306 +size 56034 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en.png index 1aebfc1e25..ae2d011dc0 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08596a989d560562dcaf95bf822d437b54273c8b05e194bd876e41db8278960c -size 60062 +oid sha256:26da644c71f1fed42bffedc56d1bf23c5454aaa8bb8679fe705567670f9c0e69 +size 54576 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_MultiAccountSection_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_MultiAccountSection_Day_0_en.png index 62de6e4458..78dbf9344d 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_MultiAccountSection_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_MultiAccountSection_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c806de6d6f7c84f87ebadab6606d3d6352a8094a17cf02ee897072e3918ebdd -size 58279 +oid sha256:7065bbf0444b299bd8f024f1f1c9143a1b7ef5b20eba22d95a573f059e5f502d +size 54175 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_MultiAccountSection_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_MultiAccountSection_Night_0_en.png index 8e49010186..6914065701 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_MultiAccountSection_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_MultiAccountSection_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9c4bb59ec7ba0ed437f6fd19d96ed50328fecde7d1aa026e1a076bdf34376db -size 59229 +oid sha256:d55ace579493a40e9bafe3e212918010f9b285ee3ea0dd5ada6c25d21e3aa622 +size 55288 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_2_en.png index c4d6e129cd..36bb8cffea 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8b5970490e96a693655df832f9c4bf83dd55a8b06da27b48881d9f61b2dfd9c -size 55110 +oid sha256:1b654ef6029e31f4c5de17ee69807cd10ca307804939efae3c8a5859eb94c8e8 +size 53744 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png index dfbbd46e39..9a15041143 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5ff0c767c13a80f8305096982d1fb92800d3a25fb50115c631fd3916fd7f52c -size 30180 +oid sha256:0dfa48cfb76e2c62e9eef83d5d3c3ffb1006b0d68a6898f79117e137ae55f942 +size 30267 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png index eff729cb56..2275ac754f 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6b7049a6865a0ea4529cc43d16a27b9107e26d6583f429affe8327840b84ac2a -size 56050 +oid sha256:8b281cb130783d24f386536badeae5d669aeabe7f74f65042b13202dfce14960 +size 54623 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png index 83c58ce783..636e5f40e7 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b4a208d39a5f6040d17da5290a8f2f81cd917aa02c8e38b092fc79497e1e563 -size 18394 +oid sha256:f74dd5cf34442fe490ef8277851a330c21b1456105d64dcbbc30015631cfe83f +size 18568 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_2_en.png index d4d2263960..8f4f9a52aa 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:889734242ce96bfc206ae1421ab9c1cbccbcb11f99889445ea27833cbd057a0a -size 55231 +oid sha256:b5f222a27028cf852b3c92985b2ed70c406adf950fd4a9c3fe11885ede4b458d +size 53832 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png index 4f5dba242e..5a6ac97cf8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5fa0396ed5afbb31ef60cbc74c3369e3eb306f0b4eb168424165c6246ea7cdca -size 29276 +oid sha256:8385e865dbfd322194631f9716761b66d94b86b47d351e777b653818a0a6fc3a +size 29291 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png index dcd18cf977..f470fc5e23 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5bb86c6fea38d0e798cffa5fee0610a32048aeb1d3427cd9b5b749dfacee0e55 -size 56063 +oid sha256:4dbfe0a0cc6a956b6288a82912e2de32a9555ced9a31a67ee63fed29b09b78fa +size 54701 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png index 612b340865..d53880f9da 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6d55832abbcffc4d84b7139fbfb19d4c96a5ebcc9233ff139c5aae6b9f406d9 -size 17831 +oid sha256:a7826ffc4183453ef0d969f92cc1a034e0405732910c203213daf68a9870327a +size 17991 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_SearchMultipleUsersResultItem_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_SearchMultipleUsersResultItem_en.png index c8a69b5b23..bad2ab5865 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_SearchMultipleUsersResultItem_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_SearchMultipleUsersResultItem_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cff8d671701fb10f9eced75ad665e8610169a75d29e9698a3ee77da2e7c2e53e -size 82800 +oid sha256:0924b8f2a751ed562e73a259d7e28b341b20e4760004f1af11b2965355aa208e +size 82663 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_SearchSingleUserResultItem_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_SearchSingleUserResultItem_en.png index 29aa563c1d..9cd5f8301d 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_SearchSingleUserResultItem_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_SearchSingleUserResultItem_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7458d0f821af41610a30d3f044a7ddf8c84e65d405227a6db987280c39e506e4 -size 42396 +oid sha256:e95c5ea5faf80c0e6c74bba083bce824b9e5853378c0c731cc14c1f53829da9e +size 42992 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_5_en.png index 92f01aaa4a..8d83e1e828 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56ed064ba1b8dd3a1fd7238197eed66e7f15f4bcb290958131994f671dec2799 -size 38436 +oid sha256:8fd6daaaf9b3d2ce8708c12f64eadf905874de008edba5415e2d452d1cc5906e +size 38504 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_6_en.png index 8e4175320b..ffa3c3ccf1 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:54337827a41fe2a2003874c3a068a4e8279fc1196e0f44b968ad9adfefe3598b -size 54763 +oid sha256:85cf2d191cb255838a25dec2b69899b096170c65463e81a34261df533b861eb1 +size 53062 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_9_en.png index bf3985b806..4f6d627398 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:90138507cc2a34102c353c9e4d8c8af54ec547f92bc32b1158d980719d2f57e6 -size 37193 +oid sha256:543e5d99df73c97b6e1fcfa184e865568d9cea4d23c2ab92a9f64be66ae303d8 +size 38127 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_5_en.png index 53fc154850..3aa6cceb27 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d303fe75dcd58dd7961378cf03bde8ad5dbed7a0e437d5cd829d7963e89cca1 -size 39113 +oid sha256:de723755b90c8cacce16e27a16dcc9103e27bad86f492fd540745d90eabd7984 +size 39352 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_6_en.png index 21e05536d2..9a5c16673a 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69196aa9bf0d856a4a58f7ce5177f80e0ef58a138d501e58d3aa22215d979f03 -size 55735 +oid sha256:ece00a0efbaaef3ffa2a6cd21542a4d9f37fd722ddad8f52a2b5c5b22afaec5e +size 54275 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_9_en.png index 7556dca7b7..e467ac0551 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e14260ce5a9453b13bdbf6d6310fc4ea094e70e4fd27b6c84ea42f1fa24bf26c -size 37148 +oid sha256:fe7d54ea6d6bd3f74ab93360042afdad0def7b704c023b896a427d4e5e038f82 +size 37831 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_1_en.png index 92a8f6edc5..b581fb7b5e 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:860e69982f2f4604f766012b223901a074d1dae69a7b62d47c27bee948be9625 -size 19774 +oid sha256:5e7c8f6b2beaf11a388c1c1eea86882836a8dc992dda0a616718e28ea10e9218 +size 19831 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_2_en.png index 8aa5ec8c06..98e770a0e3 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:47af637bd7dd4c178e212cde67b652381cba2bff1f0802bc8e17e792aba9bf5e -size 26628 +oid sha256:a80c27eeeb0b6d7bcae6dce55c1b76e8339a87e12ff9e489e4b94f7f8cfad048 +size 26686 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_3_en.png index 7646b26049..8cba1edf39 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:584e0aa699195c24dbf9e096837975f10d65cb9134b5e27f5ceb0940f58693b2 -size 53162 +oid sha256:6d6ed05f8651e3a080a4faf8a77e8f80bc56cd52452e64e279af80098216b913 +size 50201 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_1_en.png index a863215e63..00a76e245b 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f9aee160678ab11d9fa7c149f0399c296c796202160753f6f9eb2259d4d362d -size 18664 +oid sha256:2c6313c54b31b1bb0d01d3d8a144ee42a9ad8e48be5e38546d8330b7c83c51fd +size 18729 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_2_en.png index 642e9454ea..c48b02266d 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:003981330bc57f34df10934331f1001cd3968209393b4adc34e61afd784e9b36 -size 24938 +oid sha256:4c494394f5d6485ebdea10c9aa04057eb9e5d05680be5a10eaa1cf13e08833cb +size 25000 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_3_en.png index b7ca611ad7..1a33369536 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a1196280397ffa9ba440b31a022a95bb2ee8734507d7a75eb4cf4c134b536205 -size 52796 +oid sha256:bcf1370e3cd3bee3c2ae0607d3a4d21f1e6f4aa9f3558c63f918e4cc64f126a6 +size 49709 diff --git a/tests/uitests/src/test/snapshots/images/libraries.accountselect.impl_AccountSelectView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.accountselect.impl_AccountSelectView_Day_1_en.png index 626008fa6c..2c3d86ccf7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.accountselect.impl_AccountSelectView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.accountselect.impl_AccountSelectView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de56ceb6ae4d4accaec97891cca6785a0ee02571748f83b9fa83b8b10582dd81 -size 49075 +oid sha256:2fb60b8f3e1e7a412434b7914d8c68c5266d598e9fa4f3f1a3b243a16dc7da4c +size 43723 diff --git a/tests/uitests/src/test/snapshots/images/libraries.accountselect.impl_AccountSelectView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.accountselect.impl_AccountSelectView_Night_1_en.png index 6742836144..3897f6c49c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.accountselect.impl_AccountSelectView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.accountselect.impl_AccountSelectView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:109e7536b35f9396266b64fd84083bbfddc82caa47de3500bebe4cce9a71d1a7 -size 49924 +oid sha256:14e02b252ef0fd343b0d4cc6f7745a36dc15351ead4d3920a9e78b0fd329f04b +size 44581 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_CheckableResolvedUserRow_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_CheckableResolvedUserRow_en.png index 837bf8922a..2622790d8a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_CheckableResolvedUserRow_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_CheckableResolvedUserRow_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e52b296963423635bd42274768882d3aa30a6f2865c18f3999356d9cc815154 -size 50445 +oid sha256:afef26d6f1eaae9c9990095ff76081796ab408b611fc6d5e54eaf4e5149d5416 +size 50236 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_CheckableUnresolvedUserRow_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_CheckableUnresolvedUserRow_en.png index 710791d0b0..2fde0deb9d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_CheckableUnresolvedUserRow_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_CheckableUnresolvedUserRow_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c36cacfcdf856303fa981fe90271bbda2583d363aadd44b88eb8556d6cb09b12 -size 108348 +oid sha256:58e898ed1ed67402f639f61628729bbabad0142c9047aeacf3e1312ef2d1a469 +size 103204 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Day_0_en.png index c3a2cefc62..1743c14ddc 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ae8f733f41116d35d039edc8243e11eb4175b1485cbfb72b02d0e4d1caf07af -size 9587 +oid sha256:3d5708861e397d6d20cf6900e4fa566dc86961eeadea6ceeb13f15f5f9e93caf +size 9796 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Day_1_en.png index afd7a35b27..26913e3446 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eace16f819a0fa1aa10a859315d86c639abc51367295e8ea2d2d3826415152e1 -size 9569 +oid sha256:bc971461b2e57aef9021633759cdf7e3771d52bd9d9a23631765da0e4ece028f +size 9495 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Night_0_en.png index adbd45547a..77fea21917 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c128b9907bb834a08569f8cb6c93c2c97249f813a405b4dff0cfa35b23793112 -size 9663 +oid sha256:d45fb1723e9b0a1a45618f68d18697ec8e5cabeab1224447913a366510aff352 +size 9828 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Night_1_en.png index 05615cc2e0..d66fba44a3 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_MatrixUserRow_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:24bb6401edef8bd83a6f5d6854a50c13039553b042db690dc5e1763f364764b9 -size 9529 +oid sha256:99964776c4a2be5d5fbbc9d600516fd758238c382e9ae4a7e49bf91193d10898 +size 9420 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnresolvedUserRow_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnresolvedUserRow_en.png index a998c229dc..441b38a3b8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnresolvedUserRow_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnresolvedUserRow_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:441264fe4ba673ab069b38d45243bbff77e2a17f99fd849d9c8b6cd30486e54d -size 55142 +oid sha256:228ec3cb50e9bf8079a1e484bcc36b84dadd3ffd0c790257a98f05b48e3e423d +size 55445 From aaf788b4486f49f0c14bfa2a4d3880221bda289f Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 15 Dec 2025 10:25:08 +0100 Subject: [PATCH 125/347] Fix crash when calling `Room.predecessorRoom` when the room is destroyed (#5894) * Fix crash when calling `Client.predecessorRoom` when the room is destroyed * Handle the root cause of this crash: destroying the room on activity recreation --- .../room/joined/JoinedRoomLoadedFlowNode.kt | 15 +++++++++++++-- .../libraries/matrix/impl/room/RustBaseRoom.kt | 4 +++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt index 5a6ef9133b..0b3ba57776 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt @@ -8,7 +8,9 @@ package io.element.android.appnav.room.joined +import android.app.Activity import android.os.Parcelable +import androidx.activity.compose.LocalActivity import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.lifecycle.lifecycleScope @@ -96,6 +98,9 @@ class JoinedRoomLoadedFlowNode( private val callback: Callback = callback() override val graph = roomGraphFactory.create(inputs.room) + // This is an ugly hack to check activity recreation + private var currentActivity: Activity? = null + init { lifecycle.subscribe( onCreate = { @@ -115,8 +120,12 @@ class JoinedRoomLoadedFlowNode( }, onDestroy = { Timber.v("OnDestroy") - activeRoomsHolder.removeRoom(inputs.room.sessionId, inputs.room.roomId) - inputs.room.destroy() + // If we're just going through an activity recreation there's no need to destroy the Room object + // Destroying it would actually cause an issue where its methods can no longer be called + if (currentActivity?.isChangingConfigurations != true) { + activeRoomsHolder.removeRoom(inputs.room.sessionId, inputs.room.roomId) + inputs.room.destroy() + } appNavigationStateService.onLeavingRoom(id) } ) @@ -289,6 +298,8 @@ class JoinedRoomLoadedFlowNode( @Composable override fun View(modifier: Modifier) { + currentActivity = LocalActivity.current + BackstackView() } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt index be7f6240ee..4fabff8cc0 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoom.kt @@ -85,7 +85,9 @@ class RustBaseRoom( }.stateIn(roomCoroutineScope, started = SharingStarted.Lazily, initialValue = initialRoomInfo) override fun predecessorRoom(): PredecessorRoom? { - return innerRoom.predecessorRoom()?.map() + return runCatchingExceptions { innerRoom.predecessorRoom()?.map() } + .onFailure { Timber.e(it, "Could not get predecessor room") } + .getOrNull() } override suspend fun subscribeToSync() = roomSyncSubscriber.subscribe(roomId) From d4c7cb77fbad023c8dc7f3fc2cb0ddc511bddfc1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Dec 2025 10:45:59 +0000 Subject: [PATCH 126/347] fix(deps): update dependency com.android.tools.build:gradle to v8.13.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 1ed3ea4f4e..b5a2607c01 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ [versions] # Project -android_gradle_plugin = "8.13.1" +android_gradle_plugin = "8.13.2" # When updateing this, please also update the version in the file ./idea/kotlinc.xml kotlin = "2.2.20" kotlinpoet = "2.2.0" From 0476cbd4d928e0dabf1ff8c9da01779413410485 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 12 Dec 2025 18:09:06 +0100 Subject: [PATCH 127/347] misc(power level) : expose RoomMemberModerationPermissions after PR review --- .../messages/impl/MessagesStateProvider.kt | 7 ++--- .../impl/members/RoomMemberListState.kt | 2 +- .../members/RoomMemberListStateProvider.kt | 7 +++-- .../api/RoomMemberModerationPermissions.kt | 29 +++++++++++++++++++ .../api/RoomMemberModerationState.kt | 3 +- .../impl/InternalRoomMemberModerationState.kt | 4 +-- ...ternalRoomMemberModerationStateProvider.kt | 7 ++--- .../impl/RoomMemberModerationPresenter.kt | 19 ++++-------- .../impl/RoomMemberModerationPresenterTest.kt | 4 +-- 9 files changed, 52 insertions(+), 30 deletions(-) create mode 100644 features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index 7831265fd0..cec9f68b45 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -41,6 +41,7 @@ import io.element.android.features.messages.impl.timeline.protection.aTimelinePr import io.element.android.features.roomcall.api.RoomCallState import io.element.android.features.roomcall.api.aStandByCallState import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents +import io.element.android.features.roommembermoderation.api.RoomMemberModerationPermissions import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -164,11 +165,9 @@ fun aMessagesState( ) fun aRoomMemberModerationState( - canKick: Boolean = false, - canBan: Boolean = false, + permissions: RoomMemberModerationPermissions = RoomMemberModerationPermissions.DEFAULT, ) = object : RoomMemberModerationState { - override val canKick: Boolean = canKick - override val canBan: Boolean = canBan + override val permissions: RoomMemberModerationPermissions = permissions override val eventSink: (RoomMemberModerationEvents) -> Unit = {} } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt index 007d276dd3..7c928fb27a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt @@ -26,7 +26,7 @@ data class RoomMemberListState( val moderationState: RoomMemberModerationState, val eventSink: (RoomMemberListEvents) -> Unit, ) { - val showBannedSection: Boolean = moderationState.canBan && roomMembers.dataOrNull()?.banned?.isNotEmpty() == true + val showBannedSection: Boolean = moderationState.permissions.canBan && roomMembers.dataOrNull()?.banned?.isNotEmpty() == true } enum class SelectedSection { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt index 580db7667a..b37738c30f 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt @@ -10,6 +10,7 @@ package io.element.android.features.roomdetails.impl.members import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents +import io.element.android.features.roommembermoderation.api.RoomMemberModerationPermissions import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.map @@ -99,8 +100,10 @@ fun aRoomMemberModerationState( canKick: Boolean = false, ): RoomMemberModerationState { return object : RoomMemberModerationState { - override val canKick: Boolean = canKick - override val canBan: Boolean = canBan + override val permissions: RoomMemberModerationPermissions = RoomMemberModerationPermissions( + canBan = canBan, + canKick = canKick, + ) override val eventSink: (RoomMemberModerationEvents) -> Unit = {} } } diff --git a/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt new file mode 100644 index 0000000000..223456de69 --- /dev/null +++ b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt @@ -0,0 +1,29 @@ +/* + * 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.roommembermoderation.api + +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions + +data class RoomMemberModerationPermissions( + val canKick: Boolean, + val canBan: Boolean, +) { + companion object { + val DEFAULT = RoomMemberModerationPermissions( + canKick = false, + canBan = false, + ) + } +} + +fun RoomPermissions.roomMemberModerationPermissions(): RoomMemberModerationPermissions { + return RoomMemberModerationPermissions( + canKick = canOwnUserKick(), + canBan = canOwnUserBan(), + ) +} diff --git a/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationState.kt b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationState.kt index 85f3e8ec19..c9ee958f6f 100644 --- a/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationState.kt +++ b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationState.kt @@ -12,8 +12,7 @@ import androidx.compose.runtime.Immutable @Immutable interface RoomMemberModerationState { - val canKick: Boolean - val canBan: Boolean + val permissions: RoomMemberModerationPermissions val eventSink: (RoomMemberModerationEvents) -> Unit } diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationState.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationState.kt index fe48ece1fd..f45a277992 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationState.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationState.kt @@ -10,14 +10,14 @@ package io.element.android.features.roommembermoderation.impl import io.element.android.features.roommembermoderation.api.ModerationActionState import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents +import io.element.android.features.roommembermoderation.api.RoomMemberModerationPermissions import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.ImmutableList data class InternalRoomMemberModerationState( - override val canKick: Boolean, - override val canBan: Boolean, + override val permissions: RoomMemberModerationPermissions, val selectedUser: MatrixUser?, val actions: ImmutableList, val kickUserAsyncAction: AsyncAction, diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationStateProvider.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationStateProvider.kt index d90f352cfa..120a299a7d 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationStateProvider.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/InternalRoomMemberModerationStateProvider.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.roommembermoderation.api.ModerationAction import io.element.android.features.roommembermoderation.api.ModerationActionState import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents +import io.element.android.features.roommembermoderation.api.RoomMemberModerationPermissions import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser @@ -83,8 +84,7 @@ fun anAlice() = MatrixUser( ) fun aRoomMembersModerationState( - canKick: Boolean = false, - canBan: Boolean = false, + permissions: RoomMemberModerationPermissions = RoomMemberModerationPermissions.DEFAULT, selectedUser: MatrixUser? = null, actions: List = emptyList(), kickUserAsyncAction: AsyncAction = AsyncAction.Uninitialized, @@ -92,8 +92,7 @@ fun aRoomMembersModerationState( unbanUserAsyncAction: AsyncAction = AsyncAction.Uninitialized, eventSink: (RoomMemberModerationEvents) -> Unit = {}, ) = InternalRoomMemberModerationState( - canKick = canKick, - canBan = canBan, + permissions = permissions, selectedUser = selectedUser, actions = actions.toImmutableList(), kickUserAsyncAction = kickUserAsyncAction, diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt index 96749ba5ac..16a11aee96 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt @@ -21,7 +21,9 @@ import im.vector.app.features.analytics.plan.RoomModeration import io.element.android.features.roommembermoderation.api.ModerationAction import io.element.android.features.roommembermoderation.api.ModerationActionState import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents +import io.element.android.features.roommembermoderation.api.RoomMemberModerationPermissions import io.element.android.features.roommembermoderation.api.RoomMemberModerationState +import io.element.android.features.roommembermoderation.api.roomMemberModerationPermissions import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runUpdatingState @@ -55,11 +57,8 @@ class RoomMemberModerationPresenter( override fun present(): RoomMemberModerationState { val coroutineScope = rememberCoroutineScope() val syncUpdateFlow = room.syncUpdateFlow.collectAsState() - val permissions by room.permissionsAsState(Permissions()) { perms -> - Permissions( - canKick = perms.canOwnUserKick(), - canBan = perms.canOwnUserBan(), - ) + val permissions by room.permissionsAsState(RoomMemberModerationPermissions.DEFAULT) { perms -> + perms.roomMemberModerationPermissions() } val currentUserMemberPowerLevel = room.userPowerLevelAsState(syncUpdateFlow.value) @@ -136,8 +135,7 @@ class RoomMemberModerationPresenter( } return InternalRoomMemberModerationState( - canKick = permissions.canKick, - canBan = permissions.canBan, + permissions = permissions, selectedUser = selectedUser, actions = moderationActions.value, kickUserAsyncAction = kickUserAsyncAction.value, @@ -149,7 +147,7 @@ class RoomMemberModerationPresenter( private fun computeModerationActions( member: RoomMember?, - permissions: Permissions, + permissions: RoomMemberModerationPermissions, currentUserMemberPowerLevel: Long, ): ImmutableList { return buildList { @@ -209,11 +207,6 @@ class RoomMemberModerationPresenter( ) } - private data class Permissions( - val canKick: Boolean = false, - val canBan: Boolean = false, - ) - private fun CoroutineScope.runActionAndWaitForMembershipChange( action: MutableState>, block: suspend () -> Result diff --git a/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt b/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt index 4ce50a2488..3f59151eea 100644 --- a/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt +++ b/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt @@ -13,6 +13,7 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.roommembermoderation.api.ModerationAction import io.element.android.features.roommembermoderation.api.ModerationActionState import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents +import io.element.android.features.roommembermoderation.api.RoomMemberModerationPermissions import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.core.coroutine.CoroutineDispatchers @@ -49,8 +50,7 @@ class RoomMemberModerationPresenterTest { val room = aJoinedRoom() createRoomMemberModerationPresenter(room = room).test { val initialState = awaitState() - assertThat(initialState.canKick).isFalse() - assertThat(initialState.canBan).isFalse() + assertThat(initialState.permissions).isEqualTo(RoomMemberModerationPermissions.DEFAULT) assertThat(initialState.selectedUser).isNull() assertThat(initialState.banUserAsyncAction).isEqualTo(AsyncAction.Uninitialized) assertThat(initialState.kickUserAsyncAction).isEqualTo(AsyncAction.Uninitialized) From df77b61df6d8cc9b01c0ad27305d504ad511b9af Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 15 Dec 2025 15:33:03 +0100 Subject: [PATCH 128/347] fix: edit moderators not working --- .../impl/roles/ChangeRolesPresenter.kt | 4 +- .../impl/roles/ChangeRolesPresenterTest.kt | 80 +++++++++++-------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt index e460870b5a..4181fb6e2e 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt @@ -44,7 +44,7 @@ import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach @@ -81,7 +81,7 @@ class ChangeRolesPresenter( val owners = if (role == RoomMember.Role.Admin) { room.usersWithRole { role -> role is RoomMember.Role.Owner } } else { - emptyFlow() + flowOf(persistentListOf()) } combine( owners, diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt index e1998f94a3..8747585354 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt @@ -256,44 +256,48 @@ class ChangeRolesPresenterTest { @Test fun `present - UserSelectionToggle adds and removes users from the selected user list`() = runTest { + val roomMemberList = aRoomMemberList() val room = FakeJoinedRoom().apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) + givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList))) } val presenter = createChangeRolesPresenter(room = room) + val userMember = roomMemberList.first { it.role == RoomMember.Role.User } presenter.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.selectedUsers).hasSize(1) - initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) + initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser())) assertThat(awaitItem().selectedUsers).hasSize(2) - initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) + initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser())) assertThat(awaitItem().selectedUsers).hasSize(1) } } @Test fun `present - hasPendingChanges is true when the initial selected users don't match the new ones`() = runTest { + val roomMemberList = aRoomMemberList() val room = FakeJoinedRoom().apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) + givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList))) } val presenter = createChangeRolesPresenter(room = room) + val userMember = roomMemberList.first { it.role == RoomMember.Role.User } presenter.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.hasPendingChanges).isFalse() assertThat(initialState.selectedUsers).hasSize(1) - initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) + initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser())) with(awaitItem()) { assertThat(selectedUsers).hasSize(2) assertThat(hasPendingChanges).isTrue() } - initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) + initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser())) with(awaitItem()) { assertThat(selectedUsers).hasSize(1) assertThat(hasPendingChanges).isFalse() @@ -303,9 +307,10 @@ class ChangeRolesPresenterTest { @Test fun `present - Exit will display success false if no pending changes`() = runTest { + val roomMemberList = aRoomMemberList() val room = FakeJoinedRoom().apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) + givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList))) } val presenter = createChangeRolesPresenter(room = room) presenter.test { @@ -321,9 +326,10 @@ class ChangeRolesPresenterTest { @Test fun `present - CloseDialog will remove exit confirmation`() = runTest { + val roomMemberList = aRoomMemberList() val room = FakeJoinedRoom().apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) + givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList))) } val presenter = createChangeRolesPresenter(room = room) presenter.test { @@ -345,9 +351,10 @@ class ChangeRolesPresenterTest { @Test fun `present - Exit will display a confirmation dialog if there are pending changes, calling it again will actually exit`() = runTest { + val roomMemberList = aRoomMemberList() val room = FakeJoinedRoom().apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) + givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList))) } val presenter = createChangeRolesPresenter(room = room) presenter.test { @@ -371,12 +378,13 @@ class ChangeRolesPresenterTest { @Test fun `present - Save will display a confirmation when adding admins`() = runTest { + val roomMemberList = aRoomMemberList() val room = FakeJoinedRoom( updateUserRoleResult = { Result.success(Unit) }, baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }), ).apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) + givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList))) } val presenter = createChangeRolesPresenter(role = RoomMember.Role.Admin, room = room) presenter.test { @@ -395,9 +403,10 @@ class ChangeRolesPresenterTest { @Test fun `present - CloseDialog will remove the confirmation dialog`() = runTest { + val roomMemberList = aRoomMemberList() val room = FakeJoinedRoom().apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) + givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList))) } val presenter = createChangeRolesPresenter(role = RoomMember.Role.Admin, room = room) presenter.test { @@ -419,25 +428,27 @@ class ChangeRolesPresenterTest { @Test fun `present - Save will just save the data for moderators`() = runTest { val analyticsService = FakeAnalyticsService() + val roomMemberList = aRoomMemberList() val room = FakeJoinedRoom( updateUserRoleResult = { Result.success(Unit) }, baseRoom = FakeBaseRoom(updateMembersResult = { Result.success(Unit) }), ).apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Moderator))) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) + givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList))) } val presenter = createChangeRolesPresenter( role = RoomMember.Role.Moderator, room = room, analyticsService = analyticsService ) + val userMember = roomMemberList.first { it.role == RoomMember.Role.User } presenter.test { - skipItems(1) + skipItems(2) val initialState = awaitItem() - assertThat(initialState.selectedUsers).isEmpty() - initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) + assertThat(initialState.selectedUsers).hasSize(1) + initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser())) awaitItem().also { - assertThat(it.selectedUsers).hasSize(1) + assertThat(it.selectedUsers).hasSize(2) it.eventSink(ChangeRolesEvent.Save) } assertThat(awaitItem().savingState).isInstanceOf(AsyncAction.Loading::class.java) @@ -516,20 +527,22 @@ class ChangeRolesPresenterTest { @Test fun `present - Save can handle failures and CloseDialog clears them`() = runTest { + val roomMemberList = aRoomMemberList() val room = FakeJoinedRoom( updateUserRoleResult = { Result.failure(IllegalStateException("Failed")) } ).apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(role = RoomMember.Role.Moderator, userId = A_USER_ID))) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList)) + givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsFromRoomMemberList(roomMemberList))) } val presenter = createChangeRolesPresenter(role = RoomMember.Role.Moderator, room = room) + val userMember = roomMemberList.first { it.role == RoomMember.Role.User } presenter.test { - skipItems(1) + skipItems(2) val initialState = awaitItem() - assertThat(initialState.selectedUsers).isEmpty() - initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) + assertThat(initialState.selectedUsers).hasSize(1) + initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(userMember.toMatrixUser())) awaitItem().also { - assertThat(it.selectedUsers).hasSize(1) + assertThat(it.selectedUsers).hasSize(2) it.eventSink(ChangeRolesEvent.Save) } val loadingState = awaitItem() @@ -553,13 +566,12 @@ class ChangeRolesPresenterTest { } } - private fun roomPowerLevelsWithRole( - role: RoomMember.Role, - userId: UserId = A_USER_ID, + private fun roomPowerLevelsFromRoomMemberList( + roomMemberList: List, ): RoomPowerLevels { return RoomPowerLevels( values = defaultRoomPowerLevelValues(), - users = persistentMapOf(userId to role.powerLevel) + users = roomMemberList.associate { it.userId to it.role.powerLevel }.toImmutableMap() ) } From a21b66b86275d35311a2a0e2824b7d6874e42141 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 15 Dec 2025 20:46:23 +0100 Subject: [PATCH 129/347] change(space) : last admin navigate to security&privacy --- .../android/features/space/impl/SpaceFlowNode.kt | 10 ++++++---- .../features/space/impl/leave/LeaveSpaceView.kt | 3 +-- .../space/impl/settings/SpaceSettingsFlowNode.kt | 9 +++++++-- .../android/libraries/architecture/NodeCallback.kt | 7 +++++-- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt index 5fe646aaeb..4c91da0301 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/SpaceFlowNode.kt @@ -65,7 +65,7 @@ class SpaceFlowNode( data object Root : NavTarget @Parcelize - data object Settings : NavTarget + data class Settings(val initialTarget: SpaceSettingsFlowNode.NavTarget = SpaceSettingsFlowNode.NavTarget.Root) : NavTarget @Parcelize data object Leave : NavTarget @@ -89,7 +89,7 @@ class SpaceFlowNode( } override fun navigateToRolesAndPermissions() { - // TODO + backstack.push(NavTarget.Settings(SpaceSettingsFlowNode.NavTarget.RolesAndPermissions)) } } createNode(buildContext, listOf(callback)) @@ -101,7 +101,7 @@ class SpaceFlowNode( } override fun navigateToSpaceSettings() { - backstack.push(NavTarget.Settings) + backstack.push(NavTarget.Settings()) } override fun navigateToRoomMemberList() { @@ -114,8 +114,10 @@ class SpaceFlowNode( } createNode(buildContext, listOf(callback)) } - NavTarget.Settings -> { + is NavTarget.Settings -> { val callback = object : SpaceSettingsFlowNode.Callback { + override fun initialTarget() = navTarget.initialTarget + override fun navigateToSpaceMembers() { callback.navigateToRoomMemberList() } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt index 02598f25ed..d405162b88 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpaceView.kt @@ -132,8 +132,7 @@ fun LeaveSpaceView( state.eventSink(LeaveSpaceEvents.LeaveSpace) }, onCancel = onCancel, - // TODO enable when navigation is ready - showRolesAndPermissionsButton = false, // state.isLastAdmin, + showRolesAndPermissionsButton = state.isLastAdmin, onRolesAndPermissionsClick = onRolesAndPermissionsClick, ) } diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt index b5f0495bcb..8fc7f51aa7 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsFlowNode.kt @@ -39,13 +39,14 @@ class SpaceSettingsFlowNode( private val roomDetailsEditEntryPoint: RoomDetailsEditEntryPoint ) : BaseFlowNode( backstack = BackStack( - initialElement = NavTarget.Root, + initialElement = initialElement(plugins), savedStateMap = buildContext.savedStateMap, ), buildContext = buildContext, plugins = plugins, ) { interface Callback : Plugin { + fun initialTarget(): NavTarget = NavTarget.Root fun navigateToSpaceMembers() fun startLeaveSpaceFlow() fun closeSettings() @@ -56,7 +57,7 @@ class SpaceSettingsFlowNode( data object Root : NavTarget @Parcelize - data object EditDetails: NavTarget + data object EditDetails : NavTarget @Parcelize data object SecurityAndPrivacy : NavTarget @@ -138,3 +139,7 @@ class SpaceSettingsFlowNode( BackstackView(modifier) } } + +fun initialElement(plugins: List): SpaceSettingsFlowNode.NavTarget { + return plugins.callback().initialTarget() +} diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeCallback.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeCallback.kt index 4a35f99db4..e949dcaf63 100644 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeCallback.kt +++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeCallback.kt @@ -10,8 +10,11 @@ package io.element.android.libraries.architecture import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin -import com.bumble.appyx.core.plugin.plugins inline fun Node.callback(): I { - return requireNotNull(plugins().singleOrNull()) { "Make sure to actually pass a Callback plugin to your node" } + return plugins.callback() +} + +inline fun List.callback(): I { + return requireNotNull(filterIsInstance().singleOrNull()) { "Make sure to actually pass a Callback plugin to your node" } } From 5d2ca95e4099f67c38fe484c38d5ccca9b0cb922 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 15 Dec 2025 21:05:07 +0100 Subject: [PATCH 130/347] quality: format and remove unused code --- .../impl/permissions/ChangeRoomPermissionsPresenter.kt | 1 - .../rolesandpermissions/impl/root/RolesAndPermissionsNode.kt | 1 - .../impl/RoomMemberModerationPresenter.kt | 5 ----- .../android/features/space/impl/root/SpacePresenter.kt | 2 +- .../features/space/impl/settings/SpaceSettingsPermissions.kt | 3 --- 5 files changed, 1 insertion(+), 11 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt index c0e659ac04..562da8d879 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt @@ -54,7 +54,6 @@ class ChangeRoomPermissionsPresenter( RoomPermissionType.SPACE_MANAGE_ROOMS, RoomPermissionType.CHANGE_SETTINGS, ) - } private fun RoomPermissionsSection.shouldShow(isSpace: Boolean): Boolean { diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt index d6efa661bc..f094174c66 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt @@ -27,7 +27,6 @@ class RolesAndPermissionsNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, private val presenter: RolesAndPermissionsPresenter, - private val room: BaseRoom, ) : Node(buildContext, plugins = plugins), RolesAndPermissionsNavigator { interface Callback : Plugin, RolesAndPermissionsNavigator { override fun openAdminList() diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt index 3512a0c94d..16a11aee96 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt @@ -207,11 +207,6 @@ class RoomMemberModerationPresenter( ) } - private data class Permissions( - val canKick: Boolean = false, - val canBan: Boolean = false, - ) - private fun CoroutineScope.runActionAndWaitForMembershipChange( action: MutableState>, block: suspend () -> Result diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt index 40a58ddbd9..6800846231 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt @@ -19,7 +19,6 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject import im.vector.app.features.analytics.plan.JoinedRoom.Trigger -import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState @@ -36,6 +35,7 @@ import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.room.CurrentUserMembership +import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.join.JoinRoom import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.spaces.SpaceRoom diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt index 9a90435f77..e3ec70a51d 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsPermissions.kt @@ -20,15 +20,12 @@ data class SpaceSettingsPermissions( val canEditRolesAndPermissions: Boolean, val securityAndPrivacyPermissions: SecurityAndPrivacyPermissions, ) { - fun hasAny(joinRule: JoinRule?): Boolean { return editDetailsPermissions.hasAny || canEditRolesAndPermissions || securityAndPrivacyPermissions.hasAny(isSpace = true, joinRule = joinRule) } - - companion object { val DEFAULT = SpaceSettingsPermissions( editDetailsPermissions = RoomDetailsEditPermissions.DEFAULT, From 6880cf518c5f4520e5b17dac7c6e78727b6612c5 Mon Sep 17 00:00:00 2001 From: ElementBot <110224175+ElementBot@users.noreply.github.com> Date: Mon, 15 Dec 2025 23:51:19 +0100 Subject: [PATCH 131/347] Sync Strings from Localazy (#5904) Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com> --- app/src/main/res/xml/locales_config.xml | 1 + .../src/main/res/values-hr/translations.xml | 6 + .../src/main/res/values-hr/translations.xml | 7 + .../src/main/res/values-hr/translations.xml | 10 + .../src/main/res/values-hr/translations.xml | 11 + .../src/main/res/values-ro/translations.xml | 2 +- .../src/main/res/values-hr/translations.xml | 8 + .../src/main/res/values-da/translations.xml | 1 + .../src/main/res/values-hr/translations.xml | 22 + .../src/main/res/values-hr/translations.xml | 14 + .../src/main/res/values-hr/translations.xml | 16 + .../src/main/res/values-hr/translations.xml | 55 + .../src/main/res/values-hr/translations.xml | 18 + .../src/main/res/values-hr/translations.xml | 5 + .../src/main/res/values-hr/translations.xml | 34 + .../src/main/res/values-hr/translations.xml | 37 + .../src/main/res/values-hr/translations.xml | 10 + .../src/main/res/values-hr/translations.xml | 40 + .../src/main/res/values-hr/translations.xml | 98 + .../src/main/res/values-hr/translations.xml | 18 + .../src/main/res/values-hr/translations.xml | 84 + .../src/main/res/values-hr/translations.xml | 10 + .../src/main/res/values-hr/translations.xml | 20 + .../main/res/values-en-rUS/translations.xml | 1 + .../src/main/res/values-hr/translations.xml | 82 + .../src/main/res/values-hr/translations.xml | 7 + .../src/main/res/values-hr/translations.xml | 20 + .../src/main/res/values-hr/translations.xml | 8 + .../src/main/res/values-da/translations.xml | 29 +- .../src/main/res/values-hr/translations.xml | 84 + .../src/main/res/values-hu/translations.xml | 2 + .../src/main/res/values-ro/translations.xml | 36 +- .../src/main/res/values-hr/translations.xml | 5 + .../src/main/res/values-da/translations.xml | 53 +- .../main/res/values-en-rUS/translations.xml | 5 + .../src/main/res/values-et/translations.xml | 6 + .../src/main/res/values-hr/translations.xml | 173 ++ .../src/main/res/values-hu/translations.xml | 2 + .../src/main/res/values-ro/translations.xml | 63 +- .../impl/src/main/res/values/localazy.xml | 4 +- .../src/main/res/values-da/translations.xml | 2 +- .../src/main/res/values-hr/translations.xml | 7 + .../src/main/res/values-ro/translations.xml | 2 +- .../src/main/res/values-hr/translations.xml | 5 + .../src/main/res/values-hr/translations.xml | 22 + .../src/main/res/values-ro/translations.xml | 2 + .../src/main/res/values-hr/translations.xml | 70 + .../src/main/res/values-da/translations.xml | 23 +- .../main/res/values-en-rUS/translations.xml | 5 + .../src/main/res/values-et/translations.xml | 6 + .../src/main/res/values-hr/translations.xml | 44 + .../src/main/res/values-ro/translations.xml | 26 +- .../impl/src/main/res/values/localazy.xml | 4 +- .../src/main/res/values-hr/translations.xml | 8 + .../src/main/res/values-hr/translations.xml | 17 + .../src/main/res/values-hr/translations.xml | 12 + .../src/main/res/values-hr/translations.xml | 19 + .../src/main/res/values-hr/translations.xml | 54 + .../src/main/res/values-hr/translations.xml | 4 + .../src/main/res/values-hr/translations.xml | 5 + .../src/main/res/values-hr/translations.xml | 73 + .../src/main/res/values-hr/translations.xml | 7 + .../src/main/res/values-hr/translations.xml | 21 + .../src/main/res/values-hr/translations.xml | 7 + .../src/main/res/values-hr/translations.xml | 5 + .../src/main/res/values-da/translations.xml | 1 + .../main/res/values-en-rUS/translations.xml | 4 + .../src/main/res/values-et/translations.xml | 2 + .../src/main/res/values-hr/translations.xml | 105 + .../src/main/res/values-ro/translations.xml | 4 + .../impl/src/main/res/values/localazy.xml | 2 +- .../src/main/res/values-hr/translations.xml | 11 + .../src/main/res/values-hr/translations.xml | 11 + .../src/main/res/values-hr/translations.xml | 33 + .../src/main/res/values-hr/translations.xml | 12 + .../src/main/res/values-da/translations.xml | 4 + .../main/res/values-en-rUS/translations.xml | 2 + .../src/main/res/values-et/translations.xml | 32 +- .../src/main/res/values-hr/translations.xml | 533 +++++ .../src/main/res/values-ro/translations.xml | 43 + .../src/main/res/values/localazy.xml | 32 +- plugins/src/main/kotlin/extension/locales.kt | 1 + ....spaces_SpaceAnnouncementView_Day_0_de.png | 4 +- ...omponents_RoomListContentView_Day_0_de.png | 4 +- ...omponents_RoomListContentView_Day_5_de.png | 4 +- ....search_RoomListSearchContent_Day_1_de.png | 4 +- .../features.home.impl_HomeView_Day_0_de.png | 4 +- .../features.home.impl_HomeView_Day_13_de.png | 4 +- .../features.home.impl_HomeView_Day_14_de.png | 4 +- .../features.home.impl_HomeView_Day_1_de.png | 4 +- .../features.home.impl_HomeView_Day_2_de.png | 4 +- .../features.home.impl_HomeView_Day_5_de.png | 4 +- .../features.home.impl_HomeView_Day_9_de.png | 4 +- ...sible_HistoryVisibleStateView_Day_0_de.png | 3 + ...essagesViewWithHistoryVisible_Day_0_de.png | 3 + ....components_ThreadSummaryView_Day_0_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 | 2 +- ...ItemEventRowWithThreadSummary_Day_0_de.png | 2 +- ...s.messages.impl_MessagesView_Day_10_de.png | 3 + ...s.messages.impl_MessagesView_Day_11_de.png | 3 + ...s.messages.impl_MessagesView_Day_12_de.png | 3 + ...references.impl.labs_LabsView_Day_0_de.png | 4 +- ...references.impl.labs_LabsView_Day_1_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 | 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 +- ...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 +- ...ared_UserProfileHeaderSection_Day_0_de.png | 4 +- ...rofile.shared_UserProfileView_Day_2_de.png | 4 +- ...lecules_ComposerAlertMolecule_Day_3_de.png | 4 +- ...lecules_ComposerAlertMolecule_Day_4_de.png | 4 +- ...lecules_ComposerAlertMolecule_Day_5_de.png | 4 +- ..._TextComposerEditNotEncrypted_Day_0_de.png | 4 +- ...omposerFormattingNotEncrypted_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 +- ...extComposerSimpleNotEncrypted_Day_0_de.png | 4 +- ...TextComposerVoiceNotEncrypted_Day_0_de.png | 4 +- screenshots/html/data.js | 1893 +++++++++-------- ...sible_HistoryVisibleStateView_Day_0_en.png | 4 +- ...ble_HistoryVisibleStateView_Night_0_en.png | 4 +- ...essagesViewWithHistoryVisible_Day_0_en.png | 4 +- ...sagesViewWithHistoryVisible_Night_0_en.png | 4 +- ...s.messages.impl_MessagesView_Day_11_en.png | 4 +- ...messages.impl_MessagesView_Night_11_en.png | 4 +- ...references.impl.labs_LabsView_Day_0_en.png | 4 +- ...references.impl.labs_LabsView_Day_1_en.png | 4 +- ...ferences.impl.labs_LabsView_Night_0_en.png | 4 +- ...ferences.impl.labs_LabsView_Night_1_en.png | 4 +- 178 files changed, 3447 insertions(+), 1206 deletions(-) create mode 100644 appnav/src/main/res/values-hr/translations.xml create mode 100644 features/analytics/api/src/main/res/values-hr/translations.xml create mode 100644 features/analytics/impl/src/main/res/values-hr/translations.xml create mode 100644 features/announcement/impl/src/main/res/values-hr/translations.xml create mode 100644 features/call/impl/src/main/res/values-hr/translations.xml create mode 100644 features/createroom/impl/src/main/res/values-hr/translations.xml create mode 100644 features/deactivation/impl/src/main/res/values-hr/translations.xml create mode 100644 features/ftue/impl/src/main/res/values-hr/translations.xml create mode 100644 features/home/impl/src/main/res/values-hr/translations.xml create mode 100644 features/invite/impl/src/main/res/values-hr/translations.xml create mode 100644 features/invitepeople/impl/src/main/res/values-hr/translations.xml create mode 100644 features/joinroom/impl/src/main/res/values-hr/translations.xml create mode 100644 features/knockrequests/impl/src/main/res/values-hr/translations.xml create mode 100644 features/leaveroom/api/src/main/res/values-hr/translations.xml create mode 100644 features/lockscreen/impl/src/main/res/values-hr/translations.xml create mode 100644 features/login/impl/src/main/res/values-hr/translations.xml create mode 100644 features/logout/impl/src/main/res/values-hr/translations.xml create mode 100644 features/messages/impl/src/main/res/values-hr/translations.xml create mode 100644 features/poll/api/src/main/res/values-hr/translations.xml create mode 100644 features/poll/impl/src/main/res/values-hr/translations.xml create mode 100644 features/preferences/impl/src/main/res/values-hr/translations.xml create mode 100644 features/rageshake/api/src/main/res/values-hr/translations.xml create mode 100644 features/rageshake/impl/src/main/res/values-hr/translations.xml create mode 100644 features/reportroom/impl/src/main/res/values-hr/translations.xml create mode 100644 features/rolesandpermissions/impl/src/main/res/values-hr/translations.xml create mode 100644 features/roomaliasresolver/impl/src/main/res/values-hr/translations.xml create mode 100644 features/roomdetails/impl/src/main/res/values-en-rUS/translations.xml create mode 100644 features/roomdetails/impl/src/main/res/values-hr/translations.xml create mode 100644 features/roomdetailsedit/impl/src/main/res/values-hr/translations.xml create mode 100644 features/roomdirectory/impl/src/main/res/values-hr/translations.xml create mode 100644 features/roommembermoderation/impl/src/main/res/values-hr/translations.xml create mode 100644 features/securebackup/impl/src/main/res/values-hr/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-en-rUS/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-hr/translations.xml create mode 100644 features/signedout/impl/src/main/res/values-hr/translations.xml create mode 100644 features/space/impl/src/main/res/values-hr/translations.xml create mode 100644 features/startchat/impl/src/main/res/values-hr/translations.xml create mode 100644 features/userprofile/shared/src/main/res/values-hr/translations.xml create mode 100644 features/verifysession/impl/src/main/res/values-hr/translations.xml create mode 100644 libraries/androidutils/src/main/res/values-hr/translations.xml create mode 100644 libraries/dateformatter/impl/src/main/res/values-hr/translations.xml create mode 100644 libraries/eventformatter/impl/src/main/res/values-hr/translations.xml create mode 100644 libraries/matrixui/src/main/res/values-hr/translations.xml create mode 100644 libraries/mediaviewer/impl/src/main/res/values-hr/translations.xml create mode 100644 libraries/permissions/api/src/main/res/values-hr/translations.xml create mode 100644 libraries/permissions/impl/src/main/res/values-hr/translations.xml create mode 100644 libraries/push/impl/src/main/res/values-en-rUS/translations.xml create mode 100644 libraries/push/impl/src/main/res/values-hr/translations.xml create mode 100644 libraries/pushproviders/firebase/src/main/res/values-hr/translations.xml create mode 100644 libraries/pushproviders/unifiedpush/src/main/res/values-hr/translations.xml create mode 100644 libraries/textcomposer/impl/src/main/res/values-hr/translations.xml create mode 100644 libraries/troubleshoot/impl/src/main/res/values-hr/translations.xml create mode 100644 libraries/ui-strings/src/main/res/values-hr/translations.xml create mode 100644 screenshots/de/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_de.png create mode 100644 screenshots/de/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_de.png create mode 100644 screenshots/de/features.messages.impl_MessagesView_Day_10_de.png create mode 100644 screenshots/de/features.messages.impl_MessagesView_Day_11_de.png create mode 100644 screenshots/de/features.messages.impl_MessagesView_Day_12_de.png diff --git a/app/src/main/res/xml/locales_config.xml b/app/src/main/res/xml/locales_config.xml index a92d7b2ef9..a171646bad 100644 --- a/app/src/main/res/xml/locales_config.xml +++ b/app/src/main/res/xml/locales_config.xml @@ -15,6 +15,7 @@ + diff --git a/appnav/src/main/res/values-hr/translations.xml b/appnav/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..f75fa613f2 --- /dev/null +++ b/appnav/src/main/res/values-hr/translations.xml @@ -0,0 +1,6 @@ + + + "Odjava i nadogradnja" + "%1$s više ne podržava stari protokol. Odjavite se i ponovno prijavite kako biste se nastavili služiti aplikacijom." + "Vaš matični poslužitelj više ne podržava stari protokol. Odjavite se i ponovno prijavite kako biste se nastavili služiti aplikacijom." + diff --git a/features/analytics/api/src/main/res/values-hr/translations.xml b/features/analytics/api/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..ac1e83c87b --- /dev/null +++ b/features/analytics/api/src/main/res/values-hr/translations.xml @@ -0,0 +1,7 @@ + + + "Podijelite anonimne podatke o korištenju kako biste nam pomogli u otkrivanju problema." + "Možete pročitati sve naše uvjete %1$s ." + "ovdje" + "Dijeljenje analitičkih podataka" + diff --git a/features/analytics/impl/src/main/res/values-hr/translations.xml b/features/analytics/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..b85046c7a9 --- /dev/null +++ b/features/analytics/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,10 @@ + + + "Nećemo bilježiti niti profilirati nikakve osobne podatke" + "Podijelite anonimne podatke o korištenju kako biste nam pomogli u otkrivanju problema." + "Možete pročitati sve naše uvjete %1$s ." + "ovdje" + "Ovo možete isključiti u bilo kojem trenutku" + "Nećemo dijeliti vaše podatke s trećim stranama" + "Pomozite nam poboljšati %1$s" + diff --git a/features/announcement/impl/src/main/res/values-hr/translations.xml b/features/announcement/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..e78f29f19a --- /dev/null +++ b/features/announcement/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,11 @@ + + + "Pregledajte prostore koje ste stvorili ili kojima ste se pridružili" + "Prihvatite ili odbijte pozivnice za prostore" + "Otkrijte sve sobe kojima se možete pridružiti u svojim prostorima" + "Pridružite se javnim prostorima" + "Napustite sve prostore kojima ste se pridružili" + "Uskoro stiže filtriranje i stvaranje prostora te upravljanje njima." + "Dobrodošli u beta inačicu prostora! S ovom prvom inačicom možete:" + "Predstavljamo prostore" + diff --git a/features/announcement/impl/src/main/res/values-ro/translations.xml b/features/announcement/impl/src/main/res/values-ro/translations.xml index 48fa06fca4..716f1faeb2 100644 --- a/features/announcement/impl/src/main/res/values-ro/translations.xml +++ b/features/announcement/impl/src/main/res/values-ro/translations.xml @@ -5,7 +5,7 @@ "Descoperiți toate camerele la care vă puteți alătura în spațiile dumneavoastră." "Alăturați-vă spațiilor publice" "Părăsiți spațiile la care v-ați alăturat." - "Crearea și gestionarea spațiilor vor fi disponibile în curând." + "Filtrarea, crearea și gestionarea spațiilor vor fi disponibile în curând." "Bun venit la versiunea beta a Spațiilor! Cu această primă versiune puteți:" "Vă prezentăm Spații" diff --git a/features/call/impl/src/main/res/values-hr/translations.xml b/features/call/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..e58dc362fa --- /dev/null +++ b/features/call/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,8 @@ + + + "Poziv u tijeku" + "Dodirnite za povratak u poziv" + "☎️ Poziv u tijeku" + "Element Call ne podržava korištenje Bluetooth audiouređaja u ovoj inačici Androida. Odaberite drugi audiouređaj." + "Dolazni Element Call" + diff --git a/features/createroom/impl/src/main/res/values-da/translations.xml b/features/createroom/impl/src/main/res/values-da/translations.xml index 422aae09bd..1a69f150fb 100644 --- a/features/createroom/impl/src/main/res/values-da/translations.xml +++ b/features/createroom/impl/src/main/res/values-da/translations.xml @@ -14,6 +14,7 @@ Du kan ændre dette når som helst i rummets indstillinger." "Alle kan bede om at deltage i rummet, men en administrator eller en moderator skal acceptere anmodningen" "Spørg om at deltage" "Hvis dette rum skal være synligt i det offentlige register, skal du bruge en rum-adresse." + "Rummets adresse" "Navn på rum" "Rummets synlighed" "Opret et rum" diff --git a/features/createroom/impl/src/main/res/values-hr/translations.xml b/features/createroom/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..1d6d7e5af7 --- /dev/null +++ b/features/createroom/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,22 @@ + + + "Nova soba" + "Pozovi osobe" + "Došlo je do pogreške prilikom stvaranja sobe" + "Samo pozvane osobe mogu pristupiti ovoj sobi. Sve su poruke sveobuhvatno šifrirane." + "Privatna soba" + "Svatko može pronaći ovu sobu. +To možete u svakom trenutku promijeniti u postavkama sobe." + "Javna soba" + "Svatko se može pridružiti ovoj sobi" + "Svatko" + "Pristup sobi" + "Svatko može zatražiti pridruživanje sobi, ali administrator ili moderator morat će prihvatiti zahtjev." + "Zatraži pridruživanje" + "Da bi ova soba bila vidljiva u javnom direktoriju soba, trebat će vam adresa sobe." + "Adresa sobe" + "Naziv sobe" + "Vidljivost sobe" + "Stvori sobu" + "Tema (neobavezno)" + diff --git a/features/deactivation/impl/src/main/res/values-hr/translations.xml b/features/deactivation/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..04148fdc48 --- /dev/null +++ b/features/deactivation/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,14 @@ + + + "Potvrdite da želite deaktivirati svoj račun. Ova se radnja ne može poništiti." + "Izbriši sve moje poruke" + "Upozorenje: budući korisnici mogu vidjeti nepotpune razgovore." + "Deaktiviranje vašeg računa je %1$s, to će:" + "nepovratno" + "%1$s vaš račun (ne možete se ponovno prijaviti i vaš ID se ne može ponovno upotrijebiti)." + "Trajno onemogući" + "Ukloniti vas iz svih soba za razgovore." + "Izbrisati podatke o vašem računu s našeg poslužitelja identiteta." + "Vaše će poruke i dalje biti vidljive registriranim korisnicima, ali neće biti dostupne novim ili neregistriranim korisnicima ako ih odlučite izbrisati." + "Deaktiviraj račun" + diff --git a/features/ftue/impl/src/main/res/values-hr/translations.xml b/features/ftue/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..cb0e330872 --- /dev/null +++ b/features/ftue/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,16 @@ + + + "Ne možete potvrditi?" + "Izradi novi ključ za oporavak" + "Potvrdite ovaj uređaj kako biste postavili sigurnu razmjenu poruka." + "Potvrdite svoj identitet" + "Upotrijebite drugi uređaj" + "Upotrijebi ključ za oporavak" + "Sada možete sigurno čitati ili slati poruke, a svatko s kim razgovarate također može vjerovati ovom uređaju." + "Uređaj je potvrđen" + "Upotrijebite drugi uređaj" + "Čekanje na drugi uređaj…" + "Postavke možete promijeniti poslije." + "Omogućite obavijesti i nikada ne propustite poruku" + "Unesi ključ za oporavak" + diff --git a/features/home/impl/src/main/res/values-hr/translations.xml b/features/home/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..dd1769b998 --- /dev/null +++ b/features/home/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,55 @@ + + + "Onemogućite optimizaciju baterije za ovu aplikaciju kako biste bili sigurni da ćete primati sve obavijesti." + "Onemogući optimizaciju" + "Obavijesti ne stižu?" + "Vaš je signal obavijesti ažuriran – jasniji je, brži i manje ometajući." + "Ažurirali smo vaše zvukove" + "Ako ste izgubili sve postojeće uređaje, oporavite svoj kriptografski identitet i povijest poruka pomoću ključa za oporavak." + "Postavljanje oporavka" + "Postavite oporavak kako biste zaštitili svoj račun" + "Potvrdite svoj ključ za oporavak kako biste zadržali pristup pohrani ključeva i povijesti poruka." + "Unesite svoj ključ za oporavak" + "Zaboravili ste ključ za oporavak?" + "Vaša pohrana ključeva nije sinkronizirana" + "Kako biste bili sigurni da nikada nećete propustiti važan poziv, promijenite postavke kako biste omogućili obavijesti preko cijelog zaslona kada je telefon zaključan." + "Poboljšajte svoje iskustvo poziva" + "Razgovori" + "Prostori" + "Jeste li sigurni da želite odbiti poziv za pridruživanje %1$s?" + "Odbij poziv" + "Jeste li sigurni da želite odbiti ovaj privatni razgovor s korisnikom %1$s?" + "Odbij razgovor" + "Nema pozivnica" + "Pozvao vas je korisnik %1$s (%2$s)" + "Ovaj se postupak izvodi samo jednom, hvala na čekanju." + "Postavljanje vašeg računa." + "Stvori novi razgovor ili sobu" + "Ukloni filtre" + "Započnite tako da nekome pošaljete poruku." + "Još nema razgovora." + "Favoriti" + "Razgovor možete dodati u favorite u postavkama razgovora. +Zasad možete poništiti odabir filtera kako biste vidjeli ostale razgovore." + "Još nemate omiljenih razgovora" + "Pozivnice" + "Nemate pozivnica na čekanju." + "Nizak prioritet" + "Još nemate razgovora niskog prioriteta" + "Možete poništiti odabir filtera kako biste vidjeli ostale razgovore" + "Nemate razgovora za ovaj odabir" + "Osobe" + "Nemate još nijednu izravnu poruku" + "Sobe" + "Niste još ni u jednoj sobi" + "Nepročitano" + "Čestitamo! +Nemate nepročitanih poruka!" + "Zahtjev za pridruživanje je poslan" + "Razgovori" + "Označi kao pročitano" + "Označi kao nepročitano" + "Ova je soba nadograđena" + "Izgleda da koristite novi uređaj. Izvršite provjeru drugim uređajem da biste pristupili svojim šifriranim porukama." + "Potvrdi identitet" + diff --git a/features/invite/impl/src/main/res/values-hr/translations.xml b/features/invite/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..6d853dacf1 --- /dev/null +++ b/features/invite/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,18 @@ + + + "Nećete vidjeti nikakve poruke ili pozivnice za sobu od ovog korisnika" + "Blokiraj korisnika" + "Prijavite ovu sobu svom davatelju usluga računa." + "Navedite razlog prijave…" + "Odbij i blokiraj" + "Jeste li sigurni da želite odbiti poziv za pridruživanje %1$s?" + "Odbij poziv" + "Jeste li sigurni da želite odbiti ovaj privatni razgovor s korisnikom %1$s?" + "Odbij razgovor" + "Nema pozivnica" + "Pozvao vas je korisnik %1$s (%2$s)" + "Da, odbij i blokiraj" + "Jeste li sigurni da želite odbiti poziv za pridruživanje ovoj sobi? Time ćete također spriječiti da %1$s kontaktira s vama ili vas pozove u sobe." + "Odbij poziv i blokiraj" + "Odbij i blokiraj" + diff --git a/features/invitepeople/impl/src/main/res/values-hr/translations.xml b/features/invitepeople/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..66031c5fd7 --- /dev/null +++ b/features/invitepeople/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,5 @@ + + + "Već je član" + "Već je pozvan/a" + diff --git a/features/joinroom/impl/src/main/res/values-hr/translations.xml b/features/joinroom/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..1a8489255a --- /dev/null +++ b/features/joinroom/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,34 @@ + + + "Korisnik %1$s vam je zabranio pristup." + "Zabranjen vam je pristup" + "Razlog: %1$s." + "Otkaži zahtjev" + "Da, otkaži" + "Jeste li sigurni da želite otkazati svoj zahtjev za pridruživanje ovoj sobi?" + "Otkaži zahtjev za pridruživanje" + "Da, odbij i blokiraj" + "Jeste li sigurni da želite odbiti poziv za pridruživanje ovoj sobi? Time ćete također spriječiti da %1$s kontaktira s vama ili vas pozove u sobe." + "Odbij poziv i blokiraj" + "Odbij i blokiraj" + "Pridruživanje nije uspjelo" + "Morate biti pozvani da se pridružite ili možda postoje ograničenja pristupa." + "Zaboravi" + "Trebate imati pozivnicu kako biste se pridružili" + "Pozvao/la" + "Pridruži se" + "Možda ćete morati biti pozvani ili biti član prostora kako biste se pridružili." + "Pošalji zahtjev za pridruživanje" + "Dopuštenih znakova %1$d od %2$d" + "Poruka (nije obavezna)" + "Primit ćete pozivnicu za pridruživanje sobi ako vaš zahtjev bude prihvaćen." + "Zahtjev za pridruživanje je poslan" + "Nismo mogli prikazati pregled sobe. To bi moglo biti zbog problema s mrežom ili poslužiteljem." + "Nismo mogli prikazati pregled ove sobe" + "%1$s još ne podržava prostore. Prostorima možete pristupiti na internetu." + "Prostori još nisu podržani" + "Kliknite donji gumb i administrator sobe dobit će obavijest. Moći ćete se pridružiti razgovoru nakon što dobijete odobrenje." + "Morate biti član ove sobe da biste vidjeli povijest poruka." + "Želite li se pridružiti ovoj sobi?" + "Pregled nije dostupan" + diff --git a/features/knockrequests/impl/src/main/res/values-hr/translations.xml b/features/knockrequests/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..7f8d39503f --- /dev/null +++ b/features/knockrequests/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,37 @@ + + + "Da, prihvati sve" + "Jeste li sigurni da želite prihvatiti sve zahtjeve za pridruživanje?" + "Prihvati sve zahtjeve" + "Prihvati sve" + "Nismo mogli prihvatiti sve zahtjeve. Želite li pokušati ponovno?" + "Prihvaćanje svih zahtjeva nije uspjelo" + "Prihvaćanje svih zahtjeva za pridruživanje" + "Nismo mogli prihvatiti ovaj zahtjev. Želite li pokušati ponovno?" + "Prihvaćanje zahtjeva nije uspjelo" + "Prihvaća se zahtjev za pridruživanje" + "Da, odbij i zabrani" + "Jeste li sigurni da želite odbiti i zabraniti korisnika %1$s? Taj korisnik neće moći ponovno zatražiti pristup ovoj sobi." + "Odbij i zabrani pristup" + "Odbijanje i zabrana pristupa" + "Da, odbij" + "Jeste li sigurni da želite odbiti zahtjev korisnika %1$s za pridruživanje ovoj sobi?" + "Odbij pristup" + "Odbij i zabrani" + "Nismo mogli odbiti ovaj zahtjev. Želite li pokušati ponovno?" + "Odbijanje zahtjeva nije uspjelo" + "Odbijanje zahtjeva za pridruživanje" + "Kada netko zatraži pridruživanje sobi, ovdje ćete moći vidjeti njihov zahtjev." + "Nema zahtjeva za pridruživanje koji su na čekanju" + "Učitavanje zahtjeva za pridruživanje…" + "Zahtjevi za pridruživanje" + + "%1$s i još %2$d želi se pridružiti ovoj sobi" + "%1$s i još %2$d želi se pridružiti ovoj sobi" + "%1$s i još %2$d želi se pridružiti ovoj sobi" + + "Prikaži sve" + "Prihvati" + "%1$s želi se pridružiti ovoj sobi" + "Prikaz" + diff --git a/features/leaveroom/api/src/main/res/values-hr/translations.xml b/features/leaveroom/api/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..4eb9e3405c --- /dev/null +++ b/features/leaveroom/api/src/main/res/values-hr/translations.xml @@ -0,0 +1,10 @@ + + + "Jeste li sigurni da želite napustiti ovaj razgovor? Ovaj razgovor nije javan i nećete se moći ponovno pridružiti bez pozivnice." + "Jeste li sigurni da želite napustiti ovu sobu? Ovdje ste jedino vi. Ako odete, nitko se ubuduće neće moći pridružiti, pa ni vi." + "Jeste li sigurni da želite napustiti ovu sobu? Ova soba nije javna i nećete joj se moći ponovno pridružiti bez pozivnice." + "Odaberi vlasnike" + "Vi ste jedini vlasnik ove sobe. Morate prenijeti vlasništvo na nekog drugog prije nego što napustite sobu." + "Prenesi vlasništvo" + "Jeste li sigurni da želite napustiti sobu?" + diff --git a/features/lockscreen/impl/src/main/res/values-hr/translations.xml b/features/lockscreen/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..1a81bcc6cb --- /dev/null +++ b/features/lockscreen/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,40 @@ + + + "biometrijska provjera autentičnosti" + "biometrijsko otključavanje" + "Otključavanje biometrijom" + "Potvrdi biometriju" + "Zaboravili ste PIN?" + "Promijeni PIN kod" + "Omogući biometrijsko otključavanje" + "Ukloni PIN" + "Jeste li sigurni da želite ukloniti PIN?" + "Želite li ukloniti PIN?" + "Dopusti %1$s" + "Radije bih upotrijebio/la PIN" + "Uštedite si malo vremena i iskoristite %1$s kako biste svaki put otključali aplikaciju" + "Odaberite PIN" + "Potvrdite PIN" + "Zaključajte %1$s kako biste dodatno osigurali svoje razgovore. + +Odaberite nešto nezaboravno. Ako zaboravite ovaj PIN, bit ćete odjavljeni iz aplikacije." + "Ovo ne možete iz sigurnosnih razloga odabrati kao svoj PIN kod" + "Odaberite drugi PIN" + "Unesite dvaput isti PIN" + "PIN-ovi se ne podudaraju" + "Morat ćete se ponovno prijaviti i izraditi novi PIN da biste mogli nastaviti" + "Odjavit ćete se" + + "Imate %1$d pokušaj otključavanja" + "Imate %1$d pokušaja otključavanja" + "Imate %1$d pokušaja otključavanja" + + + "Pogrešan PIN. Imate još %1$d pokušaj" + "Pogrešan PIN. Imate još %1$d pokušaja" + "Pogrešan PIN. Imate još %1$d pokušaja" + + "Upotrijebi biometriju" + "Upotrijebi PIN" + "Odjavljivanje…" + diff --git a/features/login/impl/src/main/res/values-hr/translations.xml b/features/login/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..2c0251df66 --- /dev/null +++ b/features/login/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,98 @@ + + + "Promijeni davatelja računa" + "Adresa matičnog poslužitelja" + "Unesite pojam za pretraživanje ili adresu domene." + "Potražite tvrtku, zajednicu ili privatni poslužitelj." + "Pronađite davatelja računa" + "Ovdje će se čuvati vaši razgovori – baš kao što biste koristili davatelja usluga e-pošte za čuvanje svojih e-poruka." + "Prijavit ćete se na %s" + "Ovdje će se čuvati vaši razgovori – baš kao što biste koristili davatelja usluga e-pošte za čuvanje svojih e-poruka." + "Izradit ćete račun na %s" + "Matrix.org velik je, besplatni poslužitelj na javnoj Matrixovoj mreži koji pruža sigurnu, decentraliziranu komunikaciju, a kojim upravlja zaklada Matrix.org." + "Ostalo" + "Koristite drugog davatelja računa, kao što je vlastiti privatni poslužitelj ili poslovni račun." + "Promijeni davatelja računa" + "Google Play" + "Potrebna je aplikacija Element Pro na %1$s. Molimo vas da je preuzmete iz trgovine." + "Potreban je Element Pro" + "Nismo mogli pristupiti ovom matičnom poslužitelju. Provjerite jeste li ispravno unijeli URL matičnog poslužitelja. Ako je URL ispravan, obratite se administratoru matičnog poslužitelja za daljnju pomoć." + "Poslužitelj nije dostupan zbog problema u .well-known datoteci: +%1$s" + "Odabrani davatelj usluga računa ne podržava sliding sync. Za korištenje je potrebna nadogradnja poslužitelja %1$ssliding sync." + "%1$s nije dopušteno povezivanje s %2$s." + "Ova je aplikacija konfigurirana tako da dopušta: %1$s." + "Davatelj usluga računa %1$s nije dopušten." + "URL matičnog poslužitelja" + "Unesite adresu domene." + "Koja je adresa vašeg poslužitelja?" + "Odaberite svoj poslužitelj" + "Izradi račun" + "Ovaj je račun deaktiviran." + "Netočno korisničko ime i/ili zaporka" + "To nije valjani identifikator korisnika. Očekivani oblik: ‘@korisnik:matičniposlužitelj.org’" + "Ovaj je poslužitelj konfiguriran za korištenje tokena za osvježavanje. Oni nisu podržani kada se upotrebljava prijava temeljena na zaporki." + "Odabrani matični poslužitelj ne podržava zaporku ili OIDC prijavu. Obratite se administratoru ili odaberite drugi matični poslužitelj." + "Unesite svoje podatke" + "Matrix je otvorena mreža za sigurnu, decentraliziranu komunikaciju." + "Dobro došli natrag!" + "Prijavi se na poslužitelj %1$s" + "Inačica %1$s" + "Prijavi se ručno" + "Prijavi se na poslužitelj %1$s" + "Prijavi se pomoću QR koda" + "Izradi račun" + "Dobro došli u nikad brži %1$s. Snažniji no ikad za postizanje brzine i jednostavnosti." + "Dobro došli u %1$s. Snažniji no ikad – za brzinu i jednostavnost." + "Budi u elementu" + "Uspostavljanje sigurne veze" + "Nije moguće uspostaviti sigurnu vezu s novim uređajem. Vaši postojeći uređaji i dalje su sigurni i ne morate se brinuti zbog njih." + "Što sad?" + "Pokušajte se ponovno prijaviti pomoću QR koda u slučaju da se radilo o problemu s mrežom" + "Ako se problem ponovi, pokušajte s drugom Wi-Fi mrežom ili mobilnim podatcima umjesto Wi-Fi-ja." + "Ako to ne uspije, prijavite se ručno" + "Veza nije sigurna" + "Od vas će se zatražiti da unesete dvije znamenke prikazane na ovom uređaju." + "Unesite ispod navedeni broj u svoj drugi uređaj" + "Prijavite se na drugi uređaj i pokušajte ponovno ili upotrijebite drugi uređaj na kojem ste već prijavljeni." + "Niste prijavljeni na drugom uređaju" + "Prijava je otkazana na drugom uređaju." + "Zahtjev za prijavu je otkazan" + "Prijava je odbijena na drugom uređaju." + "Prijava je odbijena" + "Prijava je istekla. Pokušajte ponovno." + "Prijava nije dovršena na vrijeme" + "Vaš drugi uređaj ne podržava prijavu na %s pomoću QR koda. + +Pokušajte se prijaviti ručno ili skenirajte QR kod drugim uređajem." + "QR kod nije podržan" + "Vaš davatelj usluga računa ne podržava %1$s ." + "%1$s nije podržan" + "Spremno za skeniranje" + "Otvorite %1$s na stolnom uređaju" + "Kliknite na svoj avatar" + "Odaberite %1$s" + "“Poveži novi uređaj”" + "Skenirajte QR kod ovim uređajem" + "Dostupno samo ako vaš davatelj usluge računa to podržava." + "Otvorite %1$s na drugom uređaju kako biste dobili QR kod" + "Upotrijebite QR kod prikazan na drugom uređaju." + "Pokušajte ponovno" + "Pogrešan QR kod" + "Idi na postavke kamere" + "Za nastavak morate dati dopuštenje za %1$s da biste se mogli služiti kamerom svog uređaja." + "Dopustite pristup kameri kako biste mogli skenirati QR kod" + "Skeniraj QR kod" + "Kreni ispočetka" + "Došlo je do neočekivane pogreške. Pokušajte ponovno." + "Čekanje na vaš drugi uređaj" + "Davatelj usluge računa može zatražiti sljedeći kod za potvrdu prijave." + "Vaš verifikacijski kod" + "Promijeni davatelja računa" + "Privatni poslužitelj za zaposlenike aplikacije Element." + "Matrix je otvorena mreža za sigurnu, decentraliziranu komunikaciju." + "Ovdje će se čuvati vaši razgovori – baš kao što biste koristili davatelja usluga e-pošte za čuvanje svojih e-poruka." + "Prijavit ćete se na poslužitelj %1$s" + "Odaberite davatelja usluga računa" + "Izradit ćete račun na poslužitelju %1$s" + diff --git a/features/logout/impl/src/main/res/values-hr/translations.xml b/features/logout/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..331eca04c4 --- /dev/null +++ b/features/logout/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,18 @@ + + + "Jeste li sigurni da se želite odjaviti?" + "Odjava" + "Odjava" + "Odjavljivanje…" + "Odjavit ćete se iz svoje posljednje sesije. Ako se sada odjavite, nećete moći pristupiti svojim šifriranim porukama." + "Isključili ste sigurnosno kopiranje" + "Vaši su se ključevi još uvijek sigurnosno kopirali kada ste se isključili iz mreže. Ponovno se povežite kako bi se vaši ključevi mogli sigurnosno kopirati prije nego što se odjavite." + "Vaši se ključevi još uvijek sigurnosno kopiraju" + "Pričekajte da se to dovrši prije nego što se odjavite." + "Vaši se ključevi još uvijek sigurnosno kopiraju" + "Odjava" + "Odjavit ćete se iz svoje posljednje sesije. Ako se sada odjavite, nećete moći pristupiti svojim šifriranim porukama." + "Oporavak nije postavljen" + "Odjavit ćete se iz svoje posljednje sesije. Ako se sada odjavite, možda nećete moći pristupiti svojim šifriranim porukama." + "Jeste li spremili svoj ključ za oporavak?" + diff --git a/features/messages/impl/src/main/res/values-hr/translations.xml b/features/messages/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..c3427df591 --- /dev/null +++ b/features/messages/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,84 @@ + + + "Aktivnosti" + "Zastave" + "Hrana i piće" + "Životinje i priroda" + "Objekti" + "Emotikoni i osobe" + "Putovanja i mjesta" + "Nedavni emotikoni" + "Simboli" + "Opisi možda neće biti vidljivi osobama koji se služe starijim aplikacijama." + "Dodirnite za promjenu kvalitete prijenosa videozapisa" + "Datoteka se nije mogla prenijeti." + "Prijenos medija za obradu nije uspio, pokušajte ponovno." + "Prijenos medija nije uspio, pokušajte ponovno." + "Maksimalna dopuštena veličina datoteke je %1$s." + "Datoteka je prevelika za prijenos" + "Stavka %1$d od %2$d" + "Optimiziraj kvalitetu slike" + "Obrada…" + "Blokiraj korisnika" + "Označite ako želite sakriti sve trenutačne i buduće poruke od ovog korisnika" + "Ova poruka bit će prijavljena administratoru vašeg matičnog poslužitelja. On neće moći pročitati nijednu šifriranu poruku." + "Razlog za prijavu ovog sadržaja" + "Kamera" + "Uslikaj" + "Snimi videozapis" + "Privitak" + "Biblioteka fotografija i videozapisa" + "Lokacija" + "Anketa" + "Oblikovanje teksta" + "Povijest poruka trenutačno nije dostupna." + "Povijest poruka nije dostupna u ovoj sobi. Potvrdite ovaj uređaj kako biste vidjeli povijest poruka." + "Želite li ih pozvati natrag?" + "Sami ste u ovom razgovoru" + "Obavijestite cijelu sobu" + "Svi" + "Pošalji ponovno" + "Slanje vaše poruke nije uspjelo" + "Dodaj reakciju" + "Ovo je početak sobe %1$s." + "Ovo je početak ovog razgovora." + "Nepodržani poziv. Pitajte pozivatelja može li se služiti novom aplikacijom Element X." + "Prikaži manje" + "Poruka je kopirana" + "Nemate dopuštenje za objavljivanje u ovoj sobi" + + "%1$d član reagirao je s %2$s" + "%1$d člana reagirala su s %2$s" + "%1$d članova reagiralo je s %2$s" + + + "Vi i %1$d član reagirali ste s %2$s" + "Vi i %1$d člana reagirali ste s %2$s" + "Vi i %1$d članova reagirali ste s %2$s" + + "Reagirali ste s %1$s" + "Prikaži manje" + "Prikaži više" + "Prikaži sažetak reakcija" + "Novo" + + "%1$d promjena sobe" + "%1$d promjene sobe" + "%1$d promjena sobe" + + "Prijeđi u novu sobu" + "Ova je soba zamijenjena i više nije aktivna" + "Pogledaj stare poruke" + "Ova je soba nastavak druge sobe" + + "%1$s, %2$s i ostalih %3$d" + "%1$s, %2$s i ostalih %3$d" + "%1$s, %2$s i ostalih %3$d" + + + "%1$s tipka" + "%1$s tipka" + "%1$s tipka" + + "%1$s i %2$s" + diff --git a/features/poll/api/src/main/res/values-hr/translations.xml b/features/poll/api/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..117ed51c6b --- /dev/null +++ b/features/poll/api/src/main/res/values-hr/translations.xml @@ -0,0 +1,10 @@ + + + + "%1$d posto ukupnog broja glasova" + "%1$d posto ukupnog broja glasova" + "%1$d posto ukupnog broja glasova" + + "Uklonit će prethodni odabir" + "Ovo je pobjednički odgovor" + diff --git a/features/poll/impl/src/main/res/values-hr/translations.xml b/features/poll/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..adc11a1be7 --- /dev/null +++ b/features/poll/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,20 @@ + + + "Dodaj mogućnost" + "Prikaži rezultate tek nakon završetka ankete" + "Sakrij glasove" + "Mogućnost %1$d" + "Vaše promjene nisu spremljene. Jeste li sigurni da se želite vratiti?" + "Izbriši mogućnost %1$s" + "Pitanje ili tema" + "O čemu se radi u anketi?" + "Izradi anketu" + "Jeste li sigurni da želite izbrisati ovu anketu?" + "Izbriši anketu" + "Uredi anketu" + "Ne mogu pronaći nijednu tekuću anketu." + "Ne mogu pronaći nijednu prijašnju anketu." + "Tekuće" + "Prijašnje" + "Ankete" + diff --git a/features/preferences/impl/src/main/res/values-en-rUS/translations.xml b/features/preferences/impl/src/main/res/values-en-rUS/translations.xml index b1f615e697..9f69227bec 100644 --- a/features/preferences/impl/src/main/res/values-en-rUS/translations.xml +++ b/features/preferences/impl/src/main/res/values-en-rUS/translations.xml @@ -3,4 +3,5 @@ "Optimize media quality" "Automatically optimize images for faster uploads and smaller file sizes." "Optimize image upload quality" + "Try out our latest ideas in development. These features are not finalized; they may be unstable, may change." diff --git a/features/preferences/impl/src/main/res/values-hr/translations.xml b/features/preferences/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..250af33d49 --- /dev/null +++ b/features/preferences/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,82 @@ + + + "Kako biste bili sigurni da nikada nećete propustiti važan poziv, promijenite postavke kako biste omogućili obavijesti preko cijelog zaslona kada je telefon zaključan." + "Poboljšajte svoje iskustvo poziva" + "Odaberite kako želite primati obavijesti" + "Način rada za razvojne inženjere" + "Omogućite pristup značajkama i funkcionalnostima za razvojne inženjere." + "Prilagođeni osnovni URL za Element Call" + "Postavite prilagođeni osnovni URL za Element Call." + "Nevažeći URL; provjerite jeste li uključili protokol (http/https) i ispravnu adresu." + "Sakrij avatare u zahtjevima za poziv u sobu" + "Sakrij preglede medija na vremenskoj traci" + "Laboratoriji" + "Brže prenesite fotografije i videozapise te smanjite potrošnju podataka" + "Optimiziraj kvalitetu medija" + "Moderiranje i sigurnost" + "Automatski optimizirajte slike za brži prijenos i manje veličine datoteka." + "Optimiziraj kvalitetu prijenosa slika" + "%1$s. Ovdje dodirnite za promjenu." + "Visoka (1080p)" + "Niska (480p)" + "Standardna (720p)" + "Kvaliteta prijenosa videozapisa" + "Pružatelj push obavijesti" + "Onemogućite uređivač obogaćenog teksta kako biste ručno tipkali Markdown." + "Potvrde o čitanju" + "Ako je to isključeno, vaše potvrde o čitanju neće se slati nikome. I dalje ćete primati potvrde o čitanju od drugih korisnika." + "Podijeli prisutnost" + "Ako je to isključeno, nećete moći slati ili primati potvrde o čitanju ili obavijesti o tipkanju." + "Uvijek sakrij" + "Uvijek prikaži" + "U privatnim sobama" + "Skriveni medij uvijek se može prikazati tako se da se dodirne" + "Prikaži medije na vremenskoj traci" + "Omogući opciju za prikaz izvora poruke na vremenskoj traci." + "Nemate blokiranih korisnika" + "Odblokiraj" + "Moći ćete ponovno vidjeti sve njihove poruke." + "Odblokiraj korisnika" + "Deblokiranje…" + "Ime za prikaz" + "Vaše ime za prikaz" + "Došlo je do nepoznate pogreške i informacije se nisu mogle promijeniti." + "Nije moguće ažurirati profil" + "Uredi profil" + "Ažuriranje profila…" + "Omogući odgovore u nizu" + "Aplikacija će se ponovno pokrenuti kako bi se primijenila ova promjena." + "Isprobajte naše najnovije ideje u razvoju. Ove značajke nisu finalizirane; mogu biti nestabilne i mijenjati se." + "Jeste li spremni za eksperimentiranje?" + "Laboratoriji" + "Dodatne postavke" + "Audiopozivi i videopozivi" + "Neusklađenost konfiguracije" + "Pojednostavili smo postavke obavijesti kako bismo olakšali pronalaženje mogućnosti. Neke prilagođene postavke koje ste odabrali u prošlosti nisu ovdje prikazane, ali su i dalje aktivne. + +Ako nastavite, neke od vaših postavki mogu se promijeniti." + "Izravni razgovori" + "Prilagođena postavka po razgovoru" + "Došlo je do pogreške prilikom ažuriranja postavke obavijesti." + "Sve poruke" + "Samo spominjanja i ključne riječi" + "U izravnim razgovorima obavijesti me za" + "U grupnim chatovima obavijesti me za" + "Omogući obavijesti na ovom uređaju" + "Konfiguracija nije ispravljena, pokušajte ponovno." + "Grupni razgovori" + "Pozivnice" + "Vaš matični poslužitelj ne podržava ovu mogućnost u šifriranim sobama; možda nećete dobiti obavijesti u nekim sobama." + "Spominjanja" + "Sve" + "Spominjanja" + "Obavijesti me za" + "Obavijesti me o sobi @soba" + "Kako biste primali obavijesti, promijenite %1$s." + "postavke sustava" + "Obavijesti sustava su isključene" + "Obavijesti" + "Povijest push obavijesti" + "Rješavanje problema" + "Rješavanje problema s obavijestima" + diff --git a/features/rageshake/api/src/main/res/values-hr/translations.xml b/features/rageshake/api/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..c3dfcb3203 --- /dev/null +++ b/features/rageshake/api/src/main/res/values-hr/translations.xml @@ -0,0 +1,7 @@ + + + "%1$s neočekivano je prestao s radom prilikom posljednjeg korištenja. Želite li s nama podijeliti izvješće o padu?" + "Čini se da ljutito treseš telefon. Želiš li otvoriti zaslon s izvješćem o pogrešci?" + "Snažno protresi" + "Prag detekcije" + diff --git a/features/rageshake/impl/src/main/res/values-hr/translations.xml b/features/rageshake/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..e49427b2a9 --- /dev/null +++ b/features/rageshake/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,20 @@ + + + "Priloži snimku zaslona" + "Možete mi se obratiti ako imate bilo kakvih dodatnih pitanja." + "Javi mi se" + "Uredi snimku zaslona" + "Opišite problem. Što ste napravili? Što ste očekivali da će se dogoditi? Što se zapravo dogodilo. Molimo vas da što detaljnije opišete problem." + "Opišite problem…" + "Ako je moguće, molimo vas da opis bude na engleskom jeziku." + "Opis je prekratak; navedite više pojedinosti o tome što se dogodilo. Hvala!" + "Pošalji zapisnike o padu aplikacije" + "Dopusti zapisnike" + "Vaši su zapisnici preopširni pa ih nije moguće uključiti u ovo izvješće. Molimo vas da nam ih pošaljete na drugi način." + "Pošalji snimku zaslona" + "Zapisnici će biti uključeni u vašu poruku kako bismo bili sigurni da sve ispravno funkcionira. Kako biste poslali poruku bez zapisnika, isključite ovu postavku." + "%1$s neočekivano je prestao s radom prilikom posljednjeg korištenja. Želite li s nama podijeliti izvješće o padu?" + "Ako imate problema s obavijestima, prijenos pravila za slanje obavijesti može nam pomoći da utvrdimo uzrok. Imajte na umu da ta pravila mogu sadržavati privatne podatke, kao što su vaše ime za prikaz ili ključne riječi za koje želite primati obavijesti." + "Postavke slanja obavijesti" + "Prikaz zapisnika" + diff --git a/features/reportroom/impl/src/main/res/values-hr/translations.xml b/features/reportroom/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..50ecc7a24d --- /dev/null +++ b/features/reportroom/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,8 @@ + + + "Vaša je prijava uspješno poslana, ali naišli smo na problem prilikom pokušaja napuštanja sobe. Pokušajte ponovno." + "Sobu nije moguće napustiti" + "Prijavi ovu sobu svom administratoru. Ako su poruke šifrirane, vaš administrator neće ih moći pročitati." + "Navedite razlog prijave…" + "Prijavi sobu" + diff --git a/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml index 4a0b5d179d..382372329b 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml @@ -1,14 +1,16 @@ - "Kun admins" + "Administrator" "Spær brugere" "Fjern beskeder" - "Invitér personer og acceptér anmodninger om at deltage" + "Medlem" + "Invitér andre" + "Administrer medlemmer" "Beskeder og indhold" - "Admins og moderatorer" - "Fjern personer og afvis anmodninger om at deltage" + "Moderator" + "Fjern personer" "Skift rummets avatar" - "Rediger rum" + "Redigér detaljer" "Skift rummets navn" "Skift emne for rummet" "Send beskeder" @@ -32,6 +34,12 @@ "Du har ændringer, der ikke er gemt." "Gem ændringer?" "Der er ingen spærrede brugere i dette rum." + + "%1$d Spærret" + "%1$d Spærret" + + "Tjek stavningen eller prøv en ny søgning" + "Ingen resultater for \"%1$s\"" "%1$d person" "%1$d personer" @@ -43,8 +51,13 @@ "Fjern brugerens spærring fra rummet" "Spærret" "Medlemmer" - "Kun admins" - "Admins og moderatorer" + + "%1$d Inviteret" + "%1$d Inviteret" + + "Afventer" + "Administrator" + "Moderator" "Ejeren" "Medlemmer af rummet" "Ophæver spærring af %1$s" @@ -57,10 +70,12 @@ "Beskeder og indhold" "Moderatorer" "Ejere" + "Tilladelser" "Nulstil tilladelser" "Når du nulstiller tilladelserne, mister du de nuværende indstillinger." "Nulstil tilladelser?" "Roller" "Detaljer om rummet" + "Detaljer om gruppe" "Roller og tilladelser" diff --git a/features/rolesandpermissions/impl/src/main/res/values-hr/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..db31f8f985 --- /dev/null +++ b/features/rolesandpermissions/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,84 @@ + + + "Administrator" + "Zabrana pristupa osobama" + "Uklanjanje poruka" + "Član" + "Pozivanje osoba" + "Upravljanje članovima" + "Poruke i sadržaj" + "Moderator" + "Uklanjanje osoba" + "Promjena avatara" + "Uredi pojedinosti" + "Promjena imena" + "Promjena teme" + "Slanje poruka" + "Uredi administratore" + "Nećete moći poništiti ovu radnju. Postavit ćete da korisnik ima isti položaj kao i vi." + "Dodati administratora?" + "Nećete moći poništiti ovu radnju. Prenosite vlasništvo na odabrane korisnike. Nakon što odete, to će biti trajno." + "Želite li prenijeti vlasništvo?" + "Degradiraj" + "Nećete moći poništiti ovu promjenu jer sami sebe degradirate. Ako ste posljednji privilegirani korisnik u sobi, nećete moći ponovno dobiti privilegije." + "Želite li se degradirati?" + "%1$s (na čekanju)" + "(na čekanju)" + "Administratori automatski imaju moderatorske ovlasti" + "Vlasnici automatski imaju administratorske ovlasti." + "Uredi moderatore" + "Odaberi vlasnike" + "Administratori" + "Moderatori" + "Članovi" + "Niste spremili sve promjene." + "Želite li spremiti promjene?" + "Nema zabranjenih korisnika." + + "%1$d zabranjen" + "%1$d zabranjena" + "%1$d zabranjenih" + + "Provjerite pravopis ili pokušajte s novim pretraživanjem" + "Nema rezultata za “%1$s”" + + "%1$d osoba" + "%1$d osobe" + "%1$d ljudi" + + "Zabrani korisnika" + "Samo ukloni člana" + "Poništi zabranu" + "Moći će se ponovno pridružiti ovoj sobi ako budu pozvani." + "Poništi zabranu pristupa korisniku" + "Zabranjeni" + "Članovi" + + "%1$d pozvan" + "%1$d pozvana" + "%1$d pozvanih" + + "Na čekanju" + "Administrator" + "Moderator" + "Vlasnik" + "Članovi sobe" + "Uklanja se zabrana korisniku %1$s" + "Administratori" + "Administratori i vlasnici" + "Promijeni moju ulogu" + "Degradiraj u člana" + "Degradiraj u moderatora" + "Moderiranje članova" + "Poruke i sadržaj" + "Moderatori" + "Vlasnici" + "Dopuštenja" + "Poništi dopuštenja" + "Nakon što poništite dopuštenja, izgubit ćete trenutačne postavke." + "Želite li poništiti dopuštenja?" + "Uloge" + "Pojedinosti o sobi" + "Pojedinosti o prostoru" + "Uloge i dopuštenja" + diff --git a/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml index 77e6e3b389..0f80fbb227 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml @@ -34,6 +34,8 @@ "Mentetlen módosításai vannak." "Menti a módosításokat?" "Ebben a szobában nincsenek kitiltott felhasználók." + "Ellenőrizze a helyesírást, vagy próbáljon meg egy új keresést" + "Nincs találat a következőre: „%1$s\"" "%1$d személy" "%1$d személy" diff --git a/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml index c2b248f264..4d3be082dd 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml @@ -1,14 +1,16 @@ - "Doar administratori" + "Administrator" "Interziceți persoane" "Ștergeți mesajele" - "Invitați persoane și acceptați cereri de alaturare" + "Membru" + "Invitați persoane" + "Gestionați membrii" "Mesaje și conținut" - "Administratori și moderatori" - "Îndepărtați persoane și refuzați cereri de alăturare" + "Moderator" + "Îndepărtați persoane" "Schimbați avatarul camerei" - "Editați camera" + "Editați detaliile" "Schimbă numele camerei" "Schimbați subiectul camerei" "Trimiteți mesaje" @@ -31,9 +33,17 @@ "Membri" "Aveți modificări nesalvate." "Salvați modificările?" - "Nu există utilizatori interziși în această cameră." + "Nu există utilizatori interziși." + + "%1$d Interzis" + "%1$d Interziși" + "%1$d Interziși" + + "Verificați ortografia sau încercați o căutare nouă" + "Niciun rezultat pentru “%1$s”" - "o persoană" + "%1$d persoană" + "%1$d persoane" "%1$d persoane" "Îndepărtați și interziceți membrul" @@ -43,8 +53,14 @@ "Revocati excluderea din camera" "Excluși" "Membri" - "Doar administratori" - "Administratori și moderatori" + + "%1$d Invitat" + "%1$d Invitați" + "%1$d Invitați" + + "În așteptare" + "Administrator" + "Moderator" "Proprietar" "Membrii camerei" "Se anulează interzicerea lui %1$s" @@ -57,10 +73,12 @@ "Mesaje și conținut" "Moderatori" "Proprietari" + "Permisiuni" "Resetați permisiunile" "După ce resetați permisiunile, veți pierde setările curente." "Resetați permisiunile?" "Roluri" "Detaliile camerei" + "Detalii spațiu" "Roluri și permisiuni" diff --git a/features/roomaliasresolver/impl/src/main/res/values-hr/translations.xml b/features/roomaliasresolver/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..2d1e42c405 --- /dev/null +++ b/features/roomaliasresolver/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,5 @@ + + + "Nismo mogli prikazati pregled ove sobe" + "Nije uspjelo razrješavanje aliasa sobe." + diff --git a/features/roomdetails/impl/src/main/res/values-da/translations.xml b/features/roomdetails/impl/src/main/res/values-da/translations.xml index c2ed3caaca..18e1246e98 100644 --- a/features/roomdetails/impl/src/main/res/values-da/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-da/translations.xml @@ -1,19 +1,21 @@ - "Du skal bruge en rum-adresse for at gøre den synlig i kataloget." - "Rummets adresse" + "Du skal bruge en adresse for at gøre det synligt i det offentlige register." + "Redigér adresse" "Der opstod en fejl under opdatering af notifikationsindstillingen." "Din hjemmeserver understøtter ikke denne mulighed i krypterede rum, og derfor er det muligt at du ikke får besked i alle rum." "Afstemninger" - "Kun admins" + "Administrator" "Spær brugere" "Fjern beskeder" - "Invitér personer og acceptér anmodninger om at deltage" + "Medlem" + "Invitér andre" + "Administrer medlemmer" "Beskeder og indhold" - "Admins og moderatorer" - "Fjern personer og afvis anmodninger om at deltage" + "Moderator" + "Fjern personer" "Skift rummets avatar" - "Rediger rum" + "Redigér detaljer" "Skift rummets navn" "Skift emne for rummet" "Send beskeder" @@ -40,7 +42,7 @@ "Krypteret" "Ikke krypteret" "Offentligt rum" - "Rediger rum" + "Redigér detaljer" "Der opstod en ukendt fejl, og oplysningerne kunne ikke ændres." "Rummet kunne ikke opdateres" "Beskeder er sikret med låse. Kun du og modtagerne har de unikke nøgler til at låse dem op." @@ -69,6 +71,12 @@ "Emne" "Opdaterer rum…" "Der er ingen spærrede brugere i dette rum." + + "%1$d Spærret" + "%1$d Spærret" + + "Tjek stavningen eller prøv en ny søgning" + "Ingen resultater for \"%1$s\"" "%1$d person" "%1$d personer" @@ -80,8 +88,13 @@ "Fjern brugerens spærring fra rummet" "Spærret" "Medlemmer" - "Kun admins" - "Admins og moderatorer" + + "%1$d Inviteret" + "%1$d Inviteret" + + "Afventer" + "Administrator" + "Moderator" "Ejeren" "Medlemmer af rummet" "Ophæver spærring af %1$s" @@ -108,14 +121,15 @@ "Beskeder og indhold" "Moderatorer" "Ejere" + "Tilladelser" "Nulstil tilladelser" "Når du nulstiller tilladelserne, mister du de nuværende indstillinger." "Nulstil tilladelser?" "Roller" "Detaljer om rummet" "Roller og tilladelser" - "Tilføj adresse på rum" - "Alle kan bede om at deltage i lokalet, men en administrator eller moderator skal acceptere anmodningen." + "Tilføj adresse" + "Alle skal anmode om adgang." "Spørg om at deltage" "Ja, aktivér kryptering" "Når det først er aktiveret, kan kryptering for et rum ikke deaktiveres igen. Beskedhistorik vil kun være synlig for rummedlemmer, siden de blev inviteret, eller siden de blev medlem af rummet. @@ -125,16 +139,18 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Når kryptering først er aktiveret, kan den ikke deaktiveres igen." "Kryptering" "Aktivér end-to-end-kryptering" - "Alle kan finde og deltage" + "Alle kan være med." "Enhver" - "Andre kan kun deltage, hvis de bliver inviteret" - "Kun med invitation" - "Adgang til rummet" + "Kun inviterede personer kan deltage i dette rum." + "Kun inviterede" + "Adgang" "Medlemmer af gruppen" "Grupper understøttes ikke i øjeblikket" - "Du skal bruge en rum-adresse for at gøre den synlig i kataloget." + "Du skal bruge en adresse for at gøre det synligt i det offentlige register." + "Adresse" "Tillad, at dette rum kan findes ved at søge i %1$s fortegnelse over offentlige rum" - "Synlig i det offentlige register over rum" + "Gør det muligt at blive fundet ved søgninger i det offentlige register." + "Synlig i det offentlige register" "Enhver" "Hvem kan læse historikken?" "Kun medlemmer, efter de blev inviteret" @@ -142,5 +158,6 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Rum-adresser er en måde at finde og få adgang til værelser på. Dette sikrer også, at du nemt kan dele dit rum med andre. Du kan vælge at offentliggøre dit rum i din hjemmeservers offentlige katalog over rum." "Udgivelse af rum" + "Synlighed" "Sikkerhed og privatliv" diff --git a/features/roomdetails/impl/src/main/res/values-en-rUS/translations.xml b/features/roomdetails/impl/src/main/res/values-en-rUS/translations.xml new file mode 100644 index 0000000000..9a4b56e287 --- /dev/null +++ b/features/roomdetails/impl/src/main/res/values-en-rUS/translations.xml @@ -0,0 +1,5 @@ + + + "Anyone in authorized spaces can join, but everyone else must request access." + "Anyone in authorized spaces can join." + diff --git a/features/roomdetails/impl/src/main/res/values-et/translations.xml b/features/roomdetails/impl/src/main/res/values-et/translations.xml index 570991ff9e..f4199cb10b 100644 --- a/features/roomdetails/impl/src/main/res/values-et/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-et/translations.xml @@ -125,8 +125,10 @@ "Jututoa üksikasjad" "Rollid ja õigused" "Lisa aadress" + "Liituda saavad kõik volitatud kogukondade liikmed, kuid kõik teised peavad küsima võimalust ligipääsuks." "Kõik võivad paluda jututoaga liitumist." "Küsi võimalust liitumiseks" + "Liituda saavad kõik „%1$s“ kogukonna liikmed, kuid kõik teised peavad küsima võimalust ligipääsuks." "Jah, lülita krüptimine sisse" "Kui jututoa krüptimine on kord sisse lülitatud, siis seda välja lülitada ei saa. Sõnumite ajalugu on nähtav vaid jututoa liikmetele alates kutse saamise või liitumise hetkest. Keegi teine peale jututoa liikmete ei saa sõnumeid lugeda. See võib takistada suhtlusrobotite ja/või võrgusildade toimimist. @@ -137,10 +139,13 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Võta läbiv krüptimine kasutusele" "Kõik võivad jututoaga liituda" "Kõik" + "Vali kogukonnad, mille liikmed saavad selle jututoaga liituda ilma kutseta. %1$s" "Halda kogukondi" "Liituda saab vaid kutse olemasolul" "Vaid kutsega" "Ligipääs" + "Liituda saavad kõik volitatud kogukondade liikmed." + "Liituda võivad kõik „%1$s“ liikmed." "Kogukonna liikmed" "Kogukondade tugi veel puudub" "Selleks, et jututuba oleks nähtav jututubade avalikus kataloogis, vajab ta aadressi." @@ -155,6 +160,7 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada. Lisaks võid sa jututoa avaldada oma koduserveri avalikus jututubade kataloogis." "Jututoa avaldamine" + "Aadressid on mugav viis jututubade ja kogukondade leidmiseks ning tagab mugava võimaluse nende jagamiseks." "Nähtavus" "Turvalisus ja privaatsus" diff --git a/features/roomdetails/impl/src/main/res/values-hr/translations.xml b/features/roomdetails/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..b6ed2e142f --- /dev/null +++ b/features/roomdetails/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,173 @@ + + + "Trebat će vam adresa kako bi bila vidljiva u javnom direktoriju." + "Uredi adresu" + "Došlo je do pogreške prilikom ažuriranja postavke obavijesti." + "Vaš matični poslužitelj ne podržava ovu mogućnost u šifriranim sobama; možda nećete dobiti obavijesti u nekim sobama." + "Ankete" + "Administrator" + "Zabrana pristupa osobama" + "Uklanjanje poruka" + "Član" + "Pozivanje osoba" + "Upravljanje članovima" + "Poruke i sadržaj" + "Moderator" + "Uklanjanje osoba" + "Promjena avatara" + "Uredi pojedinosti" + "Promjena imena" + "Promjena teme" + "Slanje poruka" + "Uredi administratore" + "Nećete moći poništiti ovu radnju. Postavit ćete da korisnik ima isti položaj kao i vi." + "Dodati administratora?" + "Nećete moći poništiti ovu radnju. Prenosite vlasništvo na odabrane korisnike. Nakon što odete, to će biti trajno." + "Želite li prenijeti vlasništvo?" + "Degradiraj" + "Nećete moći poništiti ovu promjenu jer sami sebe degradirate. Ako ste posljednji privilegirani korisnik u sobi, nećete moći ponovno dobiti privilegije." + "Želite li se degradirati?" + "%1$s (na čekanju)" + "(na čekanju)" + "Administratori automatski imaju moderatorske ovlasti" + "Vlasnici automatski imaju administratorske ovlasti." + "Uredi moderatore" + "Odaberi vlasnike" + "Administratori" + "Moderatori" + "Članovi" + "Niste spremili sve promjene." + "Želite li spremiti promjene?" + "Dodaj temu" + "Šifrirano" + "Nije šifrirano" + "Javna soba" + "Uredi pojedinosti" + "Došlo je do nepoznate pogreške i podatci se nisu mogli promijeniti." + "Nije moguće ažurirati sobu" + "Poruke su zaključane. Samo vi i primatelji imate jedinstvene ključeve za njihovo otključavanje." + "Omogućeno je šifriranje poruka" + "Došlo je do pogreške prilikom učitavanja postavki obavijesti." + "Isključivanje zvuka u ovoj sobi nije uspjelo, pokušajte ponovno." + "Uključivanje zvuka u ovoj sobi nije uspjelo, pokušajte ponovno." + "Ne zatvarajte aplikaciju dok se ne završi." + "Priprema pozivnica…" + "Pozovi osobe" + "Napusti razgovor" + "Napusti sobu" + "Mediji i datoteke" + "Prilagođeno" + "Zadano" + "Obavijesti" + "Prikvačene poruke" + "Profil" + "Zahtjevi za pridruživanje" + "Uloge i dopuštenja" + "Naziv sobe" + "Sigurnost i privatnost" + "Sigurnost" + "Podijeli sobu" + "Informacije o sobi" + "Tema" + "Ažuriranje pojedinosti…" + "Nema zabranjenih korisnika." + + "%1$d zabranjen" + "%1$d zabranjena" + "%1$d zabranjenih" + + "Provjerite pravopis ili pokušajte s novim pretraživanjem" + "Nema rezultata za “%1$s”" + + "%1$d osoba" + "%1$d osobe" + "%1$d ljudi" + + "Zabrani korisnika" + "Samo ukloni člana" + "Poništi zabranu" + "Moći će se ponovno pridružiti ovoj sobi ako budu pozvani." + "Poništi zabranu pristupa korisniku" + "Zabranjeni" + "Članovi" + + "%1$d pozvan" + "%1$d pozvana" + "%1$d pozvanih" + + "Na čekanju" + "Administrator" + "Moderator" + "Vlasnik" + "Članovi sobe" + "Uklanja se zabrana korisniku %1$s" + "Dopusti prilagođenu postavku" + "Uključivanjem ovoga poništit ćete zadanu postavku" + "Obavijesti me u ovom razgovoru za" + "Možete to promijeniti u %1$s ." + "globalne postavke" + "Zadana postavka" + "Ukloni prilagođenu postavku" + "Došlo je do pogreške prilikom učitavanja postavki obavijesti." + "Vraćanje zadanog načina rada nije uspjelo, pokušajte ponovno." + "Postavljanje načina rada nije uspjelo, pokušajte ponovno." + "Vaš matični poslužitelj ne podržava ovu mogućnost u šifriranim sobama; nećete dobiti obavijest u ovoj sobi." + "Sve poruke" + "Samo spominjanja i ključne riječi" + "U ovoj sobi obavijesti me za" + "Administratori" + "Administratori i vlasnici" + "Promijeni moju ulogu" + "Degradiraj u člana" + "Degradiraj u moderatora" + "Moderiranje članova" + "Poruke i sadržaj" + "Moderatori" + "Vlasnici" + "Dopuštenja" + "Poništi dopuštenja" + "Nakon što poništite dopuštenja, izgubit ćete trenutačne postavke." + "Želite li poništiti dopuštenja?" + "Uloge" + "Pojedinosti o sobi" + "Uloge i dopuštenja" + "Dodaj adresu" + "Svatko tko se nalazi u ovlaštenim prostorima može se pridružiti, ali svi ostali moraju zatražiti pristup." + "Svi moraju zatražiti pristup." + "Zatraži pridruživanje" + "Svatko u %1$s može se pridružiti, ali svi ostali moraju zatražiti pristup." + "Da, omogući šifriranje" + "Nakon što se šifriranje za sobu omogući, više se neće moći onemogućiti. Povijest poruka bit će vidljiva samo članovima sobe otkad su pozvani ili otkad su joj se pridružili. +Nitko osim članova sobe neće moći čitati poruke. Zbog toga botovi i mostovi možda neće ispravno funkcionirati. +Ne preporučujemo omogućavanje šifriranja za sobe koje svatko može pronaći i pridružiti im se." + "Želite li omogućiti šifriranje?" + "Nakon što se šifriranje omogući, više se neće moći onemogućiti." + "Šifriranje" + "Omogući sveobuhvatno šifriranje" + "Svatko se može pridružiti." + "Svatko" + "Odaberite iz kojih se prostora članovi mogu pridružiti ovoj sobi bez pozivnice. %1$s" + "Upravljaj prostorima" + "Samo pozvane osobe mogu se pridružiti." + "Samo s pozivnicom" + "Pristup" + "Svatko tko se nalazi u ovlaštenim prostorima može se pridružiti." + "Svatko u %1$s može se pridružiti." + "Članovi prostora" + "Prostori trenutačno nisu podržani" + "Trebat će vam adresa kako bi bila vidljiva u javnom direktoriju." + "Adresa" + "Omogući pronalazak ove sobe pretraživanjem %1$s javnog direktorija soba" + "Omogući pronalazak pretraživanjem javnog direktorija." + "Vidljivo u javnom direktoriju" + "Svatko" + "Tko zna čitati povijest" + "Samo za članove nakon što su pozvani" + "Samo za članove nakon što se odabere ova mogućnost" + "Adrese soba služe za pronalaženje i pristup sobama. Time se također osigurava jednostavno dijeljenje sobe s drugim korisnicima. +Možete odabrati objavljivanje svoje sobe u javnom direktoriju soba na matičnom poslužitelju." + "Objavljivanje sobe" + "Adrese služe za pronalaženje soba i prostora te pristup njima. Tako ih ujedno možete jednostavno dijeliti s drugima." + "Vidljivost" + "Sigurnost i privatnost" + diff --git a/features/roomdetails/impl/src/main/res/values-hu/translations.xml b/features/roomdetails/impl/src/main/res/values-hu/translations.xml index bbcf93fcf7..440ae23d09 100644 --- a/features/roomdetails/impl/src/main/res/values-hu/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-hu/translations.xml @@ -71,6 +71,8 @@ "Téma" "Szoba frissítése…" "Ebben a szobában nincsenek kitiltott felhasználók." + "Ellenőrizze a helyesírást, vagy próbáljon meg egy új keresést" + "Nincs találat a következőre: „%1$s\"" "%1$d személy" "%1$d személy" diff --git a/features/roomdetails/impl/src/main/res/values-ro/translations.xml b/features/roomdetails/impl/src/main/res/values-ro/translations.xml index f0c43e53a5..effa5c3204 100644 --- a/features/roomdetails/impl/src/main/res/values-ro/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ro/translations.xml @@ -1,19 +1,21 @@ - "Veți avea nevoie de o adresă de cameră pentru a o face vizibilă în director." - "Adresa camerei" + "Veți avea nevoie de o adresă pentru a o face vizibilă în directorul public." + "Editați adresa" "A apărut o eroare în timpul actualizării setărilor pentru notificari." "Serverul dumneavoastră nu acceptă această opțiune în camerele criptate, este posibil să nu primiți notificări în unele camere." "Sondaje" - "Doar administratori" + "Administrator" "Interziceți persoane" "Ștergeți mesajele" - "Invitați persoane și acceptați cereri de alaturare" + "Membru" + "Invitați persoane" + "Gestionați membrii" "Mesaje și conținut" - "Administratori și moderatori" - "Îndepărtați persoane și refuzați cereri de alăturare" + "Moderator" + "Îndepărtați persoane" "Schimbați avatarul camerei" - "Editați camera" + "Editați detaliile" "Schimbă numele camerei" "Schimbați subiectul camerei" "Trimiteți mesaje" @@ -40,7 +42,7 @@ "Criptat" "Necriptat" "Cameră publică" - "Editați camera" + "Editați detaliile" "A apărut o eroare la actualizarea detaliilor camerei" "Nu s-a putut actualiza camera" "Mesajele sunt securizate cu încuietori. Doar dumneavoastră și destinatarii aveți cheile unice pentru a le debloca." @@ -68,9 +70,17 @@ "Informatii camera" "Subiect" "Se actualizează camera…" - "Nu există utilizatori interziși în această cameră." + "Nu există utilizatori interziși." + + "%1$d Interzis" + "%1$d Interziși" + "%1$d Interziși" + + "Verificați ortografia sau încercați o căutare nouă" + "Niciun rezultat pentru “%1$s”" - "o persoană" + "%1$d persoană" + "%1$d persoane" "%1$d persoane" "Îndepărtați și interziceți membrul" @@ -80,8 +90,14 @@ "Revocati excluderea din camera" "Excluși" "Membri" - "Doar administratori" - "Administratori și moderatori" + + "%1$d Invitat" + "%1$d Invitați" + "%1$d Invitați" + + "În așteptare" + "Administrator" + "Moderator" "Proprietar" "Membrii camerei" "Se anulează interzicerea lui %1$s" @@ -108,15 +124,18 @@ "Mesaje și conținut" "Moderatori" "Proprietari" + "Permisiuni" "Resetați permisiunile" "După ce resetați permisiunile, veți pierde setările curente." "Resetați permisiunile?" "Roluri" "Detaliile camerei" "Roluri și permisiuni" - "Adăugați adresa camerei" - "Oricine poate cere să se alăture camerei, dar un administrator sau moderator va trebui să accepte cererea." + "Adăugați o adresă" + "Oricine se află în spațiile autorizate se poate alătura, dar toți ceilalți trebuie să solicite accesul." + "Toată lumea trebuie să solicite acces." "Cereți să vă alăturați" + "Oricine în %1$s se poate alătura, dar toți ceilalți trebuie să solicite acces." "Da, activați criptarea" "Odată activată, criptarea pentru o cameră nu poate fi dezactivată. Mesajele anterioare vor fi vizibile numai pentru membrii camerei de la momentul la care au fost invitați sau de la momentul la care s-au alăturat camerei. Nimeni în afară de membrii camerei nu va putea citi messaje. Acest lucru poate împiedica funcționarea corectă a boților și a punților. @@ -125,15 +144,21 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Odată activată, criptarea nu poate fi dezactivată." "Criptare" "Activați criptarea end-to-end" - "Oricine poate găsi și alătura camerei" + "Oricine se poate alătura." "Oricine" - "Persoanele se pot alătura numai dacă invitate" + "Alegeți membrii căror spații se pot alătura acestei camere fără invitație. %1$s" + "Gestionați spațiile" + "Doar persoanele invitate se pot alătura." "Doar pe bază de invitație" - "Acces la cameră" + "Acces" + "Oricine se află într-un spațiu autorizat poate participa." + "Oricine din %1$s se poate alătura." "Membrii spațiului" "Spațiile nu sunt momentan suportate." - "Veți avea nevoie de o adresă de cameră pentru a o face vizibilă în director." + "Veți avea nevoie de o adresă pentru a o face vizibilă în directorul public." + "Adresă" "Permiteți găsirea acestei camere prin căutarea în directorul de camere publice al %1$s" + "Permiteți găsirea prin căutarea în directorul public." "Vizibilă în directorul de camere publice" "Oricine" "Cine poate citi mesajele anterioare" @@ -142,5 +167,7 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Adresele camerelor sunt modalități de a găsi și accesa camere. Acest lucru vă asigură, de asemenea, că puteți partaja cu ușurință camera dumneavoastră cu alte persoane. Puteți alege să publicați camera în directorul public al camerelor serverului dumneavoastră." "Publicare cameră" + "Adresele sunt o modalitate de a găsi și accesa camere și spații. Acest lucru asigură, de asemenea, că le puteți partaja cu ușurință cu alții." + "Vizibilitate" "Securitate & confidențialitate" diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index deb2d62902..4ed7d0c242 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -129,7 +129,7 @@ "Room details" "Roles & permissions" "Add address" - "Anyone in authorized spaces can join, but everyone else must request access." + "Anyone in authorised spaces can join, but everyone else must request access." "Everyone must request access." "Ask to join" "Anyone in %1$s can join, but everyone else must request access." @@ -148,7 +148,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Only invited people can join." "Invite only" "Access" - "Anyone in authorized spaces can join." + "Anyone in authorised spaces can join." "Anyone in %1$s can join." "Space members" "Spaces are not currently supported" diff --git a/features/roomdetailsedit/impl/src/main/res/values-da/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-da/translations.xml index 489bd9b13b..d751b1da96 100644 --- a/features/roomdetailsedit/impl/src/main/res/values-da/translations.xml +++ b/features/roomdetailsedit/impl/src/main/res/values-da/translations.xml @@ -1,6 +1,6 @@ - "Rediger rum" + "Redigér detaljer" "Der opstod en ukendt fejl, og oplysningerne kunne ikke ændres." "Rummet kunne ikke opdateres" "Opdaterer rum…" diff --git a/features/roomdetailsedit/impl/src/main/res/values-hr/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..7cd06d6bd8 --- /dev/null +++ b/features/roomdetailsedit/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,7 @@ + + + "Uredi pojedinosti" + "Došlo je do nepoznate pogreške i podatci se nisu mogli promijeniti." + "Nije moguće ažurirati sobu" + "Ažuriranje pojedinosti…" + diff --git a/features/roomdetailsedit/impl/src/main/res/values-ro/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-ro/translations.xml index 9d9e769196..401eeee575 100644 --- a/features/roomdetailsedit/impl/src/main/res/values-ro/translations.xml +++ b/features/roomdetailsedit/impl/src/main/res/values-ro/translations.xml @@ -1,6 +1,6 @@ - "Editați camera" + "Editați detaliile" "A apărut o eroare la actualizarea detaliilor camerei" "Nu s-a putut actualiza camera" "Se actualizează camera…" diff --git a/features/roomdirectory/impl/src/main/res/values-hr/translations.xml b/features/roomdirectory/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..2057f54c18 --- /dev/null +++ b/features/roomdirectory/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,5 @@ + + + "Učitavanje nije uspjelo" + "Direktorij soba" + diff --git a/features/roommembermoderation/impl/src/main/res/values-hr/translations.xml b/features/roommembermoderation/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..48185160db --- /dev/null +++ b/features/roommembermoderation/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,22 @@ + + + "Zabrani korisnika" + "Zabrani" + "Neće se moći ponovno pridružiti ako budu pozvani." + "Jeste li sigurni da želite zabraniti pristup ovom članu?" + "Neće se moći ponovno pridružiti ovom prostoru ako budu pozvani, ali će i dalje zadržati članstvo u svim sobama ili podprostorima." + "Zabranjuje se pristup korisniku %1$s" + "Ukloni" + "Moći će se ponovno pridružiti ovoj sobi ako budu pozvani." + "Jeste li sigurni da želite ukloniti ovog člana?" + "Moći će se ponovno pridružiti ovom prostoru ako budu pozvani, a i dalje će zadržati članstvo u svim sobama ili podprostorima." + "Prikaži profil" + "Ukloni korisnika" + "Želite li ukloniti člana i zabraniti mu da se ubuduće pridruži?" + "Uklanjanje člana %1$s…" + "Poništi zabranu pristupa korisniku" + "Poništi zabranu" + "Mogli bi se ponovno pridružiti ako budu pozvani" + "Jeste li sigurni da želite poništiti zabranu pristupa ovom članu?" + "Uklanja se zabrana korisniku %1$s" + diff --git a/features/roommembermoderation/impl/src/main/res/values-ro/translations.xml b/features/roommembermoderation/impl/src/main/res/values-ro/translations.xml index 4811b5263f..9f21c8d351 100644 --- a/features/roommembermoderation/impl/src/main/res/values-ro/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-ro/translations.xml @@ -4,10 +4,12 @@ "Interzicere" "Nu se vor putea alătura din nou acestei camere dacă sunt invitați." "Sunteți sigur că doriți să interziceți acest membru?" + "Nu vor putea să se alăture din nou acestui spațiu dacă sunt invitați, dar își vor păstra în continuare calitatea de membru al oricăror camere sau subspații." "Se interzice %1$s" "Îndepărtați" "Se vor putea alătura din nou acestei săli dacă sunt invitați." "Sunteți sigur că doriți să îndepărtați acest membru?" + "Vor putea să se alăture din nou acestui spațiu dacă sunt invitați și își vor păstra în continuare calitatea de membru al oricăror camere sau subspații." "Vizualizare profil" "Înlăturați membrul" "Înlăturați membrul și interziceți-i să se alăture în viitor?" diff --git a/features/securebackup/impl/src/main/res/values-hr/translations.xml b/features/securebackup/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..dcdfe830a7 --- /dev/null +++ b/features/securebackup/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,70 @@ + + + "Brisanje pohrane ključeva" + "Uključivanje sigurnosnog kopiranja" + "Sigurno pohranite svoj kriptografski identitet i ključeve poruka na poslužitelju. To će vam omogućiti pregled povijesti poruka na svim novim uređajima. %1$s." + "Pohrana ključeva" + "Za postavljanje oporavka mora biti uključena pohrana ključeva." + "Prenesi ključeve s ovog uređaja" + "Dopusti pohranu ključeva" + "Promjena ključa za oporavak" + "Ako ste izgubili sve postojeće uređaje, oporavite svoj kriptografski identitet i povijest poruka pomoću ključa za oporavak." + "Unesi ključ za oporavak" + "Vaša pohrana ključeva trenutačno nije sinkronizirana." + "Postavljanje oporavka" + "Pristupite svojim šifriranim porukama ako se odjavite iz aplikacije s%1$s sa svih uređaja ili ih izgubite." + "Otvorite %1$s na stolnom uređaju" + "Ponovno se prijavite na svoj račun" + "Kada se od vas zatraži da potvrdite svoj uređaj, odaberite %1$s" + "“Poništi sve”" + "Pridržavajte se uputa za izradu novog ključa za oporavak" + "Spremite svoj novi ključ za oporavak u upravitelj zaporki ili šifriranu bilješku" + "Resetirajte šifriranje za svoj račun pomoću drugog uređaja" + "Nastavi s poništavanjem" + "Sačuvat će se podatci o vašem računu, kontakti, postavke i popis razgovora" + "Izgubit ćete svu povijest poruka koja je pohranjena samo na poslužitelju" + "Morat ćete ponovno potvrditi sve svoje postojeće uređaje i kontakte" + "Poništite svoj identitet samo ako nemate pristup drugom prijavljenom uređaju i ako ste izgubili ključ za oporavak." + "Ne možete potvrditi? Morat ćete poništiti svoj identitet." + "Isključi" + "Izgubit ćete šifrirane poruke ako se odjavite sa svih uređaja." + "Jeste li sigurni da želite isključiti sigurnosno kopiranje?" + "Brisanjem pohrane ključeva uklonit ćete svoj kriptografski identitet i ključeve poruka s poslužitelja te isključiti sljedeće sigurnosne značajke:" + "Na novim uređajima nećete imati šifriranu povijest poruka" + "Ako se odjavite iz aplikacije %1$s na svim uređajima, izgubit ćete pristup svojim šifriranim porukama." + "Jeste li sigurni da želite isključiti pohranu ključeva i izbrisati je?" + "Izradite novi ključ za oporavak ako ste izgubili postojeći. Nakon promjene ključa za oporavak, prijašnji više neće funkcionirati." + "Generiraj novi ključ za oporavak" + "Ne dijelite ovo ni s kim!" + "Ključ za oporavak je promijenjen" + "Želite li promijeniti ključ za oporavak?" + "Izradi novi ključ za oporavak" + "Pazite da nitko ne vidi ovaj zaslon!" + "Pokušajte ponovno potvrditi pristup pohrani ključeva." + "Neispravan ključ za oporavak" + "Ako imate sigurnosni ključ ili sigurnosnu frazu, i ovo će funkcionirati." + "Unos…" + "Izgubili ste ključ za oporavak?" + "Ključ za oporavak je potvrđen" + "Unesite svoj ključ za oporavak" + "Kopirani ključ za oporavak" + "Generiranje…" + "Spremi ključ za oporavak" + "Zapišite ovaj ključ za oporavak i čuvajte ga na sigurnom mjestu, poput upravitelja zaporki, šifrirane bilješke ili fizičkog sefa." + "Dodirnite za kopiranje ključa za oporavak" + "Spremite svoj ključ za oporavak na sigurno mjesto" + "Nakon ovog koraka nećete moći pristupiti svom novom ključu za oporavak." + "Jeste li spremili svoj ključ za oporavak?" + "Vaša pohrana ključeva zaštićena je ključem za oporavak. Ako vam je nakon postavljanja potreban novi ključ za oporavak, možete ga ponovno izraditi odabirom mogućnosti ‘Promijeni ključ za oporavak’." + "Generirajte svoj ključ za oporavak" + "Ne dijelite ovo ni s kim!" + "Postavljanje oporavka je uspjelo" + "Postavljanje oporavka" + "Da, poništi sada" + "Ovaj je proces nepovratan." + "Jeste li sigurni da želite poništiti svoj identitet?" + "Došlo je do nepoznate pogreške. Provjerite je li zaporka vašeg računa ispravna i pokušajte ponovno." + "Unos…" + "Potvrdite da želite poništiti svoj identitet." + "Unesite zaporku računa kako biste nastavili" + diff --git a/features/securityandprivacy/impl/src/main/res/values-da/translations.xml b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml index 46a20980bd..f7ab1b6ce0 100644 --- a/features/securityandprivacy/impl/src/main/res/values-da/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml @@ -1,9 +1,9 @@ - "Du skal bruge en rum-adresse for at gøre den synlig i kataloget." - "Rummets adresse" - "Tilføj adresse på rum" - "Alle kan bede om at deltage i lokalet, men en administrator eller moderator skal acceptere anmodningen." + "Du skal bruge en adresse for at gøre det synligt i det offentlige register." + "Redigér adresse" + "Tilføj adresse" + "Alle skal anmode om adgang." "Spørg om at deltage" "Ja, aktivér kryptering" "Når det først er aktiveret, kan kryptering for et rum ikke deaktiveres igen. Beskedhistorik vil kun være synlig for rummedlemmer, siden de blev inviteret, eller siden de blev medlem af rummet. @@ -13,16 +13,18 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Når kryptering først er aktiveret, kan den ikke deaktiveres igen." "Kryptering" "Aktivér end-to-end-kryptering" - "Alle kan finde og deltage" + "Alle kan være med." "Enhver" - "Andre kan kun deltage, hvis de bliver inviteret" - "Kun med invitation" - "Adgang til rummet" + "Kun inviterede personer kan deltage i dette rum." + "Kun inviterede" + "Adgang" "Medlemmer af gruppen" "Grupper understøttes ikke i øjeblikket" - "Du skal bruge en rum-adresse for at gøre den synlig i kataloget." + "Du skal bruge en adresse for at gøre det synligt i det offentlige register." + "Adresse" "Tillad, at dette rum kan findes ved at søge i %1$s fortegnelse over offentlige rum" - "Synlig i det offentlige register over rum" + "Gør det muligt at blive fundet ved søgninger i det offentlige register." + "Synlig i det offentlige register" "Enhver" "Hvem kan læse historikken?" "Kun medlemmer, efter de blev inviteret" @@ -30,5 +32,6 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Rum-adresser er en måde at finde og få adgang til værelser på. Dette sikrer også, at du nemt kan dele dit rum med andre. Du kan vælge at offentliggøre dit rum i din hjemmeservers offentlige katalog over rum." "Udgivelse af rum" + "Synlighed" "Sikkerhed og privatliv" diff --git a/features/securityandprivacy/impl/src/main/res/values-en-rUS/translations.xml b/features/securityandprivacy/impl/src/main/res/values-en-rUS/translations.xml new file mode 100644 index 0000000000..9a4b56e287 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-en-rUS/translations.xml @@ -0,0 +1,5 @@ + + + "Anyone in authorized spaces can join, but everyone else must request access." + "Anyone in authorized spaces can join." + diff --git a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml index c78857389f..f6986ce49b 100644 --- a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml @@ -3,8 +3,10 @@ "Selleks, et jututuba oleks nähtav jututubade avalikus kataloogis, vajab ta aadressi." "Muuda aadressi" "Lisa aadress" + "Liituda saavad kõik volitatud kogukondade liikmed, kuid kõik teised peavad küsima võimalust ligipääsuks." "Kõik võivad paluda jututoaga liitumist." "Küsi võimalust liitumiseks" + "Liituda saavad kõik „%1$s“ kogukonna liikmed, kuid kõik teised peavad küsima võimalust ligipääsuks." "Jah, lülita krüptimine sisse" "Kui jututoa krüptimine on kord sisse lülitatud, siis seda välja lülitada ei saa. Sõnumite ajalugu on nähtav vaid jututoa liikmetele alates kutse saamise või liitumise hetkest. Keegi teine peale jututoa liikmete ei saa sõnumeid lugeda. See võib takistada suhtlusrobotite ja/või võrgusildade toimimist. @@ -15,10 +17,13 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Võta läbiv krüptimine kasutusele" "Kõik võivad jututoaga liituda" "Kõik" + "Vali kogukonnad, mille liikmed saavad selle jututoaga liituda ilma kutseta. %1$s" "Halda kogukondi" "Liituda saab vaid kutse olemasolul" "Vaid kutsega" "Ligipääs" + "Liituda saavad kõik volitatud kogukondade liikmed." + "Liituda võivad kõik „%1$s“ liikmed." "Kogukonna liikmed" "Kogukondade tugi veel puudub" "Selleks, et jututuba oleks nähtav jututubade avalikus kataloogis, vajab ta aadressi." @@ -33,6 +38,7 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada. Lisaks võid sa jututoa avaldada oma koduserveri avalikus jututubade kataloogis." "Jututoa avaldamine" + "Aadressid on mugav viis jututubade ja kogukondade leidmiseks ning tagab mugava võimaluse nende jagamiseks." "Nähtavus" "Turvalisus ja privaatsus" diff --git a/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..02fada87db --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,44 @@ + + + "Trebat će vam adresa kako bi bila vidljiva u javnom direktoriju." + "Uredi adresu" + "Dodaj adresu" + "Svatko tko se nalazi u ovlaštenim prostorima može se pridružiti, ali svi ostali moraju zatražiti pristup." + "Svi moraju zatražiti pristup." + "Zatraži pridruživanje" + "Svatko u %1$s može se pridružiti, ali svi ostali moraju zatražiti pristup." + "Da, omogući šifriranje" + "Nakon što se šifriranje za sobu omogući, više se neće moći onemogućiti. Povijest poruka bit će vidljiva samo članovima sobe otkad su pozvani ili otkad su joj se pridružili. +Nitko osim članova sobe neće moći čitati poruke. Zbog toga botovi i mostovi možda neće ispravno funkcionirati. +Ne preporučujemo omogućavanje šifriranja za sobe koje svatko može pronaći i pridružiti im se." + "Želite li omogućiti šifriranje?" + "Nakon što se šifriranje omogući, više se neće moći onemogućiti." + "Šifriranje" + "Omogući sveobuhvatno šifriranje" + "Svatko se može pridružiti." + "Svatko" + "Odaberite iz kojih se prostora članovi mogu pridružiti ovoj sobi bez pozivnice. %1$s" + "Upravljaj prostorima" + "Samo pozvane osobe mogu se pridružiti." + "Samo s pozivnicom" + "Pristup" + "Svatko tko se nalazi u ovlaštenim prostorima može se pridružiti." + "Svatko u %1$s može se pridružiti." + "Članovi prostora" + "Prostori trenutačno nisu podržani" + "Trebat će vam adresa kako bi bila vidljiva u javnom direktoriju." + "Adresa" + "Omogući pronalazak ove sobe pretraživanjem %1$s javnog direktorija soba" + "Omogući pronalazak pretraživanjem javnog direktorija." + "Vidljivo u javnom direktoriju" + "Svatko" + "Tko zna čitati povijest" + "Samo za članove nakon što su pozvani" + "Samo za članove nakon što se odabere ova mogućnost" + "Adrese soba služe za pronalaženje i pristup sobama. Time se također osigurava jednostavno dijeljenje sobe s drugim korisnicima. +Možete odabrati objavljivanje svoje sobe u javnom direktoriju soba na matičnom poslužitelju." + "Objavljivanje sobe" + "Adrese služe za pronalaženje soba i prostora te pristup njima. Tako ih ujedno možete jednostavno dijeliti s drugima." + "Vidljivost" + "Sigurnost i privatnost" + diff --git a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml index 213e35562d..8c3dabd163 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml @@ -1,10 +1,12 @@ - "Veți avea nevoie de o adresă de cameră pentru a o face vizibilă în director." - "Adresa camerei" - "Adăugați adresa camerei" - "Oricine poate cere să se alăture camerei, dar un administrator sau moderator va trebui să accepte cererea." + "Veți avea nevoie de o adresă pentru a o face vizibilă în directorul public." + "Editați adresa" + "Adăugați o adresă" + "Oricine se află în spațiile autorizate se poate alătura, dar toți ceilalți trebuie să solicite accesul." + "Toată lumea trebuie să solicite acces." "Cereți să vă alăturați" + "Oricine în %1$s se poate alătura, dar toți ceilalți trebuie să solicite acces." "Da, activați criptarea" "Odată activată, criptarea pentru o cameră nu poate fi dezactivată. Mesajele anterioare vor fi vizibile numai pentru membrii camerei de la momentul la care au fost invitați sau de la momentul la care s-au alăturat camerei. Nimeni în afară de membrii camerei nu va putea citi messaje. Acest lucru poate împiedica funcționarea corectă a boților și a punților. @@ -13,15 +15,21 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Odată activată, criptarea nu poate fi dezactivată." "Criptare" "Activați criptarea end-to-end" - "Oricine poate găsi și alătura camerei" + "Oricine se poate alătura." "Oricine" - "Persoanele se pot alătura numai dacă invitate" + "Alegeți membrii căror spații se pot alătura acestei camere fără invitație. %1$s" + "Gestionați spațiile" + "Doar persoanele invitate se pot alătura." "Doar pe bază de invitație" - "Acces la cameră" + "Acces" + "Oricine se află într-un spațiu autorizat poate participa." + "Oricine din %1$s se poate alătura." "Membrii spațiului" "Spațiile nu sunt momentan suportate." - "Veți avea nevoie de o adresă de cameră pentru a o face vizibilă în director." + "Veți avea nevoie de o adresă pentru a o face vizibilă în directorul public." + "Adresă" "Permiteți găsirea acestei camere prin căutarea în directorul de camere publice al %1$s" + "Permiteți găsirea prin căutarea în directorul public." "Vizibilă în directorul de camere publice" "Oricine" "Cine poate citi mesajele anterioare" @@ -30,5 +38,7 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Adresele camerelor sunt modalități de a găsi și accesa camere. Acest lucru vă asigură, de asemenea, că puteți partaja cu ușurință camera dumneavoastră cu alte persoane. Puteți alege să publicați camera în directorul public al camerelor serverului dumneavoastră." "Publicare cameră" + "Adresele sunt o modalitate de a găsi și accesa camere și spații. Acest lucru asigură, de asemenea, că le puteți partaja cu ușurință cu alții." + "Vizibilitate" "Securitate & confidențialitate" diff --git a/features/securityandprivacy/impl/src/main/res/values/localazy.xml b/features/securityandprivacy/impl/src/main/res/values/localazy.xml index f6236edb8b..374cf94870 100644 --- a/features/securityandprivacy/impl/src/main/res/values/localazy.xml +++ b/features/securityandprivacy/impl/src/main/res/values/localazy.xml @@ -3,7 +3,7 @@ "You’ll need an address in order to make it visible in the public directory." "Edit address" "Add address" - "Anyone in authorized spaces can join, but everyone else must request access." + "Anyone in authorised spaces can join, but everyone else must request access." "Everyone must request access." "Ask to join" "Anyone in %1$s can join, but everyone else must request access." @@ -22,7 +22,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Only invited people can join." "Invite only" "Access" - "Anyone in authorized spaces can join." + "Anyone in authorised spaces can join." "Anyone in %1$s can join." "Space members" "Spaces are not currently supported" diff --git a/features/signedout/impl/src/main/res/values-hr/translations.xml b/features/signedout/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..17af7626b1 --- /dev/null +++ b/features/signedout/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,8 @@ + + + "Promijenili ste zaporku u drugoj sesiji" + "Izbrisali ste sesiju iz druge sesije" + "Administrator vašeg poslužitelja poništio je vaš pristup" + "Možda ste odjavljeni iz jednog od razloga navedenih u nastavku. Ponovno se prijavite kako biste nastavili koristiti %s." + "Odjavljeni ste" + diff --git a/features/space/impl/src/main/res/values-hr/translations.xml b/features/space/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..9babbb3d69 --- /dev/null +++ b/features/space/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,17 @@ + + + "%1$s (administrator)" + + "Napusti %1$d sobu i prostor" + "Napusti %1$d sobe i prostor" + "Napusti %1$d soba i prostor" + + "Odaberite sobe koje želite napustiti, a za koje niste jedini administrator:" + "Morate dodijeliti drugog administratora za ovaj prostor prije nego što ga napustite." + "Nećete biti uklonjeni iz sljedećih soba jer ste jedini administrator:" + "Želite li napustiti %1$s?" + "Vi ste jedini administrator za %1$s" + "Napusti prostor" + "Uloge i dopuštenja" + "Sigurnost i privatnost" + diff --git a/features/startchat/impl/src/main/res/values-hr/translations.xml b/features/startchat/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..8f0407fcde --- /dev/null +++ b/features/startchat/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,12 @@ + + + "Nova soba" + "Direktorij soba" + "Došlo je do pogreške prilikom pokretanja razgovora" + "Pridruži se sobi putem adrese" + "Adresa nije valjana" + "Unos…" + "Pronađena je odgovarajuća soba" + "Soba nije pronađena" + "npr. #naziv-sobe:matrix.org" + diff --git a/features/userprofile/shared/src/main/res/values-hr/translations.xml b/features/userprofile/shared/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..5bfaf99a61 --- /dev/null +++ b/features/userprofile/shared/src/main/res/values-hr/translations.xml @@ -0,0 +1,19 @@ + + + "Blokiraj" + "Blokirani korisnici neće vam moći slati poruke i sve njihove poruke bit će skrivene. Možete ih odblokirati u bilo kojem trenutku." + "Blokiraj korisnika" + "Odblokiraj" + "Moći ćete ponovno vidjeti sve njihove poruke." + "Odblokiraj korisnika" + "Blokiraj" + "Blokirani korisnici neće vam moći slati poruke i sve njihove poruke bit će skrivene. Možete ih odblokirati u bilo kojem trenutku." + "Blokiraj korisnika" + "Profil" + "Odblokiraj" + "Moći ćete ponovno vidjeti sve njihove poruke." + "Odblokiraj korisnika" + "Pomoću mrežne aplikacije provjerite ovog korisnika." + "Provjeri korisnika %1$s" + "Došlo je do pogreške prilikom pokretanja razgovora" + diff --git a/features/verifysession/impl/src/main/res/values-hr/translations.xml b/features/verifysession/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..a2ccb7ce0a --- /dev/null +++ b/features/verifysession/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,54 @@ + + + "Ne možete potvrditi?" + "Izradi novi ključ za oporavak" + "Potvrdite ovaj uređaj kako biste postavili sigurnu razmjenu poruka." + "Potvrdite svoj identitet" + "Upotrijebite drugi uređaj" + "Upotrijebi ključ za oporavak" + "Sada možete sigurno čitati ili slati poruke, a svatko s kim razgovarate također može vjerovati ovom uređaju." + "Uređaj je potvrđen" + "Upotrijebite drugi uređaj" + "Čekanje na drugi uređaj…" + "Nešto nije u redu. Zahtjev je istekao ili je odbijen." + "Potvrdite da se emotikoni u nastavku podudaraju s onima prikazanima na vašem drugom uređaju." + "Usporedi emotikone" + "Potvrdite da se emotikoni u nastavku podudaraju s onima prikazanima na uređaju drugog korisnika." + "Potvrdite da se brojevi u nastavku podudaraju s onima prikazanima na vašoj drugoj sesiji." + "Usporedi brojeve" + "Sada možete sigurno čitati ili slati poruke na svom drugom uređaju." + "Sada možete biti sigurni u vjerodostojnost identiteta ovog korisnika prilikom slanja ili primanja poruka." + "Uređaj je potvrđen" + "Unesi ključ za oporavak" + "Zahtjev je istekao, odbijen je ili je došlo do neusklađenosti u provjeri." + "Dokažite da ste to vi kako biste mogli pristupiti povijesti svojih šifriranih poruka." + "Otvori postojeću sesiju" + "Ponovi provjeru" + "Spreman/na sam." + "Čekanje podudaranja…" + "Usporedite jedinstveni skup emotikona." + "Usporedite jedinstvene emotikone, pazeći pritom da se pojavljuju istim redoslijedom." + "Prijavljen/a" + "Zahtjev je istekao, odbijen je ili je došlo do neusklađenosti u provjeri." + "Provjera nije uspjela" + "Nastavite samo ako ste pokrenuli ovu provjeru." + "Potvrdite drugi uređaj kako biste zaštitili povijest poruka." + "Sada možete sigurno čitati ili slati poruke na svom drugom uređaju." + "Uređaj je potvrđen" + "Zatražena je provjera" + "Ne podudaraju se" + "Podudaraju se" + "Prije nego što odavde započnete provjeru, provjerite jeste li otvorili aplikaciju na drugom uređaju." + "Otvorite aplikaciju na drugom potvrđenom uređaju" + "Radi dodatne sigurnosti potvrdite ovog korisnika tako da usporedite skup emotikona na svojim uređajima. Učinite to koristeći se pouzdanim načinom komunikacije." + "Želite li potvrditi ovog korisnika?" + "Radi dodatne sigurnosti drugi korisnik želi potvrditi vaš identitet. Bit će vam prikazan skup emotikona za usporedbu." + "Trebali biste vidjeti skočni prozor na drugom uređaju. Sada započnite provjeru odatle." + "Započni provjeru na drugom uređaju" + "Započni provjeru na drugom uređaju" + "Čeka se drugi korisnik" + "Nakon prihvaćanja moći ćete nastaviti s potvrđivanjem." + "Prihvatite zahtjev za pokretanje postupka provjere u drugoj sesiji kako biste nastavili." + "Čekanje na prihvaćanje zahtjeva" + "Odjavljivanje…" + diff --git a/libraries/androidutils/src/main/res/values-hr/translations.xml b/libraries/androidutils/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..1e19b4cb89 --- /dev/null +++ b/libraries/androidutils/src/main/res/values-hr/translations.xml @@ -0,0 +1,4 @@ + + + "Nije pronađena kompatibilna aplikacija za izvršavanje ove radnje." + diff --git a/libraries/dateformatter/impl/src/main/res/values-hr/translations.xml b/libraries/dateformatter/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..f70800fcd0 --- /dev/null +++ b/libraries/dateformatter/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,5 @@ + + + "%1$s u %2$s" + "Ovaj mjesec" + diff --git a/libraries/eventformatter/impl/src/main/res/values-hr/translations.xml b/libraries/eventformatter/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..50ca735d50 --- /dev/null +++ b/libraries/eventformatter/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,73 @@ + + + "(promijenjen je i avatar)" + "%1$s promijenio/la je svoj avatar" + "Promijenili ste svoj avatar" + "%1$s degradiran/a je u člana" + "%1$s degradiran/a je u moderatora" + "%1$s promijenio/la je svoje ime za prikaz s %2$s na %3$s" + "Promijenili ste svoje ime za prikaz s %1$s na %2$s" + "%1$s uklonio/la je svoje ime za prikaz (bilo je %2$s)" + "Uklonili ste svoje ime za prikaz (bilo je %1$s)" + "%1$s postavio/la je svoje ime za prikaz na %2$s" + "Postavili ste svoje ime za prikaz na %1$s" + "%1$s promaknut/a je u administratora" + "%1$s promaknut/a je u moderatora" + "%1$s promijenio/la je avatar sobe" + "Promijenili ste avatar sobe" + "%1$s uklonio/la je avatar sobe" + "Uklonili ste avatar sobe" + "%1$s zabranio/la je pristup za %2$s" + "Zabranili ste pristup korisniku %1$s" + "Zabranili ste pristup korisniku %1$s: %2$s" + "%1$s zabranio/la je pristup korisniku %2$s: %3$s" + "%1$s stvorio/la je sobu" + "Stvorili ste sobu" + "%1$s je pozvao/la %2$s" + "%1$s prihvatio/la je poziv" + "Prihvatili ste poziv" + "Pozvali ste %1$s" + "%1$s vas je pozvao/la" + "%1$s pridružio/la se sobi" + "Pridružili ste se sobi" + "%1$s zatražio/la je pridruživanje sobi" + "Korisniku %1$s odobren je pristup sobi %2$s" + "Dopustili ste korisniku %1$s da se pridruži" + "Zatražili ste pridruživanje sobi" + "%1$s odbio/la je zahtjev za pridruživanje korisnika %2$s" + "Odbili ste zahtjev za pridruživanje korisnika %1$s" + "%1$s odbio/la je vaš zahtjev za pridruživanje" + "Korisnik %1$s više nije zainteresiran za pridruživanje" + "Otkazali ste zahtjev za pridruživanje" + "%1$s napustio/la je sobu" + "Napustili ste sobu" + "%1$s promijenio/la je naziv sobe u: %2$s" + "Promijenili ste naziv sobe u: %1$s" + "%1$s uklonio/la je naziv sobe" + "Uklonili ste naziv sobe" + "%1$s nije izvršio/la nikakve promjene" + "Niste izvršili nikakve promjene" + "%1$s promijenio/la je prikvačene poruke" + "Promijenili ste prikvačene poruke" + "%1$s prikvačio/la je poruku" + "Prikvačili ste poruku" + "%1$s otkvačio/la je poruku" + "Otkvačili ste poruku" + "%1$s odbio/la je poziv" + "Odbili ste poziv" + "%1$s uklonio/la je %2$s" + "Uklonili ste %1$s" + "Uklonili ste korisnika %1$s: %2$s" + "%1$s uklonio/la je korisnika %2$s: %3$s" + "%1$s poslao/la je pozivnicu za pridruživanje sobi korisniku %2$s" + "Poslali ste pozivnicu za pridruživanje sobi korisniku %1$s" + "%1$s povukao/la je poziv za pridruživanje sobi korisniku %2$s" + "Povukli ste poziv za pridruživanje sobi korisniku %1$s" + "%1$s promijenio/la je temu na: %2$s" + "Promijenili ste temu na: %1$s" + "%1$s uklonio/la je temu sobe" + "Uklonili ste temu sobe" + "%1$s uklonio/la je zabranu pristupa za %2$sban" + "Uklonili ste zabranu pristupa za %1$s" + "%1$s napravio/la je nepoznatu promjenu u svom članstvu" + diff --git a/libraries/matrixui/src/main/res/values-hr/translations.xml b/libraries/matrixui/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..333d8fd7b7 --- /dev/null +++ b/libraries/matrixui/src/main/res/values-hr/translations.xml @@ -0,0 +1,7 @@ + + + "Pošalji pozivnicu" + "Želite li započeti razgovor s korisnikom %1$s?" + "Želite li poslati pozivnicu?" + "Pozvao vas je korisnik %1$s (%2$s)" + diff --git a/libraries/mediaviewer/impl/src/main/res/values-hr/translations.xml b/libraries/mediaviewer/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..7637fbf350 --- /dev/null +++ b/libraries/mediaviewer/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,21 @@ + + + "Ova će se datoteka ukloniti iz sobe i članovi joj neće moći pristupiti." + "Želite li izbrisati datoteku?" + "Provjerite internetsku vezu i pokušajte ponovno." + "Ovdje će se prikazati dokumenti, audiodatoteke i glasovne poruke prenesene u ovu sobu." + "Još nema prenesenih datoteka" + "Učitavanje datoteka…" + "Učitavanje medija…" + "Datoteke" + "Mediji" + "Ovdje će se prikazati slike i videozapisi preneseni u ovu sobu." + "Još nijedan medij nije prenesen" + "Mediji i datoteke" + "Oblik datoteke" + "Naziv datoteke" + "Nema više datoteka za prikaz" + "Nema više medijskih sadržaja za prikaz" + "Prenio/la" + "Preneseno na" + diff --git a/libraries/permissions/api/src/main/res/values-hr/translations.xml b/libraries/permissions/api/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..e300660d59 --- /dev/null +++ b/libraries/permissions/api/src/main/res/values-hr/translations.xml @@ -0,0 +1,7 @@ + + + "Kako biste aplikaciji omogućili korištenje kamere, dajte dopuštenje u postavkama sustava." + "Dajte dopuštenje u postavkama sustava." + "Kako biste aplikaciji omogućili korištenje mikrofona, dajte dopuštenje u postavkama sustava." + "Kako biste aplikaciji omogućili prikaz obavijesti, dajte dopuštenje u postavkama sustava." + diff --git a/libraries/permissions/impl/src/main/res/values-hr/translations.xml b/libraries/permissions/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..e0efeca8b2 --- /dev/null +++ b/libraries/permissions/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,5 @@ + + + "Provjerite može li aplikacija prikazivati ​​obavijesti." + "Provjeri dopuštenja" + diff --git a/libraries/push/impl/src/main/res/values-da/translations.xml b/libraries/push/impl/src/main/res/values-da/translations.xml index a5b23fc7ba..5f16a8cf8a 100644 --- a/libraries/push/impl/src/main/res/values-da/translations.xml +++ b/libraries/push/impl/src/main/res/values-da/translations.xml @@ -13,6 +13,7 @@ "%d notifikation" "%d notifikationer" + "UnifiedPush-push notification-distributøren kunne ikke registreres, så du vil ikke længere modtage notifikationer. Kontrollér appens notifikationsindstillinger og push-distributørens status." "Du har nye beskeder." "📹 Indgående opkald" "** Kunne ikke sende - åbn venligst rummet" diff --git a/libraries/push/impl/src/main/res/values-en-rUS/translations.xml b/libraries/push/impl/src/main/res/values-en-rUS/translations.xml new file mode 100644 index 0000000000..95c732ea03 --- /dev/null +++ b/libraries/push/impl/src/main/res/values-en-rUS/translations.xml @@ -0,0 +1,4 @@ + + + "Background synchronization" + diff --git a/libraries/push/impl/src/main/res/values-et/translations.xml b/libraries/push/impl/src/main/res/values-et/translations.xml index 24a355ed1e..980129d748 100644 --- a/libraries/push/impl/src/main/res/values-et/translations.xml +++ b/libraries/push/impl/src/main/res/values-et/translations.xml @@ -38,6 +38,8 @@ "%1$s saatis sulle kutse jututoaga liitumiseks" "Mina" "%1$s mainis või vastas" + "Kutsus sind liituma kogukonnaga" + "%1$s kutsus sind liituma kogukonnaga" "See ongi teavitus! Klõpsi mind!" "Jutulõng „%1$s“ jututoas" "%1$s: %2$s" diff --git a/libraries/push/impl/src/main/res/values-hr/translations.xml b/libraries/push/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..86c458dbf9 --- /dev/null +++ b/libraries/push/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,105 @@ + + + "Poziv" + "Osluškivanje događaja" + "Glasne obavijesti" + "Pozivi (telefon zvoni)" + "Tihe obavijesti" + + "%1$s: %2$d poruka" + "%1$s: %2$d poruke" + "%1$s: %2$d poruka" + + + "%d obavijest" + "%d obavijesti" + "%d obavijesti" + + "Distributer obavijesti UnifiedPush nije mogao biti registriran, tako da više nećete primati obavijesti. Provjerite postavke obavijesti u aplikaciji i status distributera push obavijesti." + "Imate nove poruke." + "📹 Dolazni poziv" + "** Slanje nije uspjelo – otvorite sobu" + "Pridruži se" + "Odbij" + + "%d pozivnica" + "%d pozivnice" + "%d pozivnica" + + "Pozvao/la te na razgovor" + "%1$s pozvao/la te na razgovor" + "Korisnik vas je spomenuo: %1$s" + "Nove poruke" + + "%d nova poruka" + "%d nove poruke" + "%d novih poruka" + + "Reagirao/la je s %1$s" + "Označi kao pročitano" + "Brzi odgovor" + "Pozvao/la te je da se pridružiš sobi" + "%1$s pozvao/la te da se pridružiš sobi" + "Ja" + "%1$s je spomenuo/la ili odgovorio/la" + "Pozvao/la vas je da se pridružite prostoru" + "%1$s pozvao/la vas je da se pridružite prostoru" + "Gledate obavijest! Kliknite me!" + "Nit u %1$s" + "%1$s: %2$s" + "%1$s: %2$s %3$s" + + "%d nepročitana poruka s obavijesti" + "%d nepročitane poruke s obavijesti" + "%d nepročitanih poruka s obavijesti" + + "%1$s i %2$s" + "%1$s u %2$s" + "%1$s u %2$s i %3$s" + + "%d soba" + "%d sobe" + "%d soba" + + "Sinkronizacija u pozadini" + "Googleove usluge" + "Nisu pronađene valjane usluge Google Play. Obavijesti možda neće ispravno funkcionirati." + "Provjera blokiranih korisnika" + "Prikaži blokirane korisnike" + "Nijedan korisnik nije blokiran." + + "Blokirali ste %1$d korisnika. Nećete primati obavijesti za ovog korisnika." + "Blokirali ste %1$d korisnika. Nećete primati obavijesti za te korisnike." + "Blokirali ste %1$d korisnika. Nećete primati obavijesti za te korisnike." + + "Blokirani korisnici" + "Dohvatite naziv trenutačnog pružatelja." + "Nije odabran nijedan pružatelj push obavijesti." + "Trenutačni pružatelj push obavijesti je %1$s i trenutačni distributer je %2$s. Ali distributer %3$s nije pronađen. Možda je aplikacija deinstalirana?" + "Trenutačni pružatelj push obavijesti je %1$s, ali nijedan distributer nije konfiguriran." + "Trenutačni pružatelj push obavijesti: %1$s ." + "Trenutačni pružatelj push obavijesti: %1$s (%2$s)" + "Trenutačni pružatelj push obavijesti" + "Provjerite podržava li aplikacija barem jednog pružatelja push obavijesti" + "Nije pronađena podrška za pružatelja push obavijesti." + + "Pronađen je %1$d pružatelj push obavijesti: %2$s" + "Pronađena su %1$d pružatelja push obavijesti: %2$s" + "Pronađeno je %1$d pružatelja push obavijesti: %2$s" + + "Aplikacija je razvijena s podrškom za: %1$s" + "Podrška za pružatelja push obavijesti" + "Provjerite može li aplikacija prikazivati ​​obavijesti." + "Obavijest nije kliknuta." + "Obavijest nije moguće prikazati." + "Obavijest je kliknuta!" + "Prikaz obavijesti" + "Kliknite na obavijest za nastavak testa." + "Provjerite prima li aplikacija push obavijesti." + "Pogreška: sustav za push obavijesti odbio je zahtjev." + "Pogreška: %1$s ." + "Pogreška, nije moguće testirati push obavijesti." + "Pogreška, isteklo je vrijeme čekanja na push obavijest." + "Povratna push obavijest trajala je %1$d ms." + "Testiraj povratnu push obavijest" + diff --git a/libraries/push/impl/src/main/res/values-ro/translations.xml b/libraries/push/impl/src/main/res/values-ro/translations.xml index 7a5bcf2f06..0a83e6afad 100644 --- a/libraries/push/impl/src/main/res/values-ro/translations.xml +++ b/libraries/push/impl/src/main/res/values-ro/translations.xml @@ -13,6 +13,7 @@ "%d notificare" "%d notificări" + "Distribuitorul de notificări UnifiedPush nu a putut fi înregistrat, așadar nu veți mai primi notificări. Verificați setările de notificări ale aplicației și starea distribuitorului push." "Aveți mesaje noi" "Apel primit" "** Trimiterea eșuată - vă rugăm să deschideți camera" @@ -37,7 +38,10 @@ "%1$s v-a invitat să vă alăturați camerei" "Eu" "%1$s v-a menționat sau răspuns" + "V-a invitat să vă alăturați spațiului" + "%1$s v-a invitat să vă alăturați spațiului" "Vizualizați o notificare! Faceți clic pe mine!" + "Fir în: %1$s" "%1$s: %2$s" "%1$s: %2$s %3$s" diff --git a/libraries/push/impl/src/main/res/values/localazy.xml b/libraries/push/impl/src/main/res/values/localazy.xml index 79e50a8e65..aac5c6c72b 100644 --- a/libraries/push/impl/src/main/res/values/localazy.xml +++ b/libraries/push/impl/src/main/res/values/localazy.xml @@ -55,7 +55,7 @@ "%d room" "%d rooms" - "Background synchronization" + "Background synchronisation" "Google Services" "No valid Google Play Services found. Notifications may not work properly." "Checking blocked users" diff --git a/libraries/pushproviders/firebase/src/main/res/values-hr/translations.xml b/libraries/pushproviders/firebase/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..026949086d --- /dev/null +++ b/libraries/pushproviders/firebase/src/main/res/values-hr/translations.xml @@ -0,0 +1,11 @@ + + + "Provjerite je li Firebase dostupan." + "Firebase nije dostupan." + "Firebase je dostupan." + "Provjeri Firebase" + "Provjerite je li Firebaseov token dostupan." + "Firebaseov token nije poznat." + "Firebaseov token: %1$s." + "Provjeri Firebaseov token" + diff --git a/libraries/pushproviders/unifiedpush/src/main/res/values-hr/translations.xml b/libraries/pushproviders/unifiedpush/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..a77fcce68c --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/main/res/values-hr/translations.xml @@ -0,0 +1,11 @@ + + + "Provjerite jesu li UnifiedPush distributeri dostupni." + "Nisu pronađeni distributeri push obavijesti." + + "Pronađen je %1$d distributer: %2$s." + "Pronađena su %1$d distributera: %2$s." + "Pronađeno je %1$d distributera: %2$s." + + "Provjeri UnifiedPush" + diff --git a/libraries/textcomposer/impl/src/main/res/values-hr/translations.xml b/libraries/textcomposer/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..2b116627fb --- /dev/null +++ b/libraries/textcomposer/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,33 @@ + + + "Dodaj privitak" + "Uključi/isključi popis s grafičkim oznakama" + "Otkaži i zatvori oblikovanje teksta" + "Uključi/isključi blok koda" + "Dodaj opis" + "Šifrirana poruka…" + "Poruka…" + "Nešifrirana poruka…" + "Izradi poveznicu" + "Uredi poveznicu" + "%1$s, stanje: %2$s" + "Primijeni podebljano" + "Primijeni kurziv" + "onemogućen" + "isključen" + "uključen" + "Primijeni precrtavanje" + "Primijeni podcrtavanje" + "Uključi/isključi prikaz na cijelom zaslonu" + "Uvlaka" + "Primijeni kod u retku" + "Postavi poveznicu" + "Uključi/isključi numerirani popis" + "Otvori mogućnosti sastavljanja" + "Uključi/isključi citat" + "Ukloni poveznicu" + "Poništi uvlaku" + "Poveznica" + "Opisi možda neće biti vidljivi osobama koji se služe starijim aplikacijama." + "Držite za snimanje" + diff --git a/libraries/troubleshoot/impl/src/main/res/values-hr/translations.xml b/libraries/troubleshoot/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..a39bf5d2ad --- /dev/null +++ b/libraries/troubleshoot/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,12 @@ + + + "Povijest push obavijesti" + "Pokreni testove" + "Ponovno pokreni testove" + "Neki testovi nisu uspjeli. Provjerite pojedinosti." + "Pokrenite testove kako biste otkrili bilo kakve probleme u konfiguraciji koji bi mogli uzrokovati da se obavijesti ne ponašaju kako se očekuje." + "Pokušaj popravka" + "Svi testovi uspješno su izvedeni." + "Rješavanje problema s obavijestima" + "Neki testovi zahtijevaju vašu pažnju. Provjerite pojedinosti." + 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 6de4dc7ebd..7d58b7bfb6 100644 --- a/libraries/ui-strings/src/main/res/values-da/translations.xml +++ b/libraries/ui-strings/src/main/res/values-da/translations.xml @@ -445,6 +445,10 @@ Er du sikker på, at du vil fortsætte?" "Din besked blev ikke sendt, fordi %1$s ikke har bekræftet alle enheder" "En eller flere af dine enheder er ikke verificeret. Du kan sende beskeden alligevel, eller du kan annullere for nu og prøve igen senere, når du har verificeret alle dine enheder." "Din besked blev ikke sendt, fordi du ikke har verificeret en eller flere af dine enheder" + "Skift indstillinger" + "Administrér gruppe" + "Administrer rum" + "Tilladelser" "Rediger administratorer eller ejere" "Det lykkedes ikke at behandle medier til upload. Prøv venligst igen." "Kunne ikke hente brugeroplysninger" diff --git a/libraries/ui-strings/src/main/res/values-en-rUS/translations.xml b/libraries/ui-strings/src/main/res/values-en-rUS/translations.xml index 00d2674ed7..2fc2fb0889 100644 --- a/libraries/ui-strings/src/main/res/values-en-rUS/translations.xml +++ b/libraries/ui-strings/src/main/res/values-en-rUS/translations.xml @@ -1,6 +1,8 @@ + "Minimize message text field" "Minimize" "Favorite" "Favorited" + "This room has been configured so that new members can read history. %1$s" diff --git a/libraries/ui-strings/src/main/res/values-et/translations.xml b/libraries/ui-strings/src/main/res/values-et/translations.xml index e729286ee5..593fc9af11 100644 --- a/libraries/ui-strings/src/main/res/values-et/translations.xml +++ b/libraries/ui-strings/src/main/res/values-et/translations.xml @@ -156,6 +156,7 @@ "Jäta vahele" "Alusta" "Alusta vestlust" + "Alusta uuesti" "Alusta verifitseerimist" "Kaardi laadimiseks klõpsa" "Tee pilt" @@ -372,6 +373,7 @@ Põhjus: %1$s." "Ootame…" "Ootame selle sõnumi dekrüptimisvõtit" "Sina" + "See jututuba on seadistatud sedaviisi, et ka uued liikmed saavad lugeda varasemat ajalugu. %1$s" "Kasutaja %1$s võrguidentiteet on lähtestatud. %2$s" "Kasutaja %1$s %2$s võrguidentiteet on lähtestatud. %3$s" "(%1$s)" @@ -432,10 +434,36 @@ Kas sa oled kindel, et soovid jätkata?" "Valikud" "Kustuta: %1$s" "Seadistused" - "Lauaarvuti" - "Nutiseade" + "Skaneeri QR-koodi" + "Ava %1$s kas oma süle- või lauaarvutis" + "Skaneeri QR-koodi selle seadmega" + "Skaneerimiseks valmis" + "QR-koodi laadimiseks ava %1$s süle- või lauaarvutis" + "Numbrid ei klapi" + "Sisesta kahekohaline kood" + "Sellega verifitseerime, et ühendus sinu teise seadmega on turvaline." + "Sisesta teises seadmes kuvatud number" + "Sinu teenusepakkuja ei toeta rakendust %1$s." + "%1$s pole toetatud" + "Sinu kasutajakonto teenusepakkuja ei toeta võimalust logida sisse QR-koodi abil." + "QR-kood pole toetatud" + "Sisselogimine katkestati teises seadmes." + "Sisselogimispäring on tühistatud" + "Sisselogimine aegus. Palun proovi uuesti." + "Sisselogimine jäi etteantud aja jooksul tegemata" + "Ava %1$s teises seadmes" + "Vali %1$s" + "„Logi sisse QR-koodiga“" + "Skaneeri siin näidatud QR-koodi teise seadmega" + "Ava %1$s teises seadmes" + "Lauaarvuti" + "Laadin QR-koodi…" + "Nutiseade" + "Mis tüüpi seadet soovid siduda?" + "Kogukonnad, milles on võimalik jututoaga liituda ilma kutseta." "Halda kogukondi" "(Tundmatu kogukond)" + "Muud kogukonnad, mille liige sa ei ole" "Sinu kogukonnad" "Meediafaili valimine ei õnnestunud. Palun proovi uuesti." "Siia lisamiseks vajuta sõnumil ja vali „%1$s“." diff --git a/libraries/ui-strings/src/main/res/values-hr/translations.xml b/libraries/ui-strings/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..e350ab9f73 --- /dev/null +++ b/libraries/ui-strings/src/main/res/values-hr/translations.xml @@ -0,0 +1,533 @@ + + + "Dodaj reakciju: %1$s" + "Avatar" + "Minimiziraj tekstno polje poruke" + "Izbriši" + + "%1$d unesena znamenka" + "%1$d unesene znamenke" + "%1$d unesenih znamenaka" + + "Uredi avatar" + "Potpuna adresa bit će %1$s" + "Pojedinosti šifriranja" + "Proširi tekstno polje poruke" + "Sakrij zaporku" + "Pridruži se pozivu" + "Idi na dno" + "Pomakni kartu na moju lokaciju" + "Samo spominjanja" + "Bez zvuka" + "Nova spominjanja" + "Nove poruke" + "Poziv u tijeku" + "Avatar drugog korisnika" + "Stranica %1$d" + "Pauziraj" + "Glasovna poruka, trajanje: %1$s, trenutačno zaustavljeno na: %2$s" + "Polje za PIN" + "Reproduciraj" + "Anketa" + "Završena anketa" + "Reagiraj s %1$s" + "Reagiraj s drugim emotikonima" + "Pročitali %1$s i %2$s" + + "Pročitao %1$s i ostalih %2$d" + "Pročitala %1$s i ostala %2$d" + "Pročitalo %1$s i ostalih %2$d" + + "Pročitao korisnik %1$s" + "Dodirnite za prikaz svih" + "Ukloni reakciju: %1$s" + "Ukloni reakciju s %1$s" + "Avatar sobe" + "Pošalji datoteke" + "Potrebna je vremenski ograničena radnja, imate jednu minutu za potvrdu" + "Prikaži zaporku" + "Započni poziv" + "Soba označena za uklanjanje" + "Korisnički avatar" + "Korisnički izbornik" + "Prikaži avatar" + "Prikaži pojedinosti" + "Glasovna poruka, trajanje: %1$s" + "Snimite glasovnu poruku." + "Zaustavi snimanje" + "Vaš avatar" + "Prihvati" + "Dodaj opis" + "Dodaj na vremensku crtu" + "Natrag" + "Poziv" + "Odustani" + "Otkaži za sada" + "Odaberi fotografiju" + "Očisti" + "Zatvori" + "Dovrši provjeru" + "Potvrdi" + "Potvrdi zaporku" + "Nastavi" + "Kopiraj" + "Kopiraj opis" + "Kopiraj poveznicu" + "Kopiraj poveznicu u poruku" + "Kopiraj tekst" + "Stvori" + "Stvori sobu" + "Deaktiviraj" + "Deaktiviraj račun" + "Odbij" + "Odbij i blokiraj" + "Izbriši anketu" + "Poništi sve odabire" + "Onemogući" + "Odbaci" + "Odbaci" + "Gotovo" + "Uredi" + "Uredi opis" + "Uredi anketu" + "Omogući" + "Završi anketu" + "Unesite PIN" + "Završi" + "Zaboravili ste zaporku?" + "Proslijedi" + "Idi natrag" + "Idi na uloge i dopuštenja" + "Idi na postavke" + "Zanemari" + "Pozovi" + "Pozovi osobe" + "Pozovi osobe u %1$s" + "Pozovi osobe u %1$s" + "Pozivnice" + "Pridruži se" + "Saznajte više" + "Napusti" + "Napusti razgovor" + "Napusti sobu" + "Napusti prostor" + "Učitaj više" + "Upravljanje računom" + "Upravljanje uređajima" + "Poruka" + "Minimiziraj" + "Dalje" + "Ne" + "Ne sada" + "U redu" + "Otvori kontekstni izbornik" + "Postavke" + "Otvori s" + "Prikvači" + "Brzi odgovor" + "Citiraj" + "Reagiraj" + "Odbij" + "Ukloni" + "Ukloni opis" + "Ukloni poruku" + "Odgovori" + "Odgovori u niti" + "Prijavi" + "Prijavi grešku" + "Prijavi sadržaj" + "Prijavi razgovor" + "Prijavi sobu" + "Poništi" + "Poništi identitet" + "Pokušaj ponovno" + "Ponovno pokušaj dešifrirati" + "Spremi" + "Pretraži" + "Odaberi sve" + "Pošalji" + "Pošalji uređenu poruku" + "Pošalji poruku" + "Pošalji glasovnu poruku" + "Podijeli" + "Podijeli poveznicu" + "Prikaži" + "Ponovno se prijavite" + "Odjava" + "Svejedno se odjavi" + "Preskoči" + "Započni" + "Započni razgovor" + "Počni ispočetka" + "Započni provjeru" + "Dodirnite za učitavanje karte" + "Uslikaj" + "Dodirnite za mogućnosti" + "Pokušajte ponovno" + "Otkvači" + "Prikaz" + "Prikaži na vremenskoj traci" + "Prikaži izvor" + "Da" + "Da, pokušaj ponovno" + "Vaš poslužitelj sada podržava novi, brži protokol. Odjavite se i ponovno prijavite da biste odmah izvršili nadogradnju. Ako to sada napravite, izbjeći ćete prisilnu odjavu kada se poslije ukloni stari protokol." + "Dostupna je nadogradnja" + "O aplikaciji" + "Pravilnik o prihvatljivoj upotrebi" + "Dodaj račun" + "Dodaj još jedan račun" + "Dodavanje opisa" + "Napredne postavke" + "slika" + "Analitika" + "Napustili ste sobu" + "Odjavljeni ste iz sesije" + "Izgled" + "Audiozapis" + "Beta" + "Blokirani korisnici" + "Mjehurići" + "Poziv je započeo" + "Sigurnosna kopija razgovora" + "Kopirano u međuspremnik" + "Autorsko pravo" + "Stvaranje sobe…" + "Zahtjev je otkazan" + "Napustio/la je sobu" + "Napušteni prostor" + "Poziv je odbijen" + "Tamno" + "Pogreška kod dešifriranja" + "Opis" + "Mogućnosti za razvojne inženjere" + "ID uređaja" + "Izravni razgovor" + "Ne prikazuj ovo ponovno" + "Preuzimanje nije uspjelo" + "Preuzimanje" + "(uređeno)" + "Uređivanje" + "Uređivanje opisa" + "* %1$s %2$s" + "Prazna datoteka" + "Šifriranje" + "Šifriranje je omogućeno" + "Unesite svoj PIN" + "Pogreška" + "Došlo je do pogreške; možda nećete primati obavijesti za nove poruke. Riješite problem s obavijestima u postavkama. + +Razlog: %1$s ." + "Svi" + "Nije uspjelo" + "Favorit" + "Označeno kao favorit" + "Datoteka" + "Datoteka je izbrisana" + "Datoteka je spremljena" + "Datoteka je spremljena u preuzimanja" + "Proslijedi poruku" + "Često korišteno" + "GIF" + "Slika" + "Kao odgovor osobi %1$s" + "Instaliraj APK" + "Ovaj Matrix ID nije moguće pronaći, pa se pozivnica možda neće primiti." + "Izlazak iz sobe" + "Napuštanje prostora" + "Svijetlo" + "Redak je kopiran u međuspremnik" + "Poveznica je kopirana u međuspremnik." + "Poveži novi uređaj" + "Učitavanje…" + "Učitava se još…" + + "još %d" + "još %d" + "još %d" + + + "%1$d član" + "%1$d člana" + "%1$d članova" + + "Poruka" + "Radnje s porukama" + "Slanje poruke nije uspjelo" + "Izgled poruke" + "Poruka je uklonjena" + "Suvremeni" + "Isključi zvuk" + "Naziv" + "%1$s (%2$s)" + "Nema rezultata" + "Nema naziva sobe" + "Nema naziva prostora" + "Nije šifrirano" + "Izvan mreže" + "Licencije otvorenog koda" + "ili" + "Zaporka" + "Osobe" + "Stalna poveznica" + "Dopuštenje" + "Prikvačeno" + "Provjerite svoju internetsku vezu" + "Pričekajte…" + "Jeste li sigurni da želite završiti ovu anketu?" + "Anketa: %1$s" + "Ukupno glasova: %1$s" + "Rezultati će se objaviti nakon što završi anketa" + + "%d glas" + "%d glasa" + "%d glasova" + + "Priprema…" + "Pravilnik o zaštiti privatnosti" + "Privatna soba" + "Privatni prostor" + "Javna soba" + "Javni prostor" + "Reakcija" + "Reakcije" + "Razlog" + "Ključ za oporavak" + "Osvježavanje…" + + "%1$d odgovor" + "%1$d odgovora" + "%1$d odgovora" + + "Odgovara korisniku %1$s" + "Prijavi pogrešku" + "Prijavi problem" + "Prijava je podnesena" + "Uređivač obogaćenog teksta" + "Soba" + "Naziv sobe" + "npr. naziv vašeg projekta" + + "%1$d soba" + "%1$d sobe" + "%1$d soba" + + "Spremljene promjene" + "Spremanje" + "Zaključavanje zaslona" + "Potraži nekoga" + "Rezultati pretraživanja" + "Sigurnost" + "Vidio/la" + "Odaberi račun" + "Pošalji" + "Slanje…" + "Slanje nije uspjelo" + "Poslano" + ". " + "Poslužitelj nije podržan" + "Poslužitelj nije dostupan" + "URL poslužitelja" + "Postavke" + "Podijeli prostor" + "Podijeljena lokacija" + "Zajednički prostor" + "Odjava je u tijeku" + "Nešto je pošlo po zlu" + "Naišli smo na problem. Pokušajte ponovno." + "Prostor" + "O čemu se radi u ovom prostoru?" + + "%1$d prostor" + "%1$d prostora" + "%1$d prostora" + + "Započinjanje razgovora…" + "Naljepnica" + "Uspjeh" + "Prijedlozi" + "Sinkronizacija" + "Sustav" + "Tekst" + "Obavijesti trećih strana" + "Nit" + "Tema" + "O čemu je ova soba?" + "Nije moguće dešifrirati" + "Poslano s nesigurnog uređaja" + "Nemate pristup ovoj poruci" + "Pošiljateljev potvrđeni identitet je poništen" + "Pozivnice se nisu mogle poslati jednom korisniku ili više njih." + "Nije moguće poslati pozivnicu/e" + "Otključaj" + "Uključi zvuk" + "Nepodržani poziv" + "Nepodržani događaj" + "Korisničko ime" + "Provjera je otkazana" + "Provjera je dovršena" + "Provjera nije uspjela" + "Potvrđeno" + "Provjera uređaja" + "Potvrdi identitet" + "Provjeri korisnika" + "Videozapis" + "Visoka kvaliteta" + "Najbolja kvaliteta, ali veća veličina datoteke" + "Niska kvaliteta" + "Najbrža brzina prijenosa i najmanja veličina datoteke" + "Standardna kvaliteta" + "Ravnoteža kvalitete i brzine prijenosa" + "Glasovna poruka" + "Čekanje…" + "Čekam ovu poruku" + "Vi" + "Ova je soba konfigurirana tako da novi članovi mogu čitati stare poruke. %1$s" + "Identitet korisnika %1$s je poništen. %2$s" + "Identitet korisnika %1$s %2$s je poništen. %3$s" + "(%1$s)" + "Identitet korisnika %1$s je poništen." + "Identitet korisnika %1$s %2$s je poništen. %3$s" + "Povuci provjeru" + "Poveznica %1$s vodi vas na drugo mrežno mjesto %2$s + +Jeste li sigurni da želite nastaviti?" + "Dvaput provjerite ovu poveznicu" + "Odaberite zadanu kvalitetu videozapisa koje prenosite." + "Kvaliteta prijenosa videozapisa" + "Maksimalna dopuštena veličina datoteke je: %1$s" + "Datoteka je prevelika za prijenos" + "Soba je prijavljena" + "Soba je prijavljena i napuštena" + "Potvrda" + "Pogreška" + "Uspjeh" + "Upozorenje" + "Niste spremili sve promjene." + "Vaše promjene nisu spremljene. Jeste li sigurni da se želite vratiti?" + "Želite li spremiti promjene?" + "Maksimalna dopuštena veličina datoteke je: %1$s" + "Odaberite kvalitetu videozapisa koji želite prenijeti." + "Odaberi kvalitetu prijenosa videozapisa" + "Pretraživanje emotikona" + "Već ste prijavljeni na ovom uređaju kao %1$s." + "Vaš matični poslužitelj potrebno je nadograditi kako bi podržavao uslugu Matrix Authentication Service i stvaranje računa." + "Nije uspjelo stvaranje trajne poveznice" + "%1$s nije mogao učitati kartu. Pokušajte ponovno poslije." + "Učitavanje poruka nije uspjelo" + "%1$s nije mogao pristupiti vašoj lokaciji. Pokušajte ponovno poslije." + "Prijenos vaše glasovne poruke nije uspio." + "Soba više ne postoji ili pozivnica više ne vrijedi." + "Poruka nije pronađena" + "%1$s nema dopuštenje za pristup vašoj lokaciji. Pristup možete omogućiti u postavkama." + "%1$s nema dopuštenje za pristup vašoj lokaciji. Omogućite pristup u nastavku." + "%1$s nema dopuštenje za pristup vašem mikrofonu. Omogućite pristup kako biste mogli snimiti glasovnu poruku." + "To može biti zbog problema s mrežom ili poslužiteljem." + "Ova adresa sobe već postoji. Pokušajte urediti polje za adresu sobe ili promijeniti naziv sobe" + "Neki znakovi nisu dopušteni. Podržana su samo slova, brojke i simboli ! $ & ‘ ( ) * + / ; = ? @ [ ] - . _" + "Neke poruke nisu poslane" + "Žao nam je, došlo je do pogreške" + "Pošiljatelj događaja ne podudara se s vlasnikom uređaja koji ga je poslao." + "Autentičnost ove šifrirane poruke ne može se jamčiti na ovom uređaju" + "Šifrirao je prethodno provjereni korisnik." + "Nije šifrirano." + "Šifrirano nepoznatim ili izbrisanim uređajem." + "Šifrirano uređajem koji vlasnik nije potvrdio." + "Šifrirao neprovjereni korisnik." + "🔐️ Pridruži mi se u %1$s" + "Hej, razgovaraj sa mnom u aplikaciji %1$s: %2$s" + "%1$s Android" + "Snažno protresi za prijavu pogreške" + "Snimka zaslona" + "%1$s: %2$s" + "Mogućnosti" + "Ukloni %1$s" + "Postavke" + "Skeniraj QR kod" + "Otvorite %1$s na prijenosnom ili stolnom računalu" + "Skenirajte QR kod ovim uređajem" + "Spremno za skeniranje" + "Otvorite %1$s na stolnom računalu kako biste dobili QR kod" + "Brojevi se ne podudaraju" + "Unesite dvoznamenkasti kod" + "Time ćete potvrditi da je veza s vašim drugim uređajem sigurna." + "Unesite broj prikazan na vašem drugom uređaju" + "Vaš davatelj usluga računa ne podržava %1$s." + "%1$s nije podržan" + "Vaš davatelj usluga računa ne podržava prijavu na novi uređaj pomoću QR koda." + "QR kod nije podržan" + "Prijava je otkazana na drugom uređaju." + "Zahtjev za prijavu je otkazan" + "Prijava je istekla. Pokušajte ponovno." + "Prijava nije dovršena na vrijeme" + "Otvorite %1$s na drugom uređaju" + "Odaberi %1$s" + "“Prijavi se pomoću QR koda”" + "Skenirajte ovdje prikazani QR kod drugim uređajem" + "Otvorite %1$s na drugom uređaju" + "Stolno računalo" + "Učitavanje QR koda…" + "Mobilni uređaj" + "Koju vrstu uređaja želite povezati?" + "Prostori u kojima se članovi mogu pridružiti sobi bez pozivnice." + "Upravljaj prostorima" + "(nepoznati prostor)" + "Drugi prostori čiji niste član" + "Vaši prostori" + "Odabir medija nije uspio, pokušajte ponovno." + "Pritisnite poruku i odaberite “%1$s” kako biste uključili ovdje." + "Prikvačite važne poruke kako bi ih se lakše moglo pronaći" + + "%1$d prikvačena poruka" + "%1$d prikvačene poruke" + "%1$d prikvačenih poruka" + + "Prikvačene poruke" + "Spremate se otići u svoj %1$s račun kako biste poništili identitet. Nakon toga bit ćete vraćeni u aplikaciju." + "Ne možete potvrditi? Idite na svoj račun kako biste poništili svoj identitet." + "Povuci potvrdu i pošalji" + "Možete povući svoju potvrdu i svejedno poslati ovu poruku ili možete za sada otkazati i pokušati ponovno poslije nakon ponovne potvrde korisnika %1$s." + "Vaša poruka nije poslana jer je poništen potvrđeni identitet korisnika %1$s" + "Svejedno pošalji poruku" + "%1$s se služi jednim nepotvrđenim uređajem ili više njih. Možete svejedno poslati poruku ili je za sada otkazati i pokušati ponovno poslije. %2$s je potvrdio/la sve svoje uređaje." + "Vaša poruka nije poslana jer %1$s nije potvrdio sve uređaje" + "Jedan vaš uređaj ili više njih nije potvrđeno. Možete svejedno poslati poruku ili za sada otkazati i pokušati ponovno poslije nakon što potvrdite sve svoje uređaje." + "Vaša poruka nije poslana jer niste potvrdili jedan svoj uređaj ili više njih" + "Promijeni postavke" + "Upravljaj prostorom" + "Upravljaj sobama" + "Dopuštenja" + "Uredi administratore ili vlasnike" + "Prijenos medija za obradu nije uspio, pokušajte ponovno." + "Nije moguće dohvatiti korisničke podatke" + "Poruka u sobi %1$s" + "Proširi" + "Smanji" + "Već gledam ovu sobu!" + "%1$s od %2$s" + "%1$s Prikvačene poruke" + "Učitavanje poruke…" + "Prikaži sve" + "Razgovor" + "Podijeli lokaciju" + "Podijeli moju lokaciju" + "Otvori u Apple Maps" + "Otvori u Google Maps" + "Otvori u OpenStreetMap" + "Podijeli ovu lokaciju" + "Prostori koje ste stvorili ili kojima ste se pridružili." + "%1$s • %2$s" + "Prostor %1$s" + "Prostori" + "Prikaži članove" + "Poruka nije poslana jer je poništen potvrđeni identitet korisnika %1$s." + "Poruka nije poslana jer %1$s nije potvrdio sve uređaje." + "Poruka nije poslana jer niste potvrdili jedan svoj uređaj ili više njih." + "Lokacija" + "Inačica: %1$s (%2$s)" + "hr" + "Prijašnje poruke nisu dostupne na ovom uređaju" + "Trebate potvrditi ovaj uređaj kako biste mogli pristupiti prijašnjim porukama" + "Nemate pristup ovoj poruci" + "Nije moguće dešifrirati poruku" + "Ova je poruka blokirana jer niste potvrdili svoj uređaj ili zato što pošiljatelj treba potvrditi vaš identitet." + diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index 16b0e90b89..203f2f893a 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -97,6 +97,7 @@ "Ați uitat parola?" "Redirecționați" "Înapoi" + "Mergeți la roluri și permisiuni" "Mergeți la setări" "Ignorați" "Invitați" @@ -157,6 +158,7 @@ "Omiteți" "Începeți" "Începeți discuția" + "Începeți din nou" "Începeți verificarea" "Atingeți pentru a încărca harta" "Faceți o fotografie" @@ -235,6 +237,7 @@ Motiv:%1$s." "Deschis" "Linie copiată în clipboard" "Linkul a fost copiat în clipboard" + "Conectați un dispozitiv nou" "Se încarcă…" "Se încarcă…" @@ -249,10 +252,12 @@ Motiv:%1$s." "Mesaj" "Acțiuni mesaj" + "Mesajul nu a putut fi trimis" "Aspectul mesajelor" "Mesaj șters" "Modern" "Dezactivați sunetul" + "Nume" "%1$s (%2$s)" "Niciun rezultat" "Fără nume de cameră" @@ -330,6 +335,7 @@ Motiv:%1$s." "Ceva nu a mers bine" "Am întâmpinat o problemă. Vă rugăm să încercați din nou." "Spațiu" + "Despre ce este vorba în acest spațiu?" "%1$d Spațiu" "%1$d Spații" @@ -375,6 +381,7 @@ Motiv:%1$s." "Se aşteaptă…" "Mesaj în așteptare" "Dumneavoastră" + "Această cameră a fost configurată astfel încât noii membri să poată citi istoricul. %1$s" "Identitatea lui %1$s a fost resetată. %2$s" "Identitatea %2$s a lui %1$s a fost resetată. %3$s" "(%1$s)" @@ -435,6 +442,37 @@ Sunteți sigur că doriți să continuați?" "Opțiuni" "Ștergeți %1$s" "Setări" + "Scanați codul QR" + "Deschide %1$s pe un laptop sau un computer desktop" + "Scanați codul QR cu acest dispozitiv" + "Gata de scanare" + "Deschide %1$s pe un computer desktop pentru a obține codul QR" + "Numerele nu se potrivesc" + "Introduceți codul de 2 cifre" + "Aceasta va verifica dacă conexiunea cu celălalt dispozitiv este sigură." + "Introduceți numărul afișat pe celălalt dispozitiv" + "Furnizorul contului dumneavoastră nu acceptă %1$s." + "%1$s nu este acceptat" + "Furnizorul contului dumneavoastră nu acceptă conectarea la un dispozitiv nou cu un cod QR." + "Codul QR nu este acceptat" + "Autentificarea a fost anulată de pe celălalt dispozitiv." + "Cererea de autentificare a fost anulată" + "Conectarea a expirat. Vă rugăm să încercați din nou." + "Conectarea nu a fost finalizată la timp" + "Deschideți %1$s pe celălalt dispozitiv" + "Selectați %1$s" + "“Conectați-vă cu un cod QR”" + "Scanați codul QR afișat aici cu celălalt dispozitiv." + "Deschideți %1$s pe celălalt dispozitiv" + "Calculator desktop" + "Se încarcă codul QR…" + "Dispozitiv mobil" + "Ce tip de dispozitiv doriți să conectați?" + "Spațile din care membrii se pot alătura camerei fără invitație." + "Gestionați spațiile" + "(Spațiu necunoscut)" + "Alte spații din care nu faceți parte" + "Spațiile dumneavoastră" "Selectarea fișierelor media a eșuat, încercați din nou." "Apăsați pe un mesaj și alegeți \"%1$s\" pentru a-l include aici." "Fixați mesajele importante, astfel încât să poată fi descoperite cu ușurință" @@ -454,6 +492,10 @@ Sunteți sigur că doriți să continuați?" "Mesajul dvs. nu a fost trimis deoarece %1$s nu si-a verificat toate dispozitivele" "Unul sau mai multe dispozitive nu sunt verificate. Puteți trimite mesajul oricum sau puteți anula deocamdată și încercați din nou mai târziu după ce ați verificat toate dispozitivele." "Mesajul dumneavoastră nu a fost trimis deoarece nu ați verificat unul sau mai multe dispozitive" + "Modificați setările" + "Gestionați spațiul" + "Gestionați camerele" + "Permisiuni" "Editați administratorii sau proprietarii" "Procesarea datelor media a eșuat, vă rugăm să încercați din nou." "Nu am putut găsi detaliile utilizatorului" @@ -476,6 +518,7 @@ Sunteți sigur că doriți să continuați?" "%1$s • %2$s" "Spațiu %1$s" "Spații" + "Vizualizați membrii" "Mesajul nu a fost trimis deoarece identitatea verificată a lui %1$s s-a schimbat." "Mesajul nu a fost trimis deoarece %1$s nu a verificat toate dispozitivele." "Mesajul nu a fost trimis deoarece nu ați verificat unul sau mai multe dispozitive." diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 46a3559f3a..58fbc36794 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -156,6 +156,7 @@ "Skip" "Start" "Start chat" + "Start over" "Start verification" "Tap to load map" "Take photo" @@ -372,7 +373,7 @@ Reason: %1$s." "Waiting…" "Waiting for this message" "You" - "Messages you send will be shared with new members invited to this room. %1$s" + "This room has been configured so that new members can read history. %1$s" "%1$s\'s identity was reset. %2$s" "%1$s’s %2$s identity was reset. %3$s" "(%1$s)" @@ -433,9 +434,32 @@ Are you sure you want to continue?" "Options" "Remove %1$s" "Settings" - "Desktop computer" - "Mobile device" - "What type of device do you want to link?" + "Scan the QR code" + "Open %1$s on a laptop or desktop computer" + "Scan the QR code with this device" + "Ready to scan" + "Open %1$s on a desktop computer to get the QR code" + "The numbers don’t match" + "Enter 2-digit code" + "This will verify that the connection to your other device is secure." + "Enter the number shown on your other device" + "Your account provider does not support %1$s." + "%1$s not supported" + "Your account provider doesn’t support signing into a new device with a QR code." + "QR code not supported" + "The sign in was cancelled on the other device." + "Sign in request cancelled" + "Sign in expired. Please try again." + "The sign in was not completed in time" + "Open %1$s on the other device" + "Select %1$s" + "“Sign in with QR code”" + "Scan the QR code shown here with the other device" + "Open %1$s on the other device" + "Desktop computer" + "Loading QR code…" + "Mobile device" + "What type of device do you want to link?" "Spaces where members can join the room without an invitation." "Manage spaces" "(Unknown space)" diff --git a/plugins/src/main/kotlin/extension/locales.kt b/plugins/src/main/kotlin/extension/locales.kt index 31d59b73b8..1af7146681 100644 --- a/plugins/src/main/kotlin/extension/locales.kt +++ b/plugins/src/main/kotlin/extension/locales.kt @@ -18,6 +18,7 @@ val locales = setOf( "fa", "fi", "fr", + "hr", "hu", "in", "it", diff --git a/screenshots/de/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_de.png b/screenshots/de/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_de.png index 503aad1715..2d59285f58 100644 --- a/screenshots/de/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_de.png +++ b/screenshots/de/features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd3a50849007792a0f7c8a2d2662dd156e48f9251f1108b6748bf6b52ace8cf8 -size 69441 +oid sha256:0996d8aed1bd5cb8f99743adb77ea85ade9d65a02aefcc2032714d1b6d1f131d +size 69468 diff --git a/screenshots/de/features.home.impl.components_RoomListContentView_Day_0_de.png b/screenshots/de/features.home.impl.components_RoomListContentView_Day_0_de.png index 718868cb85..ebed766b40 100644 --- a/screenshots/de/features.home.impl.components_RoomListContentView_Day_0_de.png +++ b/screenshots/de/features.home.impl.components_RoomListContentView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc274e63a8428f432ae8ddb7d91cfabffef8d43f130c91c8927427194defb40b -size 43970 +oid sha256:cd5a8bb187b96200fb85a79a57c6ad555324df7fd825615053adb15f4b7a07db +size 44076 diff --git a/screenshots/de/features.home.impl.components_RoomListContentView_Day_5_de.png b/screenshots/de/features.home.impl.components_RoomListContentView_Day_5_de.png index 3a04710ab3..537e7cd715 100644 --- a/screenshots/de/features.home.impl.components_RoomListContentView_Day_5_de.png +++ b/screenshots/de/features.home.impl.components_RoomListContentView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf1ae6e0f2fbdb68ef717a5dc96b25ac771a3ad32f3434f75564550816f72eb2 -size 64067 +oid sha256:59cf2e0b4094609c7748ca389c9afd0e84fcbeba22a9e435c890e94f164c8fe2 +size 64367 diff --git a/screenshots/de/features.home.impl.search_RoomListSearchContent_Day_1_de.png b/screenshots/de/features.home.impl.search_RoomListSearchContent_Day_1_de.png index 5c7cd8673c..1c4fb92e9c 100644 --- a/screenshots/de/features.home.impl.search_RoomListSearchContent_Day_1_de.png +++ b/screenshots/de/features.home.impl.search_RoomListSearchContent_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f6a4818c375c234a36c4187d92a394f4056bada31d7825c63806f4a81cdce1b -size 45989 +oid sha256:f5ee7f6355bab9a287fdafcc62463798c82a4fd41a08b00a6cc7feb6e47de9a2 +size 46251 diff --git a/screenshots/de/features.home.impl_HomeView_Day_0_de.png b/screenshots/de/features.home.impl_HomeView_Day_0_de.png index f7a54299c1..d6e6402fea 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_0_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d24343a46913ad6c047a4395088dd07ca87899563a8e44a92d0393ff62bd72ff -size 63660 +oid sha256:bb38da7cb17bf60d3f65657d66a59cae1c282dea3a5855694eeb65486a0b89a9 +size 63760 diff --git a/screenshots/de/features.home.impl_HomeView_Day_13_de.png b/screenshots/de/features.home.impl_HomeView_Day_13_de.png index 3ff79f211a..5b21661b2a 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_13_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_13_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb610fdae1d9e7b90787347487e8c7fe36349b6bbf6026a9132465ada21ac860 -size 95048 +oid sha256:66dc64fb12b3cc6e2e3953eef03b1615473fd58c9476bd2beec5f72753011076 +size 95190 diff --git a/screenshots/de/features.home.impl_HomeView_Day_14_de.png b/screenshots/de/features.home.impl_HomeView_Day_14_de.png index c424e73a0f..8a5d19579b 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_14_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_14_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0554ef990f666f6ec3c17bc57fb3fe58a82d966c26fd2b79fff8c1e6b069a193 -size 89633 +oid sha256:07b0d56ddeacc0c5d28ae7cfabb5ebe69fa96cc33207945a57c5f146d0d5879a +size 89944 diff --git a/screenshots/de/features.home.impl_HomeView_Day_1_de.png b/screenshots/de/features.home.impl_HomeView_Day_1_de.png index f7a54299c1..d6e6402fea 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_1_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d24343a46913ad6c047a4395088dd07ca87899563a8e44a92d0393ff62bd72ff -size 63660 +oid sha256:bb38da7cb17bf60d3f65657d66a59cae1c282dea3a5855694eeb65486a0b89a9 +size 63760 diff --git a/screenshots/de/features.home.impl_HomeView_Day_2_de.png b/screenshots/de/features.home.impl_HomeView_Day_2_de.png index f7a54299c1..d6e6402fea 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_2_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d24343a46913ad6c047a4395088dd07ca87899563a8e44a92d0393ff62bd72ff -size 63660 +oid sha256:bb38da7cb17bf60d3f65657d66a59cae1c282dea3a5855694eeb65486a0b89a9 +size 63760 diff --git a/screenshots/de/features.home.impl_HomeView_Day_5_de.png b/screenshots/de/features.home.impl_HomeView_Day_5_de.png index f7a54299c1..d6e6402fea 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_5_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d24343a46913ad6c047a4395088dd07ca87899563a8e44a92d0393ff62bd72ff -size 63660 +oid sha256:bb38da7cb17bf60d3f65657d66a59cae1c282dea3a5855694eeb65486a0b89a9 +size 63760 diff --git a/screenshots/de/features.home.impl_HomeView_Day_9_de.png b/screenshots/de/features.home.impl_HomeView_Day_9_de.png index 05978a718f..9c81fb4fb1 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_9_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4cc0259ebbd085fe4c915e999f2fa88413da74211c1d1a5f4ee2e8d0cc18f641 -size 90765 +oid sha256:1790960b72437802d90f756b037565e0466e9088ca0205f3ebb269d56d22fd37 +size 90881 diff --git a/screenshots/de/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_de.png b/screenshots/de/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_de.png new file mode 100644 index 0000000000..4bf92d9c4d --- /dev/null +++ b/screenshots/de/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae1141874f7bfefc4d2ed324f9606a2f68e35894cb7e34be28a299283e45fc6d +size 26294 diff --git a/screenshots/de/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_de.png b/screenshots/de/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_de.png new file mode 100644 index 0000000000..1d308c6908 --- /dev/null +++ b/screenshots/de/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e5009998aeb9113c7572494c77b5c619a6f8ef31236eddda3e91ecfc5a34b5c +size 67431 diff --git a/screenshots/de/features.messages.impl.timeline.components_ThreadSummaryView_Day_0_de.png b/screenshots/de/features.messages.impl.timeline.components_ThreadSummaryView_Day_0_de.png index 9f240daeae..958bd5275f 100644 --- a/screenshots/de/features.messages.impl.timeline.components_ThreadSummaryView_Day_0_de.png +++ b/screenshots/de/features.messages.impl.timeline.components_ThreadSummaryView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:18a7f4dbf3a56c49e5b1edbd0f419620dbfcd4485bfe25db5347968b8844973b -size 9933 +oid sha256:aadadd01c5a31342a1d6eae9506c560a8710f1bc000f43dbe50fbce229da442a +size 9926 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 03e01779ab..78a683e9dd 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:f480c419bfba6a06b7737aab3bce77848c198f7f03f27a2dc92737014ccc9975 -size 364873 +oid sha256:d4e206a9a8836609ec40e98f9d95b7b6d68e47523e243097228aeeba35f04be2 +size 364866 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 d4e74cf520..7e69b98c75 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:eb4a6263b593b1ee107f4e42d18f842e304c3be1292250de795b4fefa647b275 -size 370540 +oid sha256:636f49cd6431b01fa72e92879db35522d35a7260a52d1d320efcf74fe5765358 +size 370534 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 5498d18abd..107d88db38 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:9c82703c9b9446b167fd735d1b27c7c445de0ac434c2287a193d67fe6a4170d4 -size 364073 +oid sha256:fe3daf2cf97dee0cc6b67994ce7d3178d5f16fe50fe7a9e9ff5bf0d47d282b22 +size 364064 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 15b5693fed..5a62ac8096 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:985b04b170d3e13dabc86ab4ab0f496974403f84d4a550c971634da59756633a +oid sha256:18d42f29dc43e05079e6964b8a97a2201898a8bff3ed1772cec5c18b137d87e3 size 366116 diff --git a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_de.png b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_de.png index 72c3db744f..4a48c95806 100644 --- a/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_de.png +++ b/screenshots/de/features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c699247a7d2a5f56855c4c5a050b9e65d394803f61b4a2d86753477b357140d3 +oid sha256:19ab48b39fe02b510edded16f680e11c8f2ebbd6d1455d4b3c99d33c3e6e7842 size 68132 diff --git a/screenshots/de/features.messages.impl_MessagesView_Day_10_de.png b/screenshots/de/features.messages.impl_MessagesView_Day_10_de.png new file mode 100644 index 0000000000..b4fd6a6ecb --- /dev/null +++ b/screenshots/de/features.messages.impl_MessagesView_Day_10_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15f0e4899422bbc75362f91f67b1f25b61f7c1ba5885b9a186d62cf0fa1962d7 +size 68472 diff --git a/screenshots/de/features.messages.impl_MessagesView_Day_11_de.png b/screenshots/de/features.messages.impl_MessagesView_Day_11_de.png new file mode 100644 index 0000000000..5782aa30b6 --- /dev/null +++ b/screenshots/de/features.messages.impl_MessagesView_Day_11_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:696d10fb1ac5464bd89726955a1ae65fc70b1fd5dd03c74be808ef24abeb3ca1 +size 69375 diff --git a/screenshots/de/features.messages.impl_MessagesView_Day_12_de.png b/screenshots/de/features.messages.impl_MessagesView_Day_12_de.png new file mode 100644 index 0000000000..b4fd6a6ecb --- /dev/null +++ b/screenshots/de/features.messages.impl_MessagesView_Day_12_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15f0e4899422bbc75362f91f67b1f25b61f7c1ba5885b9a186d62cf0fa1962d7 +size 68472 diff --git a/screenshots/de/features.preferences.impl.labs_LabsView_Day_0_de.png b/screenshots/de/features.preferences.impl.labs_LabsView_Day_0_de.png index 5cfc6d90de..283d6a560f 100644 --- a/screenshots/de/features.preferences.impl.labs_LabsView_Day_0_de.png +++ b/screenshots/de/features.preferences.impl.labs_LabsView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:84704e1aaeaaa2354248be2bf6864df789bce2f4f2da930d297e8596f6a00f78 -size 48333 +oid sha256:36d6e179c0fdecb3b4ebc1233fd3543c19c2615adeba0db15917e5540111d1f5 +size 48335 diff --git a/screenshots/de/features.preferences.impl.labs_LabsView_Day_1_de.png b/screenshots/de/features.preferences.impl.labs_LabsView_Day_1_de.png index ce61c23bff..3edea046cf 100644 --- a/screenshots/de/features.preferences.impl.labs_LabsView_Day_1_de.png +++ b/screenshots/de/features.preferences.impl.labs_LabsView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0573c15203e5694c4069430333804ba5671c8d67ddd78921c64a573100819bd -size 39484 +oid sha256:eb2bf0d0f83c2125a34393713a9f385734ef16e02a14e93ea152125b59b0c66e +size 39483 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_0_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_0_de.png index 5f49a124bb..898a72ea3f 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:a70776483d27d5c6851413cc05953eda817f81f57c7e2231b6c42528f4902abf -size 46405 +oid sha256:b8697c4c08bce7b3e51730641c438a88a61a86d0f4a0eee4945d1a8645cd229c +size 46344 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_10_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_10_de.png index b965446ab3..027896e5db 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:16b68ee8b268178dbd74e3909991297e73f7ffc5916997e906951232b72fdb1b -size 45298 +oid sha256:b50eb0bb60ecd651d06348e2aec20b3dd44666cca9102b0d2403471905bf47a6 +size 45238 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_11_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_11_de.png index 67f5e6f837..a24498e869 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:e9b899279b2116f3b1c72fcc29c5a53d142efeabc4eed30d2504b9a610a70c52 -size 43721 +oid sha256:548e6a8fd8f8fdb037f206412b765d89524f40711d1aa1e25fec7693761b098c +size 43758 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_12_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_12_de.png index 541990d0bb..189a57b5f7 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:43b1e9b011a6304b41957728b3dadac37f3fe3cc020d2e8eb040a0d36c4035fe -size 45613 +oid sha256:5c4eec1f4dc41a34d4dcb6bb19f06e82df3af61d5502a1d69390c92a8dfe61ae +size 45547 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_13_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_13_de.png index c52229d01a..9e19611d2b 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:15aad49bbbfa213517101643f3a8cc1395f7d344ce3643b3a186bd68979a414f -size 45522 +oid sha256:aa53be2c34487dbd6d256ac08bc0472e5a9041fcdfd4312b41b1587e1ade02c9 +size 45460 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_14_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_14_de.png index 71bab8f819..d34c5f2d0e 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:1d105ccd7161e1a17d9479960a834b416934f0f11f99010c1b3bf5e2755c5392 -size 46093 +oid sha256:1b0f4b25c48f814d0f65a9ebb90e624fd063e85c38638c34b5c2112c26d0a19e +size 46030 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_15_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_15_de.png index 115d097fd8..daea8bdf49 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:2307924f559a2e8600f2cc2e9cc3460085644a6234e12e53dc2d8940c7bfc597 -size 46626 +oid sha256:694675fede76219bec32f4eb90778dd36a71c6949bbcb5b4e324ac95801dcbbe +size 46564 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_16_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_16_de.png index eab1cb4310..8746083afc 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:bfc3e3ebc8c77b403b104cdc78585add322610adf3070d08fb2e86e0afc53db5 -size 45871 +oid sha256:26f73d4bc06ff2bb9f0e322964c1131dde1f6c546c5ff9b7209a6dbcb5dc7273 +size 45810 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_17_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_17_de.png index 070da55723..af83349940 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:f42293fc8dd0382b435aa19a7d4b2cbe7c66e88d7782d062549e5e251c831b7f -size 45104 +oid sha256:7ed62b88643773270a7a045e9c80c29fd3f939c312ec4752cbbfac0a7d001f4f +size 45039 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_18_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_18_de.png index 5e861cc01e..0f1444ad40 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:43f87f56cd260703a4770c42cb9fdb4261718e90b30f534771f5b291a187dcbb -size 42234 +oid sha256:3c320a405aa9fdaaffa5ead648fa33d42f7c946c2a07fad2c803b084319f98bd +size 42275 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_19_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_19_de.png index c33209683f..9835d06f8b 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:c977b4094b6e6740aa662b6e34e82f193b972a067e27a287caf60f75a7b82c12 -size 42191 +oid sha256:11a4d98f789ff1ad1e941a3155b4043e02b06858b319c03c6f1d2b419ed5edb3 +size 42231 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_1_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_1_de.png index c80b9b157e..58bf8b1e3a 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:b38a8012219d7c5fe55e15187ca9db001c33d7883de2e6689bf80a2d44cb6a6a -size 41968 +oid sha256:432bd93e477130a98f2a4111de5051e0f19151594843365555d1428b03b991db +size 41923 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_2_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_2_de.png index 0f8293bf72..0c18888edd 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:4c6951c25bd3df794fb978257d017dbec5537af0cb721d64b2234ca3485c2ad8 -size 39606 +oid sha256:8ff5afe13a98cec38fc19ff957fac1468ab440c8c2fca2e0d157e447a9739bc0 +size 39554 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_3_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_3_de.png index 8a22517ec7..8c4387fd4a 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:e0962c76eb96674ad2fbfa3a4950c408dd1478f0b7f20df8423c24be9d4315f1 -size 45774 +oid sha256:a6e87fbf054dca331f6380f59fa40a1dbecc40c25bcb29ae09817360527a8f10 +size 45629 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_4_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_4_de.png index e7f8df1feb..89d60e7c71 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:2eab31818c13f116be79131e067f52e8b08024488d89d471ec0d5224a99adead -size 44850 +oid sha256:687e7b880a751047ec0cfffcb85b4c0cbfb04f52958cd731036f810b05d8784e +size 44805 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_5_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_5_de.png index 8b5b874586..def514b66f 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:93c0de89ece04e338143639036cc349250a2eb874585dc903248bdc00bbdcd9d -size 41876 +oid sha256:1343c24e5eea07d5f222d96fe7ee7dc6b5c42b3033c6b707758753d66489180c +size 41916 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_6_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_6_de.png index 88b08d21ec..42dadff2cd 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:c9fd895adb29700fe7b44e508048904b56f914a9d59ee8b747aeef1605312058 -size 45348 +oid sha256:bfd031259f414e7bcda1934e152f47d062114b76b5e1b3b38329291f6086d999 +size 45315 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_7_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_7_de.png index 12899a80b8..206579177d 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:5fb30412d08e04187d202b9d31250fbc14ec62064ec6288e8a00b56ca7673d63 -size 46505 +oid sha256:2862e36d811b09539ef1fa6b80690c0dca99a845a599682087ee4df223c76308 +size 46436 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_8_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_8_de.png index 27b306ff9e..f6fe12c78a 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:40043cedd9a088e853536b94f9e051a67fdd2216f4f2f8c97ba837b8503288ad -size 45573 +oid sha256:d78af3f2a5a18d43a2e2c7aef496b0a9e826448db27ca45f6aa2264385194aea +size 45511 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetailsDark_9_de.png b/screenshots/de/features.roomdetails.impl_RoomDetailsDark_9_de.png index d70c05fa23..cd5134cc6b 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:702a543d1d4789700620def47079108a2aae90a8dd4211456f3bc3210ac70a1b -size 44526 +oid sha256:49b6ff5a0187daf1902e3b79367edaf65a3cfb3a330bc7166914dbd9c8ca9606 +size 44460 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_0_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_0_de.png index 5174170729..48b9496226 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:9d8c94f1af798243115ceb6a29b6417bd70df97b4b9cbced5ef08555e1ea7cb9 -size 47520 +oid sha256:6fe2a7ab133e43acdc59731090b26cc91393e246c45fcc55e8f38df6e1f17521 +size 47500 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_10_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_10_de.png index cfefa7b619..637ac4455f 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:d27908e15aab3fd35f2ec363a9e76626fb49208a4b54120157c7f96f4b64012a -size 46327 +oid sha256:9a106b162fbf7e67b0534b71140e34ebacf801c08d1ebe17bbeb760b460f03df +size 46303 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_11_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_11_de.png index 6e7ada6e4a..a9a740f83b 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:29735b713166068b12fc879b6d9f4a56ef2eee8fa2eb2ad1efc7b653ef32b0ff -size 44812 +oid sha256:4dda5a34c3e225141274c0452fc20d9519c14f34fad41e8dec50e786d8104918 +size 44838 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_12_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_12_de.png index 180fe6fe50..f69d34b445 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:a27da9ad0f281dbca24c2a29a40344169898eead8828e25fedbc79c1c7d3ab71 -size 46673 +oid sha256:c3c749f1109ea691f01daaa4cce07f4c131c5d13bce64c4116fe8b848966e590 +size 46648 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_13_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_13_de.png index 228a962ed5..d87e06a028 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:49de7c2ab75c132d37921a0a1d2c2906988eacd00e2c4e7dc938adcea7a44f1c -size 46579 +oid sha256:57053f9c361cf69db35174e3325b0b4753979f011b938648efc37500f0c1a185 +size 46560 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_14_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_14_de.png index 5a671e051c..fad796a3c0 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:b5f8c8b5d6737d727593fa329a6967678772423a015b84fec12da940f299416c -size 47115 +oid sha256:65382b546da02a6bd3cccfbaaf49eb08288448984a1d701587c8baf4fa538b74 +size 47093 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_15_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_15_de.png index da5fcd6b7b..b524ebe3d9 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:c98e276e97214339d1a6b19a2d79ceb79f2d5267faf2c53c2332465a0bccc93c -size 47707 +oid sha256:e770eb2039774eca98cbe08aa46af19cc72aab7ae764f969cd1cfa7fe23dc98a +size 47687 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_16_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_16_de.png index 324b1bc1a5..6993668499 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:e32bd7817e91bd16ce41e3afb76420ecd18729b673ae453f1949147a9d982898 -size 46929 +oid sha256:762116046969a7126042982e89b1b79dc82a4d1ff8763dcbf5b8343cdeca4612 +size 46909 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_17_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_17_de.png index 143b1e151a..0597569c93 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:7fc6cfb807c92f13c9ea01b72c4066a134a44bd9ffffeedb49fdd91e351f694c -size 46417 +oid sha256:c1c87b29315c1aec93f8c0c231f241deed8dbd37384468474c4db0b976d6dda4 +size 46395 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_18_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_18_de.png index 1b9f0f20c5..97c48d314e 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:0981aedebb47c08cd7251bc596be8ea8946698118b8a23a23b4f36ebf7d538f2 -size 43299 +oid sha256:d5033268749c18000be1899d82ebffdc412a0c810855dc542202bf39c354060a +size 43327 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_19_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_19_de.png index 4620074a3e..49314777bc 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:734259ef768f27d1f0d29defb9aa0560b126ec1e184f62c448c813a02552624c -size 43187 +oid sha256:82c7d37bdf17f5115f3e839e61085db472cbc2144e34b0c42db8f68c6868e269 +size 43215 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_1_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_1_de.png index 25b06a9e29..008555c998 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:3bc9395124a3cc86c4d6dc85708e952faf8c21d7d77a56dda56874bc3cf83941 -size 43154 +oid sha256:4a79e3d57386eb05835352d931fd264bcf0303bd21fa15cf44e9a3690d1e537b +size 43131 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_2_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_2_de.png index 6d52eabf17..ea3581bc36 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:8406d0c3f7aaa773429c0c5bf68e8b4420ec8e4e2202d941ec33013d1b76c376 -size 40727 +oid sha256:5bcdcdad130bc08d5242a6f83286300455f7e42dd3eee37451dfb10d7b9d7655 +size 40708 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_3_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_3_de.png index aa1f1b79fa..6bce89b21b 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:d245e4cb448f87a3261e28e982543a50e0425c20ecea26309f736effc90a670e -size 46677 +oid sha256:5bb57d0c50fb54e3cf145cc614312a4c165118dfbfd7795b7bbfc06f4d4713d4 +size 46610 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_4_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_4_de.png index ee1f81c202..0b00f96dc6 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:57e6188e4e841a9535ff5f38ff5fd1f2043eac3aa605ebc94cbfefbd7373dd31 -size 45850 +oid sha256:fee173f492c24aa69a4c64afba1f4cb856d742ac089a2bf25526a28e8fdaedae +size 45826 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_5_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_5_de.png index 76fe0591be..6bf05b9e6b 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:848d125ca33668838a9f24dcddd93e579f3b19e28e1436b2684da4311c67bdd9 -size 42845 +oid sha256:2ed7b3bb40e0dfb76872d85c07e147f55964622bf102435ae8e98524c52ede06 +size 42872 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_6_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_6_de.png index aaf48f7fd4..6649e7ee0c 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:e353bf4a444ea89a065930c8adfcd9337ceca32cc8f048ffec3b751fce72abef -size 46519 +oid sha256:016e70e04d4fa9512a72ab00f33578b59b3cb5ef27881558cc4842cf5e89b025 +size 46503 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_7_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_7_de.png index 6615d4c787..59d5e3ae1e 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:2d45174b0aceaf7594875c3039324d21d7f5fe18eaeef32d2e40826d0c59a102 -size 47787 +oid sha256:a15fae40d21bb7729f1a0dd383533d1941423d0812cf51e67adc56f5054f09d7 +size 47769 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_8_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_8_de.png index db3dce5d97..83df8713ae 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:6efbbc7358ef22b3b32c0ee7517483d5a83cfd0aa261e2391cb85867e18528d3 -size 46691 +oid sha256:908aa907fa85dc18825e3ecb5da8ad12916577df28045b256c95a21b524575a8 +size 46670 diff --git a/screenshots/de/features.roomdetails.impl_RoomDetails_9_de.png b/screenshots/de/features.roomdetails.impl_RoomDetails_9_de.png index a3eb15f711..746f9ff2c7 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:2323c44e1e07f3a98fc5ba91c4cc4b5fe34780a83ef94028ca94bbf17bcf6fec -size 45558 +oid sha256:7776bbd14000795414995fc0428a80659cb6b45d06b35c6537eb66fd69b341c4 +size 45529 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 16138ae8f3..72323a22e6 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:d9abcfd14cc3ac9fd3029dabcf0d4251941a02251a1f869ed8fe8fca8e790bae -size 16045 +oid sha256:cdb2f46dd809a4d8e28be46dcd84fed0cae4c734a5d4b65b0dd8a00849fd9df0 +size 16091 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 2a5acc9faa..0dd7f82cde 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:a4c6f61958bf82c3057e2fb0e83ce42b2425249c40f0af99983b6354be8d4952 -size 25188 +oid sha256:71063d31e200aa93ae2c966c7291d61bc325f1dc658afcf96150ccc7ad8e3322 +size 25238 diff --git a/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_de.png b/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_de.png index 18f43f132d..0414a20c94 100644 --- a/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_de.png +++ b/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e8dab068d8f07d8f9bedebc51b69c91d4d996c160791ccad75bd981b9d75fc7 -size 17112 +oid sha256:1b869af5e094555bae21115ddd8e637c463bf8d0e1f1ac9a88d0e84a7c0c191b +size 17324 diff --git a/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_de.png b/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_de.png index e69faa0ce9..10531b43bf 100644 --- a/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_de.png +++ b/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64faaae8773e35e52143f14d7bdf546b0ea1a3cb5a4962bda66bafb76b794468 -size 19122 +oid sha256:cc23094f3d51c108e64490f9ecc1f10c3ba8cb86f3273cd990181d21133dce4e +size 19320 diff --git a/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_de.png b/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_de.png index c44f6f4b4f..64a879ff74 100644 --- a/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_de.png +++ b/screenshots/de/libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:81d1ef176e9b62379ffdeac6e98c96d3fe118f920260e6deacd32437ee6e5348 -size 19088 +oid sha256:8a4dc61d7b3fc791fe6362cabcbb67a15d85669d778c1b186c73fcd470df3b21 +size 19295 diff --git a/screenshots/de/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_de.png index dc24bcec5c..6e1dd6cf39 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:596cc2da5cb85d9d740fbb9a2769adcc6a2eedb2940b1347d00fceda487402a5 -size 67976 +oid sha256:525aee31e2c09c8f7134e174de4e46f1913a5b4f3a88a4f2fba50dc615fdffc5 +size 68035 diff --git a/screenshots/de/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_de.png index ea48d1f02e..6dba6f2792 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7425263614937932efe6435296f48ee4a8fb81c4829289b1993913d4bea292f -size 66098 +oid sha256:53c40e5833c999c8e3d49bde6f565d32a4381a40e7c0bcba845d16363c6f3faf +size 66163 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_de.png index c30828e474..e56631e249 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:0bcca4a976c1fef41252b91bbe17301b1169c397833f7fda954f30c46d9ebefe -size 75296 +oid sha256:68741be741a63204b1ea6099ae2833b0aeb5defc1367d97bada887d5b96a6531 +size 75368 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_de.png index 5a1dae13dd..e92eaf2597 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:83bde3a14b7a8345678282f86a4a16f4af925daaab4b7f9393122a81c8fd4509 -size 61884 +oid sha256:8fabc114c60514f7eb512c8992a82bf1c946592c6e8187c87215cdfe7fe21a5f +size 61956 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_de.png index a3f6ea71eb..c07587a3be 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:78335f34f4ec3eed79ecb4fc5f74a6ea52ca758913db1f1253c6d67df13cc1bd -size 74715 +oid sha256:f3703422fb0a8c6fba5116f715743cfba7b4eb94139563e25d796ff51c6cbee7 +size 74797 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_de.png index 2556acee45..aebf3f050c 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:fe025380c38ab0974930b7e91e3a0a4f02e49c8422b3f1119ad3a64d6aa1e770 -size 83357 +oid sha256:41d290c3153b85b1d97f2dbb087041c1dc57db31bd8904d3919dcf0b178b2286 +size 83439 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_de.png index 8ee7cb1c67..1b83986771 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:e21a3a654f0b20a7fd6a53b8dafb83a060216fe5bb0e60a6a929cec91091500c -size 64430 +oid sha256:4cccf5887c1fe53f317e6d1823e747e651d4b615e73f81a68e730ba1d3aacc6f +size 64490 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_de.png index f5352e8ba3..f7a5b24bcc 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:5e6c5e2f1cde6c5aaac386b1ed7f478192bb15811f082eb7b564375db1c45ca5 -size 63315 +oid sha256:0296e105d089b5afb565bbac72f7a3cdd92c0381ab867494114f2ec8067af18c +size 63387 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_de.png index b68fe1da24..1864d91132 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:aedd7a97c5f98857d674da7c42f7439e0af71ccb59f0a900161ae5b7497e9723 -size 68971 +oid sha256:e97005de9f3b1ae2873888c3258aa39c92fefa98194c55ed9d6abc7c8850af27 +size 69035 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_de.png index 3ba3abf9f0..b5a3abc87e 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:29aeb44961435a5a2d1000ff1e44ed698c4c2358e0d8eaf88f762e8004693942 -size 92241 +oid sha256:826550edf105257ff91ff2c9b798a128da4172125fc2d157bba6eaeb3f3cc60a +size 92294 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_de.png index 1b640b003b..12a40cd0d9 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:163945bdc729e6355e0ac6ebf58fea897195053d79197fba64ec0601045be868 -size 62760 +oid sha256:5d859305f9f78b7c969d2ea8a3f49fe00015d1dc3c49b24dcd3d228705688d4a +size 62833 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_de.png index 9a9414770c..95325575c3 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:c0b44b23c3f31cae6bf229f992baa529eee15e087989230a355d0f29a429800b -size 63900 +oid sha256:4cab4d95d4466412843b716e27d43507c06a777aba77c9b3df3350a268c7597d +size 63975 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_de.png index 7adecea8ed..b42dec9211 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:7bcbb464943d25cda77e49f4c76bb01e587a4823080757f9718dafdb86137d2d -size 71591 +oid sha256:b33f245c717a8c8865aafe9aa3a09ff1201a8532db5327c536410b11e4479f3c +size 71660 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_de.png index 2d9f044871..da763a7902 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:243cbf861b217e6314cedc853eefdeadd231ea674d22d683e6bc43e50de1a213 -size 62292 +oid sha256:6a9589f57428065452bcfa119b12d3d5ac37376771ab4c47378b458b470785a2 +size 62360 diff --git a/screenshots/de/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_de.png index d50c99a4f4..da1d3f39eb 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:9b79bfd727b627baed2d6b99ae6d5711d4b4dcb0f74f937eb41727ede4317c79 -size 58334 +oid sha256:fc72269a07c163bc490a590d73dabb1d698e28298a69df89a058d20c8051d89f +size 58391 diff --git a/screenshots/de/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_de.png index 642d11e403..26cd7d10c5 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6b02463827dea85c10b2766293fe11d25612a677386eb9cf056333313c89057 -size 38097 +oid sha256:1656124036ba98fb559a863aba4d81fefcd9b4f52ab9cab852520dfa67bd5373 +size 38156 diff --git a/screenshots/html/data.js b/screenshots/html/data.js index a757e04ca0..2705fbc626 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,80 +1,80 @@ // 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",20427,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20434,], ["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",20427,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20427,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20427,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20427,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20427,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20427,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20427,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20427,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20427,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20427,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20427,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20434,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20434,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20434,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20434,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20434,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20434,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20434,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20434,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20434,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20434,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20434,], ["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",20427,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20427,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20434,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20434,], ["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",20427,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20427,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20434,], ["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",20427,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20427,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20427,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20427,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20427,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20427,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20427,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20427,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20427,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20427,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20427,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20427,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20427,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20427,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20427,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20434,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20434,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20434,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20434,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20434,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20434,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20434,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20434,], ["libraries.designsystem.theme.components_AllIcons_Icons_en","",0,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20427,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20427,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20427,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20427,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20427,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20434,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20434,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20434,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20434,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20434,], ["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",20427,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20434,], ["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",20427,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20434,], ["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",20427,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20434,], ["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",20427,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20434,], ["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",20427,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20434,], ["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,], @@ -84,19 +84,19 @@ export const screenshots = [ ["libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_7_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_7_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_8_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_8_en",0,], -["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20427,], -["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20427,], -["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20427,], -["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20427,], -["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20427,], -["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20427,], -["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20427,], -["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20427,], -["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20427,], +["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20434,], +["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20434,], +["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20434,], +["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20434,], +["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20434,], +["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20434,], +["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20434,], +["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20434,], +["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20434,], ["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",20427,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20434,], ["libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en","",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_0_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_1_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_1_en",0,], @@ -123,22 +123,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",20427,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20434,], ["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",20427,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20427,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20427,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20427,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20427,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20427,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20427,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20434,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20434,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20434,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20434,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20434,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20434,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20434,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20427,], -["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20427,], -["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20427,], -["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20427,], -["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20427,], +["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20434,], +["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20434,], +["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20434,], +["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20434,], +["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20434,], ["features.rageshake.impl.bugreport_BugReportViewNight_0_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_1_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_2_en","",0,], @@ -148,133 +148,133 @@ export const screenshots = [ ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20427,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20427,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20434,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20434,], ["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], ["features.call.impl.ui_CallScreenView_Day_0_en","features.call.impl.ui_CallScreenView_Night_0_en",0,], -["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20427,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20427,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20427,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20427,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20427,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20427,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20434,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20434,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20434,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20434,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20434,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20434,], ["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",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20427,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20427,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20427,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20427,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20427,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20427,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20427,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20434,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20434,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20434,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20434,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20434,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20434,], ["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",20427,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20427,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20427,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20427,], -["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20427,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20434,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20434,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20434,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20434,], +["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20434,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20427,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20434,], ["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",20427,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20427,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20427,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20427,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20427,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20427,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20427,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20427,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20434,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20434,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20434,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20434,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20434,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20434,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20434,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20434,], ["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",20427,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20427,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20427,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20427,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20427,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20427,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20427,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20427,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20427,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20427,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20434,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20434,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20434,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20434,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20434,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20434,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20434,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20434,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20434,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20434,], ["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","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20427,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20427,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20427,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20427,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20427,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20427,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20434,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20434,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20434,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20434,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20434,], ["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",20427,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20427,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20427,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20427,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20427,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20427,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20427,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20427,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20427,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20427,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20427,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20427,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20427,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20427,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20427,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20427,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20427,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20427,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20427,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20427,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20434,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20434,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20434,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20434,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20434,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20434,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20434,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20434,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20434,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20434,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20434,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20434,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20434,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20434,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20434,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20434,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20434,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20434,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20434,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20434,], ["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","",20427,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20427,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20427,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20427,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20427,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20427,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20427,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20434,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20434,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20434,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20434,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20434,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20434,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20434,], ["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",20427,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20427,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20427,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20434,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20434,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20434,], ["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",20427,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20434,], ["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",20427,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20427,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20427,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20427,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20427,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20427,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20427,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20427,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20434,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20434,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20434,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20434,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20434,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20434,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20434,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20434,], ["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,], @@ -289,19 +289,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",20427,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20427,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20427,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20427,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20427,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20430,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20430,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20430,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20430,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20430,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20427,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20427,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20430,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20434,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20434,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20434,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20434,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20434,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20434,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20434,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20434,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20434,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20434,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20434,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20434,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20434,], ["libraries.matrix.ui.components_EditableAvatarView_Day_0_en","libraries.matrix.ui.components_EditableAvatarView_Night_0_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_1_en","libraries.matrix.ui.components_EditableAvatarView_Night_1_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_2_en","libraries.matrix.ui.components_EditableAvatarView_Night_2_en",0,], @@ -312,14 +312,14 @@ export const screenshots = [ ["libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Night_0_en",0,], ["features.messages.impl.timeline.components.customreaction_EmojiItem_Day_0_en","features.messages.impl.timeline.components.customreaction_EmojiItem_Night_0_en",0,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20427,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20427,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20434,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20434,], ["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,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20427,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20427,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20427,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20434,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20434,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20434,], ["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,], @@ -338,43 +338,44 @@ 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",20427,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20427,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20427,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20434,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20434,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20434,], ["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",20427,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20427,], +["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20434,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20434,], ["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",20427,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20427,], -["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20427,], -["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20427,], -["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20427,], +["features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en","features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en",20437,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20434,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20434,], +["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20434,], +["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20434,], +["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20434,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20427,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20427,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20434,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20434,], ["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",20427,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20427,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20427,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20427,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20427,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20427,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20427,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20427,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20427,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20427,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20427,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20427,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20434,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20434,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20434,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20434,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20434,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20434,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20434,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20434,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20434,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20434,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20434,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20434,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.ruler_HorizontalRuler_Day_0_en","libraries.designsystem.ruler_HorizontalRuler_Night_0_en",0,], ["libraries.designsystem.theme.components_IconButton_Buttons_en","",0,], @@ -387,8 +388,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",20427,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20427,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20434,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20434,], ["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,], @@ -396,109 +397,109 @@ 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",20427,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20434,], ["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",20427,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20434,], ["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",20427,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20434,], ["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20427,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20427,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20434,], ["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",20427,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20427,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20427,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20434,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20434,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20434,], ["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",20427,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20427,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20427,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20427,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20434,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20434,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20434,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20434,], ["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",20427,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20427,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20427,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20427,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20427,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20427,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20427,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20427,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20434,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20434,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20434,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20434,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20434,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20434,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20434,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20434,], ["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",20427,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20427,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20427,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20427,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20427,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20427,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20427,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20427,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20427,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20427,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20427,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20434,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20434,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20434,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20434,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20434,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20434,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20434,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20434,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20434,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], -["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20427,], -["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20427,], +["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20434,], +["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20434,], ["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",20427,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20427,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20427,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20427,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20427,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20427,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20427,], -["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20427,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20434,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20434,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20434,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20434,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20434,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20434,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20434,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20434,], ["libraries.designsystem.background_LightGradientBackground_Day_0_en","libraries.designsystem.background_LightGradientBackground_Night_0_en",0,], ["libraries.designsystem.theme.components_LinearProgressIndicator_Progress_Indicators_en","",0,], ["features.messages.impl.link_LinkView_Day_0_en","features.messages.impl.link_LinkView_Night_0_en",0,], -["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20427,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20434,], ["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,], @@ -553,38 +554,38 @@ 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",20427,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20427,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20427,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20427,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20434,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20434,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20434,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20434,], ["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",20427,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20427,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20427,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20427,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20427,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20427,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20427,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20427,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20427,], -["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20427,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20427,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20427,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20427,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20427,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20427,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20427,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20427,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20427,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20427,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20427,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20427,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20427,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20427,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20427,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20427,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20434,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20434,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20434,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20434,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20434,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20434,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20434,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20434,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20434,], +["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20434,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20434,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20434,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20434,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20434,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20434,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20434,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20434,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20434,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20434,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20434,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20434,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20434,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20434,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20434,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20434,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20427,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20434,], ["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,], @@ -597,22 +598,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",20427,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20427,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20434,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20434,], ["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",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20427,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20427,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20434,], ["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,], @@ -620,14 +621,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","",20427,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20427,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20434,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20434,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20427,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20434,], ["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","",20427,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20434,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -641,7 +642,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",20427,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20434,], ["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,], @@ -650,7 +651,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",20427,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20434,], ["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,], @@ -658,137 +659,141 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessagesReactionButton_Day_1_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_1_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_2_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_2_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_3_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_3_en",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20427,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20427,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20427,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20427,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20427,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20427,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20427,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20427,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20427,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20427,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20427,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20427,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20427,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20427,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20434,], +["features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en","features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en",20437,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20434,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20434,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20434,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20434,], +["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20437,], +["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20437,], +["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20437,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20434,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20434,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20434,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20434,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20434,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20434,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20434,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20434,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20434,], ["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",20427,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20434,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], -["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20427,], +["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20434,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_MultipleSelectionDialog_Night_0_en",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelectedTrailingContent_Multiple_selection_List_item_-_selection_in_trailing_content_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelected_Multiple_selection_List_item_-_selection_in_supporting_text_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItem_Multiple_selection_List_item_-_no_selection_List_items_en","",0,], ["libraries.designsystem.theme.components_NavigationBar_App_Bars_en","",0,], -["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20427,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20427,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20427,], +["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20434,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20434,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20434,], ["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",20427,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20427,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20427,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20427,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20427,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20427,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20427,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20427,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20434,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20434,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20434,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20434,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20434,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20434,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20434,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20434,], ["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",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20427,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20434,], ["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",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20427,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20427,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20434,], ["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",20427,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20434,], ["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",0,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20427,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20427,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20427,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20427,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20434,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20434,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20434,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20434,], ["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",20427,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20427,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20427,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20434,], ["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",20427,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20427,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20427,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20427,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20427,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20427,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20427,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20427,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20427,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20427,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20427,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20427,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20427,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20427,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20434,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20434,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20434,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20434,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20434,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20427,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20427,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20427,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20427,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20427,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20434,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20434,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20434,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20434,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20434,], ["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",20427,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20427,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20427,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20427,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20427,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20427,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20427,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20427,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20427,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20427,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20427,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20434,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20434,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20434,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20434,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20434,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20434,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20434,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20434,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20434,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20434,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20434,], ["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,], @@ -802,206 +807,206 @@ 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","",20427,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20427,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20427,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20427,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20434,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20434,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20434,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20434,], ["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","",20427,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20427,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20434,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20434,], ["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",20427,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20427,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20427,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20427,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20427,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20427,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20427,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20427,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20427,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20427,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20427,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20427,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20427,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20427,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20427,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20427,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20427,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20427,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20427,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20427,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20427,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20427,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20427,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20427,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20427,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20427,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20427,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20434,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20434,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20434,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20434,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20434,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20434,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20434,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20434,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20434,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20434,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20434,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20434,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20434,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20434,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20434,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20434,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20434,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20434,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20434,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20434,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20434,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20434,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20434,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20434,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20434,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20434,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20434,], ["libraries.designsystem.theme.components_RadioButton_Toggles_en","",0,], -["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20427,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20427,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20434,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20434,], ["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",20427,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20427,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20427,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20427,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20427,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20427,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20427,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20434,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20434,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20434,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20434,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20434,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20434,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20434,], ["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",20427,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20427,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20427,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20427,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20427,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20427,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20427,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20427,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20427,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20427,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20427,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20427,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20427,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20427,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20427,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20427,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20427,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20434,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20434,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20434,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20434,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20434,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20434,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20434,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20434,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20434,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20434,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20434,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20434,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20434,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20434,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20434,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20434,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20434,], ["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",20427,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20427,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20427,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20427,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20427,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20427,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20427,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20427,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20427,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20427,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20427,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20427,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20427,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20434,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20434,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20434,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20434,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20434,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20434,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20434,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20434,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20434,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20434,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20434,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20434,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20434,], ["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",20427,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20427,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20427,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20427,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20430,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20430,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20430,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20430,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20430,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20430,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20430,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20430,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20430,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20430,], -["features.roomdetails.impl_RoomDetails_0_en","",20427,], -["features.roomdetails.impl_RoomDetails_10_en","",20427,], -["features.roomdetails.impl_RoomDetails_11_en","",20427,], -["features.roomdetails.impl_RoomDetails_12_en","",20427,], -["features.roomdetails.impl_RoomDetails_13_en","",20427,], -["features.roomdetails.impl_RoomDetails_14_en","",20427,], -["features.roomdetails.impl_RoomDetails_15_en","",20427,], -["features.roomdetails.impl_RoomDetails_16_en","",20427,], -["features.roomdetails.impl_RoomDetails_17_en","",20427,], -["features.roomdetails.impl_RoomDetails_18_en","",20427,], -["features.roomdetails.impl_RoomDetails_19_en","",20427,], -["features.roomdetails.impl_RoomDetails_1_en","",20427,], -["features.roomdetails.impl_RoomDetails_2_en","",20427,], -["features.roomdetails.impl_RoomDetails_3_en","",20427,], -["features.roomdetails.impl_RoomDetails_4_en","",20427,], -["features.roomdetails.impl_RoomDetails_5_en","",20427,], -["features.roomdetails.impl_RoomDetails_6_en","",20427,], -["features.roomdetails.impl_RoomDetails_7_en","",20427,], -["features.roomdetails.impl_RoomDetails_8_en","",20427,], -["features.roomdetails.impl_RoomDetails_9_en","",20427,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20427,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20427,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20427,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20427,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20427,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20427,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20427,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20427,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20427,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20434,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20434,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20434,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20434,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20434,], +["features.roomdetails.impl_RoomDetails_0_en","",20434,], +["features.roomdetails.impl_RoomDetails_10_en","",20434,], +["features.roomdetails.impl_RoomDetails_11_en","",20434,], +["features.roomdetails.impl_RoomDetails_12_en","",20434,], +["features.roomdetails.impl_RoomDetails_13_en","",20434,], +["features.roomdetails.impl_RoomDetails_14_en","",20434,], +["features.roomdetails.impl_RoomDetails_15_en","",20434,], +["features.roomdetails.impl_RoomDetails_16_en","",20434,], +["features.roomdetails.impl_RoomDetails_17_en","",20434,], +["features.roomdetails.impl_RoomDetails_18_en","",20434,], +["features.roomdetails.impl_RoomDetails_19_en","",20434,], +["features.roomdetails.impl_RoomDetails_1_en","",20434,], +["features.roomdetails.impl_RoomDetails_2_en","",20434,], +["features.roomdetails.impl_RoomDetails_3_en","",20434,], +["features.roomdetails.impl_RoomDetails_4_en","",20434,], +["features.roomdetails.impl_RoomDetails_5_en","",20434,], +["features.roomdetails.impl_RoomDetails_6_en","",20434,], +["features.roomdetails.impl_RoomDetails_7_en","",20434,], +["features.roomdetails.impl_RoomDetails_8_en","",20434,], +["features.roomdetails.impl_RoomDetails_9_en","",20434,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20434,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20434,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20434,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20434,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20434,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20434,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20434,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20434,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20434,], ["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",20427,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20427,], -["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20427,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20427,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20427,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20427,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20427,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20427,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20427,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20434,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20434,], +["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20434,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20434,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20434,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20434,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20434,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20434,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20434,], ["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",20427,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20427,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20427,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20427,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20427,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20427,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20427,], -["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20430,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20427,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20427,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20427,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20427,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20427,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20427,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20427,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20427,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20427,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20434,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20434,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20434,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20434,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20434,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20434,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20434,], +["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20434,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20434,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20434,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20434,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20434,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20434,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20434,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20434,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20434,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20434,], ["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",20427,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20427,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20427,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20427,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20427,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20427,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20427,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20427,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20427,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20427,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20427,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20427,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20427,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20427,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20434,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20434,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20434,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20434,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20434,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20434,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20434,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20434,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20434,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20434,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20434,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20434,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20434,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20434,], ["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,], @@ -1024,14 +1029,14 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_26_en","features.home.impl.components_RoomSummaryRow_Night_26_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_27_en","features.home.impl.components_RoomSummaryRow_Night_27_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_28_en","features.home.impl.components_RoomSummaryRow_Night_28_en",0,], -["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20427,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20427,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20427,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20427,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20427,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20427,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20427,], -["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20427,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20434,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20434,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20434,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20434,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20434,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20434,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20434,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20434,], ["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",0,], ["features.home.impl.components_RoomSummaryRow_Day_3_en","features.home.impl.components_RoomSummaryRow_Night_3_en",0,], @@ -1041,105 +1046,105 @@ 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",20427,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20427,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20427,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20434,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20434,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20434,], ["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",20427,], -["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20427,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20427,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20427,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20434,], +["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20434,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20434,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20434,], ["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","",20427,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20434,], ["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","",20427,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20427,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20427,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20427,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20427,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20427,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20427,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20427,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20427,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20427,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20427,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20427,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20427,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20430,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20430,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20434,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20434,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20434,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20434,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20434,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20434,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20434,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20434,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20434,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20434,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20434,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20434,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20434,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20434,], ["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,], @@ -1153,11 +1158,11 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_1_en","libraries.matrix.ui.components_SelectedUser_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedUsersRowList_Day_0_en","libraries.matrix.ui.components_SelectedUsersRowList_Night_0_en",0,], ["libraries.textcomposer.components_SendButton_Day_0_en","libraries.textcomposer.components_SendButton_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20427,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20427,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20427,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20427,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20427,], +["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20434,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20434,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20434,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20434,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20434,], ["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,], @@ -1167,27 +1172,27 @@ export const screenshots = [ ["libraries.matrix.ui.messages.sender_SenderName_Day_6_en","libraries.matrix.ui.messages.sender_SenderName_Night_6_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_7_en","libraries.matrix.ui.messages.sender_SenderName_Night_7_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_8_en","libraries.matrix.ui.messages.sender_SenderName_Night_8_en",0,], -["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20427,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20427,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20427,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20427,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20427,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20427,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20427,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20427,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20434,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20434,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20434,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20434,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20434,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20434,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20434,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20434,], ["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",20427,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20427,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20427,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20427,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20427,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20427,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20427,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20427,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20427,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20427,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20434,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20434,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20434,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20434,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20434,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20434,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20434,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20434,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20434,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20434,], ["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,], @@ -1197,102 +1202,102 @@ 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",20427,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20434,], ["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",20427,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20434,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20427,], -["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20427,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20427,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20434,], +["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20434,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20434,], ["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",20427,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20427,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20427,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20427,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20427,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20427,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20427,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20427,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20427,], -["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20427,], -["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20427,], -["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20427,], -["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20427,], -["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20427,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20427,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20427,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20427,], -["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20427,], -["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20427,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20434,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20434,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20434,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20434,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20434,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20434,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20434,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20434,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20434,], +["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20434,], +["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20434,], +["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20434,], +["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20434,], +["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20434,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20434,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20434,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20434,], +["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20434,], +["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20434,], ["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",20427,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20427,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20427,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20427,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20427,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20427,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20427,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20434,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20434,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20434,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20434,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20434,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20434,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20434,], ["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",20427,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20434,], ["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",20427,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20434,], ["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",20427,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20427,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20427,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20427,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20427,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20427,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20427,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20427,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20427,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20427,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20427,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20427,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20427,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20427,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20427,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20434,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20434,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20434,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20434,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20434,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20434,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20434,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20434,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20434,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20434,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20434,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20434,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20434,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20434,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20434,], ["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",20427,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20427,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20434,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20434,], ["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,], @@ -1304,16 +1309,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",20427,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20427,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20427,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20427,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20427,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20434,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20434,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20434,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20434,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20434,], ["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",20427,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20427,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20434,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20434,], ["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,], @@ -1323,18 +1328,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",20427,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20434,], ["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",20427,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20434,], ["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,], @@ -1342,18 +1347,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",20427,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20434,], ["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",20427,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20427,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20434,], ["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",20427,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20434,], ["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,], @@ -1362,41 +1367,41 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20434,], ["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",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20434,], ["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",20427,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20434,], ["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","",20427,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20434,], ["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",20427,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20427,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20434,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20434,], ["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",20427,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20434,], ["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",20427,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20427,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20427,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20434,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20434,], ["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",20427,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20427,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20434,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20434,], ["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",20427,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20434,], ["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,], @@ -1405,8 +1410,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",20427,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20434,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20434,], ["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,], @@ -1421,8 +1426,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",20427,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20427,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20434,], ["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,], @@ -1445,85 +1450,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",20427,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20427,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20434,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20434,], ["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",20427,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20427,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20427,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20427,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20427,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20427,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20427,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20427,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20434,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20434,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20434,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20434,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20434,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20434,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20434,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20434,], ["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",20427,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20434,], ["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",20427,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20434,], ["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",20427,], +["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20434,], ["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",20427,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20427,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20427,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20427,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20427,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20427,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20427,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20427,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20434,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20434,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20434,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20434,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20434,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20434,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20434,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20434,], ["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",20427,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20427,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20427,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20427,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20427,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20427,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20434,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20434,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20434,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20434,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20434,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20434,], ["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","",20427,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20434,], ["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], ["libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en","libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en",0,], -["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20427,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20427,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20427,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20427,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20434,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20434,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20434,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20434,], ["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",20427,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20434,], ["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",20427,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20434,], ["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",20427,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20427,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20427,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20427,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20427,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20427,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20427,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20427,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20427,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20427,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20427,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20427,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20434,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20434,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20434,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20434,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20434,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20434,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20434,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20434,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20434,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20434,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20434,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20434,], ["features.verifysession.impl.ui_VerificationUserProfileContent_Day_0_en","features.verifysession.impl.ui_VerificationUserProfileContent_Night_0_en",0,], ["libraries.designsystem.ruler_VerticalRuler_Day_0_en","libraries.designsystem.ruler_VerticalRuler_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_1_en",0,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20427,], -["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20427,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20434,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20434,], ["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",20427,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20434,], ["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/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png index 0e62152f25..82395ab3e4 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5503fe0529183e4235336b86b2566a7780c0acb42a0555259fdc5c2d83af923c -size 26362 +oid sha256:0489a15e6f8b358780484ea33807aaa2079512f7077b81b1e7e455092968cd61 +size 25463 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png index cf08addacb..75c8eb8e45 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:25f79679d8b15bbd4cd27b79aec1d5a33f7784d73a0b6fcb5d80a3da83b28188 -size 29073 +oid sha256:da4fa289d3a4f32da964a47392458a09bdf80d4410e9ab9519225d077bb4a168 +size 28316 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png index 31ddd63f80..6ebf12ac3d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3a591fbf79b2b97bec5028b4b32b4a28ded3023355dbb446be793cd59701c284 -size 67642 +oid sha256:cf7b2508bdf41e2ee9b8b26207c604232f54314797237aceec5675524a7c8ab5 +size 66644 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png index 3dd62262e8..02b6564855 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:220888172844b7a99bed005197f78c6fe1658d8905de5e524d3e0c58b174c150 -size 69851 +oid sha256:e58f097893ebc5f8664283d3e22b055b7294ce6d6bf571b34507e2242f70e677 +size 68988 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png index 672d60c299..3fe678a873 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4e22dc6079daafbda97305b48143936228bc16e8c1dd84d46886b2d9f437dca -size 69579 +oid sha256:47c0b2a5dedb5b8ca1a027dfe93b27b97069f4c65b9e1553d7847f5f06348678 +size 68593 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png index 75c49364fe..5b2e6c0429 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b6050f9ca4c5f714f6061c31a1a77147d06ff4b500144cb100fa10e05cc13f3 -size 71108 +oid sha256:1ea74e00b157d5e0f7caf71ba839f1523bfbc0684335ba270aec05187a88c3e5 +size 70237 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png index 0273b0949c..08a1c1cf3d 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e4f5154e5b0cc46dedb451a5201377bd6a5f9d00eedead80faac2e42077e69aa -size 43421 +oid sha256:bc501692ee40937d1e02249e8cf93d15991ce0413d1b13237d41c9207faa5039 +size 43389 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png index 35bec7f802..6d3b6d9844 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:622765f7acfe732a8ad0a6b4a802c26ac92926beec5cbb213e16c8c152afa410 -size 37463 +oid sha256:6fbb7ce1d418d67b20234a47ba2b79e25fbdd80e1d9a687f62081d2933181da4 +size 37530 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png index 79f87ba1c8..8a41e84027 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e722c3f569138d1ca1e618c4bdd78e79e78a599effcf062cada98ad96c4dea4 -size 42197 +oid sha256:b15295833313b4b14b14f1bf8f21440b98cf64cf01d631def6798f0a85273e3e +size 42214 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png index 5cf3b1e3d6..b488844237 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.labs_LabsView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3cf7db826d0de2e45632e9e7828b5474f9588e07b3344ed75a254687c8758905 -size 35120 +oid sha256:ced0553d31178a78204615b68259d9ffefb08e3071eb1f06ab4181a1e4436b6a +size 35114 From d80ebe4de0d802eba764565feaca6853b7228090 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 16 Dec 2025 11:32:16 +0100 Subject: [PATCH 132/347] quality: fix translation warning --- libraries/ui-strings/src/main/res/values-da/translations.xml | 4 ---- libraries/ui-strings/src/main/res/values-hr/translations.xml | 4 ---- libraries/ui-strings/src/main/res/values-ro/translations.xml | 4 ---- libraries/ui-strings/src/main/res/values-sk/translations.xml | 4 ---- 4 files changed, 16 deletions(-) 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 7d58b7bfb6..6de4dc7ebd 100644 --- a/libraries/ui-strings/src/main/res/values-da/translations.xml +++ b/libraries/ui-strings/src/main/res/values-da/translations.xml @@ -445,10 +445,6 @@ Er du sikker på, at du vil fortsætte?" "Din besked blev ikke sendt, fordi %1$s ikke har bekræftet alle enheder" "En eller flere af dine enheder er ikke verificeret. Du kan sende beskeden alligevel, eller du kan annullere for nu og prøve igen senere, når du har verificeret alle dine enheder." "Din besked blev ikke sendt, fordi du ikke har verificeret en eller flere af dine enheder" - "Skift indstillinger" - "Administrér gruppe" - "Administrer rum" - "Tilladelser" "Rediger administratorer eller ejere" "Det lykkedes ikke at behandle medier til upload. Prøv venligst igen." "Kunne ikke hente brugeroplysninger" diff --git a/libraries/ui-strings/src/main/res/values-hr/translations.xml b/libraries/ui-strings/src/main/res/values-hr/translations.xml index e350ab9f73..5c3290e187 100644 --- a/libraries/ui-strings/src/main/res/values-hr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hr/translations.xml @@ -492,10 +492,6 @@ Jeste li sigurni da želite nastaviti?" "Vaša poruka nije poslana jer %1$s nije potvrdio sve uređaje" "Jedan vaš uređaj ili više njih nije potvrđeno. Možete svejedno poslati poruku ili za sada otkazati i pokušati ponovno poslije nakon što potvrdite sve svoje uređaje." "Vaša poruka nije poslana jer niste potvrdili jedan svoj uređaj ili više njih" - "Promijeni postavke" - "Upravljaj prostorom" - "Upravljaj sobama" - "Dopuštenja" "Uredi administratore ili vlasnike" "Prijenos medija za obradu nije uspio, pokušajte ponovno." "Nije moguće dohvatiti korisničke podatke" diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index 203f2f893a..bf82feec26 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -492,10 +492,6 @@ Sunteți sigur că doriți să continuați?" "Mesajul dvs. nu a fost trimis deoarece %1$s nu si-a verificat toate dispozitivele" "Unul sau mai multe dispozitive nu sunt verificate. Puteți trimite mesajul oricum sau puteți anula deocamdată și încercați din nou mai târziu după ce ați verificat toate dispozitivele." "Mesajul dumneavoastră nu a fost trimis deoarece nu ați verificat unul sau mai multe dispozitive" - "Modificați setările" - "Gestionați spațiul" - "Gestionați camerele" - "Permisiuni" "Editați administratorii sau proprietarii" "Procesarea datelor media a eșuat, vă rugăm să încercați din nou." "Nu am putut găsi detaliile utilizatorului" diff --git a/libraries/ui-strings/src/main/res/values-sk/translations.xml b/libraries/ui-strings/src/main/res/values-sk/translations.xml index 694b679f45..d225eecc4f 100644 --- a/libraries/ui-strings/src/main/res/values-sk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sk/translations.xml @@ -462,10 +462,6 @@ Naozaj chcete pokračovať?" "Vaša správa nebola odoslaná, pretože %1$s neoveril/a všetky zariadenia." "Jedno alebo viac vašich zariadení nie je overených. Správu môžete odoslať aj tak, alebo môžete zatiaľ zrušiť a skúsiť to znova neskôr po overení všetkých svojich zariadení." "Vaša správa nebola odoslaná, pretože ste neoverili jedno alebo viac svojich zariadení" - "Zmeniť nastavenia" - "Spravovať priestor" - "Spravovať miestnosti" - "Povolenia" "Upraviť správcov alebo vlastníkov" "Nepodarilo sa spracovať médiá na odoslanie, skúste to prosím znova." "Nepodarilo sa získať údaje o používateľovi" From 624d63fca146a75c15479913e7238b4eafebc940 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 16 Dec 2025 11:32:22 +0100 Subject: [PATCH 133/347] quality: fix import --- .../rolesandpermissions/impl/root/RolesAndPermissionsNode.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt index f094174c66..da69ee52a9 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsNode.kt @@ -19,7 +19,6 @@ import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.libraries.architecture.callback import io.element.android.libraries.di.RoomScope -import io.element.android.libraries.matrix.api.room.BaseRoom @ContributesNode(RoomScope::class) @AssistedInject From 346595a1e6168c4886ae3614a0145c71eb587f28 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 16 Dec 2025 11:44:27 +0100 Subject: [PATCH 134/347] quality: fix test --- .../impl/SecurityAndPrivacyPresenterTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index a4542b02a1..5f3d14958c 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -244,7 +244,7 @@ class SecurityAndPrivacyPresenterTest { navigator = navigator, ) presenter.test { - skipItems(2) + skipItems(1) with(awaitItem()) { assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) @@ -312,7 +312,7 @@ class SecurityAndPrivacyPresenterTest { ) val presenter = createSecurityAndPrivacyPresenter(room = room) presenter.test { - skipItems(2) + skipItems(1) with(awaitItem()) { assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) From 2bb5125a8b230679fe4ef0cce153df992da591f9 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 16 Dec 2025 10:57:07 +0000 Subject: [PATCH 135/347] Update screenshots --- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_0_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_1_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_2_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_3_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_4_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Day_9_en.png | 4 ++-- .../features.space.impl.leave_LeaveSpaceView_Night_9_en.png | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png index 76a24059e1..1eb030d19f 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cc850fc418dc1407311120e7aa096d83d6ad4cff5abb2d15335d700175585ee6 -size 52471 +oid sha256:8e28c554285760b5f6675459170589f4d61b4bf6172dabb71b4369042f1fc079 +size 51781 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png index 4c6e7d3755..7541082b2a 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c93e3409aad7e2bc4cf9b0a9ae871fa22cdf1c0f80f7e5997cf4205a7bbb27bf -size 52396 +oid sha256:533af53d229b262035ec971bf30ce85c23c110a86d991ce142827d3bcd6d0c70 +size 51690 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png index 1537cb69c2..cd3ecb0c2b 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e88b49f64d50f47716f17b41007af13ed40a3b3892c1a22b909a57bee4d3251e -size 45645 +oid sha256:0de9ff1824d612f4e75e24ff253585c00ca8fb4b4d2a8fd7b25180971f08f6dd +size 45067 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png index a6e775a2b6..eacdf55dd7 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd9b90c305f5192f7c45910541c2e576227c939e5416821e152e4ea95fa39114 -size 43157 +oid sha256:7e23b6095d38a4d2cb80e507c850dc003060e7c461aa11c29b4cd6e0f21f935d +size 42563 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png index 684c54aab0..2b197f9430 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7ec3aa60b762fce4463e0e3ef4607eb9e04b0ce6d1cab6726361c4b45114a4f -size 49964 +oid sha256:ed51a1908b68ffdb0ac37ab8e6f53d86d0a47c226458b9feb0258f5d5fe6457d +size 49379 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en.png index fc1442fd2e..cf43bd1825 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4f62f14d6db6ebd24739ab8e6bd63f0ccda5603b9b425d19a5f08d3de4f706fc -size 51008 +oid sha256:c8901e6374a2be899a3128a85f18a4167aa68a0d80fde3ab76af907f079f897a +size 50370 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png index 64b5723ed7..47db703ee1 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:afb783af20ae5131e8b6c7982c3152f1121fd90ba5f6cd06c4371f18c38d2870 -size 50909 +oid sha256:f91162c6023dc96dbf5b9d6593a8266dccefe518028e7642267c8e5c68d74127 +size 50281 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png index 5db46a1c93..0bf89b26f0 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:52cf090186c65692a28b6702576a18dc64c22bcf5406b2e89931b22304aaaa00 -size 44188 +oid sha256:a4d5793d7c85bc89ab7e73fa5d5cd0afef24c976d5bf809e6b01392d6c6631b0 +size 43666 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png index 2ce42f90d0..759b82d88e 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e72fed367e540d65c58bc30dbfd7307c2eaa8b45f32f114c04af8d7394a82188 -size 41076 +oid sha256:5900ac981fb1bef222e3cda8ea84666a987e35c4aee4811529de67fad2fa90f7 +size 40543 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png index 6fa7228b9b..b34823a90e 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b5ad3057f13e64a7962dd33d96914cc6e08ad092924e727135bba1aee06fad1 -size 47822 +oid sha256:a5aab98cc9a302e18a230410fad290564091b57320f712daf3c0cc38522a4f35 +size 47303 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_9_en.png index 9f8cf23b73..930061aba1 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:264d55c8b65befa6e242e6864ba9be09ac9c3ed46e4033630445415f3c5ade83 -size 26111 +oid sha256:08e629078ddc8fe761305d7e3b1ce22344187a9b6bf4e729b85cfc6c59d2fde2 +size 33271 diff --git a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_9_en.png index 4f49ec35cf..e4293e23a2 100644 --- a/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.space.impl.leave_LeaveSpaceView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5bfbe783ade0202f2c3e38451cc0868f858425457a19651bd37e10f35277327 -size 25774 +oid sha256:5fc7f07a583f9dedb887ca83c67543e904d7bab092ebf70e06bc5292bf1e95b3 +size 32414 From 028741d81c34775c0c90f32d08fee1481ca88b1b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 16 Dec 2025 16:13:25 +0100 Subject: [PATCH 136/347] Format files. --- .../RustNotificationServiceTest.kt | 8 +++---- .../RustNotificationSettingsServiceTest.kt | 2 +- .../RustBaseRoomDirectoryServiceTest.kt | 2 +- .../impl/roomlist/RoomListFactoryTest.kt | 2 +- .../roomlist/RoomSummaryListProcessorTest.kt | 22 ++++++++--------- .../spaces/RoomSummaryListProcessorTest.kt | 24 +++++++++---------- .../impl/spaces/RustSpaceRoomListTest.kt | 6 ++--- .../MatrixTimelineDiffProcessorTest.kt | 22 ++++++++--------- .../timeline/TimelineItemsSubscriberTest.kt | 8 +++---- 9 files changed, 48 insertions(+), 48 deletions(-) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt index a1dffa7c64..df10c163a1 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt @@ -35,7 +35,7 @@ import org.matrix.rustcomponents.sdk.NotificationStatus import org.matrix.rustcomponents.sdk.TimelineEventType class RustNotificationServiceTest { - @Test + @Test fun test() = runTest { val notificationClient = FakeFfiNotificationClient( notificationItemResult = mapOf(AN_EVENT_ID.value to aRustBatchNotificationResult()), @@ -56,7 +56,7 @@ class RustNotificationServiceTest { ) } - @Test + @Test fun `test mapping invalid item only drops that item`() = runTest { val error = IllegalStateException("This event type is not supported") val faultyEvent = object : FakeFfiTimelineEvent() { @@ -83,7 +83,7 @@ class RustNotificationServiceTest { assertThat(successfulResult?.isSuccess).isTrue() } - @Test + @Test fun `test unable to resolve event`() = runTest { val notificationClient = FakeFfiNotificationClient( notificationItemResult = emptyMap(), @@ -95,7 +95,7 @@ class RustNotificationServiceTest { assertThat(exception).isInstanceOf(NotificationResolverException::class.java) } - @Test + @Test fun `close should invoke the close method of the service`() = runTest { val closeResult = lambdaRecorder { } val notificationClient = FakeFfiNotificationClient( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsServiceTest.kt index e9a121679b..73b7b888b2 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsServiceTest.kt @@ -20,7 +20,7 @@ import org.junit.Test import org.matrix.rustcomponents.sdk.NotificationSettings class RustNotificationSettingsServiceTest { - @Test + @Test fun test() = runTest { val sut = createRustNotificationSettingsService() val result = sut.getRoomNotificationSettings( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryServiceTest.kt index a873298f3e..ed97152311 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RustBaseRoomDirectoryServiceTest.kt @@ -14,7 +14,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Test class RustBaseRoomDirectoryServiceTest { - @Test + @Test fun test() = runTest { val client = FakeFfiClient() val sut = RustRoomDirectoryService( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactoryTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactoryTest.kt index 741ed93af8..ba45b310ef 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactoryTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactoryTest.kt @@ -16,7 +16,7 @@ import org.junit.Test import kotlin.coroutines.EmptyCoroutineContext class RoomListFactoryTest { - @Test + @Test fun `createRoomList should work`() = runTest { val sut = RoomListFactory( innerRoomListService = FakeFfiRoomListService(), diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt index 78c4f54626..022aa19ee7 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt @@ -28,7 +28,7 @@ import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate class RoomSummaryListProcessorTest { private val summaries = MutableStateFlow>(emptyList()) - @Test + @Test fun `Append adds new entries at the end of the list`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -40,7 +40,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value.subList(1, 4).all { it.roomId == A_ROOM_ID_2 }).isTrue() } - @Test + @Test fun `PushBack adds a new entry at the end of the list`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -50,7 +50,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value.last().roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `PushFront inserts a new entry at the start of the list`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -60,7 +60,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value.first().roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `Set replaces an entry at some index`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -72,7 +72,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `Insert inserts a new entry at the provided index`() = runTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() @@ -84,7 +84,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `Remove removes an entry at some index`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -99,7 +99,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `PopBack removes an entry at the end of the list`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -114,7 +114,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID) } - @Test + @Test fun `PopFront removes an entry at the start of the list`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -129,7 +129,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `Clear removes all the entries`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -142,7 +142,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value).isEmpty() } - @Test + @Test fun `Truncate removes all entries after the provided length`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), @@ -157,7 +157,7 @@ class RoomSummaryListProcessorTest { assertThat(summaries.value[index].roomId).isEqualTo(A_ROOM_ID) } - @Test + @Test fun `Reset removes all entries and add the provided ones`() = runTest { summaries.value = listOf( aRoomSummary(roomId = A_ROOM_ID), diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt index 253fd58dff..d21e259d42 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt @@ -24,7 +24,7 @@ import org.matrix.rustcomponents.sdk.SpaceListUpdate class RoomSummaryListProcessorTest { private val spaceRoomsFlow = MutableStateFlow>(emptyList()) - @Test + @Test fun `Append adds new entries at the end of the list`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -36,7 +36,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value.subList(1, 4).all { it.roomId == A_ROOM_ID_2 }).isTrue() } - @Test + @Test fun `PushBack adds a new entry at the end of the list`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -46,7 +46,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value.last().roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `PushFront inserts a new entry at the start of the list`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -56,7 +56,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value.first().roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `Set replaces an entry at some index`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -68,7 +68,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `Insert inserts a new entry at the provided index`() = runTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() @@ -80,7 +80,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `Remove removes an entry at some index`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -95,7 +95,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `PopBack removes an entry at the end of the list`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -110,7 +110,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID) } - @Test + @Test fun `PopFront removes an entry at the start of the list`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -125,7 +125,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_2) } - @Test + @Test fun `Clear removes all the entries`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -138,7 +138,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value).isEmpty() } - @Test + @Test fun `Truncate removes all entries after the provided length`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -153,7 +153,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID) } - @Test + @Test fun `Reset removes all entries and add the provided ones`() = runTest { spaceRoomsFlow.value = listOf( aSpaceRoom(roomId = A_ROOM_ID), @@ -168,7 +168,7 @@ class RoomSummaryListProcessorTest { assertThat(spaceRoomsFlow.value[index].roomId).isEqualTo(A_ROOM_ID_3) } - @Test + @Test fun `When there is no replay cache SpaceListUpdateProcessor starts with an empty list`() = runTest { val spaceRoomsSharedFlow = MutableSharedFlow>(replay = 1) val processor = createProcessor( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt index a0f8181c48..e966309c87 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt @@ -29,7 +29,7 @@ import uniffi.matrix_sdk_ui.SpaceRoomListPaginationState import org.matrix.rustcomponents.sdk.SpaceRoomList as InnerSpaceRoomList class RustSpaceRoomListTest { - @Test + @Test fun `paginationStatusFlow emits values`() = runTest { val innerSpaceRoomList = FakeFfiSpaceRoomList( paginationStateResult = { SpaceRoomListPaginationState.Idle(false) } @@ -51,7 +51,7 @@ class RustSpaceRoomListTest { } } - @Test + @Test fun `spaceRoomsFlow emits values`() = runTest { val innerSpaceRoomList = FakeFfiSpaceRoomList( paginationStateResult = { SpaceRoomListPaginationState.Idle(false) } @@ -73,7 +73,7 @@ class RustSpaceRoomListTest { } } - @Test + @Test fun `paginate invokes paginate on the inner class`() = runTest { val paginateResult = lambdaRecorder { } val innerSpaceRoomList = FakeFfiSpaceRoomList( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessorTest.kt index 9b5af1ffb4..308d2f66a6 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessorTest.kt @@ -30,7 +30,7 @@ class MatrixTimelineDiffProcessorTest { private val anEvent = MatrixTimelineItem.Event(A_UNIQUE_ID, anEventTimelineItem()) private val anEvent2 = MatrixTimelineItem.Event(A_UNIQUE_ID_2, anEventTimelineItem()) - @Test + @Test fun `Append adds new entries at the end of the list`() = runTest { timelineItems.value = listOf(anEvent) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -42,7 +42,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Test + @Test fun `PushBack adds a new entry at the end of the list`() = runTest { timelineItems.value = listOf(anEvent) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -54,7 +54,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Test + @Test fun `PushFront inserts a new entry at the start of the list`() = runTest { timelineItems.value = listOf(anEvent) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -66,7 +66,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Test + @Test fun `Set replaces an entry at some index`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -78,7 +78,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Test + @Test fun `Insert inserts a new entry at the provided index`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -91,7 +91,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Test + @Test fun `Remove removes an entry at some index`() = runTest { timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -103,7 +103,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Test + @Test fun `PopBack removes an entry at the end of the list`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -114,7 +114,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Test + @Test fun `PopFront removes an entry at the start of the list`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -125,7 +125,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Test + @Test fun `Clear removes all the entries`() = runTest { timelineItems.value = listOf(anEvent, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -133,7 +133,7 @@ class MatrixTimelineDiffProcessorTest { assertThat(timelineItems.value).isEmpty() } - @Test + @Test fun `Truncate removes all entries after the provided length`() = runTest { timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) @@ -144,7 +144,7 @@ class MatrixTimelineDiffProcessorTest { ) } - @Test + @Test fun `Reset removes all entries and add the provided ones`() = runTest { timelineItems.value = listOf(anEvent, MatrixTimelineItem.Other, anEvent2) val processor = createMatrixTimelineDiffProcessor(timelineItems) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriberTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriberTest.kt index 607f575a2d..9a03374d7e 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriberTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriberTest.kt @@ -27,7 +27,7 @@ import uniffi.matrix_sdk_ui.EventItemOrigin @OptIn(ExperimentalCoroutinesApi::class) class TimelineItemsSubscriberTest { - @Test + @Test fun `when timeline emits an empty list of items, the flow must emits an empty list`() = runTest { val timelineItems: MutableSharedFlow> = MutableSharedFlow(replay = 1, extraBufferCapacity = Int.MAX_VALUE) @@ -50,7 +50,7 @@ class TimelineItemsSubscriberTest { } } - @Test + @Test fun `when timeline emits a non empty list of items, the flow must emits a non empty list`() = runTest { val timelineItems: MutableSharedFlow> = MutableSharedFlow(replay = 1, extraBufferCapacity = Int.MAX_VALUE) @@ -73,7 +73,7 @@ class TimelineItemsSubscriberTest { } } - @Test + @Test fun `when timeline emits an item with SYNC origin`() = runTest { val timelineItems: MutableSharedFlow> = MutableSharedFlow(replay = 1, extraBufferCapacity = Int.MAX_VALUE) @@ -104,7 +104,7 @@ class TimelineItemsSubscriberTest { } } - @Test + @Test fun `multiple subscriptions does not have side effect`() = runTest { val timelineItemsSubscriber = createTimelineItemsSubscriber() timelineItemsSubscriber.subscribeIfNeeded() From fd446e98dd04b417039a5519d5ea0f4d0eb75f92 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 4 Dec 2025 10:52:26 +0100 Subject: [PATCH 137/347] Link new device using QrCode. --- appnav/build.gradle.kts | 1 + .../android/appnav/LoggedInFlowNode.kt | 17 ++ .../ChooseSelfVerificationModeView.kt | 13 +- features/linknewdevice/api/build.gradle.kts | 17 ++ .../api/LinkNewDeviceEntryPoint.kt | 25 ++ features/linknewdevice/impl/build.gradle.kts | 63 ++++ .../impl/src/main/AndroidManifest.xml | 17 ++ .../impl/DefaultLinkNewDeviceEntryPoint.kt | 31 ++ .../impl/LinkNewDesktopHandler.kt | 74 +++++ .../impl/LinkNewDeviceFlowNode.kt | 284 ++++++++++++++++++ .../impl/LinkNewMobileHandler.kt | 68 +++++ .../screens/desktop/DesktopNoticeEvent.kt | 12 + .../impl/screens/desktop/DesktopNoticeNode.kt | 45 +++ .../screens/desktop/DesktopNoticePresenter.kt | 57 ++++ .../screens/desktop/DesktopNoticeState.kt | 16 + .../desktop/DesktopNoticeStateProvider.kt | 35 +++ .../impl/screens/desktop/DesktopNoticeView.kt | 112 +++++++ .../impl/screens/error/ErrorNode.kt | 43 +++ .../impl/screens/error/ErrorScreenType.kt | 40 +++ .../screens/error/ErrorScreenTypeProvider.kt | 23 ++ .../impl/screens/error/ErrorView.kt | 138 +++++++++ .../impl/screens/number/Config.kt | 12 + .../impl/screens/number/EnterNumberEvent.kt | 13 + .../impl/screens/number/EnterNumberNode.kt | 54 ++++ .../screens/number/EnterNumberPresenter.kt | 108 +++++++ .../impl/screens/number/EnterNumberState.kt | 21 ++ .../number/EnterNumberStateProvider.kt | 34 +++ .../impl/screens/number/EnterNumberView.kt | 125 ++++++++ .../number/component/NumberTextField.kt | 169 +++++++++++ .../impl/screens/number/model/Digit.kt | 23 ++ .../impl/screens/number/model/Number.kt | 56 ++++ .../impl/screens/qrcode/ShowQrCodeNode.kt | 48 +++ .../impl/screens/qrcode/ShowQrCodeView.kt | 89 ++++++ .../screens/root/LinkNewDeviceRootEvent.kt | 13 + .../screens/root/LinkNewDeviceRootNode.kt | 45 +++ .../root/LinkNewDeviceRootPresenter.kt | 85 ++++++ .../screens/root/LinkNewDeviceRootState.kt | 16 + .../root/LinkNewDeviceRootStateProvider.kt | 40 +++ .../screens/root/LinkNewDeviceRootView.kt | 152 ++++++++++ .../impl/screens/scan/ScanQrCodeEvent.kt | 13 + .../impl/screens/scan/ScanQrCodeNode.kt | 43 +++ .../impl/screens/scan/ScanQrCodePresenter.kt | 73 +++++ .../impl/screens/scan/ScanQrCodeState.kt | 15 + .../screens/scan/ScanQrCodeStateProvider.kt | 29 ++ .../impl/screens/scan/ScanQrCodeView.kt | 174 +++++++++++ .../impl/src/main/res/values/localazy.xml | 55 ++++ .../desktop/DesktopNoticePresenterTest.kt | 58 ++++ .../screens/desktop/DesktopNoticeViewTest.kt | 86 ++++++ .../impl/screens/error/ErrorViewTest.kt | 59 ++++ .../number/EnterNumberPresenterTest.kt | 191 ++++++++++++ .../screens/number/EnterNumberStateTest.kt | 94 ++++++ .../screens/number/EnterNumberViewTest.kt | 92 ++++++ .../number/FakeEnterNumberNavigator.kt | 18 ++ .../impl/screens/qrcode/ShowQrCodeViewTest.kt | 47 +++ .../root/LinkNewDeviceRootPresenterTest.kt | 74 +++++ .../screens/root/LinkNewDeviceRootViewTest.kt | 102 +++++++ .../screens/scan/ScanQrCodePresenterTest.kt | 112 +++++++ .../impl/screens/scan/ScanQrCodeViewTest.kt | 70 +++++ features/linknewdevice/test/build.gradle.kts | 19 ++ .../preferences/api/PreferencesEntryPoint.kt | 1 + .../preferences/impl/PreferencesFlowNode.kt | 4 + .../impl/root/PreferencesRootNode.kt | 2 + .../impl/root/PreferencesRootPresenter.kt | 4 + .../impl/root/PreferencesRootState.kt | 1 + .../impl/root/PreferencesRootStateProvider.kt | 1 + .../impl/root/PreferencesRootView.kt | 11 + .../impl/DefaultPreferencesEntryPointTest.kt | 1 + .../impl/root/PreferencesRootPresenterTest.kt | 17 ++ gradle/libs.versions.toml | 3 + .../androidutils/system/Brightness.kt | 27 ++ .../atomic/atoms/LoadingButtonAtom.kt | 26 ++ .../designsystem/utils/ForceMaxBrightness.kt | 24 ++ .../libraries/featureflag/api/FeatureFlags.kt | 7 + .../libraries/matrix/api/MatrixClient.kt | 17 ++ .../api/linknewdevice/CheckCodeSender.kt | 22 ++ .../matrix/api/linknewdevice/ErrorType.kt | 45 +++ .../api/linknewdevice/LinkDesktopHandler.kt | 41 +++ .../api/linknewdevice/LinkMobileHandler.kt | 26 ++ .../libraries/matrix/api/logs/LoggerTags.kt | 14 + .../libraries/matrix/impl/RustMatrixClient.kt | 32 ++ .../HumanQrGrantLoginExceptionExtension.kt | 21 ++ .../impl/linknewdevice/RustCheckCodeSender.kt | 33 ++ .../linknewdevice/RustLinkDesktopHandler.kt | 82 +++++ .../linknewdevice/RustLinkMobileHandler.kt | 75 +++++ .../libraries/matrix/test/FakeMatrixClient.kt | 17 ++ .../android/libraries/matrix/test/TestData.kt | 28 ++ .../test/linknewdevice/FakeCheckCodeSender.kt | 25 ++ .../linknewdevice/FakeLinkDesktopHandler.kt | 31 ++ .../linknewdevice/FakeLinkMobileHandler.kt | 32 ++ libraries/qrcode/build.gradle.kts | 1 + .../libraries/qrcode/QrCodeCameraView.kt | 9 +- .../android/libraries/qrcode/QrCodeImage.kt | 92 ++++++ .../src/main/res/values/localazy.xml | 26 -- tools/localazy/config.json | 11 + 94 files changed, 4431 insertions(+), 36 deletions(-) create mode 100644 features/linknewdevice/api/build.gradle.kts create mode 100644 features/linknewdevice/api/src/main/kotlin/io/element/android/features/linknewdevice/api/LinkNewDeviceEntryPoint.kt create mode 100644 features/linknewdevice/impl/build.gradle.kts create mode 100644 features/linknewdevice/impl/src/main/AndroidManifest.xml create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/DefaultLinkNewDeviceEntryPoint.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDesktopHandler.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewMobileHandler.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeEvent.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeNode.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenter.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeState.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeStateProvider.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeView.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorNode.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorScreenType.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorScreenTypeProvider.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorView.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/Config.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberEvent.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberNode.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberPresenter.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberState.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberStateProvider.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberView.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/component/NumberTextField.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/model/Digit.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/model/Number.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeNode.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeView.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootEvent.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootNode.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenter.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootState.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootStateProvider.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootView.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeEvent.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeNode.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenter.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeState.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeStateProvider.kt create mode 100644 features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeView.kt create mode 100644 features/linknewdevice/impl/src/main/res/values/localazy.xml create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenterTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeViewTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorViewTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberPresenterTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberStateTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberViewTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/FakeEnterNumberNavigator.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeViewTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenterTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootViewTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenterTest.kt create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeViewTest.kt create mode 100644 features/linknewdevice/test/build.gradle.kts create mode 100644 libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/Brightness.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/LoadingButtonAtom.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/ForceMaxBrightness.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/CheckCodeSender.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/ErrorType.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/LinkDesktopHandler.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/LinkMobileHandler.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/logs/LoggerTags.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/HumanQrGrantLoginExceptionExtension.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustCheckCodeSender.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandler.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkMobileHandler.kt create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeCheckCodeSender.kt create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeLinkDesktopHandler.kt create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeLinkMobileHandler.kt create mode 100644 libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeImage.kt diff --git a/appnav/build.gradle.kts b/appnav/build.gradle.kts index aa0bc04772..84d614b3d9 100644 --- a/appnav/build.gradle.kts +++ b/appnav/build.gradle.kts @@ -48,6 +48,7 @@ dependencies { implementation(projects.features.announcement.api) implementation(projects.features.ftue.api) + implementation(projects.features.linknewdevice.api) implementation(projects.features.share.api) implementation(projects.services.apperror.impl) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 38dc39ee83..92c3cfe3dd 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -53,6 +53,7 @@ import io.element.android.features.ftue.api.FtueEntryPoint import io.element.android.features.ftue.api.state.FtueService import io.element.android.features.ftue.api.state.FtueState import io.element.android.features.home.api.HomeEntryPoint +import io.element.android.features.linknewdevice.api.LinkNewDeviceEntryPoint import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorContainer @@ -123,6 +124,7 @@ class LoggedInFlowNode( private val secureBackupEntryPoint: SecureBackupEntryPoint, private val userProfileEntryPoint: UserProfileEntryPoint, private val ftueEntryPoint: FtueEntryPoint, + private val linkNewDeviceEntryPoint: LinkNewDeviceEntryPoint, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, private val ftueService: FtueService, @@ -293,6 +295,9 @@ class LoggedInFlowNode( @Parcelize data object Ftue : NavTarget + @Parcelize + data object LinkNewDevice : NavTarget + @Parcelize data object RoomDirectory : NavTarget @@ -419,6 +424,10 @@ class LoggedInFlowNode( callback.navigateToAddAccount() } + override fun navigateToLinkNewDevice() { + backstack.push(NavTarget.LinkNewDevice) + } + override fun navigateToBugReport() { callback.navigateToBugReport() } @@ -475,6 +484,14 @@ class LoggedInFlowNode( NavTarget.Ftue -> { ftueEntryPoint.createNode(this, buildContext) } + NavTarget.LinkNewDevice -> { + val callback = object : LinkNewDeviceEntryPoint.Callback { + override fun onDone() { + backstack.pop() + } + } + linkNewDeviceEntryPoint.createNode(this, buildContext, callback) + } NavTarget.RoomDirectory -> { roomDirectoryEntryPoint.createNode( parentNode = this, diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt index e4e922f933..bd0cdead71 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt @@ -25,6 +25,7 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.ftue.impl.R import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.designsystem.atomic.atoms.LoadingButtonAtom import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage @@ -88,8 +89,8 @@ fun ChooseSelfVerificationModeView( ) { Text( modifier = Modifier - .clickable(onClick = onLearnMore) - .padding(vertical = 4.dp, horizontal = 16.dp), + .clickable(onClick = onLearnMore) + .padding(vertical = 4.dp, horizontal = 16.dp), text = stringResource(CommonStrings.action_learn_more), style = ElementTheme.typography.fontBodyLgMedium ) @@ -111,13 +112,7 @@ private fun ChooseSelfVerificationModeButtons( AsyncData.Uninitialized, is AsyncData.Failure, is AsyncData.Loading -> { - Button( - modifier = Modifier.fillMaxWidth(), - enabled = false, - showProgress = true, - text = stringResource(CommonStrings.common_loading), - onClick = {}, - ) + LoadingButtonAtom() } is AsyncData.Success -> { if (state.buttonsState.data.canUseAnotherDevice) { diff --git a/features/linknewdevice/api/build.gradle.kts b/features/linknewdevice/api/build.gradle.kts new file mode 100644 index 0000000000..7d368f0a63 --- /dev/null +++ b/features/linknewdevice/api/build.gradle.kts @@ -0,0 +1,17 @@ +/* + * 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. + */ +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.features.linknewdevice.api" +} + +dependencies { + implementation(projects.libraries.architecture) +} diff --git a/features/linknewdevice/api/src/main/kotlin/io/element/android/features/linknewdevice/api/LinkNewDeviceEntryPoint.kt b/features/linknewdevice/api/src/main/kotlin/io/element/android/features/linknewdevice/api/LinkNewDeviceEntryPoint.kt new file mode 100644 index 0000000000..061bbeb084 --- /dev/null +++ b/features/linknewdevice/api/src/main/kotlin/io/element/android/features/linknewdevice/api/LinkNewDeviceEntryPoint.kt @@ -0,0 +1,25 @@ +/* + * 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.linknewdevice.api + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import io.element.android.libraries.architecture.FeatureEntryPoint + +interface LinkNewDeviceEntryPoint : FeatureEntryPoint { + interface Callback : Plugin { + fun onDone() + } + + fun createNode( + parentNode: Node, + buildContext: BuildContext, + callback: Callback, + ): Node +} diff --git a/features/linknewdevice/impl/build.gradle.kts b/features/linknewdevice/impl/build.gradle.kts new file mode 100644 index 0000000000..9c1aa9e990 --- /dev/null +++ b/features/linknewdevice/impl/build.gradle.kts @@ -0,0 +1,63 @@ +import extension.setupDependencyInjection +import extension.testCommonDependencies + +/* + * 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. + */ + +plugins { + id("io.element.android-compose-library") + id("kotlin-parcelize") + alias(libs.plugins.kotlin.serialization) +} + +android { + namespace = "io.element.android.features.linknewdevice.impl" + + testOptions { + unitTests { + isIncludeAndroidResources = true + } + } +} + +setupDependencyInjection() + +dependencies { + // TODO Cleanup + implementation(projects.appconfig) + implementation(projects.features.enterprise.api) + implementation(projects.features.rageshake.api) + implementation(projects.libraries.core) + implementation(projects.libraries.androidutils) + implementation(projects.libraries.architecture) + implementation(projects.libraries.featureflag.api) + implementation(projects.libraries.matrix.api) + implementation(projects.libraries.matrix.api) + implementation(projects.libraries.designsystem) + implementation(projects.libraries.testtags) + implementation(projects.libraries.uiStrings) + implementation(projects.libraries.permissions.api) + implementation(projects.libraries.sessionStorage.api) + implementation(projects.libraries.qrcode) + implementation(projects.libraries.oidc.api) + implementation(projects.libraries.uiUtils) + implementation(projects.libraries.wellknown.api) + implementation(libs.androidx.browser) + implementation(libs.androidx.webkit) + implementation(libs.serialization.json) + api(projects.features.linknewdevice.api) + + testCommonDependencies(libs, true) + testImplementation(projects.features.linknewdevice.test) + testImplementation(projects.features.enterprise.test) + testImplementation(projects.libraries.featureflag.test) + testImplementation(projects.libraries.matrix.test) + testImplementation(projects.libraries.oidc.test) + testImplementation(projects.libraries.permissions.test) + testImplementation(projects.libraries.sessionStorage.test) + testImplementation(projects.libraries.wellknown.test) +} diff --git a/features/linknewdevice/impl/src/main/AndroidManifest.xml b/features/linknewdevice/impl/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..d225716fc4 --- /dev/null +++ b/features/linknewdevice/impl/src/main/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/DefaultLinkNewDeviceEntryPoint.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/DefaultLinkNewDeviceEntryPoint.kt new file mode 100644 index 0000000000..5edc3cdfcd --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/DefaultLinkNewDeviceEntryPoint.kt @@ -0,0 +1,31 @@ +/* + * 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.linknewdevice.impl + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import dev.zacsweers.metro.ContributesBinding +import io.element.android.features.linknewdevice.api.LinkNewDeviceEntryPoint +import io.element.android.libraries.architecture.createNode +import io.element.android.libraries.di.SessionScope + +@ContributesBinding(SessionScope::class) +class DefaultLinkNewDeviceEntryPoint : LinkNewDeviceEntryPoint { + override fun createNode( + parentNode: Node, + buildContext: BuildContext, + callback: LinkNewDeviceEntryPoint.Callback, + ): Node { + return parentNode.createNode( + buildContext = buildContext, + plugins = listOf( + callback, + ) + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDesktopHandler.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDesktopHandler.kt new file mode 100644 index 0000000000..a8a8ff14b6 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDesktopHandler.kt @@ -0,0 +1,74 @@ +/* + * 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.linknewdevice.impl + +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import io.element.android.libraries.core.log.logger.LoggerTag +import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopStep +import io.element.android.libraries.matrix.api.logs.LoggerTags +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch +import timber.log.Timber + +private val loggerTag = LoggerTag("LinkNewDesktopHandler", LoggerTags.linkNewDevice) + +@Inject +@SingleIn(SessionScope::class) +class LinkNewDesktopHandler( + private val matrixClient: MatrixClient, +) { + private val sessionScope = matrixClient.sessionCoroutineScope + private val linkDesktopStepFlow = MutableStateFlow( + LinkDesktopStep.Uninitialized + ) + + val stepFlow: StateFlow + get() = linkDesktopStepFlow.asStateFlow() + + private var currentJob: Job? = null + private var handler: LinkDesktopHandler? = null + + fun createNewHandler() { + currentJob?.cancel() + currentJob = null + handler = matrixClient.createLinkDesktopHandler().getOrNull() + } + + fun reset() { + currentJob?.cancel() + currentJob = null + sessionScope.launch { + linkDesktopStepFlow.emit(LinkDesktopStep.Uninitialized) + } + } + + fun onScannedCode(data: ByteArray) { + currentJob?.cancel() + currentJob = null + val currentHandler = handler + if (currentHandler == null) { + Timber.tag(loggerTag.value).e("onScannedCode: Handler is not initialized. Call createNewHandler() first.") + } else { + currentJob = matrixClient.sessionCoroutineScope.launch { + currentHandler.linkDesktopStep.onEach { + linkDesktopStepFlow.emit(it) + }.launchIn(this) + currentHandler.handleScannedQrCode(data) + } + } + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt new file mode 100644 index 0000000000..3294476c44 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt @@ -0,0 +1,284 @@ +/* + * 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.linknewdevice.impl + +import android.app.Activity +import android.os.Parcelable +import androidx.activity.compose.LocalActivity +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.lifecycle.subscribe +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import com.bumble.appyx.navmodel.backstack.BackStack +import com.bumble.appyx.navmodel.backstack.operation.newRoot +import com.bumble.appyx.navmodel.backstack.operation.pop +import com.bumble.appyx.navmodel.backstack.operation.push +import com.bumble.appyx.navmodel.backstack.operation.replace +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.compound.theme.ElementTheme +import io.element.android.features.linknewdevice.api.LinkNewDeviceEntryPoint +import io.element.android.features.linknewdevice.impl.screens.desktop.DesktopNoticeNode +import io.element.android.features.linknewdevice.impl.screens.error.ErrorNode +import io.element.android.features.linknewdevice.impl.screens.error.ErrorScreenType +import io.element.android.features.linknewdevice.impl.screens.number.EnterNumberNode +import io.element.android.features.linknewdevice.impl.screens.qrcode.ShowQrCodeNode +import io.element.android.features.linknewdevice.impl.screens.root.LinkNewDeviceRootNode +import io.element.android.features.linknewdevice.impl.screens.scan.ScanQrCodeNode +import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab +import io.element.android.libraries.architecture.BackstackView +import io.element.android.libraries.architecture.BaseFlowNode +import io.element.android.libraries.architecture.callback +import io.element.android.libraries.architecture.createNode +import io.element.android.libraries.core.log.logger.LoggerTag +import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.di.annotations.SessionCoroutineScope +import io.element.android.libraries.matrix.api.linknewdevice.ErrorType +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopStep +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep +import io.element.android.libraries.matrix.api.logs.LoggerTags +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.parcelize.Parcelize +import timber.log.Timber + +private val tag = LoggerTag("LinkNewDeviceFlowNode", LoggerTags.linkNewDevice) + +@ContributesNode(SessionScope::class) +@AssistedInject +class LinkNewDeviceFlowNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + @SessionCoroutineScope + private val sessionCoroutineScope: CoroutineScope, + private val linkNewMobileHandler: LinkNewMobileHandler, + private val linkNewDesktopHandler: LinkNewDesktopHandler, +) : BaseFlowNode( + backstack = BackStack( + initialElement = NavTarget.Root, + savedStateMap = buildContext.savedStateMap, + ), + buildContext = buildContext, + plugins = plugins, +) { + private val callback: LinkNewDeviceEntryPoint.Callback = callback() + private var activity: Activity? = null + private var darkTheme: Boolean = false + + override fun onBuilt() { + super.onBuilt() + var job1: Job? = null + var job2: Job? = null + + lifecycle.subscribe( + onCreate = { + linkNewMobileHandler.reset() + linkNewDesktopHandler.reset() + @Suppress("AssignedValueIsNeverRead") + job1 = observeLinkNewMobileHandler() + @Suppress("AssignedValueIsNeverRead") + job2 = observeLinkNewDesktopHandler() + }, + onDestroy = { + job1?.cancel() + job2?.cancel() + } + ) + } + + sealed interface NavTarget : Parcelable { + // Will display the not supported state or the device type selection + @Parcelize + data object Root : NavTarget + + @Parcelize + data class MobileShowQrCode( + val data: String, + ) : NavTarget + + @Parcelize + data object MobileEnterNumber : NavTarget + + @Parcelize + data object DesktopNotice : NavTarget + + @Parcelize + data object DesktopScanQrCode : NavTarget + + @Parcelize + data class Error( + val errorScreenType: ErrorScreenType, + ) : NavTarget + } + + private fun observeLinkNewMobileHandler(): Job { + Timber.tag(tag.value).d("startObservingLinkNewMobileHandler") + return linkNewMobileHandler.stepFlow + .onEach { linkMobileStep -> + Timber.tag(tag.value).d("step: ${linkMobileStep::class.java.simpleName}") + when (linkMobileStep) { + LinkMobileStep.Uninitialized -> Unit + LinkMobileStep.Done -> { + callback.onDone() + } + is LinkMobileStep.Error -> { + navigateToError(linkMobileStep.errorType) + } + is LinkMobileStep.QrReady -> { + // The QrCode is ready, navigate to its display + backstack.push(NavTarget.MobileShowQrCode(linkMobileStep.data)) + } + is LinkMobileStep.QrScanned -> { + backstack.replace(NavTarget.MobileEnterNumber) + } + LinkMobileStep.Starting -> { + // This step is not received at the moment, so do nothing + } + LinkMobileStep.SyncingSecrets -> { + // LinkMobileStep.Done is not received at the moment, so consider that the flow is done here + callback.onDone() + } + is LinkMobileStep.WaitingForAuth -> { + navigateToBrowser(linkMobileStep.verificationUri) + } + } + } + .launchIn(sessionCoroutineScope) + } + + private fun observeLinkNewDesktopHandler(): Job { + Timber.tag(tag.value).d("startObservingLinkNewDesktopHandler") + return linkNewDesktopHandler.stepFlow.onEach { linkDesktopStep -> + Timber.tag(tag.value).d("step: ${linkDesktopStep::class.java.simpleName}") + when (linkDesktopStep) { + LinkDesktopStep.Done -> callback.onDone() + is LinkDesktopStep.Error -> { + navigateToError(linkDesktopStep.errorType) + } + is LinkDesktopStep.EstablishingSecureChannel -> Unit + is LinkDesktopStep.InvalidQrCode -> { + // This error will be handled by the ScanQrCodeNode + } + LinkDesktopStep.Starting -> Unit + LinkDesktopStep.SyncingSecrets -> Unit + LinkDesktopStep.Uninitialized -> Unit + is LinkDesktopStep.WaitingForAuth -> { + navigateToBrowser(linkDesktopStep.verificationUri) + } + } + } + .launchIn(sessionCoroutineScope) + } + + private fun navigateToError(errorType: ErrorType) { + // Map the error to an error screen + // TODO Update this mapping + val error = when (errorType) { + is ErrorType.DeviceIdAlreadyInUse -> ErrorScreenType.UnknownError + is ErrorType.InvalidCheckCode -> ErrorScreenType.InsecureChannelDetected + is ErrorType.MissingSecretsBackup -> ErrorScreenType.UnknownError + is ErrorType.NotFound -> ErrorScreenType.Expired + is ErrorType.UnableToCreateDevice -> ErrorScreenType.UnknownError + is ErrorType.Unknown -> ErrorScreenType.UnknownError + is ErrorType.UnsupportedProtocol -> ErrorScreenType.UnknownError + } + // It is OK to push on backstack, since when user leaves the error screen, a new root will be set + backstack.push(NavTarget.Error(error)) + } + + override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { + return when (navTarget) { + NavTarget.Root -> { + val callback = object : LinkNewDeviceRootNode.Callback { + override fun onDone() { + callback.onDone() + } + + override fun linkDesktopDevice() { + linkNewDesktopHandler.reset() + backstack.push(NavTarget.DesktopNotice) + } + } + createNode(buildContext, listOf(callback)) + } + NavTarget.DesktopNotice -> { + val callback = object : DesktopNoticeNode.Callback { + override fun navigateBack() { + backstack.pop() + } + + override fun navigateToQrCodeScanner() { + backstack.push(NavTarget.DesktopScanQrCode) + } + } + createNode(buildContext, listOf(callback)) + } + NavTarget.DesktopScanQrCode -> { + val callback = object : ScanQrCodeNode.Callback { + override fun cancel() { + backstack.pop() + } + } + createNode(buildContext, listOf(callback)) + } + NavTarget.MobileEnterNumber -> { + val callback = object : EnterNumberNode.Callback { + override fun navigateToWrongNumberError() { + backstack.push(NavTarget.Error(ErrorScreenType.Mismatch2Digits)) + } + + override fun navigateBack() { + backstack.pop() + } + } + createNode(buildContext, listOf(callback)) + } + is NavTarget.MobileShowQrCode -> { + val callback = object : ShowQrCodeNode.Callback { + override fun navigateBack() { + backstack.pop() + } + } + val inputs = ShowQrCodeNode.Inputs( + data = navTarget.data, + ) + createNode(buildContext, listOf(inputs, callback)) + } + is NavTarget.Error -> { + val callback = object : ErrorNode.Callback { + override fun onRetry() { + backstack.newRoot(NavTarget.Root) + } + } + createNode(buildContext, listOf(callback, navTarget.errorScreenType)) + } + } + } + + private fun navigateToBrowser(url: String) { + activity?.openUrlInChromeCustomTab(null, darkTheme, url) + } + + @Composable + override fun View(modifier: Modifier) { + activity = requireNotNull(LocalActivity.current) + darkTheme = !ElementTheme.isLightTheme + DisposableEffect(Unit) { + onDispose { + activity = null + } + } + BackstackView() + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewMobileHandler.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewMobileHandler.kt new file mode 100644 index 0000000000..157d946eaa --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewMobileHandler.kt @@ -0,0 +1,68 @@ +/* + * 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.linknewdevice.impl + +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import io.element.android.libraries.core.log.logger.LoggerTag +import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep +import io.element.android.libraries.matrix.api.logs.LoggerTags +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch +import timber.log.Timber + +private val loggerTag = LoggerTag("LinkNewMobileHandler", LoggerTags.linkNewDevice) + +@Inject +@SingleIn(SessionScope::class) +class LinkNewMobileHandler( + private val matrixClient: MatrixClient, +) { + private val sessionScope = matrixClient.sessionCoroutineScope + private var currentJob: Job? = null + private var handler: LinkMobileHandler? = null + + private val linkMobileStepFlow = MutableStateFlow( + LinkMobileStep.Uninitialized + ) + + val stepFlow: StateFlow + get() = linkMobileStepFlow.asStateFlow() + + fun createAndStartNewHandler() { + Timber.tag(loggerTag.value).d("createAndStartNewHandler()") + currentJob?.cancel() + handler = matrixClient.createLinkMobileHandler().getOrNull() + handler?.let { h -> + currentJob = sessionScope.launch { + h.linkMobileStep + .onEach { + linkMobileStepFlow.emit(it) + } + .launchIn(this) + h.start() + } + } + } + + fun reset() { + currentJob?.cancel() + currentJob = null + sessionScope.launch { + linkMobileStepFlow.emit(LinkMobileStep.Uninitialized) + } + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeEvent.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeEvent.kt new file mode 100644 index 0000000000..3d94da3fc6 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeEvent.kt @@ -0,0 +1,12 @@ +/* + * 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.linknewdevice.impl.screens.desktop + +sealed interface DesktopNoticeEvent { + data object Continue : DesktopNoticeEvent +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeNode.kt new file mode 100644 index 0000000000..895d02731a --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeNode.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.linknewdevice.impl.screens.desktop + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.libraries.architecture.callback +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +@AssistedInject +class DesktopNoticeNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: DesktopNoticePresenter, +) : Node(buildContext, plugins = plugins) { + interface Callback : Plugin { + fun navigateBack() + fun navigateToQrCodeScanner() + } + + private val callback: Callback = callback() + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + DesktopNoticeView( + state = state, + modifier = modifier, + onBackClick = callback::navigateBack, + onReadyToScanClick = callback::navigateToQrCodeScanner, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenter.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenter.kt new file mode 100644 index 0000000000..3b01725fe1 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenter.kt @@ -0,0 +1,57 @@ +/* + * 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.linknewdevice.impl.screens.desktop + +import android.Manifest +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import dev.zacsweers.metro.Inject +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.permissions.api.PermissionsEvent +import io.element.android.libraries.permissions.api.PermissionsPresenter + +@Inject +class DesktopNoticePresenter( + permissionsPresenterFactory: PermissionsPresenter.Factory, +) : Presenter { + private val cameraPermissionPresenter: PermissionsPresenter = permissionsPresenterFactory.create(Manifest.permission.CAMERA) + private var pendingPermissionRequest by mutableStateOf(false) + + @Composable + override fun present(): DesktopNoticeState { + val cameraPermissionState = cameraPermissionPresenter.present() + var canContinue by remember { mutableStateOf(false) } + LaunchedEffect(cameraPermissionState.permissionGranted) { + if (cameraPermissionState.permissionGranted && pendingPermissionRequest) { + pendingPermissionRequest = false + canContinue = true + } + } + + fun handleEvent(event: DesktopNoticeEvent) { + when (event) { + DesktopNoticeEvent.Continue -> if (cameraPermissionState.permissionGranted) { + canContinue = true + } else { + pendingPermissionRequest = true + cameraPermissionState.eventSink(PermissionsEvent.RequestPermissions) + } + } + } + + return DesktopNoticeState( + cameraPermissionState = cameraPermissionState, + canContinue = canContinue, + eventSink = ::handleEvent, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeState.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeState.kt new file mode 100644 index 0000000000..81991b5ab2 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeState.kt @@ -0,0 +1,16 @@ +/* + * 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.linknewdevice.impl.screens.desktop + +import io.element.android.libraries.permissions.api.PermissionsState + +data class DesktopNoticeState( + val cameraPermissionState: PermissionsState, + val canContinue: Boolean, + val eventSink: (DesktopNoticeEvent) -> Unit, +) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeStateProvider.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeStateProvider.kt new file mode 100644 index 0000000000..194bd6fafc --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeStateProvider.kt @@ -0,0 +1,35 @@ +/* + * 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.linknewdevice.impl.screens.desktop + +import android.Manifest +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.permissions.api.PermissionsState +import io.element.android.libraries.permissions.api.aPermissionsState + +open class DesktopNoticeStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aDesktopNoticeState(), + aDesktopNoticeState(cameraPermissionState = aPermissionsState(showDialog = true, permission = Manifest.permission.CAMERA)), + ) +} + +fun aDesktopNoticeState( + cameraPermissionState: PermissionsState = aPermissionsState( + showDialog = false, + permission = Manifest.permission.CAMERA, + ), + canContinue: Boolean = false, + eventSink: (DesktopNoticeEvent) -> Unit = {}, +) = DesktopNoticeState( + cameraPermissionState = cameraPermissionState, + canContinue = canContinue, + eventSink = eventSink +) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeView.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeView.kt new file mode 100644 index 0000000000..c7f0bb61e7 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeView.kt @@ -0,0 +1,112 @@ +/* + * 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. + */ + +@file:OptIn(ExperimentalMaterial3Api::class) + +package io.element.android.features.linknewdevice.impl.screens.desktop + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +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.linknewdevice.impl.R +import io.element.android.libraries.designsystem.atomic.organisms.NumberedListOrganism +import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage +import io.element.android.libraries.designsystem.components.BigIcon +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.LocalBuildMeta +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.utils.annotatedTextWithBold +import io.element.android.libraries.permissions.api.PermissionsView +import kotlinx.collections.immutable.persistentListOf + +/** + * Desktop notice screen: + * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=2027-23618 + */ +@Composable +fun DesktopNoticeView( + state: DesktopNoticeState, + onBackClick: () -> Unit, + onReadyToScanClick: () -> Unit, + modifier: Modifier = Modifier, +) { + val latestOnReadyToScanClick by rememberUpdatedState(onReadyToScanClick) + LaunchedEffect(state.canContinue) { + if (state.canContinue) { + latestOnReadyToScanClick() + } + } + + val appName = LocalBuildMeta.current.applicationName + FlowStepPage( + onBackClick = onBackClick, + title = stringResource(R.string.screen_link_new_device_desktop_title, appName), + iconStyle = BigIcon.Style.Default(CompoundIcons.Computer()), + modifier = modifier, + buttons = { + Button( + text = stringResource(R.string.screen_link_new_device_desktop_submit), + onClick = { state.eventSink(DesktopNoticeEvent.Continue) }, + modifier = Modifier.fillMaxWidth(), + ) + } + ) { + Column( + Modifier.fillMaxWidth() + ) { + Spacer(modifier = Modifier.height(40.dp)) + NumberedListOrganism( + modifier = Modifier.fillMaxSize(), + items = persistentListOf( + AnnotatedString(stringResource(R.string.screen_link_new_device_desktop_step1, appName)), + annotatedTextWithBold( + text = stringResource( + id = R.string.screen_link_new_device_mobile_step2, + stringResource(R.string.screen_link_new_device_mobile_step2_action), + ), + boldText = stringResource(R.string.screen_link_new_device_mobile_step2_action) + ), + AnnotatedString(stringResource(R.string.screen_link_new_device_desktop_step3)), + ) + ) + } + } + + PermissionsView( + title = stringResource(R.string.screen_qr_code_login_no_camera_permission_state_title), + content = stringResource(R.string.screen_qr_code_login_no_camera_permission_state_description, appName), + icon = { Icon(imageVector = CompoundIcons.TakePhotoSolid(), contentDescription = null) }, + state = state.cameraPermissionState, + ) +} + +@PreviewsDayNight +@Composable +internal fun DesktopNoticeViewPreview( + @PreviewParameter(DesktopNoticeStateProvider::class) state: DesktopNoticeState, +) = ElementPreview { + DesktopNoticeView( + state = state, + onBackClick = { }, + onReadyToScanClick = { }, + ) +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorNode.kt new file mode 100644 index 0000000000..70fd3b49a4 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorNode.kt @@ -0,0 +1,43 @@ +/* + * 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.linknewdevice.impl.screens.error + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.libraries.architecture.callback +import io.element.android.libraries.architecture.inputs +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +@AssistedInject +class ErrorNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, +) : Node(buildContext = buildContext, plugins = plugins) { + interface Callback : Plugin { + fun onRetry() + } + + private val callback: Callback = callback() + private val errorScreenType = inputs() + + @Composable + override fun View(modifier: Modifier) { + ErrorView( + modifier = modifier, + errorScreenType = errorScreenType, + onRetry = callback::onRetry, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorScreenType.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorScreenType.kt new file mode 100644 index 0000000000..b92a19ef8a --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorScreenType.kt @@ -0,0 +1,40 @@ +/* + * 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.linknewdevice.impl.screens.error + +import android.os.Parcelable +import androidx.compose.runtime.Immutable +import io.element.android.libraries.architecture.NodeInputs +import kotlinx.parcelize.Parcelize + +@Immutable +sealed interface ErrorScreenType : NodeInputs, Parcelable { + @Parcelize + data object Cancelled : ErrorScreenType + + @Parcelize + data object Expired : ErrorScreenType + + @Parcelize + data object Mismatch2Digits : ErrorScreenType + + @Parcelize + data object InsecureChannelDetected : ErrorScreenType + + @Parcelize + data object Declined : ErrorScreenType + + @Parcelize + data object ProtocolNotSupported : ErrorScreenType + + @Parcelize + data object SlidingSyncNotAvailable : ErrorScreenType + + @Parcelize + data object UnknownError : ErrorScreenType +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorScreenTypeProvider.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorScreenTypeProvider.kt new file mode 100644 index 0000000000..7fd699101b --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorScreenTypeProvider.kt @@ -0,0 +1,23 @@ +/* + * 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.linknewdevice.impl.screens.error + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +class ErrorScreenTypeProvider : PreviewParameterProvider { + override val values: Sequence = sequenceOf( + ErrorScreenType.Cancelled, + ErrorScreenType.Declined, + ErrorScreenType.Expired, + ErrorScreenType.ProtocolNotSupported, + ErrorScreenType.Mismatch2Digits, + ErrorScreenType.InsecureChannelDetected, + ErrorScreenType.SlidingSyncNotAvailable, + ErrorScreenType.UnknownError, + ) +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorView.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorView.kt new file mode 100644 index 0000000000..3a77f19f49 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorView.kt @@ -0,0 +1,138 @@ +/* + * 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.linknewdevice.impl.screens.error + +import androidx.activity.compose.BackHandler +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +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.AnnotatedString +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.features.linknewdevice.impl.R +import io.element.android.libraries.designsystem.atomic.organisms.NumberedListOrganism +import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage +import io.element.android.libraries.designsystem.components.BigIcon +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.LocalBuildMeta +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.persistentListOf + +@Composable +fun ErrorView( + errorScreenType: ErrorScreenType, + onRetry: () -> Unit, + modifier: Modifier = Modifier, +) { + val appName = LocalBuildMeta.current.applicationName + BackHandler(onBack = onRetry) + FlowStepPage( + modifier = modifier, + iconStyle = BigIcon.Style.AlertSolid, + title = titleText(errorScreenType, appName), + subTitle = subtitleText(errorScreenType, appName), + content = { Content(errorScreenType) }, + buttons = { Buttons(onRetry) }, + ) +} + +@Composable +private fun titleText(errorScreenType: ErrorScreenType, appName: String) = when (errorScreenType) { + ErrorScreenType.Cancelled -> stringResource(R.string.screen_qr_code_login_error_cancelled_title) + ErrorScreenType.Declined -> stringResource(R.string.screen_qr_code_login_error_declined_title) + ErrorScreenType.Expired -> stringResource(R.string.screen_qr_code_login_error_expired_title) + ErrorScreenType.ProtocolNotSupported -> stringResource(R.string.screen_qr_code_login_error_linking_not_suported_title) + ErrorScreenType.InsecureChannelDetected -> stringResource(id = R.string.screen_qr_code_login_connection_note_secure_state_title) + ErrorScreenType.Mismatch2Digits -> stringResource(id = R.string.screen_link_new_device_wrong_number_title) + ErrorScreenType.SlidingSyncNotAvailable -> stringResource(id = R.string.screen_qr_code_login_error_sliding_sync_not_supported_title, appName) + is ErrorScreenType.UnknownError -> stringResource(CommonStrings.common_something_went_wrong) +} + +@Composable +private fun subtitleText(errorScreenType: ErrorScreenType, appName: String) = when (errorScreenType) { + ErrorScreenType.Cancelled -> stringResource(R.string.screen_qr_code_login_error_cancelled_subtitle) + ErrorScreenType.Declined -> stringResource(R.string.screen_qr_code_login_error_declined_subtitle) + ErrorScreenType.Expired -> stringResource(R.string.screen_qr_code_login_error_expired_subtitle) + ErrorScreenType.ProtocolNotSupported -> stringResource(R.string.screen_qr_code_login_error_linking_not_suported_subtitle, appName) + ErrorScreenType.Mismatch2Digits -> stringResource(id = R.string.screen_link_new_device_wrong_number_subtitle) + ErrorScreenType.InsecureChannelDetected -> stringResource(id = R.string.screen_qr_code_login_connection_note_secure_state_description) + ErrorScreenType.SlidingSyncNotAvailable -> stringResource(id = R.string.screen_qr_code_login_error_sliding_sync_not_supported_subtitle, appName) + is ErrorScreenType.UnknownError -> stringResource(R.string.screen_qr_code_login_unknown_error_description) +} + +@Composable +private fun ColumnScope.InsecureChannelDetectedError() { + Text( + modifier = Modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()), + text = stringResource(R.string.screen_qr_code_login_connection_note_secure_state_list_header), + style = ElementTheme.typography.fontBodyLgMedium, + textAlign = TextAlign.Center, + ) + NumberedListOrganism( + modifier = Modifier.fillMaxSize(), + items = persistentListOf( + AnnotatedString(stringResource(R.string.screen_qr_code_login_connection_note_secure_state_list_item_1)), + AnnotatedString(stringResource(R.string.screen_qr_code_login_connection_note_secure_state_list_item_2)), + AnnotatedString(stringResource(R.string.screen_qr_code_login_connection_note_secure_state_list_item_3)), + ) + ) +} + +@Composable +private fun Content(errorScreenType: ErrorScreenType) { + when (errorScreenType) { + ErrorScreenType.InsecureChannelDetected -> { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(top = 20.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(24.dp) + ) { + InsecureChannelDetectedError() + } + } + else -> Unit + } +} + +@Composable +private fun Buttons(onRetry: () -> Unit) { + Button( + modifier = Modifier.fillMaxWidth(), + text = stringResource(CommonStrings.action_start_over), + onClick = onRetry + ) +} + +@PreviewsDayNight +@Composable +internal fun ErrorViewPreview(@PreviewParameter(ErrorScreenTypeProvider::class) errorScreenType: ErrorScreenType) { + ElementPreview { + ErrorView( + errorScreenType = errorScreenType, + onRetry = {}, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/Config.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/Config.kt new file mode 100644 index 0000000000..b61cc82a22 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/Config.kt @@ -0,0 +1,12 @@ +/* + * 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.linknewdevice.impl.screens.number + +object Config { + const val VERIFICATION_CODE_LENGTH = 2 +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberEvent.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberEvent.kt new file mode 100644 index 0000000000..267b508669 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberEvent.kt @@ -0,0 +1,13 @@ +/* + * 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.linknewdevice.impl.screens.number + +sealed interface EnterNumberEvent { + data class UpdateNumber(val number: String) : EnterNumberEvent + data object Continue : EnterNumberEvent +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberNode.kt new file mode 100644 index 0000000000..08d8cd02bd --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberNode.kt @@ -0,0 +1,54 @@ +/* + * 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.linknewdevice.impl.screens.number + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.libraries.architecture.callback +import io.element.android.libraries.di.SessionScope + +interface EnterNumberNavigator { + fun navigateToWrongNumberError() +} + +@ContributesNode(SessionScope::class) +@AssistedInject +class EnterNumberNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + presenterFactory: EnterNumberPresenter.Factory, +) : Node(buildContext, plugins = plugins), EnterNumberNavigator { + private val presenter = presenterFactory.create(this) + + interface Callback : Plugin { + fun navigateToWrongNumberError() + fun navigateBack() + } + + private val callback: Callback = callback() + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + EnterNumberView( + state = state, + modifier = modifier, + onBackClick = callback::navigateBack, + ) + } + + override fun navigateToWrongNumberError() { + callback.navigateToWrongNumberError() + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberPresenter.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberPresenter.kt new file mode 100644 index 0000000000..74b5b6b294 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberPresenter.kt @@ -0,0 +1,108 @@ +/* + * 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.linknewdevice.impl.screens.number + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedFactory +import dev.zacsweers.metro.AssistedInject +import io.element.android.features.linknewdevice.impl.LinkNewMobileHandler +import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.core.log.logger.LoggerTag +import io.element.android.libraries.matrix.api.linknewdevice.CheckCodeSender +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep +import io.element.android.libraries.matrix.api.logs.LoggerTags +import kotlinx.coroutines.launch +import timber.log.Timber + +private val tag = LoggerTag("EnterNumberPresenter", LoggerTags.linkNewDevice) + +@AssistedInject +class EnterNumberPresenter( + @Assisted private val navigator: EnterNumberNavigator, + private val linkNewMobileHandler: LinkNewMobileHandler, +) : Presenter { + @AssistedFactory + interface Factory { + fun create(navigator: EnterNumberNavigator): EnterNumberPresenter + } + + @Composable + override fun present(): EnterNumberState { + val coroutineScope = rememberCoroutineScope() + var number by remember { mutableStateOf("") } + var sendingCode by remember>> { mutableStateOf(AsyncAction.Uninitialized) } + + // Observe the flow to react on ErrorType.InvalidCheckCode + val linkMobileStep by linkNewMobileHandler.stepFlow.collectAsState() + + var checkCodeSender: CheckCodeSender? by remember { mutableStateOf(null) } + + LaunchedEffect(linkMobileStep) { + when (val step = linkMobileStep) { + is LinkMobileStep.QrScanned -> { + checkCodeSender = step.checkCodeSender + } + else -> Unit + } + } + + fun handleEvent(event: EnterNumberEvent) { + when (event) { + is EnterNumberEvent.UpdateNumber -> { + sendingCode = AsyncAction.Uninitialized + // Keep only digits as a safety measure + number = event.number.filter { it.isDigit() } + } + EnterNumberEvent.Continue -> coroutineScope.launch { + // Get the current code sender + val sender = checkCodeSender + if (sender == null) { + Timber.tag(tag.value).e("No check code sender available") + sendingCode = AsyncAction.Failure(IllegalStateException("No check code sender available")) + } else { + sendingCode = AsyncAction.Loading + val uByte = number.toUByte() + val isValid = sender.validate(uByte) + if (isValid) { + sender.send(uByte) + .fold( + onSuccess = { + Timber.tag(tag.value).d("Code sent successfully") + // Keep loading, do not set sendingCode to AsyncAction.Success(Unit) + }, + onFailure = { + Timber.tag(tag.value).e(it, "Failed to send number code") + sendingCode = AsyncAction.Failure(it) + } + ) + } else { + // Navigate to the error state + navigator.navigateToWrongNumberError() + } + } + } + } + } + + return EnterNumberState( + number = number, + sendingCode = sendingCode, + eventSink = ::handleEvent, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberState.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberState.kt new file mode 100644 index 0000000000..b8f66018dd --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberState.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.linknewdevice.impl.screens.number + +import io.element.android.features.linknewdevice.impl.screens.number.model.Number +import io.element.android.libraries.architecture.AsyncAction + +data class EnterNumberState( + val number: String, + val sendingCode: AsyncAction, + val eventSink: (EnterNumberEvent) -> Unit, +) { + val numberEntry = Number.createEmpty(Config.VERIFICATION_CODE_LENGTH).fillWith(number) + val isContinueButtonEnabled: Boolean + get() = numberEntry.isComplete() && !sendingCode.isLoading() +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberStateProvider.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberStateProvider.kt new file mode 100644 index 0000000000..126bfeee52 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberStateProvider.kt @@ -0,0 +1,34 @@ +/* + * 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.linknewdevice.impl.screens.number + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.matrix.api.linknewdevice.ErrorType + +open class EnterNumberStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aEnterNumberState(), + aEnterNumberState(number = "1"), + aEnterNumberState(number = "12"), + aEnterNumberState(number = "12", sendingCode = AsyncAction.Loading), + aEnterNumberState(number = "12", sendingCode = AsyncAction.Failure(ErrorType.InvalidCheckCode("Invalid"))), + aEnterNumberState(number = "12", sendingCode = AsyncAction.Failure(Exception("Failed to send code"))), + ) +} + +fun aEnterNumberState( + number: String = "", + sendingCode: AsyncAction = AsyncAction.Uninitialized, + eventSink: (EnterNumberEvent) -> Unit = {}, +) = EnterNumberState( + number = number, + sendingCode = sendingCode, + eventSink = eventSink, +) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberView.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberView.kt new file mode 100644 index 0000000000..92b3447615 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberView.kt @@ -0,0 +1,125 @@ +/* + * 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. + */ + +@file:OptIn(ExperimentalMaterial3Api::class) + +package io.element.android.features.linknewdevice.impl.screens.number + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.material3.ExperimentalMaterial3Api +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.TextAlign +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.linknewdevice.impl.R +import io.element.android.features.linknewdevice.impl.screens.number.component.NumberTextField +import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage +import io.element.android.libraries.designsystem.components.BigIcon +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.matrix.api.linknewdevice.ErrorType +import io.element.android.libraries.ui.strings.CommonStrings + +/** + * Form to enter number: + * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=2076-81604 + */ +@Composable +fun EnterNumberView( + state: EnterNumberState, + onBackClick: () -> Unit, + modifier: Modifier = Modifier, +) { + FlowStepPage( + onBackClick = onBackClick, + title = stringResource(R.string.screen_link_new_device_enter_number_title), + subTitle = stringResource(R.string.screen_link_new_device_enter_number_subtitle), + iconStyle = BigIcon.Style.Default(CompoundIcons.Computer()), + modifier = modifier, + buttons = { + Button( + text = stringResource(CommonStrings.action_continue), + onClick = { state.eventSink(EnterNumberEvent.Continue) }, + enabled = state.isContinueButtonEnabled, + showProgress = state.sendingCode.isLoading(), + modifier = Modifier.fillMaxWidth(), + ) + } + ) { + Column( + Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Spacer(modifier = Modifier.height(24.dp)) + Text( + text = stringResource(R.string.screen_link_new_device_enter_number_notice), + textAlign = TextAlign.Center, + style = ElementTheme.typography.fontBodyMdRegular, + color = ElementTheme.colors.textPrimary, + ) + Spacer(modifier = Modifier.height(8.dp)) + NumberTextField( + number = state.numberEntry, + onValueChange = { state.eventSink(EnterNumberEvent.UpdateNumber(it)) }, + onDone = { + if (state.isContinueButtonEnabled) { + state.eventSink(EnterNumberEvent.Continue) + } + }, + ) + val failure = state.sendingCode.errorOrNull() + if (failure != null) { + Spacer(modifier = Modifier.height(4.dp)) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp) + ) { + Icon( + modifier = Modifier.size(14.dp), + imageVector = CompoundIcons.ErrorSolid(), + contentDescription = null, + tint = ElementTheme.colors.iconCriticalPrimary, + ) + val errorMessage = when (failure) { + is ErrorType.InvalidCheckCode -> stringResource(R.string.screen_link_new_device_enter_number_error_numbers_do_not_match) + else -> failure.message ?: stringResource(CommonStrings.error_unknown) + } + Text( + text = errorMessage, + style = ElementTheme.typography.fontBodySmRegular, + color = ElementTheme.colors.textCriticalPrimary, + ) + } + } + } + } +} + +@PreviewsDayNight +@Composable +internal fun EnterNumberViewPreview( + @PreviewParameter(EnterNumberStateProvider::class) state: EnterNumberState, +) = ElementPreview { + EnterNumberView( + state = state, + onBackClick = { }, + ) +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/component/NumberTextField.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/component/NumberTextField.kt new file mode 100644 index 0000000000..568a729ed6 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/component/NumberTextField.kt @@ -0,0 +1,169 @@ +/* + * 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.linknewdevice.impl.screens.number.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +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.LocalInspectionMode +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.features.linknewdevice.impl.screens.number.model.Digit +import io.element.android.features.linknewdevice.impl.screens.number.model.Number +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import kotlinx.coroutines.delay + +@Composable +fun NumberTextField( + number: Number, + onValueChange: (String) -> Unit, + onDone: () -> Unit, + modifier: Modifier = Modifier, +) { + val interactionSource = remember { MutableInteractionSource() } + val isFocused = LocalInspectionMode.current || interactionSource.collectIsFocusedAsState().value + BasicTextField( + modifier = modifier, + value = number.toText(), + onValueChange = { + onValueChange(it) + }, + interactionSource = interactionSource, + maxLines = 1, + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Number, + imeAction = ImeAction.Done, + ), + keyboardActions = KeyboardActions( + onDone = { + onDone() + } + ), + decorationBox = { + NumberRow( + number = number, + hasFocus = isFocused, + ) + } + ) +} + +@OptIn(ExperimentalLayoutApi::class) +@Composable +private fun NumberRow( + number: Number, + hasFocus: Boolean, +) { + FlowRow( + horizontalArrangement = Arrangement.spacedBy(12.dp, alignment = Alignment.CenterHorizontally), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + val length = number.length() + number.digits.forEachIndexed { index, digit -> + DigitView( + digit = digit, + isCurrent = index == length, + drawCursor = hasFocus, + ) + } + } +} + +@Composable +private fun DigitView( + digit: Digit, + isCurrent: Boolean, + drawCursor: Boolean, +) { + val shape = RoundedCornerShape(4.dp) + val appearanceModifier = when (digit) { + Digit.Empty -> { + val color = if (isCurrent) { + ElementTheme.colors.textPrimary + } else { + ElementTheme.colors.borderInteractiveSecondary + } + Modifier.border(1.dp, color, shape) + } + is Digit.Filled -> { + Modifier.background(ElementTheme.colors.bgActionSecondaryPressed, shape) + } + } + Box( + modifier = Modifier + .size(42.dp, 56.dp) + .then(appearanceModifier), + contentAlignment = Alignment.Center, + ) { + if (digit is Digit.Filled) { + Text( + text = digit.value.toString(), + style = ElementTheme.typography.fontHeadingLgBold, + color = ElementTheme.colors.textPrimary, + ) + } else if (drawCursor && isCurrent) { + // Draw a blinking cursor + BlinkingCursor() + } + } +} + +@Composable +private fun BlinkingCursor() { + var isCursorVisible by remember { mutableStateOf(true) } + LaunchedEffect(isCursorVisible) { + delay(500) + // Toggle cursor visibility + isCursorVisible = !isCursorVisible + } + if (isCursorVisible) { + Spacer( + modifier = Modifier + .size(2.dp, 24.dp) + .offset(x = (-5).dp) + .background(ElementTheme.colors.textPrimary, RoundedCornerShape(1.dp)) + ) + } +} + +@PreviewsDayNight +@Composable +internal fun NumberTextFieldPreview() { + ElementPreview { + val number = Number.createEmpty(4).fillWith("12") + NumberTextField( + number = number, + onValueChange = {}, + onDone = {}, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/model/Digit.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/model/Digit.kt new file mode 100644 index 0000000000..b8565ea6ca --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/model/Digit.kt @@ -0,0 +1,23 @@ +/* + * 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.linknewdevice.impl.screens.number.model + +import androidx.compose.runtime.Immutable + +@Immutable +sealed interface Digit { + data object Empty : Digit + data class Filled(val value: Char) : Digit + + fun toText(): String { + return when (this) { + is Empty -> "" + is Filled -> value.toString() + } + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/model/Number.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/model/Number.kt new file mode 100644 index 0000000000..be60f27f76 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/number/model/Number.kt @@ -0,0 +1,56 @@ +/* + * 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.linknewdevice.impl.screens.number.model + +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList + +data class Number( + val digits: ImmutableList, +) { + companion object { + fun createEmpty(size: Int): Number { + val digits = List(size) { Digit.Empty } + return Number( + digits = digits.toImmutableList() + ) + } + } + + val size = digits.size + + /** + * Fill the first digits with the given text. + * Can't be more than the size of the NumberEntry + * Keep the Empty digits at the end + * @return the new NumberEntry + */ + fun fillWith(text: String): Number { + val newDigits = MutableList(size) { Digit.Empty } + text.forEachIndexed { index, char -> + if (index < size && char.isDigit()) { + newDigits[index] = Digit.Filled(char) + } + } + return copy(digits = newDigits.toImmutableList()) + } + + fun length(): Int { + return digits.count { it is Digit.Filled } + } + + fun toText(): String { + return digits.joinToString("") { + it.toText() + } + } + + fun isComplete(): Boolean { + return digits.all { it is Digit.Filled } + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeNode.kt new file mode 100644 index 0000000000..a884c3e97f --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeNode.kt @@ -0,0 +1,48 @@ +/* + * 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.linknewdevice.impl.screens.qrcode + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.libraries.architecture.NodeInputs +import io.element.android.libraries.architecture.callback +import io.element.android.libraries.architecture.inputs +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +@AssistedInject +class ShowQrCodeNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, +) : Node(buildContext, plugins = plugins) { + class Inputs( + val data: String, + ) : NodeInputs + + interface Callback : Plugin { + fun navigateBack() + } + + private val inputs: Inputs = inputs() + private val callback: Callback = callback() + + @Composable + override fun View(modifier: Modifier) { + ShowQrCodeView( + data = inputs.data, + modifier = modifier, + onBackClick = callback::navigateBack, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeView.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeView.kt new file mode 100644 index 0000000000..501415f621 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeView.kt @@ -0,0 +1,89 @@ +/* + * 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. + */ + +@file:OptIn(ExperimentalMaterial3Api::class) + +package io.element.android.features.linknewdevice.impl.screens.qrcode + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.material3.ExperimentalMaterial3Api +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.AnnotatedString +import androidx.compose.ui.unit.dp +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.linknewdevice.impl.R +import io.element.android.libraries.designsystem.atomic.organisms.NumberedListOrganism +import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage +import io.element.android.libraries.designsystem.components.BigIcon +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.LocalBuildMeta +import io.element.android.libraries.designsystem.utils.annotatedTextWithBold +import io.element.android.libraries.qrcode.QrCodeImage +import kotlinx.collections.immutable.persistentListOf + +/** + * QrCode display screen: + * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=2027-23617 + */ +@Composable +fun ShowQrCodeView( + data: String, + onBackClick: () -> Unit, + modifier: Modifier = Modifier, +) { + val appName = LocalBuildMeta.current.applicationName + FlowStepPage( + onBackClick = onBackClick, + title = stringResource(R.string.screen_link_new_device_mobile_title, appName), + iconStyle = BigIcon.Style.Default(CompoundIcons.TakePhotoSolid()), + modifier = modifier, + ) { + Column( + Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + QrCodeImage( + data = data, + modifier = Modifier + .size(220.dp) + ) + Spacer(modifier = Modifier.height(32.dp)) + NumberedListOrganism( + modifier = Modifier.fillMaxSize(), + items = persistentListOf( + AnnotatedString(stringResource(R.string.screen_link_new_device_mobile_step1, appName)), + annotatedTextWithBold( + text = stringResource( + id = R.string.screen_link_new_device_mobile_step2, + stringResource(R.string.screen_link_new_device_mobile_step2_action), + ), + boldText = stringResource(R.string.screen_link_new_device_mobile_step2_action) + ), + AnnotatedString(stringResource(R.string.screen_link_new_device_mobile_step3)), + ) + ) + } + } +} + +@PreviewsDayNight +@Composable +internal fun ShowQrCodeViewPreview() = ElementPreview { + ShowQrCodeView( + data = "DATA", + onBackClick = { }, + ) +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootEvent.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootEvent.kt new file mode 100644 index 0000000000..8ce6af90b0 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootEvent.kt @@ -0,0 +1,13 @@ +/* + * 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.linknewdevice.impl.screens.root + +sealed interface LinkNewDeviceRootEvent { + data object LinkMobileDevice : LinkNewDeviceRootEvent + data object CloseDialog : LinkNewDeviceRootEvent +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootNode.kt new file mode 100644 index 0000000000..f43ffa64df --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootNode.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.linknewdevice.impl.screens.root + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.libraries.architecture.callback +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +@AssistedInject +class LinkNewDeviceRootNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: LinkNewDeviceRootPresenter, +) : Node(buildContext, plugins = plugins) { + interface Callback : Plugin { + fun onDone() + fun linkDesktopDevice() + } + + private val callback: Callback = callback() + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + LinkNewDeviceRootView( + state = state, + modifier = modifier, + onBackClick = callback::onDone, + onLinkDesktopDeviceClick = callback::linkDesktopDevice, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenter.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenter.kt new file mode 100644 index 0000000000..e39179c463 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenter.kt @@ -0,0 +1,85 @@ +/* + * 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.linknewdevice.impl.screens.root + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import dev.zacsweers.metro.Inject +import io.element.android.features.linknewdevice.impl.LinkNewMobileHandler +import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep +import kotlinx.coroutines.launch + +@Inject +class LinkNewDeviceRootPresenter( + private val matrixClient: MatrixClient, + private val linkNewMobileHandler: LinkNewMobileHandler, +) : Presenter { + @Composable + override fun present(): LinkNewDeviceRootState { + val coroutineScope = rememberCoroutineScope() + var isSupported by remember { mutableStateOf>(AsyncData.Uninitialized) } + var qrCodeData by remember { mutableStateOf>(AsyncData.Uninitialized) } + + LaunchedEffect(Unit) { + matrixClient.canLinkNewDevice().fold( + onSuccess = { supported -> + isSupported = AsyncData.Success(supported) + }, + onFailure = { + isSupported = AsyncData.Failure(it) + } + ) + } + + val step by linkNewMobileHandler.stepFlow.collectAsState() + + LaunchedEffect(step) { + when (val finalStep = step) { + is LinkMobileStep.Uninitialized -> { + qrCodeData = AsyncData.Uninitialized + } + is LinkMobileStep.QrReady -> { + qrCodeData = AsyncData.Success(Unit) + } + is LinkMobileStep.Error -> { + qrCodeData = AsyncData.Failure(finalStep.errorType) + } + else -> Unit + } + } + + fun handleEvent(event: LinkNewDeviceRootEvent) { + when (event) { + is LinkNewDeviceRootEvent.LinkMobileDevice -> coroutineScope.launch { + qrCodeData = AsyncData.Loading() + // Wait for the QrCode to be ready + linkNewMobileHandler.reset() + linkNewMobileHandler.createAndStartNewHandler() + } + LinkNewDeviceRootEvent.CloseDialog -> coroutineScope.launch { + linkNewMobileHandler.reset() + } + } + } + + return LinkNewDeviceRootState( + isSupported = isSupported, + qrCodeData = qrCodeData, + eventSink = ::handleEvent, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootState.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootState.kt new file mode 100644 index 0000000000..6cf6694b2a --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootState.kt @@ -0,0 +1,16 @@ +/* + * 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.linknewdevice.impl.screens.root + +import io.element.android.libraries.architecture.AsyncData + +data class LinkNewDeviceRootState( + val isSupported: AsyncData, + val qrCodeData: AsyncData, + val eventSink: (LinkNewDeviceRootEvent) -> Unit, +) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootStateProvider.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootStateProvider.kt new file mode 100644 index 0000000000..f1bb7ad455 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootStateProvider.kt @@ -0,0 +1,40 @@ +/* + * 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.linknewdevice.impl.screens.root + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.matrix.api.linknewdevice.ErrorType + +open class LinkNewDeviceRootStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aLinkNewDeviceRootState(), + aLinkNewDeviceRootState(isSupported = AsyncData.Success(true)), + aLinkNewDeviceRootState(isSupported = AsyncData.Success(false)), + aLinkNewDeviceRootState(isSupported = AsyncData.Failure(Exception("Should not happen"))), + aLinkNewDeviceRootState( + isSupported = AsyncData.Success(true), + qrCodeData = AsyncData.Loading(), + ), + aLinkNewDeviceRootState( + isSupported = AsyncData.Success(true), + qrCodeData = AsyncData.Failure(ErrorType.NotFound("The rendezvous session was not found and might have expired")), + ), + ) +} + +fun aLinkNewDeviceRootState( + isSupported: AsyncData = AsyncData.Uninitialized, + qrCodeData: AsyncData = AsyncData.Uninitialized, + eventSink: (LinkNewDeviceRootEvent) -> Unit = { }, +) = LinkNewDeviceRootState( + isSupported = isSupported, + qrCodeData = qrCodeData, + eventSink = eventSink, +) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootView.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootView.kt new file mode 100644 index 0000000000..d9249d3e89 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootView.kt @@ -0,0 +1,152 @@ +/* + * 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. + */ + +@file:OptIn(ExperimentalMaterial3Api::class) + +package io.element.android.features.linknewdevice.impl.screens.root + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.PreviewParameter +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.linknewdevice.impl.R +import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.designsystem.atomic.atoms.LoadingButtonAtom +import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage +import io.element.android.libraries.designsystem.components.BigIcon +import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.IconSource +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.ui.strings.CommonStrings + +/** + * Device selection screen: + * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=2027-23616 + * Not supported screen: + * https://www.figma.com/design/pDlJZGBsri47FNTXMnEdXB/Compound-Android-Templates?node-id=2186-70004 + */ +@Composable +fun LinkNewDeviceRootView( + state: LinkNewDeviceRootState, + onBackClick: () -> Unit, + onLinkDesktopDeviceClick: () -> Unit, + modifier: Modifier = Modifier, +) { + val (title, subtitle, iconStyle) = if (state.isSupported.dataOrNull() == false) { + Triple( + stringResource(R.string.screen_link_new_device_error_not_supported_title), + stringResource(R.string.screen_link_new_device_error_not_supported_subtitle), + BigIcon.Style.AlertSolid + ) + } else { + Triple( + stringResource(R.string.screen_link_new_device_root_title), + null, + BigIcon.Style.Default(CompoundIcons.Devices()) + ) + } + FlowStepPage( + onBackClick = onBackClick, + title = title, + subTitle = subtitle, + iconStyle = iconStyle, + buttons = { + when (state.isSupported) { + is AsyncData.Uninitialized, + is AsyncData.Loading -> { + LoadingButtonAtom() + } + is AsyncData.Failure -> { + Text( + text = stringResource(id = CommonStrings.error_unknown), + color = ElementTheme.colors.textCriticalPrimary, + style = ElementTheme.typography.fontBodyMdRegular, + textAlign = TextAlign.Center, + ) + Button( + onClick = onBackClick, + text = stringResource(CommonStrings.action_dismiss), + modifier = Modifier.fillMaxWidth(), + ) + } + is AsyncData.Success -> { + if (state.isSupported.data) { + when (state.qrCodeData) { + AsyncData.Uninitialized, + is AsyncData.Failure -> { + Button( + onClick = { state.eventSink(LinkNewDeviceRootEvent.LinkMobileDevice) }, + text = stringResource(id = R.string.screen_link_new_device_root_mobile_device), + modifier = Modifier.fillMaxWidth(), + leadingIcon = IconSource.Vector(CompoundIcons.Mobile()), + ) + Button( + onClick = onLinkDesktopDeviceClick, + text = stringResource(id = R.string.screen_link_new_device_root_desktop_computer), + modifier = Modifier.fillMaxWidth(), + leadingIcon = IconSource.Vector(CompoundIcons.Computer()), + ) + } + is AsyncData.Loading, + is AsyncData.Success -> { + Button( + onClick = { state.eventSink(LinkNewDeviceRootEvent.LinkMobileDevice) }, + text = stringResource(id = R.string.screen_link_new_device_root_loading_qr_code), + showProgress = true, + enabled = false, + modifier = Modifier.fillMaxWidth(), + ) + Button( + onClick = onLinkDesktopDeviceClick, + text = stringResource(id = R.string.screen_link_new_device_root_desktop_computer), + modifier = Modifier.fillMaxWidth(), + enabled = false, + leadingIcon = IconSource.Vector(CompoundIcons.Computer()), + ) + } + } + } else { + Button( + onClick = onBackClick, + text = stringResource(CommonStrings.action_dismiss), + modifier = Modifier.fillMaxWidth(), + ) + } + } + } + }, + modifier = modifier, + ) + + val failure = state.qrCodeData.errorOrNull() + if (failure != null) { + ErrorDialog( + content = failure.message ?: stringResource(CommonStrings.error_unknown), + onSubmit = { state.eventSink(LinkNewDeviceRootEvent.CloseDialog) }, + ) + } +} + +@PreviewsDayNight +@Composable +internal fun LinkNewDeviceRootViewPreview( + @PreviewParameter(LinkNewDeviceRootStateProvider::class) state: LinkNewDeviceRootState +) = ElementPreview { + LinkNewDeviceRootView( + state = state, + onBackClick = { }, + onLinkDesktopDeviceClick = { }, + ) +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeEvent.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeEvent.kt new file mode 100644 index 0000000000..c17a28649c --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeEvent.kt @@ -0,0 +1,13 @@ +/* + * 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.linknewdevice.impl.screens.scan + +sealed interface ScanQrCodeEvent { + data class QrCodeScanned(val data: ByteArray) : ScanQrCodeEvent + data object TryAgain : ScanQrCodeEvent +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeNode.kt new file mode 100644 index 0000000000..ff4f88f9ae --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeNode.kt @@ -0,0 +1,43 @@ +/* + * 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.linknewdevice.impl.screens.scan + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.libraries.architecture.callback +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +@AssistedInject +class ScanQrCodeNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: ScanQrCodePresenter, +) : Node(buildContext, plugins = plugins) { + interface Callback : Plugin { + fun cancel() + } + + private val callback: Callback = callback() + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + ScanQrCodeView( + state = state, + onBackClick = callback::cancel, + modifier = modifier + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenter.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenter.kt new file mode 100644 index 0000000000..5f0131a8df --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenter.kt @@ -0,0 +1,73 @@ +/* + * 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.linknewdevice.impl.screens.scan + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import dev.zacsweers.metro.Inject +import io.element.android.features.linknewdevice.impl.LinkNewDesktopHandler +import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopStep +import kotlinx.coroutines.launch + +@Inject +class ScanQrCodePresenter( + private val linkNewDesktopHandler: LinkNewDesktopHandler, +) : Presenter { + @Composable + override fun present(): ScanQrCodeState { + val coroutineScope = rememberCoroutineScope() + var scanAction: AsyncAction by remember { mutableStateOf(AsyncAction.Loading) } + + // Observe the flow to react on LinkDesktopStep.InvalidQrCode + val linkDesktopStep by linkNewDesktopHandler.stepFlow.collectAsState() + + LaunchedEffect(Unit) { + linkNewDesktopHandler.createNewHandler() + } + + LaunchedEffect(linkDesktopStep) { + when (val step = linkDesktopStep) { + is LinkDesktopStep.InvalidQrCode -> { + scanAction = AsyncAction.Failure(Exception(step.error)) + } + else -> Unit + } + } + + fun handleEvent(event: ScanQrCodeEvent) { + when (event) { + ScanQrCodeEvent.TryAgain -> { + scanAction = AsyncAction.Loading + } + is ScanQrCodeEvent.QrCodeScanned -> coroutineScope.launch { + // In this case the scanning will stop and a loader will be shown + scanAction = AsyncAction.Success(Unit) + try { + linkNewDesktopHandler.onScannedCode(event.data) + } catch (e: Exception) { + // Should not happen as errors are handled through the LinkDesktopStep flow + scanAction = AsyncAction.Failure(e) + } + } + } + } + + return ScanQrCodeState( + scanAction = scanAction, + eventSink = ::handleEvent, + ) + } +} diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeState.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeState.kt new file mode 100644 index 0000000000..6cb0363836 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeState.kt @@ -0,0 +1,15 @@ +/* + * 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.linknewdevice.impl.screens.scan + +import io.element.android.libraries.architecture.AsyncAction + +data class ScanQrCodeState( + val scanAction: AsyncAction, + val eventSink: (ScanQrCodeEvent) -> Unit, +) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeStateProvider.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeStateProvider.kt new file mode 100644 index 0000000000..40e7df8884 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeStateProvider.kt @@ -0,0 +1,29 @@ +/* + * 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.linknewdevice.impl.screens.scan + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.architecture.AsyncAction + +open class ScanQrCodeStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aScanQrCodeState(), + aScanQrCodeState(scanAction = AsyncAction.Loading), + aScanQrCodeState(scanAction = AsyncAction.Success(Unit)), + aScanQrCodeState(scanAction = AsyncAction.Failure(Exception("Scan failed"))), + ) +} + +fun aScanQrCodeState( + scanAction: AsyncAction = AsyncAction.Uninitialized, + eventSink: (ScanQrCodeEvent) -> Unit = {}, +) = ScanQrCodeState( + scanAction = scanAction, + eventSink = eventSink +) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeView.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeView.kt new file mode 100644 index 0000000000..937aee08b4 --- /dev/null +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeView.kt @@ -0,0 +1,174 @@ +/* + * 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.linknewdevice.impl.screens.scan + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.progressSemantics +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.TextAlign +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.linknewdevice.impl.R +import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage +import io.element.android.libraries.designsystem.components.BigIcon +import io.element.android.libraries.designsystem.modifiers.cornerBorder +import io.element.android.libraries.designsystem.modifiers.squareSize +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.qrcode.QrCodeCameraView +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +fun ScanQrCodeView( + state: ScanQrCodeState, + onBackClick: () -> Unit, + modifier: Modifier = Modifier, +) { + FlowStepPage( + modifier = modifier, + onBackClick = onBackClick, + iconStyle = BigIcon.Style.Default(CompoundIcons.Computer()), + title = stringResource(R.string.screen_link_new_device_desktop_scanning_title), + content = { Content(state = state) }, + buttons = { Buttons(state = state) } + ) +} + +@Composable +private fun Content( + state: ScanQrCodeState, +) { + BoxWithConstraints( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.Center, + ) { + val modifier = if (constraints.maxWidth > constraints.maxHeight) { + Modifier.fillMaxHeight() + } else { + Modifier.fillMaxWidth() + }.then( + Modifier + .padding(start = 20.dp, end = 20.dp, top = 50.dp, bottom = 32.dp) + .squareSize() + .cornerBorder( + strokeWidth = 4.dp, + color = ElementTheme.colors.textPrimary, + cornerSizeDp = 42.dp, + ) + ) + Box( + modifier = modifier, + contentAlignment = Alignment.Center, + ) { + QrCodeCameraView( + modifier = Modifier.fillMaxSize(), + onScanQrCode = { state.eventSink.invoke(ScanQrCodeEvent.QrCodeScanned(it)) }, + isScanning = state.scanAction.isLoading(), + ) + } + } +} + +@Composable +private fun ColumnScope.Buttons( + state: ScanQrCodeState, +) { + Column(Modifier.heightIn(min = 130.dp)) { + when (state.scanAction) { + is AsyncAction.Failure -> { + Button( + text = stringResource(id = CommonStrings.action_try_again), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp), + onClick = { + state.eventSink.invoke(ScanQrCodeEvent.TryAgain) + } + ) + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = CompoundIcons.ErrorSolid(), + tint = ElementTheme.colors.iconCriticalPrimary, + contentDescription = null, + modifier = Modifier.size(24.dp) + ) + Spacer(modifier = Modifier.width(4.dp)) + Text( + text = stringResource(R.string.screen_qr_code_login_invalid_scan_state_subtitle), + textAlign = TextAlign.Center, + color = ElementTheme.colors.textCriticalPrimary, + style = ElementTheme.typography.fontBodySmMedium, + ) + } + Text( + text = stringResource(R.string.screen_qr_code_login_invalid_scan_state_description), + textAlign = TextAlign.Center, + style = ElementTheme.typography.fontBodySmRegular, + color = ElementTheme.colors.textSecondary, + ) + } + } + is AsyncAction.Success -> { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + CircularProgressIndicator( + modifier = Modifier + .progressSemantics() + .size(20.dp), + strokeWidth = 2.dp + ) + } + } + AsyncAction.Loading, + AsyncAction.Uninitialized, + is AsyncAction.Confirming -> Unit + } + } +} + +@PreviewsDayNight +@Composable +internal fun ScanQrCodeViewPreview(@PreviewParameter(ScanQrCodeStateProvider::class) state: ScanQrCodeState) = ElementPreview { + ScanQrCodeView( + state = state, + onBackClick = {}, + ) +} diff --git a/features/linknewdevice/impl/src/main/res/values/localazy.xml b/features/linknewdevice/impl/src/main/res/values/localazy.xml new file mode 100644 index 0000000000..9bf7ac2132 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values/localazy.xml @@ -0,0 +1,55 @@ + + + "Scan the QR code" + "Open %1$s on a laptop or desktop computer" + "Scan the QR code with this device" + "Ready to scan" + "Open %1$s on a desktop computer to get the QR code" + "The numbers don’t match" + "Enter 2-digit code" + "This will verify that the connection to your other device is secure." + "Enter the number shown on your other device" + "Your account provider does not support %1$s." + "%1$s not supported" + "Your account provider doesn’t support signing into a new device with a QR code." + "QR code not supported" + "The sign in was cancelled on the other device." + "Sign in request cancelled" + "Sign in expired. Please try again." + "The sign in was not completed in time" + "Open %1$s on the other device" + "Select %1$s" + "“Sign in with QR code”" + "Scan the QR code shown here with the other device" + "Open %1$s on the other device" + "Desktop computer" + "Loading QR code…" + "Mobile device" + "What type of device do you want to link?" + "Please try again and make sure that you’ve entered the 2-digit code correctly. If the numbers still don’t match then contact your account provider." + "The numbers don’t match" + "A secure connection could not be made to the new device. Your existing devices are still safe and you don\'t need to worry about them." + "What now?" + "Try signing in again with a QR code in case this was a network problem" + "If you encounter the same problem, try a different wifi network or use your mobile data instead of wifi" + "If that doesn’t work, sign in manually" + "Connection not secure" + "The sign in was cancelled on the other device." + "Sign in request cancelled" + "The sign in was declined on the other device." + "Sign in declined" + "Sign in expired. Please try again." + "The sign in was not completed in time" + "Your other device does not support signing in to %s with a QR code. + +Try signing in manually, or scan the QR code with another device." + "QR code not supported" + "Your account provider does not support %1$s." + "%1$s not supported" + "Use the QR code shown on the other device." + "Try again" + "Wrong QR code" + "You need to give permission for %1$s to use your device’s camera in order to continue." + "Allow camera access to scan the QR code" + "An unexpected error occurred. Please try again." + diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenterTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenterTest.kt new file mode 100644 index 0000000000..ba3892c965 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenterTest.kt @@ -0,0 +1,58 @@ +/* + * 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.linknewdevice.impl.screens.desktop + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.permissions.test.FakePermissionsPresenter +import io.element.android.libraries.permissions.test.FakePermissionsPresenterFactory +import io.element.android.tests.testutils.test +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class DesktopNoticePresenterTest { + @Test + fun `present - initial state`() = runTest { + val presenter = createPresenter() + presenter.test { + awaitItem().run { + assertThat(cameraPermissionState.permission).isEqualTo("android.permission.POST_NOTIFICATIONS") + assertThat(canContinue).isFalse() + } + } + } + + @Test + fun `present - Continue with camera permissions can continue`() = runTest { + val permissionsPresenter = FakePermissionsPresenter().apply { setPermissionGranted() } + val permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter) + val presenter = createPresenter(permissionsPresenterFactory = permissionsPresenterFactory) + presenter.test { + awaitItem().eventSink(DesktopNoticeEvent.Continue) + assertThat(awaitItem().canContinue).isTrue() + } + } + + @Test + fun `present - Continue with unknown camera permissions opens permission dialog`() = runTest { + val permissionsPresenter = FakePermissionsPresenter() + val permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter) + val presenter = createPresenter(permissionsPresenterFactory = permissionsPresenterFactory) + presenter.test { + awaitItem().eventSink(DesktopNoticeEvent.Continue) + assertThat(awaitItem().cameraPermissionState.showDialog).isTrue() + } + } + + private fun createPresenter( + permissionsPresenterFactory: FakePermissionsPresenterFactory = FakePermissionsPresenterFactory(), + ): DesktopNoticePresenter { + return DesktopNoticePresenter( + permissionsPresenterFactory = permissionsPresenterFactory, + ) + } +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeViewTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeViewTest.kt new file mode 100644 index 0000000000..ac0a129f49 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticeViewTest.kt @@ -0,0 +1,86 @@ +/* + * 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.linknewdevice.impl.screens.desktop + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.features.linknewdevice.impl.R +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 io.element.android.tests.testutils.pressBackKey +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class DesktopNoticeViewTest { + @get:Rule + val rule = createAndroidComposeRule() + + @Test + fun `on back pressed - calls the expected callback`() { + ensureCalledOnce { callback -> + rule.setView( + state = aDesktopNoticeState(), + onBackClicked = callback, + ) + rule.pressBackKey() + } + } + + @Test + fun `on back button clicked - calls the expected callback`() { + ensureCalledOnce { callback -> + rule.setView( + state = aDesktopNoticeState(), + onBackClicked = callback, + ) + rule.pressBack() + } + } + + @Test + fun `when can continue - calls the expected callback`() { + ensureCalledOnce { callback -> + rule.setView( + state = aDesktopNoticeState(canContinue = true), + onReadyToScanClick = callback, + ) + } + } + + @Test + fun `on submit button clicked - emits the Continue event`() { + val eventRecorder = EventsRecorder() + rule.setView( + state = aDesktopNoticeState(eventSink = eventRecorder), + ) + rule.clickOn(R.string.screen_link_new_device_desktop_submit) + eventRecorder.assertSingle(DesktopNoticeEvent.Continue) + } + + private fun AndroidComposeTestRule.setView( + state: DesktopNoticeState, + onBackClicked: () -> Unit = EnsureNeverCalled(), + onReadyToScanClick: () -> Unit = EnsureNeverCalled(), + ) { + setContent { + DesktopNoticeView( + state = state, + onBackClick = onBackClicked, + onReadyToScanClick = onReadyToScanClick, + ) + } + } +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorViewTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorViewTest.kt new file mode 100644 index 0000000000..8f44182dd4 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/error/ErrorViewTest.kt @@ -0,0 +1,59 @@ +/* + * 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.linknewdevice.impl.screens.error + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.tests.testutils.clickOn +import io.element.android.tests.testutils.ensureCalledOnce +import io.element.android.tests.testutils.pressBackKey +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class ErrorViewTest { + @get:Rule + val rule = createAndroidComposeRule() + + @Test + fun `on back pressed - calls the onRetry callback`() { + ensureCalledOnce { callback -> + rule.setErrorView( + onRetry = callback + ) + rule.pressBackKey() + } + } + + @Test + fun `on start over button clicked - calls the expected callback`() { + ensureCalledOnce { callback -> + rule.setErrorView( + onRetry = callback + ) + rule.clickOn(CommonStrings.action_start_over) + } + } + + private fun AndroidComposeTestRule.setErrorView( + onRetry: () -> Unit, + errorScreenType: ErrorScreenType = ErrorScreenType.UnknownError, + ) { + setContent { + ErrorView( + errorScreenType = errorScreenType, + onRetry = onRetry, + ) + } + } +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberPresenterTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberPresenterTest.kt new file mode 100644 index 0000000000..fe2e11e95c --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberPresenterTest.kt @@ -0,0 +1,191 @@ +/* + * 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. + */ + +@file:OptIn(ExperimentalCoroutinesApi::class) + +package io.element.android.features.linknewdevice.impl.screens.number + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.linknewdevice.impl.LinkNewMobileHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep +import io.element.android.libraries.matrix.test.AN_EXCEPTION +import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.matrix.test.linknewdevice.FakeCheckCodeSender +import io.element.android.libraries.matrix.test.linknewdevice.FakeLinkMobileHandler +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.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.advanceUntilIdle +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test + +class EnterNumberPresenterTest { + @get:Rule + val warmUpRule = WarmUpRule() + + @Test + fun `present - initial state`() = runTest { + createPresenter().test { + val initialState = awaitItem() + assertThat(initialState.number).isEmpty() + assertThat(initialState.sendingCode.isUninitialized()).isTrue() + } + } + + @Test + fun `present - enter numbers`() = runTest { + createPresenter().test { + val initialState = awaitItem() + assertThat(initialState.number).isEmpty() + initialState.eventSink(EnterNumberEvent.UpdateNumber("12")) + val state2 = awaitItem() + assertThat(state2.number).isEqualTo("12") + // Non numeric characters are ignored + state2.eventSink(EnterNumberEvent.UpdateNumber("1a")) + val state3 = awaitItem() + assertThat(state3.number).isEqualTo("1") + } + } + + @Test + fun `present - continue in wrong state generates an error`() = runTest { + createPresenter().test { + val initialState = awaitItem() + initialState.eventSink(EnterNumberEvent.Continue) + val state2 = awaitItem() + assertThat(state2.sendingCode.isFailure()).isTrue() + } + } + + @Test + fun `present - continue when number is not valid invokes the navigator`() = runTest { + val linkMobileHandler = FakeLinkMobileHandler( + startResult = {}, + ) + val validateResult = lambdaRecorder { false } + val checkCodeSender = FakeCheckCodeSender( + validateResult = validateResult, + ) + val matrixClient = FakeMatrixClient( + sessionCoroutineScope = backgroundScope, + createLinkMobileHandlerResult = { Result.success(linkMobileHandler) } + ) + val linkNewMobileHandler = LinkNewMobileHandler(matrixClient) + linkNewMobileHandler.createAndStartNewHandler() + val navigateToWrongNumberErrorLambda = lambdaRecorder { } + val navigator = FakeEnterNumberNavigator( + navigateToWrongNumberErrorLambda = navigateToWrongNumberErrorLambda, + ) + createPresenter( + navigator = navigator, + linkNewMobileHandler = linkNewMobileHandler, + ).test { + val initialState = awaitItem() + linkMobileHandler.emitStep( + LinkMobileStep.QrScanned(checkCodeSender) + ) + runCurrent() + initialState.eventSink(EnterNumberEvent.UpdateNumber("88")) + skipItems(1) + initialState.eventSink(EnterNumberEvent.Continue) + skipItems(1) + val finalState = awaitItem() + assertThat(finalState.sendingCode.isLoading()).isTrue() + advanceUntilIdle() + validateResult.assertions().isCalledOnce().with(value(88.toUByte())) + navigateToWrongNumberErrorLambda.assertions().isCalledOnce() + } + } + + @Test + fun `present - continue when the number is valid but sending fails`() = runTest { + val linkMobileHandler = FakeLinkMobileHandler( + startResult = {}, + ) + val validateResult = lambdaRecorder { true } + val sendResult = lambdaRecorder> { Result.failure(AN_EXCEPTION) } + val checkCodeSender = FakeCheckCodeSender( + validateResult = validateResult, + sendResult = sendResult, + ) + val matrixClient = FakeMatrixClient( + sessionCoroutineScope = backgroundScope, + createLinkMobileHandlerResult = { Result.success(linkMobileHandler) } + ) + val linkNewMobileHandler = LinkNewMobileHandler(matrixClient) + linkNewMobileHandler.createAndStartNewHandler() + createPresenter( + linkNewMobileHandler = linkNewMobileHandler, + ).test { + val initialState = awaitItem() + linkMobileHandler.emitStep( + LinkMobileStep.QrScanned(checkCodeSender) + ) + runCurrent() + initialState.eventSink(EnterNumberEvent.UpdateNumber("88")) + skipItems(1) + initialState.eventSink(EnterNumberEvent.Continue) + skipItems(1) + val loadingState = awaitItem() + assertThat(loadingState.sendingCode.isLoading()).isTrue() + val finalState = awaitItem() + assertThat(finalState.sendingCode.isFailure()).isTrue() + validateResult.assertions().isCalledOnce().with(value(88.toUByte())) + sendResult.assertions().isCalledOnce().with(value(88.toUByte())) + } + } + + @Test + fun `present - continue when the number is valid and sending is successful`() = runTest { + val linkMobileHandler = FakeLinkMobileHandler( + startResult = {}, + ) + val validateResult = lambdaRecorder { true } + val sendResult = lambdaRecorder> { Result.success(Unit) } + val checkCodeSender = FakeCheckCodeSender( + validateResult = validateResult, + sendResult = sendResult, + ) + val matrixClient = FakeMatrixClient( + sessionCoroutineScope = backgroundScope, + createLinkMobileHandlerResult = { Result.success(linkMobileHandler) } + ) + val linkNewMobileHandler = LinkNewMobileHandler(matrixClient) + linkNewMobileHandler.createAndStartNewHandler() + createPresenter( + linkNewMobileHandler = linkNewMobileHandler, + ).test { + val initialState = awaitItem() + linkMobileHandler.emitStep( + LinkMobileStep.QrScanned(checkCodeSender) + ) + runCurrent() + initialState.eventSink(EnterNumberEvent.UpdateNumber("88")) + skipItems(1) + initialState.eventSink(EnterNumberEvent.Continue) + skipItems(1) + val loadingState = awaitItem() + assertThat(loadingState.sendingCode.isLoading()).isTrue() + expectNoEvents() + advanceUntilIdle() + validateResult.assertions().isCalledOnce().with(value(88.toUByte())) + sendResult.assertions().isCalledOnce().with(value(88.toUByte())) + } + } + + private fun createPresenter( + navigator: EnterNumberNavigator = FakeEnterNumberNavigator(), + linkNewMobileHandler: LinkNewMobileHandler = LinkNewMobileHandler(FakeMatrixClient()), + ) = EnterNumberPresenter( + navigator = navigator, + linkNewMobileHandler = linkNewMobileHandler, + ) +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberStateTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberStateTest.kt new file mode 100644 index 0000000000..e7466a1b21 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberStateTest.kt @@ -0,0 +1,94 @@ +/* + * 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.linknewdevice.impl.screens.number + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.linknewdevice.impl.screens.number.model.Digit +import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.matrix.test.AN_EXCEPTION +import org.junit.Test + +class EnterNumberStateTest { + @Test + fun `isContinueButtonEnabled is false if number is not complete`() { + val sut = aEnterNumberState( + number = "", + sendingCode = AsyncAction.Uninitialized, + ) + assertThat(sut.copy(number = "1").isContinueButtonEnabled).isFalse() + } + + @Test + fun `isContinueButtonEnabled is true if number is complete`() { + val sut = aEnterNumberState( + number = "12", + sendingCode = AsyncAction.Uninitialized, + ) + assertThat(sut.isContinueButtonEnabled).isTrue() + } + + @Test + fun `isContinueButtonEnabled is false if number is complete and sending is loading`() { + val sut = aEnterNumberState( + number = "12", + sendingCode = AsyncAction.Loading, + ) + assertThat(sut.isContinueButtonEnabled).isFalse() + } + + @Test + fun `isContinueButtonEnabled is true if number is complete and sending is not loading`() { + listOf( + AsyncAction.Uninitialized, + AsyncAction.Failure(AN_EXCEPTION), + AsyncAction.Success(Unit), + ).forEach { action -> + val sut = aEnterNumberState( + number = "12", + sendingCode = action, + ) + assertThat(sut.isContinueButtonEnabled).isTrue() + } + } + + @Test + fun `numberEntry is computed from number - case empty`() { + val sut = aEnterNumberState( + number = "", + ) + assertThat(sut.numberEntry.size).isEqualTo(2) + assertThat(sut.numberEntry.digits).containsExactly( + Digit.Empty, + Digit.Empty, + ) + } + + @Test + fun `numberEntry is computed from number - case half filled`() { + val sut = aEnterNumberState( + number = "1", + ) + assertThat(sut.numberEntry.size).isEqualTo(2) + assertThat(sut.numberEntry.digits).containsExactly( + Digit.Filled('1'), + Digit.Empty, + ) + } + + @Test + fun `numberEntry is computed from number - case filled`() { + val sut = aEnterNumberState( + number = "12", + ) + assertThat(sut.numberEntry.size).isEqualTo(2) + assertThat(sut.numberEntry.digits).containsExactly( + Digit.Filled('1'), + Digit.Filled('2'), + ) + } +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberViewTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberViewTest.kt new file mode 100644 index 0000000000..20e1d898dd --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/EnterNumberViewTest.kt @@ -0,0 +1,92 @@ +/* + * 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.linknewdevice.impl.screens.number + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.test.ext.junit.runners.AndroidJUnit4 +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 io.element.android.tests.testutils.pressBackKey +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class EnterNumberViewTest { + @get:Rule + val rule = createAndroidComposeRule() + + @Test + fun `on back pressed - calls the expected callback`() { + ensureCalledOnce { callback -> + rule.setView( + state = aEnterNumberState(), + onBackClicked = callback, + ) + rule.pressBackKey() + } + } + + @Test + fun `on back button clicked - calls the expected callback`() { + ensureCalledOnce { callback -> + rule.setView( + state = aEnterNumberState(), + onBackClicked = callback, + ) + rule.pressBack() + } + } + + @Test + fun `on continue button clicked - emits the Continue event`() { + val eventRecorder = EventsRecorder() + rule.setView( + state = aEnterNumberState( + number = "12", + eventSink = eventRecorder, + ), + ) + rule.clickOn(CommonStrings.action_continue) + eventRecorder.assertSingle(EnterNumberEvent.Continue) + } + + @Test + fun `when the number is not complete, continue button is disabled`() { + val eventRecorder = EventsRecorder(expectEvents = false) + rule.setView( + state = aEnterNumberState( + number = "1", + eventSink = eventRecorder, + ), + ) + val continueStr = rule.activity.getString(CommonStrings.action_continue) + rule.onNodeWithText(continueStr).assertIsNotEnabled() + } + + private fun AndroidComposeTestRule.setView( + state: EnterNumberState, + onBackClicked: () -> Unit = EnsureNeverCalled(), + ) { + setContent { + EnterNumberView( + state = state, + onBackClick = onBackClicked, + ) + } + } +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/FakeEnterNumberNavigator.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/FakeEnterNumberNavigator.kt new file mode 100644 index 0000000000..a96ab7fe30 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/number/FakeEnterNumberNavigator.kt @@ -0,0 +1,18 @@ +/* + * 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.linknewdevice.impl.screens.number + +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeEnterNumberNavigator( + private val navigateToWrongNumberErrorLambda: () -> Unit = { lambdaError() }, +) : EnterNumberNavigator { + override fun navigateToWrongNumberError() { + navigateToWrongNumberErrorLambda() + } +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeViewTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeViewTest.kt new file mode 100644 index 0000000000..c6c89ba818 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodeViewTest.kt @@ -0,0 +1,47 @@ +/* + * 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.linknewdevice.impl.screens.qrcode + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.tests.testutils.EnsureNeverCalled +import io.element.android.tests.testutils.ensureCalledOnce +import io.element.android.tests.testutils.pressBackKey +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class ShowQrCodeViewTest { + @get:Rule + val rule = createAndroidComposeRule() + + @Test + fun `on back pressed - calls the expected callback`() { + ensureCalledOnce { callback -> + rule.setView( + onBackClick = callback + ) + rule.pressBackKey() + } + } + + private fun AndroidComposeTestRule.setView( + onBackClick: () -> Unit = EnsureNeverCalled(), + ) { + setContent { + ShowQrCodeView( + data = "DATA", + onBackClick = onBackClick, + ) + } + } +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenterTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenterTest.kt new file mode 100644 index 0000000000..5d945e9605 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenterTest.kt @@ -0,0 +1,74 @@ +/* + * 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.linknewdevice.impl.screens.root + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.linknewdevice.impl.LinkNewMobileHandler +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.test.AN_EXCEPTION +import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.test +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test + +class LinkNewDeviceRootPresenterTest { + @get:Rule + val warmUpRule = WarmUpRule() + + @Test + fun `present - initial state`() = runTest { + val matrixClient = FakeMatrixClient( + canLinkNewDeviceResult = { Result.success(true) } + ) + createPresenter( + matrixClient = matrixClient, + ).test { + val initialState = awaitItem() + assertThat(initialState.isSupported.isUninitialized()).isTrue() + assertThat(awaitItem().isSupported.dataOrNull()).isTrue() + } + } + + @Test + fun `present - new login device not supported`() = runTest { + val matrixClient = FakeMatrixClient( + canLinkNewDeviceResult = { Result.success(false) } + ) + createPresenter( + matrixClient = matrixClient, + ).test { + val initialState = awaitItem() + assertThat(initialState.isSupported.isUninitialized()).isTrue() + assertThat(awaitItem().isSupported.dataOrNull()).isFalse() + } + } + + @Test + fun `present - error`() = runTest { + val matrixClient = FakeMatrixClient( + canLinkNewDeviceResult = { Result.failure(AN_EXCEPTION) } + ) + createPresenter( + matrixClient = matrixClient, + ).test { + val initialState = awaitItem() + assertThat(initialState.isSupported.isUninitialized()).isTrue() + assertThat(awaitItem().isSupported.isFailure()).isTrue() + } + } + + private fun createPresenter( + matrixClient: MatrixClient = FakeMatrixClient(), + linkNewMobileHandler: LinkNewMobileHandler = LinkNewMobileHandler(matrixClient), + ) = LinkNewDeviceRootPresenter( + matrixClient = matrixClient, + linkNewMobileHandler = linkNewMobileHandler, + ) +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootViewTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootViewTest.kt new file mode 100644 index 0000000000..e352debfb0 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootViewTest.kt @@ -0,0 +1,102 @@ +/* + * 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.linknewdevice.impl.screens.root + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.features.linknewdevice.impl.R +import io.element.android.libraries.architecture.AsyncData +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.pressBackKey +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class LinkNewDeviceRootViewTest { + @get:Rule + val rule = createAndroidComposeRule() + + @Test + fun `on back pressed - calls the onRetry callback`() { + val eventRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { callback -> + rule.setLinkNewDeviceRootView( + state = aLinkNewDeviceRootState( + eventSink = eventRecorder, + ), + onBackClick = callback + ) + rule.pressBackKey() + } + } + + @Test + fun `link desktop button clicked - calls the expected callback`() { + val eventRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { callback -> + rule.setLinkNewDeviceRootView( + state = aLinkNewDeviceRootState( + isSupported = AsyncData.Success(true), + eventSink = eventRecorder, + ), + onLinkDesktopDeviceClick = callback, + ) + rule.clickOn(R.string.screen_link_new_device_root_desktop_computer) + } + } + + @Test + fun `link mobile button clicked - emits the expected event`() { + val eventRecorder = EventsRecorder() + rule.setLinkNewDeviceRootView( + state = aLinkNewDeviceRootState( + isSupported = AsyncData.Success(true), + eventSink = eventRecorder, + ) + ) + rule.clickOn(R.string.screen_link_new_device_root_mobile_device) + eventRecorder.assertSingle(LinkNewDeviceRootEvent.LinkMobileDevice) + } + + @Test + fun `not supported - dismiss click - invokes the expected callback`() { + val eventRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { callback -> + rule.setLinkNewDeviceRootView( + state = aLinkNewDeviceRootState( + isSupported = AsyncData.Success(false), + eventSink = eventRecorder, + ), + onBackClick = callback, + ) + rule.clickOn(CommonStrings.action_dismiss) + } + } + + private fun AndroidComposeTestRule.setLinkNewDeviceRootView( + state: LinkNewDeviceRootState = aLinkNewDeviceRootState(), + onBackClick: () -> Unit = EnsureNeverCalled(), + onLinkDesktopDeviceClick: () -> Unit = EnsureNeverCalled(), + ) { + setContent { + LinkNewDeviceRootView( + state = state, + onBackClick = onBackClick, + onLinkDesktopDeviceClick = onLinkDesktopDeviceClick, + ) + } + } +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenterTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenterTest.kt new file mode 100644 index 0000000000..a258e19fb9 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenterTest.kt @@ -0,0 +1,112 @@ +/* + * 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. + */ + +@file:OptIn(ExperimentalCoroutinesApi::class) + +package io.element.android.features.linknewdevice.impl.screens.scan + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.linknewdevice.impl.LinkNewDesktopHandler +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeDecodeException +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopStep +import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.matrix.test.QR_CODE_DATA_RECIPROCATE +import io.element.android.libraries.matrix.test.linknewdevice.FakeLinkDesktopHandler +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.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test + +class ScanQrCodePresenterTest { + @get:Rule + val warmUpRule = WarmUpRule() + + @Test + fun `present - initial state`() = runTest { + val matrixClient = FakeMatrixClient( + createLinkDesktopHandlerResult = { Result.success(FakeLinkDesktopHandler()) } + ) + createPresenter( + matrixClient = matrixClient, + ).test { + val initialState = awaitItem() + assertThat(initialState.scanAction.isLoading()).isTrue() + } + } + + @Test + fun `present - handle scanned event - success`() = runTest { + val handleScannedQrCodeResult = lambdaRecorder { } + val matrixClient = FakeMatrixClient( + sessionCoroutineScope = backgroundScope, + createLinkDesktopHandlerResult = { + Result.success( + FakeLinkDesktopHandler( + handleScannedQrCodeResult = handleScannedQrCodeResult, + ) + ) + } + ) + createPresenter( + matrixClient = matrixClient, + ).test { + val initialState = awaitItem() + assertThat(initialState.scanAction.isLoading()).isTrue() + initialState.eventSink(ScanQrCodeEvent.QrCodeScanned(QR_CODE_DATA_RECIPROCATE)) + val scannedState = awaitItem() + assertThat(scannedState.scanAction.isSuccess()).isTrue() + runCurrent() + handleScannedQrCodeResult.assertions().isCalledOnce().with(value(QR_CODE_DATA_RECIPROCATE)) + } + } + + @Test + fun `present - handle scanned event - failure`() = runTest { + val handleScannedQrCodeResult = lambdaRecorder { } + val handler = FakeLinkDesktopHandler( + handleScannedQrCodeResult = handleScannedQrCodeResult, + ) + val matrixClient = FakeMatrixClient( + sessionCoroutineScope = backgroundScope, + createLinkDesktopHandlerResult = { + Result.success(handler) + } + ) + createPresenter( + matrixClient = matrixClient, + ).test { + val initialState = awaitItem() + assertThat(initialState.scanAction.isLoading()).isTrue() + initialState.eventSink(ScanQrCodeEvent.QrCodeScanned(QR_CODE_DATA_RECIPROCATE)) + val scannedState = awaitItem() + assertThat(scannedState.scanAction.isSuccess()).isTrue() + handler.emitStep(LinkDesktopStep.InvalidQrCode(QrCodeDecodeException.Crypto("Invalid QR Code"))) + skipItems(1) + val errorState = awaitItem() + assertThat(errorState.scanAction.isFailure()).isTrue() + handleScannedQrCodeResult.assertions().isCalledOnce().with(value(QR_CODE_DATA_RECIPROCATE)) + // Reset by trying again + errorState.eventSink(ScanQrCodeEvent.TryAgain) + val resetState = awaitItem() + assertThat(resetState.scanAction.isLoading()).isTrue() + } + } +} + +private fun createPresenter( + matrixClient: MatrixClient, +): ScanQrCodePresenter { + return ScanQrCodePresenter( + linkNewDesktopHandler = LinkNewDesktopHandler(matrixClient), + ) +} diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeViewTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeViewTest.kt new file mode 100644 index 0000000000..fcc3afeb7d --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodeViewTest.kt @@ -0,0 +1,70 @@ +/* + * 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.linknewdevice.impl.screens.scan + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.matrix.test.AN_EXCEPTION +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.pressBackKey +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class ScanQrCodeViewTest { + @get:Rule + val rule = createAndroidComposeRule() + + @Test + fun `on back pressed - calls the expected callback`() { + val eventRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { callback -> + rule.setView( + state = aScanQrCodeState( + eventSink = eventRecorder, + ), + onBackClick = callback + ) + rule.pressBackKey() + } + } + + @Test + fun `try again button clicked - emits the expected event`() { + val eventRecorder = EventsRecorder() + rule.setView( + state = aScanQrCodeState( + scanAction = AsyncAction.Failure(AN_EXCEPTION), + eventSink = eventRecorder, + ) + ) + rule.clickOn(CommonStrings.action_try_again) + eventRecorder.assertSingle(ScanQrCodeEvent.TryAgain) + } + + private fun AndroidComposeTestRule.setView( + state: ScanQrCodeState = aScanQrCodeState(), + onBackClick: () -> Unit = EnsureNeverCalled(), + ) { + setContent { + ScanQrCodeView( + state = state, + onBackClick = onBackClick, + ) + } + } +} diff --git a/features/linknewdevice/test/build.gradle.kts b/features/linknewdevice/test/build.gradle.kts new file mode 100644 index 0000000000..388612f920 --- /dev/null +++ b/features/linknewdevice/test/build.gradle.kts @@ -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. + */ + +plugins { + id("io.element.android-compose-library") +} + +android { + namespace = "io.element.android.features.linknewdevice.test" +} + +dependencies { + implementation(projects.features.linknewdevice.api) + implementation(projects.tests.testutils) +} diff --git a/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/PreferencesEntryPoint.kt b/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/PreferencesEntryPoint.kt index 82ff1e7edd..5a59d9be8a 100644 --- a/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/PreferencesEntryPoint.kt +++ b/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/PreferencesEntryPoint.kt @@ -41,6 +41,7 @@ interface PreferencesEntryPoint : FeatureEntryPoint { interface Callback : Plugin { fun navigateToAddAccount() + fun navigateToLinkNewDevice() fun navigateToBugReport() fun navigateToSecureBackup() fun navigateToRoomNotificationSettings(roomId: RoomId) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt index c7328fb6ed..c646923c77 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt @@ -163,6 +163,10 @@ class PreferencesFlowNode( backstack.push(NavTarget.Labs) } + override fun navigateToLinkNewDevice() { + callback.navigateToLinkNewDevice() + } + override fun navigateToUserProfile(matrixUser: MatrixUser) { backstack.push(NavTarget.UserProfile(matrixUser)) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt index 7dafcfae81..6b54a763af 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootNode.kt @@ -45,6 +45,7 @@ class PreferencesRootNode( fun navigateToLockScreenSettings() fun navigateToAdvancedSettings() fun navigateToLabs() + fun navigateToLinkNewDevice() fun navigateToUserProfile(matrixUser: MatrixUser) fun navigateToBlockedUsers() fun startSignOutFlow() @@ -84,6 +85,7 @@ class PreferencesRootNode( onOpenDeveloperSettings = callback::navigateToDeveloperSettings, onOpenAdvancedSettings = callback::navigateToAdvancedSettings, onOpenLabs = callback::navigateToLabs, + onLinkNewDeviceClick = callback::navigateToLinkNewDevice, onManageAccountClick = { onManageAccountClick(activity, it, isDark) }, onOpenNotificationSettings = callback::navigateToNotificationSettings, onOpenLockScreenSettings = callback::navigateToLockScreenSettings, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt index 4e83f7c6b2..1e056c0bf0 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt @@ -69,6 +69,9 @@ class PreferencesRootPresenter( val isMultiAccountEnabled by remember { featureFlagService.isFeatureEnabledFlow(FeatureFlags.MultiAccount) }.collectAsState(initial = false) + val showLinkNewDevice by remember { + featureFlagService.isFeatureEnabledFlow(FeatureFlags.QrCodeLogin) + }.collectAsState(initial = false) val otherSessions by remember { sessionStore.sessionsFlow().map { list -> @@ -146,6 +149,7 @@ class PreferencesRootPresenter( devicesManagementUrl = devicesManagementUrl.value, showAnalyticsSettings = hasAnalyticsProviders, canReportBug = canReportBug, + showLinkNewDevice = showLinkNewDevice, showDeveloperSettings = showDeveloperSettings, canDeactivateAccount = canDeactivateAccount, showBlockedUsersItem = showBlockedUsersItem, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt index dd03b3e775..d637ae6c87 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt @@ -25,6 +25,7 @@ data class PreferencesRootState( val accountManagementUrl: String?, val devicesManagementUrl: String?, val canReportBug: Boolean, + val showLinkNewDevice: Boolean, val showAnalyticsSettings: Boolean, val showDeveloperSettings: Boolean, val canDeactivateAccount: Boolean, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt index c979bd2580..b8d1f1c2b6 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt @@ -31,6 +31,7 @@ fun aPreferencesRootState( accountManagementUrl = "aUrl", devicesManagementUrl = "anOtherUrl", showAnalyticsSettings = true, + showLinkNewDevice = true, canReportBug = true, showDeveloperSettings = true, showBlockedUsersItem = true, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt index 66398d9dbc..5e3c9d6759 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt @@ -54,6 +54,7 @@ fun PreferencesRootView( onAddAccountClick: () -> Unit, onSecureBackupClick: () -> Unit, onManageAccountClick: (url: String) -> Unit, + onLinkNewDeviceClick: () -> Unit, onOpenAnalytics: () -> Unit, onOpenRageShake: () -> Unit, onOpenLockScreenSettings: () -> Unit, @@ -101,6 +102,7 @@ fun PreferencesRootView( ManageAccountSection( state = state, onManageAccountClick = onManageAccountClick, + onLinkNewDeviceClick = onLinkNewDeviceClick, onOpenBlockedUsers = onOpenBlockedUsers ) @@ -193,8 +195,16 @@ private fun ColumnScope.ManageAppSection( private fun ColumnScope.ManageAccountSection( state: PreferencesRootState, onManageAccountClick: (url: String) -> Unit, + onLinkNewDeviceClick: () -> Unit, onOpenBlockedUsers: () -> Unit, ) { + if (state.showLinkNewDevice) { + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.common_link_new_device)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Devices())), + onClick = onLinkNewDeviceClick, + ) + } state.accountManagementUrl?.let { url -> ListItem( headlineContent = { Text(stringResource(id = CommonStrings.action_manage_account)) }, @@ -353,6 +363,7 @@ private fun ContentToPreview(matrixUser: MatrixUser) { onOpenAbout = {}, onSecureBackupClick = {}, onManageAccountClick = {}, + onLinkNewDeviceClick = {}, onOpenNotificationSettings = {}, onOpenLockScreenSettings = {}, onOpenUserProfile = {}, diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/DefaultPreferencesEntryPointTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/DefaultPreferencesEntryPointTest.kt index 7a950629be..963d7846b4 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/DefaultPreferencesEntryPointTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/DefaultPreferencesEntryPointTest.kt @@ -50,6 +50,7 @@ class DefaultPreferencesEntryPointTest { } val callback = object : PreferencesEntryPoint.Callback { override fun navigateToAddAccount() = lambdaError() + override fun navigateToLinkNewDevice() = lambdaError() override fun navigateToBugReport() = lambdaError() override fun navigateToSecureBackup() = lambdaError() override fun navigateToRoomNotificationSettings(roomId: RoomId) = lambdaError() diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt index 1fa141b297..d10f860f0d 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt @@ -87,6 +87,7 @@ class PreferencesRootPresenterTest { assertThat(loadedState.accountManagementUrl).isNull() assertThat(loadedState.devicesManagementUrl).isNull() assertThat(loadedState.showAnalyticsSettings).isFalse() + assertThat(loadedState.showLinkNewDevice).isFalse() assertThat(loadedState.showDeveloperSettings).isTrue() assertThat(loadedState.canDeactivateAccount).isTrue() assertThat(loadedState.canReportBug).isTrue() @@ -258,6 +259,22 @@ class PreferencesRootPresenterTest { } } + @Test + fun `present - link new device`() = runTest { + createPresenter( + matrixClient = FakeMatrixClient( + sessionId = A_SESSION_ID, + canDeactivateAccountResult = { true }, + ), + featureFlagService = FakeFeatureFlagService( + initialState = mapOf(FeatureFlags.QrCodeLogin.key to true) + ), + ).test { + val state = awaitFirstItem() + assertThat(state.showLinkNewDevice).isTrue() + } + } + private suspend fun ReceiveTurbine.awaitFirstItem(): T { skipItems(1) return awaitItem() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b5a2607c01..96378f0eb7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -211,6 +211,9 @@ maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2" maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2" opusencoder = "io.element.android:opusencoder:1.2.0" zxing_cpp = "io.github.zxing-cpp:android:2.3.0" +# Stick to 3.3.3 because of https://github.com/zxing/zxing/issues/1170 +google_zxing = "com.google.zxing:core:3.3.3" + haze = { module = "dev.chrisbanes.haze:haze", version.ref = "haze" } haze_materials = { module = "dev.chrisbanes.haze:haze-materials", version.ref = "haze" } color_picker = "io.mhssn:colorpicker:1.0.0" diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/Brightness.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/Brightness.kt new file mode 100644 index 0000000000..8cf1cc6827 --- /dev/null +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/Brightness.kt @@ -0,0 +1,27 @@ +/* + * 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.androidutils.system + +import android.app.Activity +import android.view.WindowManager + +/** + * Set the screen brightness for the given activity. + * + * @receiver current Activity. + * @param full If true, override brightness to full; otherwise, set to none (default). + */ +fun Activity.setFullBrightness(full: Boolean) { + window.attributes = window.attributes.apply { + screenBrightness = if (full) { + WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL + } else { + WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE + } + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/LoadingButtonAtom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/LoadingButtonAtom.kt new file mode 100644 index 0000000000..666d48d457 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/LoadingButtonAtom.kt @@ -0,0 +1,26 @@ +/* + * 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.designsystem.atomic.atoms + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +fun LoadingButtonAtom( + modifier: Modifier = Modifier, +) = Button( + modifier = modifier.fillMaxWidth(), + enabled = false, + showProgress = true, + text = stringResource(CommonStrings.common_loading), + onClick = {}, +) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/ForceMaxBrightness.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/ForceMaxBrightness.kt new file mode 100644 index 0000000000..b0c9e8cea7 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/ForceMaxBrightness.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.designsystem.utils + +import androidx.activity.compose.LocalActivity +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import io.element.android.libraries.androidutils.system.setFullBrightness + +@Composable +fun ForceMaxBrightness() { + val activity = LocalActivity.current ?: return + DisposableEffect(Unit) { + activity.setFullBrightness(true) + onDispose { + activity.setFullBrightness(false) + } + } +} 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 2cbfb50944..f7227a9ac9 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 @@ -125,4 +125,11 @@ enum class FeatureFlags( defaultValue = { true }, isFinished = false, ), + QrCodeLogin( + key = "feature.qr_code_login", + title = "QR Code Login", + description = "Allow logging in on other devices using a QR code.", + defaultValue = { false }, + isFinished = false, + ), } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index ae803110d5..6220349756 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -19,6 +19,8 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.encryption.EncryptionService +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MediaPreviewService import io.element.android.libraries.matrix.api.notification.NotificationService @@ -195,6 +197,21 @@ interface MatrixClient { */ suspend fun markRoomAsFullyRead(roomId: RoomId, eventId: EventId): Result + /** + * Check if linking a new device using QrCode is supported by the server. + */ + suspend fun canLinkNewDevice(): Result + + /** + * Create a handler to link a new mobile device, i.e. a device capable of scanning QrCodes. + */ + fun createLinkMobileHandler(): Result + + /** + * Create a handler to link a new desktop device, i.e. a device not capable of scanning QrCodes. + */ + fun createLinkDesktopHandler(): Result + suspend fun performDatabaseVacuum(): Result } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/CheckCodeSender.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/CheckCodeSender.kt new file mode 100644 index 0000000000..ecb440de83 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/CheckCodeSender.kt @@ -0,0 +1,22 @@ +/* + * 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.linknewdevice + +interface CheckCodeSender { + /** + * Validates the given [code]. Returns true if the code is valid, false otherwise. + * This method can be called multiple times to validate different codes. + */ + suspend fun validate(code: UByte): Boolean + + /** + * Sends the given [code]. + * This method can be called only once. + */ + suspend fun send(code: UByte): Result +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/ErrorType.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/ErrorType.kt new file mode 100644 index 0000000000..0f61007d47 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/ErrorType.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.libraries.matrix.api.linknewdevice + +sealed class ErrorType(message: String) : Exception(message) { + /** + * The requested device ID is already in use. + */ + class DeviceIdAlreadyInUse(message: String) : ErrorType(message) + + /** + * The check code was incorrect. + */ + class InvalidCheckCode(message: String) : ErrorType(message) + + /** + * The other client proposed an unsupported protocol. + */ + class UnsupportedProtocol(message: String) : ErrorType(message) + + /** + * Secrets backup not set up properly. + */ + class MissingSecretsBackup(message: String) : ErrorType(message) + + /** + * The rendezvous session was not found and might have expired. + */ + class NotFound(message: String) : ErrorType(message) + + /** + * The device could not be created. + */ + class UnableToCreateDevice(message: String) : ErrorType(message) + + /** + * An unknown error has happened. + */ + class Unknown(message: String) : ErrorType(message) +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/LinkDesktopHandler.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/LinkDesktopHandler.kt new file mode 100644 index 0000000000..d600c1a8bf --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/LinkDesktopHandler.kt @@ -0,0 +1,41 @@ +/* + * 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.linknewdevice + +import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeDecodeException +import kotlinx.coroutines.flow.StateFlow + +interface LinkDesktopHandler { + val linkDesktopStep: StateFlow + suspend fun handleScannedQrCode(data: ByteArray) +} + +sealed interface LinkDesktopStep { + data object Uninitialized : LinkDesktopStep + data object Starting : LinkDesktopStep + data class WaitingForAuth( + val verificationUri: String, + ) : LinkDesktopStep + + data class EstablishingSecureChannel( + val checkCode: UByte, + val checkCodeString: String, + ) : LinkDesktopStep + + data class InvalidQrCode( + val error: QrCodeDecodeException, + ) : LinkDesktopStep + + data class Error( + val errorType: ErrorType, + ) : LinkDesktopStep + + data object SyncingSecrets : LinkDesktopStep + + data object Done : LinkDesktopStep +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/LinkMobileHandler.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/LinkMobileHandler.kt new file mode 100644 index 0000000000..0c261cdd1a --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/linknewdevice/LinkMobileHandler.kt @@ -0,0 +1,26 @@ +/* + * 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.linknewdevice + +import kotlinx.coroutines.flow.Flow + +interface LinkMobileHandler { + val linkMobileStep: Flow + suspend fun start() +} + +sealed interface LinkMobileStep { + data object Uninitialized : LinkMobileStep + data object Starting : LinkMobileStep + data class QrReady(val data: String) : LinkMobileStep + data class WaitingForAuth(val verificationUri: String) : LinkMobileStep + data class QrScanned(val checkCodeSender: CheckCodeSender) : LinkMobileStep + data class Error(val errorType: ErrorType) : LinkMobileStep + data object SyncingSecrets : LinkMobileStep + data object Done : LinkMobileStep +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/logs/LoggerTags.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/logs/LoggerTags.kt new file mode 100644 index 0000000000..7f19b2d3db --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/logs/LoggerTags.kt @@ -0,0 +1,14 @@ +/* + * 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.logs + +import io.element.android.libraries.core.log.logger.LoggerTag + +object LoggerTags { + val linkNewDevice = LoggerTag("LinkNewDevice") +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 8784a69d7c..1de606637a 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -25,6 +25,8 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.RoomPreset +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.oidc.AccountManagementAction import io.element.android.libraries.matrix.api.room.BaseRoom @@ -45,6 +47,8 @@ import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.impl.encryption.RustEncryptionService import io.element.android.libraries.matrix.impl.exception.mapClientException +import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkDesktopHandler +import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkMobileHandler import io.element.android.libraries.matrix.impl.mapper.map import io.element.android.libraries.matrix.impl.media.RustMediaLoader import io.element.android.libraries.matrix.impl.media.RustMediaPreviewService @@ -726,6 +730,34 @@ class RustMatrixClient( } } + override suspend fun canLinkNewDevice(): Result = withContext(sessionDispatcher) { + runCatchingExceptions { + innerClient.isLoginWithQrCodeSupported() + } + } + + override fun createLinkMobileHandler(): Result { + return runCatchingExceptions { + val handler = innerClient.newGrantLoginWithQrCodeHandler() + RustLinkMobileHandler( + inner = handler, + sessionCoroutineScope = sessionCoroutineScope, + sessionDispatcher = sessionDispatcher, + ) + } + } + + override fun createLinkDesktopHandler(): Result { + return runCatchingExceptions { + val handler = innerClient.newGrantLoginWithQrCodeHandler() + RustLinkDesktopHandler( + inner = handler, + sessionCoroutineScope = sessionCoroutineScope, + sessionDispatcher = sessionDispatcher, + ) + } + } + override suspend fun markRoomAsFullyRead(roomId: RoomId, eventId: EventId): Result = withContext(sessionDispatcher) { runCatchingExceptions { val room = innerClient.getRoom(roomId.value) ?: error("Could not fetch associated room") diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/HumanQrGrantLoginExceptionExtension.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/HumanQrGrantLoginExceptionExtension.kt new file mode 100644 index 0000000000..2d47b60def --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/HumanQrGrantLoginExceptionExtension.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.linknewdevice + +import io.element.android.libraries.matrix.api.linknewdevice.ErrorType +import org.matrix.rustcomponents.sdk.HumanQrGrantLoginException + +internal fun HumanQrGrantLoginException.map() = when (this) { + is HumanQrGrantLoginException.DeviceIdAlreadyInUse -> ErrorType.DeviceIdAlreadyInUse(message.orEmpty()) + is HumanQrGrantLoginException.InvalidCheckCode -> ErrorType.InvalidCheckCode(message.orEmpty()) + is HumanQrGrantLoginException.MissingSecretsBackup -> ErrorType.MissingSecretsBackup(message.orEmpty()) + is HumanQrGrantLoginException.NotFound -> ErrorType.NotFound(message.orEmpty()) + is HumanQrGrantLoginException.UnableToCreateDevice -> ErrorType.UnableToCreateDevice(message.orEmpty()) + is HumanQrGrantLoginException.Unknown -> ErrorType.Unknown(message.orEmpty()) + is HumanQrGrantLoginException.UnsupportedProtocol -> ErrorType.UnsupportedProtocol(message.orEmpty()) +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustCheckCodeSender.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustCheckCodeSender.kt new file mode 100644 index 0000000000..9919d1fafc --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustCheckCodeSender.kt @@ -0,0 +1,33 @@ +/* + * 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.linknewdevice + +import io.element.android.libraries.core.extensions.runCatchingExceptions +import io.element.android.libraries.matrix.api.linknewdevice.CheckCodeSender +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.withContext +import org.matrix.rustcomponents.sdk.CheckCodeSender as FfiCheckCodeSender + +class RustCheckCodeSender( + private val inner: FfiCheckCodeSender, + private val sessionDispatcher: CoroutineDispatcher, +) : CheckCodeSender { + override suspend fun validate(code: UByte): Boolean = withContext(sessionDispatcher) { + runCatchingExceptions { + // TODO https://github.com/matrix-org/matrix-rust-sdk/pull/5957 + // inner.validate(code) + true + }.getOrNull() ?: true + } + + override suspend fun send(code: UByte): Result = withContext(sessionDispatcher) { + runCatchingExceptions { + inner.send(code) + } + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandler.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandler.kt new file mode 100644 index 0000000000..fd37b73ad8 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandler.kt @@ -0,0 +1,82 @@ +/* + * 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.linknewdevice + +import io.element.android.libraries.core.log.logger.LoggerTag +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopStep +import io.element.android.libraries.matrix.api.logs.LoggerTags +import io.element.android.libraries.matrix.impl.auth.qrlogin.QrErrorMapper +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.matrix.rustcomponents.sdk.GrantLoginWithQrCodeHandler +import org.matrix.rustcomponents.sdk.GrantQrLoginProgress +import org.matrix.rustcomponents.sdk.GrantQrLoginProgressListener +import org.matrix.rustcomponents.sdk.HumanQrGrantLoginException +import org.matrix.rustcomponents.sdk.QrCodeData +import org.matrix.rustcomponents.sdk.QrCodeDecodeException +import timber.log.Timber + +private val tag = LoggerTag("RustLinkDesktopHandler", LoggerTags.linkNewDevice) + +class RustLinkDesktopHandler( + private val inner: GrantLoginWithQrCodeHandler, + private val sessionCoroutineScope: CoroutineScope, + private val sessionDispatcher: CoroutineDispatcher, +) : LinkDesktopHandler { + private val _linkDesktopStep = MutableStateFlow(LinkDesktopStep.Uninitialized) + override val linkDesktopStep: StateFlow = _linkDesktopStep.asStateFlow() + + override suspend fun handleScannedQrCode(data: ByteArray) = withContext(sessionDispatcher) { + Timber.tag(tag.value).d("Emit Uninitialized") + _linkDesktopStep.emit(LinkDesktopStep.Uninitialized) + try { + val qrCodeData = QrCodeData.fromBytes(data) + inner.scan( + qrCodeData = qrCodeData, + progressListener = object : GrantQrLoginProgressListener { + override fun onUpdate(state: GrantQrLoginProgress) { + sessionCoroutineScope.launch { + val mappedState = state.map() + Timber.tag(tag.value).d("Emit ${mappedState::class.java.simpleName}") + _linkDesktopStep.emit(mappedState) + } + } + } + ) + } catch (e: QrCodeDecodeException) { + Timber.tag(tag.value).w(e, "Invalid QR code scanned") + _linkDesktopStep.emit( + LinkDesktopStep.InvalidQrCode( + error = QrErrorMapper.map(e) + ) + ) + } catch (e: HumanQrGrantLoginException) { + Timber.tag(tag.value).w(e, "Error during QR login grant") + _linkDesktopStep.emit(LinkDesktopStep.Error(e.map())) + } + } + + private fun GrantQrLoginProgress.map() = when (this) { + GrantQrLoginProgress.Done -> LinkDesktopStep.Done + GrantQrLoginProgress.Starting -> LinkDesktopStep.Starting + GrantQrLoginProgress.SyncingSecrets -> LinkDesktopStep.SyncingSecrets + is GrantQrLoginProgress.WaitingForAuth -> LinkDesktopStep.WaitingForAuth( + verificationUri = verificationUri, + ) + is GrantQrLoginProgress.EstablishingSecureChannel -> LinkDesktopStep.EstablishingSecureChannel( + checkCode = checkCode, + checkCodeString = checkCodeString, + ) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkMobileHandler.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkMobileHandler.kt new file mode 100644 index 0000000000..0189987d96 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkMobileHandler.kt @@ -0,0 +1,75 @@ +/* + * 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.linknewdevice + +import io.element.android.libraries.core.log.logger.LoggerTag +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep +import io.element.android.libraries.matrix.api.logs.LoggerTags +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.matrix.rustcomponents.sdk.GrantGeneratedQrLoginProgress +import org.matrix.rustcomponents.sdk.GrantGeneratedQrLoginProgressListener +import org.matrix.rustcomponents.sdk.GrantLoginWithQrCodeHandler +import org.matrix.rustcomponents.sdk.HumanQrGrantLoginException +import timber.log.Timber + +private val tag = LoggerTag("RustLinkMobileHandler", LoggerTags.linkNewDevice) + +class RustLinkMobileHandler( + private val inner: GrantLoginWithQrCodeHandler, + private val sessionCoroutineScope: CoroutineScope, + private val sessionDispatcher: CoroutineDispatcher, +) : LinkMobileHandler { + private val _linkMobileStep = MutableStateFlow(LinkMobileStep.Uninitialized) + override val linkMobileStep: Flow = _linkMobileStep.asStateFlow() + + override suspend fun start() = withContext(sessionDispatcher) { + Timber.tag(tag.value).d("Emit Uninitialized") + _linkMobileStep.emit(LinkMobileStep.Uninitialized) + try { + inner.generate( + progressListener = object : GrantGeneratedQrLoginProgressListener { + override fun onUpdate(state: GrantGeneratedQrLoginProgress) { + sessionCoroutineScope.launch { + val mappedState = state.map() + Timber.tag(tag.value).d("Emit ${mappedState::class.java.simpleName}") + _linkMobileStep.emit(mappedState) + } + } + } + ) + } catch (e: HumanQrGrantLoginException) { + Timber.tag(tag.value).w(e, "Error during QR login grant") + _linkMobileStep.emit(LinkMobileStep.Error(e.map())) + } + } + + private fun GrantGeneratedQrLoginProgress.map(): LinkMobileStep { + return when (this) { + GrantGeneratedQrLoginProgress.Done -> LinkMobileStep.Done + is GrantGeneratedQrLoginProgress.QrReady -> { + LinkMobileStep.QrReady(String(qrCode.toBytes(), Charsets.ISO_8859_1)) + } + is GrantGeneratedQrLoginProgress.QrScanned -> LinkMobileStep.QrScanned( + RustCheckCodeSender( + inner = checkCodeSender, + sessionDispatcher = sessionDispatcher, + ) + ) + GrantGeneratedQrLoginProgress.Starting -> LinkMobileStep.Starting + GrantGeneratedQrLoginProgress.SyncingSecrets -> LinkMobileStep.SyncingSecrets + is GrantGeneratedQrLoginProgress.WaitingForAuth -> LinkMobileStep.WaitingForAuth(verificationUri) + } + } +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 38d4d1aefe..1e66c838c4 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -18,6 +18,8 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.encryption.EncryptionService +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MediaPreviewService import io.element.android.libraries.matrix.api.notification.NotificationService @@ -95,6 +97,9 @@ class FakeMatrixClient( private val deactivateAccountResult: (String, Boolean) -> Result = { _, _ -> lambdaError() }, private val currentSlidingSyncVersionLambda: () -> Result = { lambdaError() }, private val ignoreUserResult: (UserId) -> Result = { lambdaError() }, + private val canLinkNewDeviceResult: () -> Result = { lambdaError() }, + private val createLinkMobileHandlerResult: () -> Result = { lambdaError() }, + private val createLinkDesktopHandlerResult: () -> Result = { lambdaError() }, private var unIgnoreUserResult: (UserId) -> Result = { Result.success(Unit) }, private val canReportRoomLambda: () -> Boolean = { false }, private val isLivekitRtcSupportedLambda: () -> Boolean = { false }, @@ -356,4 +361,16 @@ class FakeMatrixClient( override suspend fun performDatabaseVacuum(): Result { return performDatabaseVacuumLambda() } + + override suspend fun canLinkNewDevice(): Result = simulateLongTask { + return canLinkNewDeviceResult() + } + + override fun createLinkDesktopHandler(): Result { + return createLinkDesktopHandlerResult() + } + + override fun createLinkMobileHandler(): Result { + return createLinkMobileHandlerResult() + } } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt index dbbf2f2fae..dcacadd975 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt @@ -100,3 +100,31 @@ const val A_LOGIN_HINT = "mxid:@alice:example.org" @ColorInt const val A_COLOR_INT: Int = 0xFFFF0000.toInt() + +// From https://github.com/matrix-org/matrix-rust-sdk/blob/3a63838cdb50cde3d74da920186fbae0a2e6db37/crates/matrix-sdk-crypto/src/types/qr_login.rs#L275 +// Test vector for the QR code data, copied from the MSC. +@Suppress("ktlint:standard:argument-list-wrapping") +val QR_CODE_DATA = listOf( + 0x4D, 0x41, 0x54, 0x52, 0x49, 0x58, 0x02, 0x03, 0xd8, 0x86, 0x68, 0x6a, 0xb2, 0x19, 0x7b, + 0x78, 0x0e, 0x30, 0x0a, 0x9d, 0x4a, 0x21, 0x47, 0x48, 0x07, 0x00, 0xd7, 0x92, 0x9f, 0x39, + 0xab, 0x31, 0xb9, 0xe5, 0x14, 0x37, 0x02, 0x48, 0xed, 0x6b, 0x00, 0x47, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x7a, 0x76, 0x6f, 0x75, 0x73, + 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x2f, 0x65, 0x38, 0x64, 0x61, 0x36, 0x33, 0x35, 0x35, 0x2d, 0x35, 0x35, 0x30, 0x62, + 0x2d, 0x34, 0x61, 0x33, 0x32, 0x2d, 0x61, 0x31, 0x39, 0x33, 0x2d, 0x31, 0x36, 0x31, 0x39, + 0x64, 0x39, 0x38, 0x33, 0x30, 0x36, 0x36, 0x38, +).map { it.toByte() }.toByteArray() + +// Test vector for the QR code data, copied from the MSC, with the mode set to reciprocate. +@Suppress("ktlint:standard:argument-list-wrapping") +val QR_CODE_DATA_RECIPROCATE = listOf( + 0x4D, 0x41, 0x54, 0x52, 0x49, 0x58, 0x02, 0x04, 0xd8, 0x86, 0x68, 0x6a, 0xb2, 0x19, 0x7b, + 0x78, 0x0e, 0x30, 0x0a, 0x9d, 0x4a, 0x21, 0x47, 0x48, 0x07, 0x00, 0xd7, 0x92, 0x9f, 0x39, + 0xab, 0x31, 0xb9, 0xe5, 0x14, 0x37, 0x02, 0x48, 0xed, 0x6b, 0x00, 0x47, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x7a, 0x76, 0x6f, 0x75, 0x73, + 0x2e, 0x6c, 0x61, 0x62, 0x2e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x2f, 0x65, 0x38, 0x64, 0x61, 0x36, 0x33, 0x35, 0x35, 0x2d, 0x35, 0x35, 0x30, 0x62, + 0x2d, 0x34, 0x61, 0x33, 0x32, 0x2d, 0x61, 0x31, 0x39, 0x33, 0x2d, 0x31, 0x36, 0x31, 0x39, + 0x64, 0x39, 0x38, 0x33, 0x30, 0x36, 0x36, 0x38, 0x00, 0x0A, 0x6d, 0x61, 0x74, 0x72, 0x69, + 0x78, 0x2e, 0x6f, 0x72, 0x67, +).map { it.toByte() }.toByteArray() diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeCheckCodeSender.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeCheckCodeSender.kt new file mode 100644 index 0000000000..a0692b6f5c --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeCheckCodeSender.kt @@ -0,0 +1,25 @@ +/* + * 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.test.linknewdevice + +import io.element.android.libraries.matrix.api.linknewdevice.CheckCodeSender +import io.element.android.tests.testutils.lambda.lambdaError +import io.element.android.tests.testutils.simulateLongTask + +class FakeCheckCodeSender( + private val validateResult: (UByte) -> Boolean = { lambdaError() }, + private val sendResult: (UByte) -> Result = { lambdaError() }, +) : CheckCodeSender { + override suspend fun validate(code: UByte): Boolean = simulateLongTask { + validateResult(code) + } + + override suspend fun send(code: UByte): Result = simulateLongTask { + sendResult(code) + } +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeLinkDesktopHandler.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeLinkDesktopHandler.kt new file mode 100644 index 0000000000..0bf9dafd01 --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeLinkDesktopHandler.kt @@ -0,0 +1,31 @@ +/* + * 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.test.linknewdevice + +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopStep +import io.element.android.tests.testutils.lambda.lambdaError +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +class FakeLinkDesktopHandler( + private val handleScannedQrCodeResult: (ByteArray) -> Unit = { lambdaError() }, +) : LinkDesktopHandler { + private val mutableLinkDesktopStep: MutableStateFlow = MutableStateFlow(LinkDesktopStep.Uninitialized) + override val linkDesktopStep: StateFlow + get() = mutableLinkDesktopStep.asStateFlow() + + override suspend fun handleScannedQrCode(data: ByteArray) { + handleScannedQrCodeResult(data) + } + + suspend fun emitStep(step: LinkDesktopStep) { + mutableLinkDesktopStep.emit(step) + } +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeLinkMobileHandler.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeLinkMobileHandler.kt new file mode 100644 index 0000000000..de704ea2dd --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/linknewdevice/FakeLinkMobileHandler.kt @@ -0,0 +1,32 @@ +/* + * 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.test.linknewdevice + +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep +import io.element.android.tests.testutils.lambda.lambdaError +import io.element.android.tests.testutils.simulateLongTask +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +class FakeLinkMobileHandler( + private val startResult: () -> Unit = { lambdaError() }, +) : LinkMobileHandler { + private val mutableLinkMobileStep: MutableStateFlow = MutableStateFlow(LinkMobileStep.Uninitialized) + override val linkMobileStep: StateFlow + get() = mutableLinkMobileStep.asStateFlow() + + override suspend fun start() = simulateLongTask { + startResult() + } + + suspend fun emitStep(step: LinkMobileStep) { + mutableLinkMobileStep.emit(step) + } +} diff --git a/libraries/qrcode/build.gradle.kts b/libraries/qrcode/build.gradle.kts index cbf4c2de78..cf76e117c0 100644 --- a/libraries/qrcode/build.gradle.kts +++ b/libraries/qrcode/build.gradle.kts @@ -19,4 +19,5 @@ dependencies { implementation(libs.androidx.camera.view) implementation(libs.androidx.camera.camera2) implementation(libs.zxing.cpp) + implementation(libs.google.zxing) } diff --git a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt index 7f089818d0..18bd1cff10 100644 --- a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt +++ b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeCameraView.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat import androidx.lifecycle.compose.LocalLifecycleOwner @@ -117,7 +118,13 @@ fun QrCodeCameraView( .background(color = ElementTheme.colors.bgSubtlePrimary), contentAlignment = Alignment.Center, ) { - Text("CameraView") + Text( + text = buildString { + append("CameraView\n") + append(if (isScanning) "scanning" else "frozen") + }, + textAlign = TextAlign.Center, + ) } } else { AndroidView( diff --git a/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeImage.kt b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeImage.kt new file mode 100644 index 0000000000..e045e42f17 --- /dev/null +++ b/libraries/qrcode/src/main/kotlin/io/element/android/libraries/qrcode/QrCodeImage.kt @@ -0,0 +1,92 @@ +/* + * 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.qrcode + +import android.graphics.Bitmap +import android.graphics.Color +import androidx.annotation.ColorInt +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.IntSize +import com.google.zxing.BarcodeFormat +import com.google.zxing.common.BitMatrix +import com.google.zxing.qrcode.QRCodeWriter +import io.element.android.libraries.designsystem.modifiers.squareSize +import io.element.android.libraries.designsystem.utils.ForceMaxBrightness + +private fun String.toBitMatrix(size: Int): BitMatrix { + return QRCodeWriter().encode( + this, + BarcodeFormat.QR_CODE, + size, + size, + ) +} + +private fun BitMatrix.toBitmap( + @ColorInt backgroundColor: Int = Color.WHITE, + @ColorInt foregroundColor: Int = Color.BLACK, +): Bitmap { + val colorBuffer = IntArray(width * height) + var rowOffset = 0 + for (y in 0 until height) { + for (x in 0 until width) { + val arrayIndex = x + rowOffset + colorBuffer[arrayIndex] = if (get(x, y)) foregroundColor else backgroundColor + } + rowOffset += width + } + return Bitmap.createBitmap(colorBuffer, width, height, Bitmap.Config.ARGB_8888) +} + +@Composable +fun QrCodeImage( + data: String, + forceMaxBrightness: Boolean = true, + modifier: Modifier = Modifier, +) { + if (forceMaxBrightness) { + ForceMaxBrightness() + } + var size by remember { mutableStateOf(IntSize.Zero) } + Box( + modifier = modifier + .squareSize() + .onSizeChanged { + size = it + }, + ) { + val image = remember(data, size) { + val sideSide = maxOf(size.width, size.height).coerceAtLeast(128) + data.toBitMatrix(sideSide).toBitmap().asImageBitmap() + } + Image( + contentDescription = null, + bitmap = image, + ) + } +} + +@Composable +@Preview +internal fun QrCodeViewPreview() { + QrCodeImage( + modifier = Modifier.fillMaxHeight(), + data = "RANDOM_QRCODE_DATA", + ) +} diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 58fbc36794..8c15fb354a 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -434,32 +434,6 @@ Are you sure you want to continue?" "Options" "Remove %1$s" "Settings" - "Scan the QR code" - "Open %1$s on a laptop or desktop computer" - "Scan the QR code with this device" - "Ready to scan" - "Open %1$s on a desktop computer to get the QR code" - "The numbers don’t match" - "Enter 2-digit code" - "This will verify that the connection to your other device is secure." - "Enter the number shown on your other device" - "Your account provider does not support %1$s." - "%1$s not supported" - "Your account provider doesn’t support signing into a new device with a QR code." - "QR code not supported" - "The sign in was cancelled on the other device." - "Sign in request cancelled" - "Sign in expired. Please try again." - "The sign in was not completed in time" - "Open %1$s on the other device" - "Select %1$s" - "“Sign in with QR code”" - "Scan the QR code shown here with the other device" - "Open %1$s on the other device" - "Desktop computer" - "Loading QR code…" - "Mobile device" - "What type of device do you want to link?" "Spaces where members can join the room without an invitation." "Manage spaces" "(Unknown space)" diff --git a/tools/localazy/config.json b/tools/localazy/config.json index f7463a6396..7afda5e5ad 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -155,6 +155,17 @@ "troubleshoot_notifications_test_unified_push_.*" ] }, + { + "name" : ":features:linknewdevice:impl", + "includeRegex" : [ + "screen\\.link_new_device\\..*", + "screen_qr_code_login_error_.*", + "screen_qr_code_login_connection_note_secure_state.*", + "screen_qr_code_login_unknown_error_description", + "screen_qr_code_login_invalid_scan_state_.*", + "screen_qr_code_login_no_camera_permission_state_.*" + ] + }, { "name" : ":features:login:impl", "includeRegex" : [ From f577edb92937f315d363895adcd967c3fa6d03dc Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 16 Dec 2025 11:59:47 +0000 Subject: [PATCH 138/347] Update screenshots --- ...device.impl.screens.desktop_DesktopNoticeView_Day_0_en.png | 3 +++ ...device.impl.screens.desktop_DesktopNoticeView_Day_1_en.png | 3 +++ ...vice.impl.screens.desktop_DesktopNoticeView_Night_0_en.png | 3 +++ ...vice.impl.screens.desktop_DesktopNoticeView_Night_1_en.png | 3 +++ ...es.linknewdevice.impl.screens.error_ErrorView_Day_0_en.png | 3 +++ ...es.linknewdevice.impl.screens.error_ErrorView_Day_1_en.png | 3 +++ ...es.linknewdevice.impl.screens.error_ErrorView_Day_2_en.png | 3 +++ ...es.linknewdevice.impl.screens.error_ErrorView_Day_3_en.png | 3 +++ ...es.linknewdevice.impl.screens.error_ErrorView_Day_4_en.png | 3 +++ ...es.linknewdevice.impl.screens.error_ErrorView_Day_5_en.png | 3 +++ ...es.linknewdevice.impl.screens.error_ErrorView_Day_6_en.png | 3 +++ ...es.linknewdevice.impl.screens.error_ErrorView_Day_7_en.png | 3 +++ ....linknewdevice.impl.screens.error_ErrorView_Night_0_en.png | 3 +++ ....linknewdevice.impl.screens.error_ErrorView_Night_1_en.png | 3 +++ ....linknewdevice.impl.screens.error_ErrorView_Night_2_en.png | 3 +++ ....linknewdevice.impl.screens.error_ErrorView_Night_3_en.png | 3 +++ ....linknewdevice.impl.screens.error_ErrorView_Night_4_en.png | 3 +++ ....linknewdevice.impl.screens.error_ErrorView_Night_5_en.png | 3 +++ ....linknewdevice.impl.screens.error_ErrorView_Night_6_en.png | 3 +++ ....linknewdevice.impl.screens.error_ErrorView_Night_7_en.png | 3 +++ ...impl.screens.number.component_NumberTextField_Day_0_en.png | 3 +++ ...pl.screens.number.component_NumberTextField_Night_0_en.png | 3 +++ ...newdevice.impl.screens.number_EnterNumberView_Day_0_en.png | 3 +++ ...newdevice.impl.screens.number_EnterNumberView_Day_1_en.png | 3 +++ ...newdevice.impl.screens.number_EnterNumberView_Day_2_en.png | 3 +++ ...newdevice.impl.screens.number_EnterNumberView_Day_3_en.png | 3 +++ ...newdevice.impl.screens.number_EnterNumberView_Day_4_en.png | 3 +++ ...newdevice.impl.screens.number_EnterNumberView_Day_5_en.png | 3 +++ ...wdevice.impl.screens.number_EnterNumberView_Night_0_en.png | 3 +++ ...wdevice.impl.screens.number_EnterNumberView_Night_1_en.png | 3 +++ ...wdevice.impl.screens.number_EnterNumberView_Night_2_en.png | 3 +++ ...wdevice.impl.screens.number_EnterNumberView_Night_3_en.png | 3 +++ ...wdevice.impl.screens.number_EnterNumberView_Night_4_en.png | 3 +++ ...wdevice.impl.screens.number_EnterNumberView_Night_5_en.png | 3 +++ ...knewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en.png | 3 +++ ...ewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en.png | 3 +++ ...evice.impl.screens.root_LinkNewDeviceRootView_Day_0_en.png | 3 +++ ...evice.impl.screens.root_LinkNewDeviceRootView_Day_1_en.png | 3 +++ ...evice.impl.screens.root_LinkNewDeviceRootView_Day_2_en.png | 3 +++ ...evice.impl.screens.root_LinkNewDeviceRootView_Day_3_en.png | 3 +++ ...evice.impl.screens.root_LinkNewDeviceRootView_Day_4_en.png | 3 +++ ...evice.impl.screens.root_LinkNewDeviceRootView_Day_5_en.png | 3 +++ ...ice.impl.screens.root_LinkNewDeviceRootView_Night_0_en.png | 3 +++ ...ice.impl.screens.root_LinkNewDeviceRootView_Night_1_en.png | 3 +++ ...ice.impl.screens.root_LinkNewDeviceRootView_Night_2_en.png | 3 +++ ...ice.impl.screens.root_LinkNewDeviceRootView_Night_3_en.png | 3 +++ ...ice.impl.screens.root_LinkNewDeviceRootView_Night_4_en.png | 3 +++ ...ice.impl.screens.root_LinkNewDeviceRootView_Night_5_en.png | 3 +++ ...inknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en.png | 3 +++ ...inknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en.png | 3 +++ ...inknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en.png | 3 +++ ...inknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en.png | 3 +++ ...knewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en.png | 3 +++ ...knewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en.png | 3 +++ ...knewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en.png | 3 +++ ...knewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en.png | 3 +++ ...login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en.png | 4 ++-- ...login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en.png | 4 ++-- ...login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en.png | 4 ++-- ...login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en.png | 4 ++-- ...login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en.png | 4 ++-- ...login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en.png | 4 ++-- ...gin.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en.png | 4 ++-- ...gin.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en.png | 4 ++-- ...gin.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en.png | 4 ++-- ...gin.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en.png | 4 ++-- ...gin.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en.png | 4 ++-- ...gin.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en.png | 4 ++-- ...res.preferences.impl.root_PreferencesRootViewDark_0_en.png | 4 ++-- ...res.preferences.impl.root_PreferencesRootViewDark_1_en.png | 4 ++-- ...es.preferences.impl.root_PreferencesRootViewLight_0_en.png | 4 ++-- ...es.preferences.impl.root_PreferencesRootViewLight_1_en.png | 4 ++-- .../test/snapshots/images/libraries.qrcode_QrCodeView_en.png | 3 +++ 73 files changed, 203 insertions(+), 32 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_7_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_7_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number.component_NumberTextField_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number.component_NumberTextField_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.qrcode_QrCodeView_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en.png new file mode 100644 index 0000000000..a28be5b7c6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b60fe3c4ca517486d0eec1435498311525b8f3b1698d04d9a41a948559332b +size 43861 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en.png new file mode 100644 index 0000000000..282cada077 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcab3501c7ec8e1bd100016736946a3462405ce90e75610967e71a01445322ed +size 43207 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en.png new file mode 100644 index 0000000000..b8de2286e7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f452019200e44097f9c4f7911fa144d4cc88fb63a58a8351a820d8e34b7d7a53 +size 42829 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en.png new file mode 100644 index 0000000000..2daeb9dca0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6dfcfce70c52b8bdbc06154d0a206f25655f01ae7548f8d624a4bd4ad87330a6 +size 40871 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_0_en.png new file mode 100644 index 0000000000..b2f95a9597 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24fd98aa0c43fdf26b67ec4dffc72d7f2d48f5d19f0a68a79c2c2c53e6c5fd12 +size 20769 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_1_en.png new file mode 100644 index 0000000000..b8fe60681d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58ddf6004bf14c10a0b65f271f6e95641891777e28ab12967e234363a10c33a5 +size 18411 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_2_en.png new file mode 100644 index 0000000000..5b85ab50d6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7f5c9646571391933edc18c8a6b672b5208a6a4636b5bc15f77b8a06c6ec4a6 +size 21751 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_3_en.png new file mode 100644 index 0000000000..ecd17390a7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:157115c94aff169efbcb87343c4167334d074a4eb78ff4ddb075fa0cfff2c400 +size 33058 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_4_en.png new file mode 100644 index 0000000000..74694ddb0a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7077c7ed0c0656c538887db2e08e7c288e522261c160a13753e1573ed18606ca +size 32697 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_5_en.png new file mode 100644 index 0000000000..dc89ee8fc3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e0ae0d30fde1317c5b8f20569597cc6039eac3e8f70c80c075ef4259e3e74c4 +size 67039 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_6_en.png new file mode 100644 index 0000000000..94ef0539ac --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9077a09b21bbdc7e2a22cf4fca9a6533ec11b1b6e898aa71d2b5393ef01f426c +size 21058 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_7_en.png new file mode 100644 index 0000000000..60b3be0d0f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Day_7_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:330d0d44bb7638a4668fa33974e3b2cd31b3ce285776c993cced2b928b01bbb0 +size 20909 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_0_en.png new file mode 100644 index 0000000000..733d9413a4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe2527eae9bc919a3994cd59e8f6d0c181aa3ab9209b1c34b2bf6e63c7a434af +size 20505 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_1_en.png new file mode 100644 index 0000000000..0199609ebf --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d015f4c5905ab38b4bd987aaf4bf0ac8f55795700de8ae19b5872d4acd5bfd8c +size 18323 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_2_en.png new file mode 100644 index 0000000000..c19826eb03 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:443ca45f4951fc0ef2d390cca6bb2c5717c0160a9df04fd3fe5bb7ede82a1f91 +size 21530 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_3_en.png new file mode 100644 index 0000000000..17753af5d1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f72a52b922d9a4b058cc5bf1475711b0d1adb6e4ebb1b3e75278a4b9117a9869 +size 32359 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_4_en.png new file mode 100644 index 0000000000..e92d032dea --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3430a0cdbd3eb28989a5f9fb397fc082b012ea2a3c284787d27da24870ecd12c +size 32244 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_5_en.png new file mode 100644 index 0000000000..f550be4d00 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a90a5fb148455d4e4d9c4d8332222927d6cf3c606e27c695e4c44af13cedad9a +size 65592 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_6_en.png new file mode 100644 index 0000000000..a9c4133bfa --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6481d57a4d3331e812b310a4a90963e30255ef894a9644df66de73eccccea7d +size 20735 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_7_en.png new file mode 100644 index 0000000000..a1fdb67640 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.error_ErrorView_Night_7_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:516a6c8873c80c96febb9edf8956bccb00b849301df4682b969d3979158316a0 +size 20632 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number.component_NumberTextField_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number.component_NumberTextField_Day_0_en.png new file mode 100644 index 0000000000..b88e154565 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number.component_NumberTextField_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce3903e4d279b4550ed6097eb030edb512ef7aee47392fcad6e48628afeed256 +size 6183 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number.component_NumberTextField_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number.component_NumberTextField_Night_0_en.png new file mode 100644 index 0000000000..91d4e1760b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number.component_NumberTextField_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a075fe842940349e4528aeefd1cfe833b682641b51f6eac51009a8f471be35e4 +size 6197 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en.png new file mode 100644 index 0000000000..d379df9f93 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c7f784a38660b1d75c7608310d84d99747beac15085d315f0f769a6ff6efa6d +size 30212 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en.png new file mode 100644 index 0000000000..09100c4e49 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:020f577d6a2504664933b4a6b642ba1f7ac41b8babbd5d118e714d2e9e0a08b3 +size 30197 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en.png new file mode 100644 index 0000000000..0857590460 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39333077444bf27e5c21750a7ecad964f761b8d784324cb12ae31035c94a0a37 +size 30806 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en.png new file mode 100644 index 0000000000..d3e5554074 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae4edadc0fda7c5c5f75866de9779da968036705965230dfcfc3a03e5f8e2757 +size 30936 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en.png new file mode 100644 index 0000000000..bbd3e09e23 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c968f0c1c8bd1d21fda861861f1a7472479a97f7413a7ccdcefbb864d619a5e +size 34248 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en.png new file mode 100644 index 0000000000..f17da429a2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7812c0a76fb369670d3bf90828aa94df52902dc092da0d22c4dc76f437f22c9e +size 33961 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en.png new file mode 100644 index 0000000000..701d1405f1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:637e1029b3a8193c2dfa4d5511933ff75c54bb2a0e37afade1b550cbd0050279 +size 29203 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en.png new file mode 100644 index 0000000000..4bf546ba11 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f02d37ae2b82d50440539bb1299053c1e431f14a4d302fc2fd9fdacd5abe34ee +size 29170 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en.png new file mode 100644 index 0000000000..8b454226be --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a55f9b20767eb0586d12639a589ab6119496939cb17d0fed6e58f3c2b22aa511 +size 29893 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en.png new file mode 100644 index 0000000000..12c06cbf70 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca8b496d6d6eb08d78b3039b479e4742bfac568cf5c2d6f3217b0af63abca9d9 +size 29918 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en.png new file mode 100644 index 0000000000..7adeb74986 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:924e2289ca0d36b7504820ccc48d9eb943ebc19262d8fd3b8357138a0ffb50ce +size 33170 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en.png new file mode 100644 index 0000000000..f342186acd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8025c4c03d58a10dd9cc7b174e6c825b2359777f442458071baacc533bba6b35 +size 32868 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en.png new file mode 100644 index 0000000000..083cc9d823 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd8e91925396d1702df49a2e342730cda9a0318adb8a3d17dd906d8185d5c846 +size 32140 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en.png new file mode 100644 index 0000000000..474b47228a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ab17222e6d51768a8863ee4d282ef36340ca6fa47e8ddb597c1dbd409e213d3 +size 32680 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_en.png new file mode 100644 index 0000000000..303f628e09 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ace7883ab223f7031d0eccdbbfe96b89f21481bdfa8c34a4470b5488b7db42ed +size 18256 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en.png new file mode 100644 index 0000000000..361a2b5af9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c59349060460c76f4b3db020ea5642e70bd21acc963ec32567eb6b5dae142c86 +size 24432 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en.png new file mode 100644 index 0000000000..2d02847167 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37b0b44b213ca6daf129f096ca3d909031a4d79bdee79fe54595e4bf08f93977 +size 25775 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en.png new file mode 100644 index 0000000000..13180a6b8d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e764db89c970799b230e16a1f345d4f78b58ff00ea7ef03e94b863763485768 +size 21795 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en.png new file mode 100644 index 0000000000..e923896419 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:670582ea30ebb350af301f4ca8c15f6bcb4c199b67366e19bbdf30456789f470 +size 23962 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en.png new file mode 100644 index 0000000000..9816c6d1c5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:096f01d87cf3414f18c67d24269d5ea5284a0652b5e6137ebb117645d8e02cb0 +size 34075 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_0_en.png new file mode 100644 index 0000000000..19573907e6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:623ceb15f4fa87d4674249693a94b89cd742ed93df9c36b2603a54bf18cb879c +size 17626 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en.png new file mode 100644 index 0000000000..269aab3c89 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddabca52e06c1bc184dc0deb71651b5d282adb55a8264fd588345937f4410f2f +size 23511 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en.png new file mode 100644 index 0000000000..ed74d392ac --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64b240c3bb9e40677dddfdaf5e8cfa09c1f2c1a19d9544bd74634a9a04262943 +size 25387 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en.png new file mode 100644 index 0000000000..bb7a6f3a24 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f13958a45f7afe8f57478a6c2539ae26e8c470bf4a412f06cfa540448506b29 +size 21070 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en.png new file mode 100644 index 0000000000..3b7e50be12 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96d9c8f4dde2d1330572e30014d6262f88575d5f012d7986c2a6a938b4a66db6 +size 22952 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en.png new file mode 100644 index 0000000000..100368ef3f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b41a1f00e6bc7cca9af41e0d4b62a9e05370f191464e3d76cee878fad9dc230e +size 31941 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en.png new file mode 100644 index 0000000000..f6a46dab95 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76af36f8440efa9c2b2c3a98d34e8ed356390158a9f1b2cbe9e86c820553213b +size 15956 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en.png new file mode 100644 index 0000000000..4e809b9b7e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c0239a08b541d07fb2d916624fe97dc997cbe0a05903b8aa93c05cc172b0640 +size 16602 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en.png new file mode 100644 index 0000000000..21294e5561 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbd8bb22a902f03847c22b27afed456eb08e60656e6777803531cc9448b7a42b +size 16760 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en.png new file mode 100644 index 0000000000..43adf5019f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7284871dd335aa43efdcde312febfefbf0e44ce38e41943609faa3c3e2c3c1c8 +size 27442 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en.png new file mode 100644 index 0000000000..db5157c4d3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8f45fcfe13302231733a1d5d845f9eee9f5428381a312e021d1f34cad47e66f +size 15312 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en.png new file mode 100644 index 0000000000..bf6cc48d4b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:def2668a2168bb3f1c37994914fd2f32df3c900bf0d43fc5b6bca9f1d8183240 +size 15927 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en.png new file mode 100644 index 0000000000..d5b00ae510 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7a4a1642295e2e8b6f7aba548b54ebc122f525a28394414aa7513d9c60bbc23 +size 16093 diff --git a/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en.png new file mode 100644 index 0000000000..2967e646da --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:807e0cd53e97683966343e75079a287e17484cc3026ac328792da17cda023ee3 +size 26379 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en.png index 0a4ee279c8..4e809b9b7e 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58217104c9a26ab0fee9cdcb24827800a61b00730e7c52a8ddb900d88f6aa55a -size 14629 +oid sha256:7c0239a08b541d07fb2d916624fe97dc997cbe0a05903b8aa93c05cc172b0640 +size 16602 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en.png index 76cac663ab..5a2f32de64 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:47a1d2a56df0fd2ac662eaef18e35a0ea524cd2fe47e381adbddea6bd300bd8a -size 19774 +oid sha256:5ebfd4977ff437718e99e23e982dd1b1aa74e8bea6b1f4ffed07d515807d840e +size 21097 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en.png index e16c2b9ffd..43adf5019f 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:325dcaac7e37ba3977d1bf867464bafe09b52d8818024b2b0994976bf9374315 -size 26128 +oid sha256:7284871dd335aa43efdcde312febfefbf0e44ce38e41943609faa3c3e2c3c1c8 +size 27442 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en.png index bb9637fc2b..845385f33c 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f8ccc661ad150a6c8ea19c3051ce68863d7add01b83d5b18d365ba0173786d7 -size 32284 +oid sha256:1d2fc6e9cdaff3313b30f506966c3b6c0cba5df0ffd6572b39b017c717837cd5 +size 33520 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en.png index 9c7478491b..618f027a77 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:82708f952ddc924e20d13a1d49725118b2e49b6e962e4a67ed3c136acd063a61 -size 31304 +oid sha256:c218a232169097b71be6a44a52fee46569fd2db49c374627fc24f4ebb492ee1d +size 32458 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en.png index 2b2e86defd..84310320d0 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3586a4cd910c491dfdd0fd516e05d830c877d940663dabab0b0a50a511a41fa -size 30449 +oid sha256:308023d6e55d65f9091dd01dc7b27e12a1b62f8560288a1a6d2b28d23c2ea317 +size 31727 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en.png index b73f4d4be2..bf6cc48d4b 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68751e4e93cfa457f753b1605637a8d1a4b9c5e600ec86097b05a5aa8e3ed345 -size 13955 +oid sha256:def2668a2168bb3f1c37994914fd2f32df3c900bf0d43fc5b6bca9f1d8183240 +size 15927 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en.png index 33e8d0cfce..816496a9ab 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3205d7cc5b33732414c493ee3564a4f94669c01796d428d100d67212f6618c5c -size 19014 +oid sha256:ad74d69f874563e3211c703a1b428972efcab4eed3672766ba441cf6ae8e8fa6 +size 20375 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en.png index dc1d1efd31..2967e646da 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:36b854e59ff8875a7132340ab2b4ef2dfea0e824d38663e95b1016fec20e064c -size 25012 +oid sha256:807e0cd53e97683966343e75079a287e17484cc3026ac328792da17cda023ee3 +size 26379 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en.png index eab090d118..53ffb846dd 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4bf95bcff03d9cb1d70b29b507563e7fb131885548297a3ba8ca49e1dc8e1fe0 -size 31055 +oid sha256:cd71385b1d51e6e6175847766149ffafafec5337109ac18c615dad0251eedee3 +size 32438 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en.png index ebda0c7f9f..2920e464c6 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c151e4afc239da27ef4a0510cce5b2ae7ac061a540c53e650333f0aba4560c3 -size 30107 +oid sha256:b0e2213b46c83b3256293a7b0638c7b9dd51d2ee9ccd3aa77d3dbce7da84d66f +size 31363 diff --git a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en.png index 06075aaa85..4d8c26a700 100644 --- a/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:72a487fd1e35beaacc38b0fd059a8cee5d6e67abc908731b7820d78f0631d452 -size 29120 +oid sha256:d2a1545d8111c03a01923f8cdfc227adc5a87bb89074f45aa542bfcb9e18ccf4 +size 30489 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_0_en.png index 4dfe012539..1ce2ca38bc 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:defcbf960501cd0f7ad34a340c72834e317e662573019a72f26df3e83ac68393 -size 39318 +oid sha256:8276f281154b0efb30086a0a29dd2151ee877661bd777d4ef8a3b42fc997088a +size 38904 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_1_en.png index 32f87b189c..3bcecbb003 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewDark_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3912aaca2e36211f4d799d9b8aa3fdebcae17ef1fa01c70de6a59e77561dd539 -size 39163 +oid sha256:8124cb5722fc04a67eed1c0c6752fae79e0c442e5e6195cfde84849cf9312756 +size 38732 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_0_en.png index af13bb583f..2ab90ddeac 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:871ce6a6581c7e7d5cbf4616055ea6bb3b27db28c6cb6f7ab4ed2f5a3b9dd588 -size 40276 +oid sha256:39115aa6c569076f4ffa7be324f10c9de9029e3c4c73cf1b9ba203872de27175 +size 39830 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_1_en.png index 6c8c320105..3aa263b83e 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.root_PreferencesRootViewLight_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e8f8c4afe5ea44d4e2b54d453c4e3a671eb107d4056518a43cdadcbba13ae0b -size 40324 +oid sha256:ae265a9ba682229a1c598e9bbeee515799e09853f62c5e6351f15b70b065aebb +size 39876 diff --git a/tests/uitests/src/test/snapshots/images/libraries.qrcode_QrCodeView_en.png b/tests/uitests/src/test/snapshots/images/libraries.qrcode_QrCodeView_en.png new file mode 100644 index 0000000000..bca09dbeb2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.qrcode_QrCodeView_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6aea8452a990307184b9d3f3ceef60e3c09de4ac8128362cafd23ab64a1fe8d7 +size 10600 From e85a396d218054755a58cdc10f4bfd2bb64489ba Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 16 Dec 2025 12:58:12 +0100 Subject: [PATCH 139/347] Format --- .../choosemode/ChooseSelfVerificationModeView.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt index bd0cdead71..8f72f038de 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/sessionverification/choosemode/ChooseSelfVerificationModeView.kt @@ -89,8 +89,8 @@ fun ChooseSelfVerificationModeView( ) { Text( modifier = Modifier - .clickable(onClick = onLearnMore) - .padding(vertical = 4.dp, horizontal = 16.dp), + .clickable(onClick = onLearnMore) + .padding(vertical = 4.dp, horizontal = 16.dp), text = stringResource(CommonStrings.action_learn_more), style = ElementTheme.typography.fontBodyLgMedium ) From 5bb9f579a49e4de8f1756a45c7bc790b6b39b040 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 16 Dec 2025 14:44:22 +0100 Subject: [PATCH 140/347] Coding convention --- .../screens/desktop/DesktopNoticePresenterTest.kt | 14 ++++++-------- .../impl/screens/scan/ScanQrCodePresenterTest.kt | 8 +++----- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenterTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenterTest.kt index ba3892c965..b6b9769b64 100644 --- a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenterTest.kt +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/desktop/DesktopNoticePresenterTest.kt @@ -47,12 +47,10 @@ class DesktopNoticePresenterTest { assertThat(awaitItem().cameraPermissionState.showDialog).isTrue() } } - - private fun createPresenter( - permissionsPresenterFactory: FakePermissionsPresenterFactory = FakePermissionsPresenterFactory(), - ): DesktopNoticePresenter { - return DesktopNoticePresenter( - permissionsPresenterFactory = permissionsPresenterFactory, - ) - } } + +private fun createPresenter( + permissionsPresenterFactory: FakePermissionsPresenterFactory = FakePermissionsPresenterFactory(), +) = DesktopNoticePresenter( + permissionsPresenterFactory = permissionsPresenterFactory, +) diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenterTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenterTest.kt index a258e19fb9..50c3ce767b 100644 --- a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenterTest.kt +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/scan/ScanQrCodePresenterTest.kt @@ -105,8 +105,6 @@ class ScanQrCodePresenterTest { private fun createPresenter( matrixClient: MatrixClient, -): ScanQrCodePresenter { - return ScanQrCodePresenter( - linkNewDesktopHandler = LinkNewDesktopHandler(matrixClient), - ) -} +) = ScanQrCodePresenter( + linkNewDesktopHandler = LinkNewDesktopHandler(matrixClient), +) From d2982009342f917b77f26838fdb61af967942db0 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 16 Dec 2025 16:40:44 +0100 Subject: [PATCH 141/347] Use the right video preset when sharing videos (#5892) --- .../preview/AttachmentsPreviewPresenter.kt | 8 +++----- ...faultMediaOptimizationSelectorPresenter.kt | 10 +++++----- .../AttachmentsPreviewPresenterTest.kt | 3 +++ ...tMediaOptimizationSelectorPresenterTest.kt | 6 +++--- libraries/mediaupload/impl/build.gradle.kts | 1 + .../DefaultMediaOptimizationConfigProvider.kt | 19 +++++++++++++++---- 6 files changed, 30 insertions(+), 17 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewPresenter.kt index d7e0332bd4..f7641ec21b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewPresenter.kt @@ -37,6 +37,7 @@ import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.mediaupload.api.MediaOptimizationConfig +import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider import io.element.android.libraries.mediaupload.api.MediaSenderFactory import io.element.android.libraries.mediaupload.api.MediaUploadInfo import io.element.android.libraries.mediaupload.api.allFiles @@ -62,6 +63,7 @@ class AttachmentsPreviewPresenter( private val mediaOptimizationSelectorPresenterFactory: MediaOptimizationSelectorPresenter.Factory, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, private val dispatchers: CoroutineDispatchers, + private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider, ) : Presenter { @AssistedFactory interface Factory { @@ -107,13 +109,9 @@ class AttachmentsPreviewPresenter( // to prepare it for sending. This is done to avoid blocking the UI thread when the // user clicks on the send button. if (mediaOptimizationSelectorState.displayMediaSelectorViews == false) { - val mediaOptimizationConfig = MediaOptimizationConfig( - compressImages = mediaOptimizationSelectorState.isImageOptimizationEnabled == true, - videoCompressionPreset = mediaOptimizationSelectorState.selectedVideoPreset ?: VideoCompressionPreset.STANDARD, - ) preprocessMediaJob = preProcessAttachment( attachment = attachment, - mediaOptimizationConfig = mediaOptimizationConfig, + mediaOptimizationConfig = mediaOptimizationConfigProvider.get(), displayProgress = false, sendActionState = sendActionState, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenter.kt index d0716abe83..c81c306f90 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenter.kt @@ -25,13 +25,12 @@ import io.element.android.libraries.di.SessionScope import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.mediaupload.api.MaxUploadSizeProvider +import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider import io.element.android.libraries.mediaupload.api.compressorHelper import io.element.android.libraries.mediaviewer.api.local.LocalMedia -import io.element.android.libraries.preferences.api.store.SessionPreferencesStore import io.element.android.libraries.preferences.api.store.VideoCompressionPreset import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.flow.first import timber.log.Timber import kotlin.math.roundToLong @@ -39,8 +38,8 @@ import kotlin.math.roundToLong class DefaultMediaOptimizationSelectorPresenter( @Assisted private val localMedia: LocalMedia, private val maxUploadSizeProvider: MaxUploadSizeProvider, - private val sessionPreferencesStore: SessionPreferencesStore, private val featureFlagService: FeatureFlagService, + private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider, mediaExtractorFactory: VideoMetadataExtractor.Factory, ) : MediaOptimizationSelectorPresenter { @ContributesBinding(SessionScope::class) @@ -124,11 +123,12 @@ class DefaultMediaOptimizationSelectorPresenter( var selectedVideoOptimizationPreset by remember { mutableStateOf>(AsyncData.Loading()) } LaunchedEffect(videoSizeEstimations.dataOrNull()) { - selectedImageOptimization = AsyncData.Success(sessionPreferencesStore.doesOptimizeImages().first()) + val mediaOptimizationConfig = mediaOptimizationConfigProvider.get() + selectedImageOptimization = AsyncData.Success(mediaOptimizationConfig.compressImages) // Find the best video preset based on the default preset and the video size estimations // Since the estimation for the current preset may be way too large to upload, we check the ones that provide lower file sizes selectedVideoOptimizationPreset = findBestVideoPreset( - defaultVideoPreset = sessionPreferencesStore.getVideoCompressionPreset().first(), + defaultVideoPreset = mediaOptimizationConfig.videoCompressionPreset, videoSizeEstimations = videoSizeEstimations, ) } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt index 5263182fa0..fe462fc988 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt @@ -44,6 +44,7 @@ import io.element.android.libraries.mediaupload.api.MediaPreProcessor import io.element.android.libraries.mediaupload.api.MediaSenderFactory import io.element.android.libraries.mediaupload.api.MediaUploadInfo import io.element.android.libraries.mediaupload.impl.DefaultMediaSender +import io.element.android.libraries.mediaupload.test.FakeMediaOptimizationConfigProvider import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor import io.element.android.libraries.mediaviewer.api.aVideoMediaInfo import io.element.android.libraries.mediaviewer.api.anApkMediaInfo @@ -598,6 +599,7 @@ class AttachmentsPreviewPresenterTest { ) } ), + mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(), ): AttachmentsPreviewPresenter { return AttachmentsPreviewPresenter( attachment = aMediaAttachment(localMedia), @@ -619,6 +621,7 @@ class AttachmentsPreviewPresenterTest { mediaOptimizationSelectorPresenterFactory = mediaOptimizationSelectorPresenterFactory, timelineMode = timelineMode, inReplyToEventId = null, + mediaOptimizationConfigProvider = mediaOptimizationConfigProvider, ) } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenterTest.kt index aad3e0b885..96cc93ea3d 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/video/DefaultMediaOptimizationSelectorPresenterTest.kt @@ -22,12 +22,12 @@ import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.mediaupload.api.MaxUploadSizeProvider +import io.element.android.libraries.mediaupload.test.FakeMediaOptimizationConfigProvider import io.element.android.libraries.mediaviewer.api.aVideoMediaInfo import io.element.android.libraries.mediaviewer.api.anImageMediaInfo import io.element.android.libraries.mediaviewer.api.local.LocalMedia import io.element.android.libraries.mediaviewer.test.viewer.aLocalMedia import io.element.android.libraries.preferences.api.store.VideoCompressionPreset -import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore import io.element.android.tests.testutils.WarmUpRule import io.mockk.mockk import kotlinx.coroutines.test.runTest @@ -233,16 +233,16 @@ class DefaultMediaOptimizationSelectorPresenterTest { private fun createDefaultMediaOptimizationSelectorPresenter( localMedia: LocalMedia = aLocalMedia(mockMediaUrl, aVideoMediaInfo()), maxUploadSizeProvider: MaxUploadSizeProvider = MaxUploadSizeProvider { Result.success(1_000L) }, - sessionPreferencesStore: InMemorySessionPreferencesStore = InMemorySessionPreferencesStore(), featureFlagService: FakeFeatureFlagService = FakeFeatureFlagService(mapOf(FeatureFlags.SelectableMediaQuality.key to true)), mediaExtractorFactory: FakeVideoMetadataExtractorFactory = FakeVideoMetadataExtractorFactory(), + mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(), ): DefaultMediaOptimizationSelectorPresenter { return DefaultMediaOptimizationSelectorPresenter( localMedia = localMedia, maxUploadSizeProvider = maxUploadSizeProvider, - sessionPreferencesStore = sessionPreferencesStore, featureFlagService = featureFlagService, mediaExtractorFactory = mediaExtractorFactory, + mediaOptimizationConfigProvider = mediaOptimizationConfigProvider, ) } } diff --git a/libraries/mediaupload/impl/build.gradle.kts b/libraries/mediaupload/impl/build.gradle.kts index dd73164eb1..827366f556 100644 --- a/libraries/mediaupload/impl/build.gradle.kts +++ b/libraries/mediaupload/impl/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { implementation(projects.libraries.androidutils) implementation(projects.libraries.core) implementation(projects.libraries.di) + implementation(projects.libraries.featureflag.api) implementation(projects.libraries.matrix.api) implementation(projects.services.toolbox.api) implementation(libs.androidx.exifinterface) diff --git a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/impl/DefaultMediaOptimizationConfigProvider.kt b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/impl/DefaultMediaOptimizationConfigProvider.kt index 4b6d298666..363263e5bf 100644 --- a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/impl/DefaultMediaOptimizationConfigProvider.kt +++ b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/impl/DefaultMediaOptimizationConfigProvider.kt @@ -10,17 +10,28 @@ package io.element.android.libraries.mediaupload.impl import dev.zacsweers.metro.ContributesBinding import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.mediaupload.api.MediaOptimizationConfig import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider import io.element.android.libraries.preferences.api.store.SessionPreferencesStore +import io.element.android.libraries.preferences.api.store.VideoCompressionPreset import kotlinx.coroutines.flow.first @ContributesBinding(SessionScope::class) class DefaultMediaOptimizationConfigProvider( private val sessionPreferencesStore: SessionPreferencesStore, + private val featureFlagsService: FeatureFlagService, ) : MediaOptimizationConfigProvider { - override suspend fun get(): MediaOptimizationConfig = MediaOptimizationConfig( - compressImages = sessionPreferencesStore.doesOptimizeImages().first(), - videoCompressionPreset = sessionPreferencesStore.getVideoCompressionPreset().first(), - ) + override suspend fun get(): MediaOptimizationConfig { + val compressImages = sessionPreferencesStore.doesOptimizeImages().first() + return MediaOptimizationConfig( + compressImages = compressImages, + videoCompressionPreset = if (featureFlagsService.isFeatureEnabled(FeatureFlags.SelectableMediaQuality)) { + sessionPreferencesStore.getVideoCompressionPreset().first() + } else { + if (compressImages) VideoCompressionPreset.STANDARD else VideoCompressionPreset.HIGH + }, + ) + } } From b5fdc179c7ec28c042358ff6f8c0b3a502702986 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 16 Dec 2025 18:04:26 +0100 Subject: [PATCH 142/347] Add unit test on RustLinkDesktopHandler Add unit test on RustLinkMobileHandler Add unit test on DefaultLinkNewDeviceEntryPoint --- .../DefaultLinkNewDeviceEntryPointTest.kt | 48 ++++++++ .../libraries/matrix/impl/RustMatrixClient.kt | 2 + .../impl/linknewdevice/QrCodeDataParser.kt | 20 ++++ .../linknewdevice/RustLinkDesktopHandler.kt | 4 +- .../fixtures/fakes/FakeFfiCheckCodeSender.kt | 13 +++ .../FakeFfiGrantLoginWithQrCodeHandler.kt | 41 +++++++ .../impl/fixtures/fakes/FakeFfiQrCodeData.kt | 5 + .../linknewdevice/FakeQrCodeDataParser.kt | 17 +++ .../RustLinkDesktopHandlerTest.kt | 109 ++++++++++++++++++ .../RustLinkMobileHandlerTest.kt | 91 +++++++++++++++ 10 files changed, 348 insertions(+), 2 deletions(-) create mode 100644 features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/DefaultLinkNewDeviceEntryPointTest.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/QrCodeDataParser.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiCheckCodeSender.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiGrantLoginWithQrCodeHandler.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/FakeQrCodeDataParser.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandlerTest.kt create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkMobileHandlerTest.kt diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/DefaultLinkNewDeviceEntryPointTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/DefaultLinkNewDeviceEntryPointTest.kt new file mode 100644 index 0000000000..2957a89495 --- /dev/null +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/DefaultLinkNewDeviceEntryPointTest.kt @@ -0,0 +1,48 @@ +/* + * 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.linknewdevice.impl + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.testing.junit4.util.MainDispatcherRule +import com.google.common.truth.Truth.assertThat +import io.element.android.features.linknewdevice.api.LinkNewDeviceEntryPoint +import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.tests.testutils.lambda.lambdaError +import io.element.android.tests.testutils.node.TestParentNode +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test + +class DefaultLinkNewDeviceEntryPointTest { + @get:Rule + val instantTaskExecutorRule = InstantTaskExecutorRule() + + @get:Rule + val mainDispatcherRule = MainDispatcherRule() + + @Test + fun `test node creation`() = runTest { + val entryPoint = DefaultLinkNewDeviceEntryPoint() + val client = FakeMatrixClient() + val parentNode = TestParentNode.create { buildContext, plugins -> + LinkNewDeviceFlowNode( + buildContext = buildContext, + plugins = plugins, + sessionCoroutineScope = backgroundScope, + linkNewMobileHandler = LinkNewMobileHandler(client), + linkNewDesktopHandler = LinkNewDesktopHandler(client), + ) + } + val callback: LinkNewDeviceEntryPoint.Callback = object : LinkNewDeviceEntryPoint.Callback { + override fun onDone() = lambdaError() + } + val result = entryPoint.createNode(parentNode, BuildContext.root(null), callback) + assertThat(result).isInstanceOf(LinkNewDeviceFlowNode::class.java) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 1de606637a..6ff66c0f71 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -49,6 +49,7 @@ import io.element.android.libraries.matrix.impl.encryption.RustEncryptionService import io.element.android.libraries.matrix.impl.exception.mapClientException import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkDesktopHandler import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkMobileHandler +import io.element.android.libraries.matrix.impl.linknewdevice.RustQrCodeDataParser import io.element.android.libraries.matrix.impl.mapper.map import io.element.android.libraries.matrix.impl.media.RustMediaLoader import io.element.android.libraries.matrix.impl.media.RustMediaPreviewService @@ -754,6 +755,7 @@ class RustMatrixClient( inner = handler, sessionCoroutineScope = sessionCoroutineScope, sessionDispatcher = sessionDispatcher, + qrCodeDataParser = RustQrCodeDataParser(), ) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/QrCodeDataParser.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/QrCodeDataParser.kt new file mode 100644 index 0000000000..6472850a8c --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/QrCodeDataParser.kt @@ -0,0 +1,20 @@ +/* + * 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.linknewdevice + +import org.matrix.rustcomponents.sdk.QrCodeData + +interface QrCodeDataParser { + fun parse(data: ByteArray): QrCodeData +} + +class RustQrCodeDataParser : QrCodeDataParser { + override fun parse(data: ByteArray): QrCodeData { + return QrCodeData.fromBytes(data) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandler.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandler.kt index fd37b73ad8..211bdc3d4e 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandler.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandler.kt @@ -23,7 +23,6 @@ import org.matrix.rustcomponents.sdk.GrantLoginWithQrCodeHandler import org.matrix.rustcomponents.sdk.GrantQrLoginProgress import org.matrix.rustcomponents.sdk.GrantQrLoginProgressListener import org.matrix.rustcomponents.sdk.HumanQrGrantLoginException -import org.matrix.rustcomponents.sdk.QrCodeData import org.matrix.rustcomponents.sdk.QrCodeDecodeException import timber.log.Timber @@ -33,6 +32,7 @@ class RustLinkDesktopHandler( private val inner: GrantLoginWithQrCodeHandler, private val sessionCoroutineScope: CoroutineScope, private val sessionDispatcher: CoroutineDispatcher, + private val qrCodeDataParser: QrCodeDataParser, ) : LinkDesktopHandler { private val _linkDesktopStep = MutableStateFlow(LinkDesktopStep.Uninitialized) override val linkDesktopStep: StateFlow = _linkDesktopStep.asStateFlow() @@ -41,7 +41,7 @@ class RustLinkDesktopHandler( Timber.tag(tag.value).d("Emit Uninitialized") _linkDesktopStep.emit(LinkDesktopStep.Uninitialized) try { - val qrCodeData = QrCodeData.fromBytes(data) + val qrCodeData = qrCodeDataParser.parse(data) inner.scan( qrCodeData = qrCodeData, progressListener = object : GrantQrLoginProgressListener { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiCheckCodeSender.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiCheckCodeSender.kt new file mode 100644 index 0000000000..4bc6c212d2 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiCheckCodeSender.kt @@ -0,0 +1,13 @@ +/* + * 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.fixtures.fakes + +import org.matrix.rustcomponents.sdk.CheckCodeSender +import org.matrix.rustcomponents.sdk.NoHandle + +class FakeFfiCheckCodeSender : CheckCodeSender(NoHandle) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiGrantLoginWithQrCodeHandler.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiGrantLoginWithQrCodeHandler.kt new file mode 100644 index 0000000000..cd0733695b --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiGrantLoginWithQrCodeHandler.kt @@ -0,0 +1,41 @@ +/* + * 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.fixtures.fakes + +import org.matrix.rustcomponents.sdk.GrantGeneratedQrLoginProgress +import org.matrix.rustcomponents.sdk.GrantGeneratedQrLoginProgressListener +import org.matrix.rustcomponents.sdk.GrantLoginWithQrCodeHandler +import org.matrix.rustcomponents.sdk.GrantQrLoginProgress +import org.matrix.rustcomponents.sdk.GrantQrLoginProgressListener +import org.matrix.rustcomponents.sdk.NoHandle +import org.matrix.rustcomponents.sdk.QrCodeData + +class FakeFfiGrantLoginWithQrCodeHandler( + private val generateResult: () -> Unit = {}, + private val scanResult: (QrCodeData) -> Unit = {}, +) : GrantLoginWithQrCodeHandler(NoHandle) { + private var generateProgressListener: GrantGeneratedQrLoginProgressListener? = null + private var scanProgressListener: GrantQrLoginProgressListener? = null + override suspend fun generate(progressListener: GrantGeneratedQrLoginProgressListener) { + generateProgressListener = progressListener + generateResult() + } + + fun emitGenerateProgress(progress: GrantGeneratedQrLoginProgress) { + generateProgressListener?.onUpdate(progress) + } + + override suspend fun scan(qrCodeData: QrCodeData, progressListener: GrantQrLoginProgressListener) { + scanProgressListener = progressListener + scanResult(qrCodeData) + } + + fun emitScanProgress(progress: GrantQrLoginProgress) { + scanProgressListener?.onUpdate(progress) + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiQrCodeData.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiQrCodeData.kt index d377643fa7..4070d1b2cd 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiQrCodeData.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiQrCodeData.kt @@ -14,8 +14,13 @@ import org.matrix.rustcomponents.sdk.QrCodeData class FakeFfiQrCodeData( private val serverNameResult: () -> String? = { lambdaError() }, + private val toBytesResult: () -> ByteArray = { lambdaError() }, ) : QrCodeData(NoHandle) { override fun serverName(): String? { return serverNameResult() } + + override fun toBytes(): ByteArray { + return toBytesResult() + } } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/FakeQrCodeDataParser.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/FakeQrCodeDataParser.kt new file mode 100644 index 0000000000..254258fcf7 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/FakeQrCodeDataParser.kt @@ -0,0 +1,17 @@ +/* + * 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.linknewdevice + +import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiQrCodeData +import org.matrix.rustcomponents.sdk.QrCodeData + +class FakeQrCodeDataParser : QrCodeDataParser { + override fun parse(data: ByteArray): QrCodeData { + return FakeFfiQrCodeData() + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandlerTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandlerTest.kt new file mode 100644 index 0000000000..a180e4d515 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkDesktopHandlerTest.kt @@ -0,0 +1,109 @@ +/* + * 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. + */ + +@file:OptIn(ExperimentalCoroutinesApi::class) + +package io.element.android.libraries.matrix.impl.linknewdevice + +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.linknewdevice.ErrorType +import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopStep +import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiGrantLoginWithQrCodeHandler +import io.element.android.libraries.matrix.test.QR_CODE_DATA +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.matrix.rustcomponents.sdk.GrantQrLoginProgress +import org.matrix.rustcomponents.sdk.HumanQrGrantLoginException +import org.matrix.rustcomponents.sdk.QrCodeDecodeException + +class RustLinkDesktopHandlerTest { + @Test + fun `handleScannedQrCode function works as expected`() = runTest { + val handler = FakeFfiGrantLoginWithQrCodeHandler() + val sut = createRustLinkDesktopHandler( + handler, + ) + sut.linkDesktopStep.test { + val initialItem = awaitItem() + assertThat(initialItem).isEqualTo(LinkDesktopStep.Uninitialized) + backgroundScope.launch { + sut.handleScannedQrCode(QR_CODE_DATA) + } + runCurrent() + // progress from the handler is mapped and emitted + listOf( + GrantQrLoginProgress.Starting to LinkDesktopStep.Starting, + GrantQrLoginProgress.SyncingSecrets to LinkDesktopStep.SyncingSecrets, + GrantQrLoginProgress.WaitingForAuth("aVerificationUri") + to LinkDesktopStep.WaitingForAuth("aVerificationUri"), + GrantQrLoginProgress.EstablishingSecureChannel(1.toUByte(), "1") + to LinkDesktopStep.EstablishingSecureChannel(1.toUByte(), "1"), + GrantQrLoginProgress.Done to LinkDesktopStep.Done, + ).forEach { (progress, expectedStep) -> + handler.emitScanProgress(progress) + assertThat(awaitItem()).isEqualTo(expectedStep) + } + } + } + + @Test + fun `when handleScannedQrCode throws QrCodeDecodeException, the handler emits error step`() = runTest { + val handler = FakeFfiGrantLoginWithQrCodeHandler( + scanResult = { throw QrCodeDecodeException.Crypto("Scan failed") } + ) + val sut = createRustLinkDesktopHandler( + handler, + ) + sut.linkDesktopStep.test { + val initialItem = awaitItem() + assertThat(initialItem).isEqualTo(LinkDesktopStep.Uninitialized) + backgroundScope.launch { + sut.handleScannedQrCode(QR_CODE_DATA) + } + runCurrent() + val errorState = awaitItem() + assertThat(errorState).isInstanceOf(LinkDesktopStep.InvalidQrCode::class.java) + } + } + + @Test + fun `when handleScannedQrCode throws HumanQrGrantLoginException, the handler emits error step`() = runTest { + val handler = FakeFfiGrantLoginWithQrCodeHandler( + scanResult = { throw HumanQrGrantLoginException.InvalidCheckCode("Invalid check code") } + ) + val sut = createRustLinkDesktopHandler( + handler, + ) + sut.linkDesktopStep.test { + val initialItem = awaitItem() + assertThat(initialItem).isEqualTo(LinkDesktopStep.Uninitialized) + backgroundScope.launch { + sut.handleScannedQrCode(QR_CODE_DATA) + } + runCurrent() + val errorState = awaitItem() + assertThat(errorState).isInstanceOf(LinkDesktopStep.Error::class.java) + val errorType = (errorState as LinkDesktopStep.Error).errorType + assertThat(errorType).isInstanceOf(ErrorType.InvalidCheckCode::class.java) + } + } + + private fun TestScope.createRustLinkDesktopHandler( + handler: FakeFfiGrantLoginWithQrCodeHandler = FakeFfiGrantLoginWithQrCodeHandler(), + ) = RustLinkDesktopHandler( + inner = handler, + sessionCoroutineScope = backgroundScope, + sessionDispatcher = StandardTestDispatcher(testScheduler), + qrCodeDataParser = FakeQrCodeDataParser(), + ) +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkMobileHandlerTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkMobileHandlerTest.kt new file mode 100644 index 0000000000..aa13996e8a --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustLinkMobileHandlerTest.kt @@ -0,0 +1,91 @@ +/* + * 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. + */ + +@file:OptIn(ExperimentalCoroutinesApi::class) + +package io.element.android.libraries.matrix.impl.linknewdevice + +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.linknewdevice.ErrorType +import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep +import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiCheckCodeSender +import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiGrantLoginWithQrCodeHandler +import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiQrCodeData +import io.element.android.libraries.matrix.test.QR_CODE_DATA_RECIPROCATE +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.matrix.rustcomponents.sdk.GrantGeneratedQrLoginProgress +import org.matrix.rustcomponents.sdk.HumanQrGrantLoginException + +class RustLinkMobileHandlerTest { + @Test + fun `start function works as expected`() = runTest { + val handler = FakeFfiGrantLoginWithQrCodeHandler() + val sut = createRustLinkMobileHandler( + handler, + ) + sut.linkMobileStep.test { + val initialItem = awaitItem() + assertThat(initialItem).isEqualTo(LinkMobileStep.Uninitialized) + backgroundScope.launch { + sut.start() + } + runCurrent() + // progress from the handler is mapped and emitted + listOf( + GrantGeneratedQrLoginProgress.Starting to LinkMobileStep.Starting::class.java, + GrantGeneratedQrLoginProgress.SyncingSecrets to LinkMobileStep.SyncingSecrets::class.java, + GrantGeneratedQrLoginProgress.WaitingForAuth("aVerificationUri") + to LinkMobileStep.WaitingForAuth::class.java, + GrantGeneratedQrLoginProgress.QrScanned(FakeFfiCheckCodeSender()) + to LinkMobileStep.QrScanned::class.java, + GrantGeneratedQrLoginProgress.QrReady(FakeFfiQrCodeData(toBytesResult = { QR_CODE_DATA_RECIPROCATE })) + to LinkMobileStep.QrReady::class.java, + GrantGeneratedQrLoginProgress.Done to LinkMobileStep.Done::class.java, + ).forEach { (progress, expectedStepClass) -> + handler.emitGenerateProgress(progress) + assertThat(awaitItem()).isInstanceOf(expectedStepClass) + } + } + } + + @Test + fun `when start throws HumanQrGrantLoginException, the handler emits error step`() = runTest { + val handler = FakeFfiGrantLoginWithQrCodeHandler( + generateResult = { throw HumanQrGrantLoginException.NotFound("Timeout") } + ) + val sut = createRustLinkMobileHandler( + handler, + ) + sut.linkMobileStep.test { + val initialItem = awaitItem() + assertThat(initialItem).isEqualTo(LinkMobileStep.Uninitialized) + backgroundScope.launch { + sut.start() + } + runCurrent() + val errorState = awaitItem() + assertThat(errorState).isInstanceOf(LinkMobileStep.Error::class.java) + val errorType = (errorState as LinkMobileStep.Error).errorType + assertThat(errorType).isInstanceOf(ErrorType.NotFound::class.java) + } + } + + private fun TestScope.createRustLinkMobileHandler( + handler: FakeFfiGrantLoginWithQrCodeHandler = FakeFfiGrantLoginWithQrCodeHandler(), + ) = RustLinkMobileHandler( + inner = handler, + sessionCoroutineScope = backgroundScope, + sessionDispatcher = StandardTestDispatcher(testScheduler), + ) +} From 086229f5dc6d26e565e470641edc327437b71bc1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 16 Dec 2025 20:03:33 +0100 Subject: [PATCH 143/347] Add test on `RustCheckCodeSender` --- .../impl/src/main/res/values/localazy.xml | 2 + .../impl/src/main/res/values/localazy.xml | 2 + .../fixtures/fakes/FakeFfiCheckCodeSender.kt | 9 +++- .../linknewdevice/RustCheckCodeSenderTest.kt | 41 +++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustCheckCodeSenderTest.kt diff --git a/features/linknewdevice/impl/src/main/res/values/localazy.xml b/features/linknewdevice/impl/src/main/res/values/localazy.xml index 9bf7ac2132..321b168751 100644 --- a/features/linknewdevice/impl/src/main/res/values/localazy.xml +++ b/features/linknewdevice/impl/src/main/res/values/localazy.xml @@ -38,6 +38,8 @@ "Sign in request cancelled" "The sign in was declined on the other device." "Sign in declined" + "You don’t need to do anything else." + "Your other device is already signed in" "Sign in expired. Please try again." "The sign in was not completed in time" "Your other device does not support signing in to %s with a QR code. diff --git a/features/login/impl/src/main/res/values/localazy.xml b/features/login/impl/src/main/res/values/localazy.xml index 9b235558c8..832c3b7f71 100644 --- a/features/login/impl/src/main/res/values/localazy.xml +++ b/features/login/impl/src/main/res/values/localazy.xml @@ -60,6 +60,8 @@ "Sign in request cancelled" "The sign in was declined on the other device." "Sign in declined" + "You don’t need to do anything else." + "Your other device is already signed in" "Sign in expired. Please try again." "The sign in was not completed in time" "Your other device does not support signing in to %s with a QR code. diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiCheckCodeSender.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiCheckCodeSender.kt index 4bc6c212d2..a19c4e3766 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiCheckCodeSender.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiCheckCodeSender.kt @@ -7,7 +7,14 @@ package io.element.android.libraries.matrix.impl.fixtures.fakes +import io.element.android.tests.testutils.lambda.lambdaError import org.matrix.rustcomponents.sdk.CheckCodeSender import org.matrix.rustcomponents.sdk.NoHandle -class FakeFfiCheckCodeSender : CheckCodeSender(NoHandle) +class FakeFfiCheckCodeSender( + private val sendResult: (UByte) -> Unit = { _ -> lambdaError() } +) : CheckCodeSender(NoHandle) { + override suspend fun send(code: UByte) { + sendResult(code) + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustCheckCodeSenderTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustCheckCodeSenderTest.kt new file mode 100644 index 0000000000..5fb4698976 --- /dev/null +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/linknewdevice/RustCheckCodeSenderTest.kt @@ -0,0 +1,41 @@ +/* + * 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.linknewdevice + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiCheckCodeSender +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class RustCheckCodeSenderTest { + @Test + fun `send invokes the Ffi object`() = runTest { + val sendResult = lambdaRecorder { } + val sut = RustCheckCodeSender( + inner = FakeFfiCheckCodeSender( + sendResult = sendResult, + ), + sessionDispatcher = StandardTestDispatcher(testScheduler), + ) + sut.send(1.toUByte()) + sendResult.assertions().isCalledOnce().with(value(1.toUByte())) + } + + @Test + fun `validate always returns true for now`() = runTest { + val sut = RustCheckCodeSender( + inner = FakeFfiCheckCodeSender(), + sessionDispatcher = StandardTestDispatcher(testScheduler), + ) + val result = sut.validate(1.toUByte()) + assertThat(result).isTrue() + } +} From 05fc9ea2170847376de051ed2160c4478b2a15bc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 16 Dec 2025 20:13:07 +0100 Subject: [PATCH 144/347] Add missing test --- .../root/LinkNewDeviceRootPresenter.kt | 2 +- .../root/LinkNewDeviceRootPresenterTest.kt | 29 +++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenter.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenter.kt index e39179c463..a17ed88fd3 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenter.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenter.kt @@ -64,7 +64,7 @@ class LinkNewDeviceRootPresenter( fun handleEvent(event: LinkNewDeviceRootEvent) { when (event) { - is LinkNewDeviceRootEvent.LinkMobileDevice -> coroutineScope.launch { + LinkNewDeviceRootEvent.LinkMobileDevice -> coroutineScope.launch { qrCodeData = AsyncData.Loading() // Wait for the QrCode to be ready linkNewMobileHandler.reset() diff --git a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenterTest.kt b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenterTest.kt index 5d945e9605..88a68786f3 100644 --- a/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenterTest.kt +++ b/features/linknewdevice/impl/src/test/kotlin/io/element/android/features/linknewdevice/impl/screens/root/LinkNewDeviceRootPresenterTest.kt @@ -12,6 +12,7 @@ import io.element.android.features.linknewdevice.impl.LinkNewMobileHandler import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.matrix.test.linknewdevice.FakeLinkMobileHandler import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.test import kotlinx.coroutines.test.runTest @@ -25,7 +26,7 @@ class LinkNewDeviceRootPresenterTest { @Test fun `present - initial state`() = runTest { val matrixClient = FakeMatrixClient( - canLinkNewDeviceResult = { Result.success(true) } + canLinkNewDeviceResult = { Result.success(true) }, ) createPresenter( matrixClient = matrixClient, @@ -39,7 +40,7 @@ class LinkNewDeviceRootPresenterTest { @Test fun `present - new login device not supported`() = runTest { val matrixClient = FakeMatrixClient( - canLinkNewDeviceResult = { Result.success(false) } + canLinkNewDeviceResult = { Result.success(false) }, ) createPresenter( matrixClient = matrixClient, @@ -53,7 +54,7 @@ class LinkNewDeviceRootPresenterTest { @Test fun `present - error`() = runTest { val matrixClient = FakeMatrixClient( - canLinkNewDeviceResult = { Result.failure(AN_EXCEPTION) } + canLinkNewDeviceResult = { Result.failure(AN_EXCEPTION) }, ) createPresenter( matrixClient = matrixClient, @@ -64,6 +65,28 @@ class LinkNewDeviceRootPresenterTest { } } + @Test + fun `present - link new mobile device`() = runTest { + val linkMobileHandler = FakeLinkMobileHandler( + startResult = {}, + ) + val matrixClient = FakeMatrixClient( + canLinkNewDeviceResult = { Result.success(true) }, + sessionCoroutineScope = backgroundScope, + createLinkMobileHandlerResult = { Result.success(linkMobileHandler) } + ) + createPresenter( + matrixClient = matrixClient, + ).test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.isSupported.dataOrNull()).isTrue() + initialState.eventSink(LinkNewDeviceRootEvent.LinkMobileDevice) + val loadingState = awaitItem() + assertThat(loadingState.qrCodeData.isLoading()).isTrue() + } + } + private fun createPresenter( matrixClient: MatrixClient = FakeMatrixClient(), linkNewMobileHandler: LinkNewMobileHandler = LinkNewMobileHandler(matrixClient), From 10b61df11badb56f185c5570eae049d30d467948 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 16 Dec 2025 14:13:15 +0100 Subject: [PATCH 145/347] quality: fix tests after latest changes --- .../ChangeRoomPermissionsPresenterTest.kt | 40 +++++++++---------- .../space/impl/root/SpacePresenter.kt | 4 +- .../space/impl/root/SpacePresenterTest.kt | 28 ++++++++++++- .../fixtures/fakes/FakeFfiRoomPowerLevels.kt | 10 ++--- 4 files changed, 53 insertions(+), 29 deletions(-) diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt index 2fb48bf6a4..e3fe01b633 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt @@ -77,13 +77,13 @@ class ChangeRoomPermissionsPresenterTest { presenter.present() }.test { val state = awaitUpdatedItem() - assertThat(state.currentPermissions?.roomName).isEqualTo(Admin.powerLevel) + assertThat(state.currentPermissions?.roomName).isEqualTo(Moderator.powerLevel) assertThat(state.hasChanges).isFalse() - state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Moderator)) + state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Admin)) awaitItem().run { - assertThat(currentPermissions?.roomName).isEqualTo(Moderator.powerLevel) + assertThat(currentPermissions?.roomName).isEqualTo(Admin.powerLevel) assertThat(hasChanges).isTrue() } } @@ -142,14 +142,14 @@ class ChangeRoomPermissionsPresenterTest { presenter.present() }.test { val state = awaitUpdatedItem() - assertThat(state.currentPermissions?.roomName).isEqualTo(Admin.powerLevel) + assertThat(state.currentPermissions?.roomName).isEqualTo(Moderator.powerLevel) assertThat(state.hasChanges).isFalse() - state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Moderator)) - state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_AVATAR, SelectableRole.Moderator)) - state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_TOPIC, SelectableRole.Moderator)) - state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.SEND_EVENTS, SelectableRole.Moderator)) - state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.REDACT_EVENTS, SelectableRole.Everyone)) + state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Admin)) + state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_AVATAR, SelectableRole.Admin)) + state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_TOPIC, SelectableRole.Admin)) + state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.SEND_EVENTS, SelectableRole.Admin)) + state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.REDACT_EVENTS, SelectableRole.Admin)) state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.KICK, SelectableRole.Admin)) state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.BAN, SelectableRole.Admin)) state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.INVITE, SelectableRole.Admin)) @@ -161,16 +161,16 @@ class ChangeRoomPermissionsPresenterTest { assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.Loading) assertThat(awaitItem().hasChanges).isFalse() awaitItem().run { - assertThat(currentPermissions?.roomName).isEqualTo(Moderator.powerLevel) + assertThat(currentPermissions?.roomName).isEqualTo(Admin.powerLevel) assertThat(saveAction).isEqualTo(AsyncAction.Success(true)) } assertThat(analyticsService.capturedEvents).containsExactlyElementsIn( listOf( - RoomModeration(RoomModeration.Action.ChangePermissionsRoomName, RoomModeration.Role.Moderator), - RoomModeration(RoomModeration.Action.ChangePermissionsRoomAvatar, RoomModeration.Role.Moderator), - RoomModeration(RoomModeration.Action.ChangePermissionsRoomTopic, RoomModeration.Role.Moderator), - RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, RoomModeration.Role.Moderator), - RoomModeration(RoomModeration.Action.ChangePermissionsRedactMessages, RoomModeration.Role.User), + RoomModeration(RoomModeration.Action.ChangePermissionsRoomName, RoomModeration.Role.Administrator), + RoomModeration(RoomModeration.Action.ChangePermissionsRoomAvatar, RoomModeration.Role.Administrator), + RoomModeration(RoomModeration.Action.ChangePermissionsRoomTopic, RoomModeration.Role.Administrator), + RoomModeration(RoomModeration.Action.ChangePermissionsSendMessages, RoomModeration.Role.Administrator), + RoomModeration(RoomModeration.Action.ChangePermissionsRedactMessages, RoomModeration.Role.Administrator), RoomModeration(RoomModeration.Action.ChangePermissionsKickMembers, RoomModeration.Role.Administrator), RoomModeration(RoomModeration.Action.ChangePermissionsBanMembers, RoomModeration.Role.Administrator), RoomModeration(RoomModeration.Action.ChangePermissionsInviteUsers, RoomModeration.Role.Administrator), @@ -207,17 +207,17 @@ class ChangeRoomPermissionsPresenterTest { presenter.present() }.test { val state = awaitUpdatedItem() - assertThat(state.currentPermissions?.roomName).isEqualTo(Admin.powerLevel) + assertThat(state.currentPermissions?.roomName).isEqualTo(Moderator.powerLevel) assertThat(state.hasChanges).isFalse() - state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Moderator)) + state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Admin)) assertThat(awaitItem().hasChanges).isTrue() state.eventSink(ChangeRoomPermissionsEvent.Save) assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.Loading) awaitItem().run { - assertThat(currentPermissions?.roomName).isEqualTo(Moderator.powerLevel) + assertThat(currentPermissions?.roomName).isEqualTo(Admin.powerLevel) // Couldn't save the changes, so they're still pending assertThat(hasChanges).isTrue() assertThat(saveAction).isInstanceOf(AsyncAction.Failure::class.java) @@ -225,7 +225,7 @@ class ChangeRoomPermissionsPresenterTest { state.eventSink(ChangeRoomPermissionsEvent.ResetPendingActions) awaitItem().run { - assertThat(currentPermissions?.roomName).isEqualTo(Moderator.powerLevel) + assertThat(currentPermissions?.roomName).isEqualTo(Admin.powerLevel) assertThat(saveAction).isEqualTo(AsyncAction.Uninitialized) assertThat(hasChanges).isTrue() } @@ -239,7 +239,7 @@ class ChangeRoomPermissionsPresenterTest { presenter.present() }.test { val state = awaitUpdatedItem() - state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Moderator)) + state.eventSink(ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction(RoomPermissionType.ROOM_NAME, SelectableRole.Admin)) assertThat(awaitItem().hasChanges).isTrue() state.eventSink(ChangeRoomPermissionsEvent.Exit) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt index 6800846231..309747d2c9 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpacePresenter.kt @@ -34,8 +34,8 @@ import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias +import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.CurrentUserMembership -import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.join.JoinRoom import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.spaces.SpaceRoom @@ -55,7 +55,7 @@ import kotlin.jvm.optionals.getOrNull @Inject class SpacePresenter( private val spaceRoomList: SpaceRoomList, - private val room: JoinedRoom, + private val room: BaseRoom, private val client: MatrixClient, private val seenInvitesStore: SeenInvitesStore, private val joinRoom: JoinRoom, diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpacePresenterTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpacePresenterTest.kt index 9b6df0d258..917aceb262 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpacePresenterTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpacePresenterTest.kt @@ -24,6 +24,7 @@ import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias +import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.join.JoinRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoomList @@ -31,7 +32,9 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_ID_2 import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.join.FakeJoinRoom +import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.libraries.matrix.test.spaces.FakeSpaceRoomList import io.element.android.libraries.previewutils.room.aSpaceRoom import io.element.android.tests.testutils.EventsRecorder @@ -71,8 +74,25 @@ class SpacePresenterTest { } @Test - fun `present - canAccessSpaceSettings when space settings ff is enabled`() = runTest { + fun `present - canAccessSpaceSettings false when space settings ff is enabled but no permissions`() = runTest { val presenter = createSpacePresenter(spaceSettingsEnabled = true) + presenter.test { + val state = awaitItem() + assertThat(state.canAccessSpaceSettings).isFalse() + } + } + + @Test + fun `present - canAccessSpaceSettings true when space settings ff is enabled and has permissions`() = runTest { + val room = FakeBaseRoom( + roomPermissions = FakeRoomPermissions( + canSendState = { true } + ) + ) + val presenter = createSpacePresenter( + room = room, + spaceSettingsEnabled = true, + ) presenter.test { skipItems(1) val state = awaitItem() @@ -335,7 +355,10 @@ class SpacePresenterTest { private fun TestScope.createSpacePresenter( client: MatrixClient = FakeMatrixClient(), - spaceRoomList: SpaceRoomList = FakeSpaceRoomList(), + room: BaseRoom = FakeBaseRoom(), + spaceRoomList: SpaceRoomList = FakeSpaceRoomList( + paginateResult = { Result.success(Unit) } + ), seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore(), joinRoom: JoinRoom = FakeJoinRoom( lambda = { _, _, _ -> Result.success(Unit) }, @@ -345,6 +368,7 @@ class SpacePresenterTest { ): SpacePresenter { return SpacePresenter( client = client, + room = room, spaceRoomList = spaceRoomList, seenInvitesStore = seenInvitesStore, joinRoom = joinRoom, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoomPowerLevels.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoomPowerLevels.kt index 72464827ed..c47c4406b6 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoomPowerLevels.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiRoomPowerLevels.kt @@ -25,11 +25,11 @@ fun defaultFfiRoomPowerLevelValues() = RoomPowerLevelsValues( invite = 0, kick = 50, eventsDefault = 0, + stateDefault = 50, redact = 50, - roomName = 100, - roomAvatar = 100, - roomTopic = 100, - stateDefault = 0, + roomName = 50, + roomAvatar = 50, + roomTopic = 50, + spaceChild = 50, usersDefault = 0, - spaceChild = 100, ) From f8824e1ce18e1954de0edcd065bb4ece74da14dc Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 16 Dec 2025 20:34:33 +0100 Subject: [PATCH 146/347] quality: add missing doc --- .../matrix/api/room/powerlevels/RoomPermissions.kt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt index 638bf5449c..6b9815d6c9 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt @@ -23,6 +23,9 @@ import kotlinx.coroutines.flow.map * Provides information about the permissions of users in a room. */ interface RoomPermissions : AutoCloseable { + /** + * Returns true if the current user is able to ban from the room. + */ fun canOwnUserBan(): Boolean /** @@ -31,7 +34,7 @@ interface RoomPermissions : AutoCloseable { fun canOwnUserInvite(): Boolean /** - * Returns true if the current user is able to kick in the room. + * Returns true if the current user is able to kick from the room. */ fun canOwnUserKick(): Boolean @@ -128,10 +131,18 @@ interface RoomPermissions : AutoCloseable { fun canUserTriggerRoomNotification(userId: UserId): Boolean } +/** + * Returns true if the current user can edit roles and permissions in the room ie. can send + * a power levels state event. + */ fun RoomPermissions.canEditRolesAndPermissions(): Boolean { return canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS) } +/** + * Returns true if the current user can start a call in the room ie. can send + * a call member state event. + */ fun RoomPermissions.canCall(): Boolean { return canOwnUserSendState(StateEventType.CALL_MEMBER) } From a1b84bdcc4ff13594632b56631f55226ac20add4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 16 Dec 2025 21:54:14 +0100 Subject: [PATCH 147/347] change: rename and reorder RoomPermissionsSection to match design --- .../impl/permissions/ChangeRoomPermissionsPresenter.kt | 4 ++-- .../impl/permissions/ChangeRoomPermissionsState.kt | 2 +- .../impl/permissions/ChangeRoomPermissionsStateProvider.kt | 1 + .../impl/permissions/ChangeRoomPermissionsView.kt | 2 +- .../impl/permissions/ChangeRoomPermissionsPresenterTest.kt | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt index 562da8d879..d085be5920 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt @@ -45,7 +45,7 @@ class ChangeRoomPermissionsPresenter( RoomPermissionType.SEND_EVENTS, RoomPermissionType.REDACT_EVENTS, ) - RoomPermissionsSection.MembershipModeration -> persistentListOf( + RoomPermissionsSection.ManageMembers -> persistentListOf( RoomPermissionType.INVITE, RoomPermissionType.KICK, RoomPermissionType.BAN, @@ -59,7 +59,7 @@ class ChangeRoomPermissionsPresenter( private fun RoomPermissionsSection.shouldShow(isSpace: Boolean): Boolean { return when (this) { RoomPermissionsSection.EditDetails -> true - RoomPermissionsSection.MembershipModeration -> true + RoomPermissionsSection.ManageMembers -> true RoomPermissionsSection.MessagesAndContent -> !isSpace RoomPermissionsSection.ManageSpace -> isSpace } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt index 817be2a405..88309ea023 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt @@ -50,9 +50,9 @@ data class ChangeRoomPermissionsState( } enum class RoomPermissionsSection { + ManageMembers, EditDetails, MessagesAndContent, - MembershipModeration, ManageSpace } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt index b44bfc5075..6c4e5aa379 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt @@ -26,6 +26,7 @@ class ChangeRoomPermissionsStateProvider : PreviewParameterProvider stringResource(R.string.screen_room_change_permissions_room_details) RoomPermissionsSection.MessagesAndContent -> stringResource(R.string.screen_room_change_permissions_messages_and_content) - RoomPermissionsSection.MembershipModeration -> stringResource(R.string.screen_room_change_permissions_member_moderation) + RoomPermissionsSection.ManageMembers -> stringResource(R.string.screen_room_change_permissions_member_moderation) RoomPermissionsSection.ManageSpace -> stringResource(R.string.screen_room_change_permissions_manage_space) } diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt index e3fe01b633..9d94c4831e 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt @@ -62,7 +62,7 @@ class ChangeRoomPermissionsPresenterTest { RoomPermissionType.SEND_EVENTS, RoomPermissionType.REDACT_EVENTS, ) - assertThat(itemsBySection[RoomPermissionsSection.MembershipModeration]).containsExactly( + assertThat(itemsBySection[RoomPermissionsSection.ManageMembers]).containsExactly( RoomPermissionType.INVITE, RoomPermissionType.KICK, RoomPermissionType.BAN, From a8f28f98910f99de70f76cfafe84254201f8eb02 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 16 Dec 2025 21:09:45 +0000 Subject: [PATCH 148/347] Update screenshots --- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png | 3 +++ ....impl.permissions_ChangeRoomPermissionsView_Night_0_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_1_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_2_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_3_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_4_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_5_en.png | 3 +++ 12 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png index 1eb030d19f..49f38a28fd 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e28c554285760b5f6675459170589f4d61b4bf6172dabb71b4369042f1fc079 -size 51781 +oid sha256:cd8976b009775ac64496007232f9771bba6b8afbb588c621c574a91b399bc4bb +size 49734 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png index 7541082b2a..f3ef799045 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:533af53d229b262035ec971bf30ce85c23c110a86d991ce142827d3bcd6d0c70 -size 51690 +oid sha256:f82f648e9f5d67abfe2cf783df7e70568a74ff5dcae876e80b54995981a65886 +size 49650 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png index cd3ecb0c2b..83b5995ef4 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0de9ff1824d612f4e75e24ff253585c00ca8fb4b4d2a8fd7b25180971f08f6dd -size 45067 +oid sha256:0ebf86fc0ac80375edd1730caab4a669aa2cc545b2ea946981901fd360114320 +size 44555 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png index eacdf55dd7..0c1593bc85 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e23b6095d38a4d2cb80e507c850dc003060e7c461aa11c29b4cd6e0f21f935d -size 42563 +oid sha256:fae74539f53342110e50a077ad78b8422d08ba931b948b2b167d90f6cbe8ade6 +size 43535 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png index 2b197f9430..5a6d410ad7 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed51a1908b68ffdb0ac37ab8e6f53d86d0a47c226458b9feb0258f5d5fe6457d -size 49379 +oid sha256:61bced1ea61f5952e83956b4c4447a0371fe99c874e2a20df431bc59e02dc838 +size 50316 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png new file mode 100644 index 0000000000..16c2a363d8 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73d9461a1d51964ba1a912376658e3e550e952821f7aa1d9bff765ed11deb920 +size 49123 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en.png index cf43bd1825..865c938ba5 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8901e6374a2be899a3128a85f18a4167aa68a0d80fde3ab76af907f079f897a -size 50370 +oid sha256:1f096dcda405a17c90bad22dc6340543d8774c9ba65f1cd8cbd03a2077186614 +size 48626 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png index 47db703ee1..cb24aa2578 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f91162c6023dc96dbf5b9d6593a8266dccefe518028e7642267c8e5c68d74127 -size 50281 +oid sha256:192fce45ea8d83d8f7aa40f9337b2dd92c3b1194da611fed1c42fd771d74fe0a +size 48534 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png index 0bf89b26f0..b16e4b3ba3 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4d5793d7c85bc89ab7e73fa5d5cd0afef24c976d5bf809e6b01392d6c6631b0 -size 43666 +oid sha256:b3ed16d04a1106b82183c4fe6ae741b598448050e2ddae2fa842b0b01d475e0a +size 43230 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png index 759b82d88e..7ae9ff70b6 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5900ac981fb1bef222e3cda8ea84666a987e35c4aee4811529de67fad2fa90f7 -size 40543 +oid sha256:0cb2f7d7cad98d111ed2c1c0b8120e5837f2586f845594e581b41b7cb96e00f2 +size 41555 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png index b34823a90e..1aa08a4e12 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a5aab98cc9a302e18a230410fad290564091b57320f712daf3c0cc38522a4f35 -size 47303 +oid sha256:0862da8d120e276afd6bdef6a9b247d3976ae70adab47077d8749600dd695884 +size 48280 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en.png new file mode 100644 index 0000000000..25c50a55cb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48e5f7460a13798d2f2963930e4e7a95c6a1ffa704d034ec21e33ba1bde6606c +size 48123 From a4e5226814eea08ddc3dc3957022550016bd6275 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 08:13:17 +0100 Subject: [PATCH 149/347] fix(deps): update dependency com.google.crypto.tink:tink-android to v1.20.0 (#5875) 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 b5a2607c01..936bf5e9e4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -82,7 +82,7 @@ google_firebase_bom = "com.google.firebase:firebase-bom:34.6.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.19.0" +google_tink = "com.google.crypto.tink:tink-android:1.20.0" # AndroidX androidx_core = { module = "androidx.core:core", version.ref = "core" } From 771277b1aafb4bce7697b50d0605c7845d32cc94 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 18 Aug 2025 11:23:40 +0200 Subject: [PATCH 150/347] Update Compose BOM version to 2025.09.01 --- 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 936bf5e9e4..0b800eb03b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ camera = "1.5.2" work = "2.11.0" # Compose -compose_bom = "2025.07.00" +compose_bom = "2025.09.01" # Coroutines coroutines = "1.10.2" From 0fde8a9b5961c2526b50f752471c9625cbe827ea Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 29 Sep 2025 17:49:03 +0200 Subject: [PATCH 151/347] Fix compilation errors and warnings. --- .../components/tooltip/ElementTooltipDefaults.kt | 6 ++++-- .../android/libraries/designsystem/preview/SheetState.kt | 4 ++-- .../designsystem/theme/components/MediumTopAppBar.kt | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/tooltip/ElementTooltipDefaults.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/tooltip/ElementTooltipDefaults.kt index b21c5550cf..c6c244b2d6 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/tooltip/ElementTooltipDefaults.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/tooltip/ElementTooltipDefaults.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.designsystem.components.tooltip import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -41,8 +42,9 @@ object ElementTooltipDefaults { windowPadding: Dp = 12.dp, ): PopupPositionProvider { val windowPaddingPx = with(LocalDensity.current) { windowPadding.roundToPx() } - val plainTooltipPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider( - spacingBetweenTooltipAndAnchor = spacingBetweenTooltipAndAnchor, + val plainTooltipPositionProvider = TooltipDefaults.rememberTooltipPositionProvider( + positioning = TooltipAnchorPosition.Above, + spacingBetweenTooltipAndAnchor = spacingBetweenTooltipAndAnchor ) return remember(windowPaddingPx, plainTooltipPositionProvider) { object : PopupPositionProvider { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/SheetState.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/SheetState.kt index d14d614306..7e687e9b89 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/SheetState.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/SheetState.kt @@ -12,12 +12,12 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SheetState import androidx.compose.material3.SheetValue import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalDensity @OptIn(ExperimentalMaterial3Api::class) @Composable fun sheetStateForPreview() = SheetState( skipPartiallyExpanded = true, + positionalThreshold = { 0.5f }, + velocityThreshold = { 400f }, initialValue = SheetValue.Expanded, - density = LocalDensity.current, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt index e4c8ca74db..a49a3595f7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt @@ -33,7 +33,7 @@ fun MediumTopAppBar( navigationIcon: @Composable () -> Unit = {}, actions: @Composable RowScope.() -> Unit = {}, windowInsets: WindowInsets = TopAppBarDefaults.windowInsets, - colors: TopAppBarColors = TopAppBarDefaults.mediumTopAppBarColors(), + colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors(), scrollBehavior: TopAppBarScrollBehavior? = null ) { androidx.compose.material3.MediumTopAppBar( From 3aa7966e2c74e108fd52d4a8d9ad62663ca0cc20 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 13 Oct 2025 10:44:33 +0200 Subject: [PATCH 152/347] Update Compose BOM version to 2025.10.00 --- 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 0b800eb03b..17736867ca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ camera = "1.5.2" work = "2.11.0" # Compose -compose_bom = "2025.09.01" +compose_bom = "2025.10.00" # Coroutines coroutines = "1.10.2" From 868108d7255d157ef19486ac3d4ee0ffdd293408 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 13 Oct 2025 13:29:07 +0200 Subject: [PATCH 153/347] Fix SearchBar colors. Ref: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=1992-8350 --- .../theme/components/SearchBar.kt | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt index 924b77882b..6a6a808951 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt @@ -20,7 +20,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SearchBar import androidx.compose.material3.SearchBarColors import androidx.compose.material3.SearchBarDefaults -import androidx.compose.material3.TextFieldColors import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable @@ -45,6 +44,9 @@ import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.ui.strings.CommonStrings +/** + * Ref: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=1992-8350 + */ @OptIn(ExperimentalMaterial3Api::class) @Composable fun SearchBar( @@ -63,14 +65,12 @@ fun SearchBar( interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, inactiveBarColors: SearchBarColors = ElementSearchBarDefaults.inactiveColors(), activeBarColors: SearchBarColors = ElementSearchBarDefaults.activeColors(), - inactiveTextInputColors: TextFieldColors = ElementSearchBarDefaults.inactiveInputFieldColors(), - activeTextInputColors: TextFieldColors = ElementSearchBarDefaults.activeInputFieldColors(), contentPrefix: @Composable ColumnScope.() -> Unit = {}, contentSuffix: @Composable ColumnScope.() -> Unit = {}, resultHandler: @Composable ColumnScope.(T) -> Unit = {}, ) { val focusManager = LocalFocusManager.current - + val colors = if (active) activeBarColors else inactiveBarColors val updatedOnQueryChange by rememberUpdatedState(onQueryChange) LaunchedEffect(active) { if (!active) { @@ -107,28 +107,25 @@ fun SearchBar( } } } - !active -> { { Icon( imageVector = CompoundIcons.Search(), contentDescription = stringResource(CommonStrings.action_search), - tint = ElementTheme.colors.iconTertiary, ) } } - else -> null }, interactionSource = interactionSource, - colors = if (active) activeTextInputColors else inactiveTextInputColors, + colors = colors.inputFieldColors, ) }, expanded = active, onExpandedChange = onActiveChange, modifier = modifier.padding(horizontal = if (!active) 16.dp else 0.dp), shape = shape, - colors = if (active) activeBarColors else inactiveBarColors, + colors = colors, tonalElevation = tonalElevation, windowInsets = windowInsets, content = { @@ -163,35 +160,43 @@ object ElementSearchBarDefaults { @OptIn(ExperimentalMaterial3Api::class) @Composable fun inactiveColors() = SearchBarDefaults.colors( - containerColor = ElementTheme.materialColors.surfaceVariant, - dividerColor = ElementTheme.materialColors.outline, + containerColor = Color.Transparent, + dividerColor = ElementTheme.colors.borderInteractivePrimary, + inputFieldColors = inactiveInputFieldColors(), ) @Composable fun inactiveInputFieldColors() = TextFieldDefaults.colors( unfocusedPlaceholderColor = ElementTheme.colors.textDisabled, focusedPlaceholderColor = ElementTheme.colors.textDisabled, - unfocusedLeadingIconColor = ElementTheme.materialColors.primary, - focusedLeadingIconColor = ElementTheme.materialColors.primary, - unfocusedTrailingIconColor = ElementTheme.materialColors.primary, - focusedTrailingIconColor = ElementTheme.materialColors.primary, + unfocusedTrailingIconColor = ElementTheme.colors.iconDisabled, + focusedTrailingIconColor = ElementTheme.colors.iconDisabled, + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + disabledContainerColor = Color.Transparent, + errorContainerColor = Color.Transparent, ) @OptIn(ExperimentalMaterial3Api::class) @Composable fun activeColors() = SearchBarDefaults.colors( containerColor = Color.Transparent, - dividerColor = ElementTheme.materialColors.outline, + dividerColor = ElementTheme.colors.borderInteractivePrimary, + inputFieldColors = activeInputFieldColors(), ) @Composable fun activeInputFieldColors() = TextFieldDefaults.colors( - unfocusedPlaceholderColor = ElementTheme.colors.textDisabled, - focusedPlaceholderColor = ElementTheme.colors.textDisabled, - unfocusedLeadingIconColor = ElementTheme.materialColors.primary, - focusedLeadingIconColor = ElementTheme.materialColors.primary, - unfocusedTrailingIconColor = ElementTheme.materialColors.primary, - focusedTrailingIconColor = ElementTheme.materialColors.primary, + unfocusedPlaceholderColor = ElementTheme.colors.textSecondary, + focusedPlaceholderColor = ElementTheme.colors.textSecondary, + unfocusedLeadingIconColor = ElementTheme.colors.iconPrimary, + focusedLeadingIconColor = ElementTheme.colors.iconPrimary, + unfocusedTrailingIconColor = ElementTheme.colors.iconTertiary, + focusedTrailingIconColor = ElementTheme.colors.iconTertiary, + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + disabledContainerColor = Color.Transparent, + errorContainerColor = Color.Transparent, ) } From fe78c70625750e8d23e12f6caa3d5c8dd221fd0c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 13 Oct 2025 13:55:06 +0200 Subject: [PATCH 154/347] Make sure preview contains the two themes. --- .../libraries/designsystem/theme/components/SearchBar.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt index 6a6a808951..7c04700913 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.ExperimentalMaterial3Api @@ -300,6 +301,7 @@ private fun ContentToPreview( resultHandler: @Composable ColumnScope.(String) -> Unit = {}, ) { SearchBar( + modifier = Modifier.heightIn(max = 200.dp), query = query, active = active, resultState = resultState, From b6991c05cb6e7879fe022b4ace42990a169a1a1d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 13 Oct 2025 14:45:34 +0200 Subject: [PATCH 155/347] Fix colors again --- .../libraries/designsystem/theme/components/SearchBar.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt index 7c04700913..c1fd7bc6f0 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt @@ -172,10 +172,10 @@ object ElementSearchBarDefaults { focusedPlaceholderColor = ElementTheme.colors.textDisabled, unfocusedTrailingIconColor = ElementTheme.colors.iconDisabled, focusedTrailingIconColor = ElementTheme.colors.iconDisabled, - focusedContainerColor = Color.Transparent, - unfocusedContainerColor = Color.Transparent, - disabledContainerColor = Color.Transparent, - errorContainerColor = Color.Transparent, + focusedContainerColor = ElementTheme.colors.bgSubtleSecondary, + unfocusedContainerColor = ElementTheme.colors.bgSubtleSecondary, + disabledContainerColor = ElementTheme.colors.bgSubtleSecondary, + errorContainerColor = ElementTheme.colors.bgSubtleSecondary, ) @OptIn(ExperimentalMaterial3Api::class) From e5d48db40f54066ab8681c7705e1901db2765f0c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Nov 2025 12:56:51 +0100 Subject: [PATCH 156/347] Compose 2025.11.01 --- 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 17736867ca..77276166d9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ camera = "1.5.2" work = "2.11.0" # Compose -compose_bom = "2025.10.00" +compose_bom = "2025.11.01" # Coroutines coroutines = "1.10.2" From 758378b17a85ce7a16304225b8443e4bf2a0981f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Dec 2025 08:51:15 +0100 Subject: [PATCH 157/347] Compose 2025.12.00 --- 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 77276166d9..ac59b8d913 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ camera = "1.5.2" work = "2.11.0" # Compose -compose_bom = "2025.11.01" +compose_bom = "2025.12.00" # Coroutines coroutines = "1.10.2" From 15bb74a8f7d89fad23ff77a09fc61f9cc31a9176 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 17 Dec 2025 08:46:11 +0000 Subject: [PATCH 158/347] Update screenshots --- .../snapshots/images/features.home.impl_HomeViewA11y_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_0_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_1_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_2_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_3_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_4_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_5_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_6_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_7_en.png | 4 ++-- .../features.invitepeople.impl_InvitePeopleView_Day_9_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_0_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_1_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_2_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_3_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_4_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_5_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_6_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_7_en.png | 4 ++-- ...features.invitepeople.impl_InvitePeopleView_Night_9_en.png | 4 ++-- ....components.customreaction.picker_EmojiPicker_Day_0_en.png | 4 ++-- ....components.customreaction.picker_EmojiPicker_Day_1_en.png | 4 ++-- ....components.customreaction.picker_EmojiPicker_Day_2_en.png | 4 ++-- ....components.customreaction.picker_EmojiPicker_Day_3_en.png | 4 ++-- ...omponents.customreaction.picker_EmojiPicker_Night_0_en.png | 4 ++-- ...omponents.customreaction.picker_EmojiPicker_Night_1_en.png | 4 ++-- ...omponents.customreaction.picker_EmojiPicker_Night_2_en.png | 4 ++-- ...omponents.customreaction.picker_EmojiPicker_Night_3_en.png | 4 ++-- ...essages.impl.timeline.components_CallMenuItem_Day_3_en.png | 4 ++-- ...sages.impl.timeline.components_CallMenuItem_Night_3_en.png | 4 ++-- ...imeline.components_TimelineItemCallNotifyView_Day_0_en.png | 4 ++-- ...eline.components_TimelineItemCallNotifyView_Night_0_en.png | 4 ++-- ...ures.messages.impl.topbars_MessagesViewTopBar_Day_0_en.png | 4 ++-- ...es.messages.impl.topbars_MessagesViewTopBar_Night_0_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_0_en.png | 4 ++-- ...lesandpermissions.impl.roles_ChangeRolesView_Day_10_en.png | 4 ++-- ...lesandpermissions.impl.roles_ChangeRolesView_Day_11_en.png | 4 ++-- ...lesandpermissions.impl.roles_ChangeRolesView_Day_12_en.png | 4 ++-- ...lesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_1_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_2_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_3_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_4_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_5_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png | 2 +- ...olesandpermissions.impl.roles_ChangeRolesView_Day_7_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_8_en.png | 4 ++-- ...olesandpermissions.impl.roles_ChangeRolesView_Day_9_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_0_en.png | 4 ++-- ...sandpermissions.impl.roles_ChangeRolesView_Night_10_en.png | 4 ++-- ...sandpermissions.impl.roles_ChangeRolesView_Night_11_en.png | 4 ++-- ...sandpermissions.impl.roles_ChangeRolesView_Night_12_en.png | 4 ++-- ...sandpermissions.impl.roles_ChangeRolesView_Night_13_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_1_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_2_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_3_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_4_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_5_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_6_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_7_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_8_en.png | 4 ++-- ...esandpermissions.impl.roles_ChangeRolesView_Night_9_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_0_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_1_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_2_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_3_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_4_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_5_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_6_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_7_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_8_en.png | 4 ++-- ...atures.startchat.impl.components_UserListView_Day_9_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_0_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_1_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_2_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_3_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_4_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_5_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_6_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_7_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_8_en.png | 4 ++-- ...ures.startchat.impl.components_UserListView_Night_9_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Day_0_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Day_1_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Day_2_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Day_3_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Day_4_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Day_5_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Night_0_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Night_1_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Night_2_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Night_3_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Night_4_en.png | 4 ++-- .../features.startchat.impl.root_StartChatView_Night_5_en.png | 4 ++-- ...ents.previews_TimePickerHorizontal_DateTime_pickers_en.png | 4 ++-- ...me.components_SearchBarActiveNoneQuery_Search_views_en.png | 4 ++-- ....components_SearchBarActiveWithContent_Search_views_en.png | 4 ++-- ...omponents_SearchBarActiveWithNoResults_Search_views_en.png | 4 ++-- ...s_SearchBarActiveWithQueryNoBackButton_Search_views_en.png | 4 ++-- ...me.components_SearchBarActiveWithQuery_Search_views_en.png | 4 ++-- ...tem.theme.components_SearchBarInactive_Search_views_en.png | 4 ++-- ...aries.designsystem.theme.components_Sliders_Sliders_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Day_0_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Day_1_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Day_2_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Day_3_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Day_4_en.png | 2 +- .../libraries.roomselect.impl_RoomSelectView_Day_5_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Night_0_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Night_1_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Night_2_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Night_3_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Night_4_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Night_5_en.png | 4 ++-- 113 files changed, 224 insertions(+), 224 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png index 7323ddc95f..78e57157df 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:88dff52e06c62a7df91c08ed0237068a2e8bcdfd5f83426a52cf7a3097ee8cfa -size 122935 +oid sha256:29076d1c09d92943b1ba143d0ed3798fe92f7d37f87f45c0ae5f7326afe66f74 +size 136708 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_0_en.png index 9241a7a37d..1e55a5b62a 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:085470e95dffbed6961109236a983d6d158d958f6bb47e597766ef6414e040aa -size 9109 +oid sha256:070f37faf63ee4bb7acabfbe19943181b367cb53d23978efe9ca669d6051e04c +size 9137 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_1_en.png index 8f21fdaf3d..db8bb9c93d 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cbe23f6cf9bc4f4a77e8e1b5b8a026c6bfc3aef1aae308a9f08488baff5fc53 -size 21416 +oid sha256:e1a765e16b340e75d0657de9bbbb429d09ebffae9e94deee982a8bcfc74e21bf +size 21454 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_2_en.png index 86f83b88fd..175a697925 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c34f3966fcb3f6b0f0d136c5ffa6abc114e1dd72dee80ff96ad0541c89a5278f -size 6637 +oid sha256:27ba0279436ab9882d4fdcfde7897696e92e9d1a4b77376334abdb88957d5d31 +size 6708 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_3_en.png index 28ae5b5bac..61c2bb212f 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8db01c01f7f0d1c79738fc79aa127f1f4f7ebb5d0add127361298f2dae81f538 -size 18920 +oid sha256:d115dd52892b91e16547d929e02fbc158d5186ea9be85b374eeb441e47205db2 +size 19004 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_4_en.png index 27d72a9313..bedf5616c3 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:195fc722f5d2e88a2dd83c5f9fb1de57e3c4613d7a391b9f998388dc3ebbb235 -size 8584 +oid sha256:19480b9a3c48af6b5ff5ea37cd8dae88d84b73c000d6f752935b31ce99cc2e61 +size 8657 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_5_en.png index 26cdab67d4..9c8a5cf6c1 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:639cb5bcb5a74d1cdb94703c42189d1a5d9fd2b9d9f49c23cd47bb340a830710 -size 37829 +oid sha256:0d5367145bab2e945d17458e24c5ad507197f8bf4600326199cf16f68f2e90f8 +size 37900 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_6_en.png index 91e9bcc3dc..31cdcec65b 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:651042b5628da42cdb4d7d8fb465ba279a12d78d8f51a688eeee90bc413002d0 -size 32992 +oid sha256:13ab803fe6533ca2b9e937022e0d8f8c32dbe89e99cb97165a16a5a9c399ebd7 +size 33067 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_7_en.png index 09e1bb63ae..0dd385c93c 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2e674fec4e26de21c82e020f9c9a7b693599ff98c1aa4d5c846c0179db3e1bf -size 25727 +oid sha256:ef3621606ac95901a2d47769ab47758901c3c826b2fa21be22f9f17a0974c5aa +size 25776 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_9_en.png index 8f21fdaf3d..db8bb9c93d 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cbe23f6cf9bc4f4a77e8e1b5b8a026c6bfc3aef1aae308a9f08488baff5fc53 -size 21416 +oid sha256:e1a765e16b340e75d0657de9bbbb429d09ebffae9e94deee982a8bcfc74e21bf +size 21454 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_0_en.png index 67ac1fa292..8a27251ee9 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5423698f4f64b323eb15bb484ddbd4791aac0df340b9ae61cca2215211bfeb1d -size 8555 +oid sha256:1787bd92c75748e69f346f7588170bf6fa9c626dd6544f4270f30f0f9b614037 +size 8631 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_1_en.png index cd60ed7afe..07c21c8e8c 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c85d701da74df18b017594fea595e65b5dc258411c0cbc22b04f2feb94ba9fb -size 21977 +oid sha256:7c4c5d0035baf55bc67abf83eae90fa0c16e044a0d0ab26634c02fb0ad5d4c26 +size 22062 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_2_en.png index 4ea1bfc3cf..5c64fe9a7e 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:345fcff2eb2a3672ee16bb60b8f27f2c9ec29888822de17075a74b3c5e0e501b -size 6502 +oid sha256:20ebf6572b217c13686bd616686d49cf156a969232533e5c6041f9ea9de9ab18 +size 6575 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_3_en.png index 3002763e4a..9b2b6a0149 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe84ec8ccea9643617e2a7e6237122652ac5c2933113dd25f8abdbbf6e959ea7 -size 19861 +oid sha256:6c80b41f4a5bc3320ddb73fb28741c61abaf19791d642a1157fde74b172fe6f3 +size 19930 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_4_en.png index 0a4b7d4d53..d77b338c7f 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ab2aa6a0103eca29b52cd107fd3826ea509bc51238c2f6e521977ef79d480f2 -size 8411 +oid sha256:a53b0f2a9d9278073e5bcf9a3aaa57b71940461b2dd7b391b12aa0297e50cdb5 +size 8476 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_5_en.png index 0fca502f1c..ea5eb9fb8a 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3a65959829bbf2c2e2f2842b78f620e417a0edaa5996f7a53f24b6cc997f9ab -size 38491 +oid sha256:9761e44904c0810b0e0b1168bda61f36da47fb1e2d49e8b948a5c50367e630b9 +size 38548 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_6_en.png index c6fc626fa3..68403b844d 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ca72547eaa183851897287859b5be5fe8dad13f2d69a374d7e62477de171f37b -size 33060 +oid sha256:7aeee770a09aac3f3cf5cd608d3ef6cbf2e58e34373e04900cf4cbec46193f56 +size 33171 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_7_en.png index df9f13f8b4..1d66b2ce8a 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d49358838af8128be8b8a1e06712a5656460e247db0ed496186cc5017a31ac4 -size 25307 +oid sha256:a5efa0d8c2c786d5d36f23311221a124499b1cf9368002271ee8ca1931309ae7 +size 25374 diff --git a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_9_en.png index cd60ed7afe..07c21c8e8c 100644 --- a/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.invitepeople.impl_InvitePeopleView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c85d701da74df18b017594fea595e65b5dc258411c0cbc22b04f2feb94ba9fb -size 21977 +oid sha256:7c4c5d0035baf55bc67abf83eae90fa0c16e044a0d0ab26634c02fb0ad5d4c26 +size 22062 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en.png index df61c68426..0d10f912be 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b01a2e008d075539241eb99ce811088bb7ab89ee94dfe39ff8abcd4f24b08e41 -size 22512 +oid sha256:ade3578eb4da40cd986459e34b6b851bfa5040d802e3d2f0321353161262db3a +size 22535 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en.png index b39848d95c..0094af760e 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f36b7ab6f350a187e83d7cfb2e55f64fd5dfcc82438facaae63c2074fff292b -size 6825 +oid sha256:975b14dea5a3b4363c6977137846227a32f35fc530e554d76617aec53b341d68 +size 6943 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_2_en.png index ce9e811519..cc836dd47a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41f000a90175e8cb9478421e4de2dbd87123cc22be29504372860f8db7f846d6 -size 5631 +oid sha256:6968b48982e16c91975d3debf329ec5cd8eae3e16d63cdd936baad4ef4cc5e1c +size 5658 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_3_en.png index a843272661..a8bbd66493 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:756c92b946bd864ad6a1cc33f0c430cea62473eff63cb1174695cb46a297deec -size 14436 +oid sha256:f1b54e9c23078f0268c37c673183035108c4301e8a9663bfa16376b270d87d85 +size 14472 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en.png index 6eacca2e07..cd3004cb0b 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c3af79602722cb1e264dc15f883e6579db9f12114b1b43e70881707e88acbe32 -size 21579 +oid sha256:8e0996466c314ebc8bf144bb0370d8865ac78476f29d434522fae83913867ffe +size 21628 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en.png index a538b62fa0..833303d006 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:597ae7e4f45edd15bd90511d7c9fcb85a0153a7bb74c22d1e9b55a24b182d12d -size 6722 +oid sha256:3877b6b6459012ca5766ed03de7666a8e073399b05d679a26487e5593812059f +size 6884 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_2_en.png index ea260a60fa..78cce88787 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2977734999971634999453a258275d5f8ad2861fb0cd5758e988606b8e1245d8 -size 5543 +oid sha256:d98044d3c2d2ffb77e8357d8642c03b92b0054859ac2db3647b0dbb2ade2d6b8 +size 5558 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_3_en.png index e36b237d79..072cb32978 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58fefc1cec3d36cb6ccd78549d2d7ce6cd940bb9ec56de5b817b7dd5324d4174 -size 14282 +oid sha256:1e582e2c6b01cfbc6924d2b895ac64a9689c56979712c8e0280e5126158a22d3 +size 14300 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_CallMenuItem_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_CallMenuItem_Day_3_en.png index 22d9c81934..2ee3df7b95 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_CallMenuItem_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_CallMenuItem_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce6b4231277e0d18a3d982802c64b56fbf2519c73a9689a05a8c6ae6a61ce1f9 -size 5510 +oid sha256:1dba02eaaa4c766068ed8feaac6a0854651e83cf177de6dfe3e71d5f65ea4b02 +size 5445 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_CallMenuItem_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_CallMenuItem_Night_3_en.png index ea6d8869e4..7f84250229 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_CallMenuItem_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_CallMenuItem_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86134025e201b0309131428a131efb042c84d044b71be96a088dff67d9571e7d -size 5445 +oid sha256:46d3a70cba326d72d7b099bbcac3d08d8f18902bcf08108f80718ad759fbe697 +size 5429 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png index 3b73f5d5c1..014fb187cc 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ad78c0b4824f806e7985410ae57ef0381e8cc90396be3b6db89921e5a6995dd -size 38244 +oid sha256:c9fd514c76baa0fd45166b9b3928a2a09e25c19451f3e80bd458cc9b0174f6d7 +size 38160 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png index ae89b6a2f3..fe1d630a82 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c85ba7b40f5cc624f9406e4808d4479ed1a6f7fa8bd5377efbee49b7c451e491 -size 38037 +oid sha256:d0c7b57c946831f8454a0a4eb283b9f1783ec5a8c8066627460923a5256c977c +size 38068 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.topbars_MessagesViewTopBar_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.topbars_MessagesViewTopBar_Day_0_en.png index 2a6f08c058..899bf4ad75 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.topbars_MessagesViewTopBar_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.topbars_MessagesViewTopBar_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f6600eeaad127d1412992dd34c5cf296ba727202fdfd38a2b8d53430b5094f42 -size 39793 +oid sha256:dca37712b4df739fea42e8070761c431da4163732caa1d005bf50fd98b79764c +size 39730 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.topbars_MessagesViewTopBar_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.topbars_MessagesViewTopBar_Night_0_en.png index b86d43a9e5..de5049cae0 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.topbars_MessagesViewTopBar_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.topbars_MessagesViewTopBar_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c5269f87f27b629f5689a743d25765fce10d755110d1cbbc0ba4d56e7759e14 -size 38167 +oid sha256:e1bea37c40c43b5887cc87e0ed95552a5e42cf0b776a1342d66b2f0b2dd7836c +size 38283 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en.png index 3825bdd8c4..c0ff48bae0 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:84b11cca43a63a1b5d68b161d7c49c5d62f2fc6f6bea630fe406de52c0773a03 -size 13377 +oid sha256:6a58fa86e0a2cb291b02c2ffb3f76fe0d57017b5220856bdd0713b6ced0a356d +size 13406 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en.png index bdff2798ab..bea20a3048 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5584bdca22931e512ada5d1e761707901ac1c98054ba564fba3120eff85a7723 -size 50276 +oid sha256:a51cf55a538fd985cc0420d732c11b3c139d0df90d42a6d42a90bd62f9881169 +size 50271 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en.png index e972b8cca8..9be716ae53 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f0d5d448b130c730783bb5d0a2cfd6b5409543e334d2196f3735325815d391e -size 52674 +oid sha256:a2ed03c7103b4e27c4d7d63434d8e7423b50873e313eaeb70a1d9336fbcb8414 +size 52721 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en.png index 5ed3836326..c84ce11429 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:52d24be04216937e0f79d52b08679b34f5d7fd7cac27f8d4fcc379b9d26b98fa -size 54383 +oid sha256:037afed9109f51f4ce85e229fb93a4a77af4b72c2cdf98b4031d9f5fc996f090 +size 54418 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png index 5ae55a94d8..8e1a2a9e52 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbee2417fcd701fce6d3f4d20e677681de6d529e5a17f0bfffc1c1592d73398a -size 58939 +oid sha256:d197fa0244d1559df5cbf81d0e7d481ce082af2b217d37b38c889a277af00a37 +size 58933 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en.png index 09b0f771ab..03baa74419 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eed59ebd3d64a679d57edf37d44541de4ac05c019254e2252cf55c31c303bd69 -size 67443 +oid sha256:4e6ff8fea6c46b55d6cb44b30fb8b9d4a5684772f2a9a4477b0eb76c1b7f96c0 +size 67481 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en.png index 4ffff911da..af17aca8d3 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9fc439dadbe18a578d5436c8a6c85c62777b95b7169322e0944fe085d79599b1 -size 61243 +oid sha256:05db7ff5f96294dd9cd6c9b60c3d438c6fede097d7fdd4b426e64d3251201fc9 +size 61271 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en.png index d1b21ebee2..f9fe320d41 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:393bf3509a833f7af78a57e546ce6d35ca3bef4d4523ff12af657d1c573b87c5 -size 61190 +oid sha256:d3bedbc4de85e76b8304aefb7b34d14880fcecd11d524b6bc087ca3166d739bb +size 61218 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en.png index a2bc4b768f..a45c9e8c94 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69ce060cdeec55a6a40494d49b099c0c34dab3027e64446c8900e021f55f6355 -size 55027 +oid sha256:b2efc1ded97f446b8e94b61dfeb8a96e518e627042c1886dafaf777b90cfa31e +size 55050 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_5_en.png index 9e8598c0c7..b0a04a76d1 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c50a521b082cc991afe1d266a15bb7287bf38b39e88b34c64ec41ba8d4f44120 -size 12469 +oid sha256:043a2bb306d01e88f3825540bc7d6c1cb4c14d9b57ad2f7ac0173e9aa5a5ce3f +size 12495 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png index 1af85a90ae..958cd1c0e2 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6109391197169d423341ba95d8f3de581b6b9663f8a017c0b727bf7d9181b228 +oid sha256:de9f998278b6383dc82be6ae41847bbcc835fc74c07bcb7c4130a3f81075ec8c size 56993 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en.png index a9ef82274d..859072a854 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3842fe35adfa08d01b34223bdde54fb9113df7eeb028f17705c432348f56ca79 -size 61437 +oid sha256:4a57f78edff78c6e31e2a8edecbd4579ce0cb318ed99101d51c4bf584dbd3185 +size 61434 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en.png index d905418495..aa0d0e395e 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98240342e9ce368a676a950eb1ec40d1720cccde36e45e9b8896c887d14d3bf1 -size 52662 +oid sha256:7a754cc6e9656b57ee4728abbf3adbe6249284336fc02a50d9d4e6c2cbde2b43 +size 52651 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en.png index d1b21ebee2..f9fe320d41 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:393bf3509a833f7af78a57e546ce6d35ca3bef4d4523ff12af657d1c573b87c5 -size 61190 +oid sha256:d3bedbc4de85e76b8304aefb7b34d14880fcecd11d524b6bc087ca3166d739bb +size 61218 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en.png index bad5ea3df7..4cbb688206 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3fb7aa111a4519e3f608a3ba1e059195c8b07bec33ae91a896596ae90abf4fd4 -size 12653 +oid sha256:70f773618ee9ec9eaed88bed76c0a03b4823f14bbf1abc11df82463495be679e +size 12736 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en.png index 58bb111a14..0ef0197cb2 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4afca3e00f67a85c273efaec9747895787a2a5f07f66f9f9ae7e34ee4e78cc3 -size 48598 +oid sha256:3dee1cd8e570f79740948aabecfa11f58267aa6601ec29e1ea8f68d3202f0e6f +size 48652 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en.png index f9a22a58e5..810c03544e 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d5e5203690478c822e1a77204f315158c81c4835ce375ced1189c85fc21db9d -size 53473 +oid sha256:a8a6c9311fcee79df31ec8bd3bf6df3369e32939910e10cabc35a721b3ec43d4 +size 53565 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en.png index 74c7a8a44d..51ae61a851 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ccafa3f630c5db13f1b083e3ce30a9b69e8407549a12f119b07191b128c19b9e -size 55031 +oid sha256:c3cec78363008275d905da949ca9eea583f37e31ec687e3dba336bc0aef51f43 +size 55104 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en.png index 8fb608a939..5ef22333b3 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41698290446bc0f2e58fac106cdef381c1b46f3655ff51fff574ff867cd70d10 -size 57006 +oid sha256:9abc0395c4295e6f6a23a67cd8d53a8aecf965326ad98f3d0b98646dd27f0851 +size 57061 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en.png index 7620426662..7d5b8826d9 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04b5299a6a10e01034298840b0249b53c5d72d6644884d8ea609588f3f3677b4 -size 67976 +oid sha256:16645d4cc9fd23d693d13f073b4c735558a269aab8314bb72224897d6d5d42ed +size 68041 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en.png index 7c3cab3e11..12c282df4e 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:50f59c4374146f6bff5f13e8a9be522a85ec642d4e9bd27dba1fc5ab1a5163c7 -size 61955 +oid sha256:014e26a0823d1bdcca32c483e45b8f9d3f35a904b8aaa449e0bb71f8fc1c2423 +size 62026 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en.png index f55e0ac7a6..8a712bf578 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37a79b2f5d6aedaef2dec74defd0f2a17af49239058a606f0785e82e56d833ec -size 61887 +oid sha256:f82351a84d8f262356afeb9f07c4dd90d675042c599f4f6f5d028581ac77c173 +size 61956 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en.png index b9a71909bf..98aabe3df1 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa1bda0999bc62e108680c0adb2dea2d692cd217671f60b7c57ec4f376a02c10 -size 55357 +oid sha256:aab9343af69ebc39fbfb90acb71251983172e76e5708d2db10c13236287cf97f +size 55418 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_5_en.png index 6ab0e8bc19..6dc63fc622 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:78ebe0649f31303d844a0175a8734a976e73b4d21769c1f62a93e41718da4815 -size 12469 +oid sha256:4363afcef8e7ad7ff66c3071a22cfcd102af99cc548382872f3d7197e26f0e8b +size 12510 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en.png index 93d5b14f5f..2c451a9c90 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71a4998d420d5cad0a799db7f51223393cca34218a1a23520606667ea320331b -size 55323 +oid sha256:39f48cc37c35b3c8c39e44c5936712277f467bd1b8c774606593d6a678f28353 +size 55378 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en.png index 0878774f51..bfd00e9c5a 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:341420a42fa71d28867237c882bbc53721f56f2b5466700722012badaeec4b1c -size 59445 +oid sha256:9ed24adcb2f35d6041a64ad143ebc56e6429ce8967c41990204bf5b04b6c4817 +size 59493 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en.png index 16aef17c3d..f711e4c89a 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8853f6226a69b2df97ea4839d2c5bb1d77f14eb62a587f929936c7013f88bff -size 51795 +oid sha256:1caaadd9b46f40c555e06c38058266b7597c50c8c59f1d5ca7b266f05f874f5e +size 51851 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en.png index f55e0ac7a6..8a712bf578 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37a79b2f5d6aedaef2dec74defd0f2a17af49239058a606f0785e82e56d833ec -size 61887 +oid sha256:f82351a84d8f262356afeb9f07c4dd90d675042c599f4f6f5d028581ac77c173 +size 61956 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_0_en.png index 9756ab494d..86c631023d 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:16ca45a42d69261efffd342a3ae53d24f748cbd404d20a2c8ec958f0d93c8fc5 -size 8957 +oid sha256:f49c7171d025cc381b02235bba5b9a09a805f8dd4c4327cb74df4186db6afd59 +size 8986 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_1_en.png index 3452586bea..7c03a9a421 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:81ece70624f9366784cad246f158584c6fb8167e7ea5874b29eb8c186b50822e -size 21505 +oid sha256:c5fb755341f8febc8af23ec0615b70a207b09f574ded58ae53f8680923ea03f2 +size 21541 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_2_en.png index f653c35d7b..2007352940 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd50f1d35f872ee93bd6b2aff1feaffcc2314b11fae60302351f738bd86d735c -size 7630 +oid sha256:78e1af4146305a5b9ba0b152814d845cf19a33c3748765bd52c07a39dc6d35b1 +size 7839 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_3_en.png index afa0af99d4..4c836e32d8 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c0c23f8cb90609cc1f6107f4d34efbc044de92286cb237487993953f5497e5e -size 6521 +oid sha256:c47a9d0c4eddd09c8ba7f1b2ae186031d617d5bffd6095a3c708cd887de99439 +size 6555 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_4_en.png index afa0af99d4..4c836e32d8 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c0c23f8cb90609cc1f6107f4d34efbc044de92286cb237487993953f5497e5e -size 6521 +oid sha256:c47a9d0c4eddd09c8ba7f1b2ae186031d617d5bffd6095a3c708cd887de99439 +size 6555 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_5_en.png index 8d83e1e828..19bec50639 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8fd6daaaf9b3d2ce8708c12f64eadf905874de008edba5415e2d452d1cc5906e -size 38504 +oid sha256:e284430f5ec6dc52040c7e0504bc1aabfc5eb9f6bf3674d1376458aef1a830ec +size 38587 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_6_en.png index ffa3c3ccf1..c758fc946a 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:85cf2d191cb255838a25dec2b69899b096170c65463e81a34261df533b861eb1 -size 53062 +oid sha256:c65c68d8eb01b9eac31d1f728f90d7c0059991803c05e8401209f4b999d656a9 +size 53155 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_7_en.png index 9df1642c6b..f4a7c108b1 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58d4c3e636f71ac1408189c3c14da3b0dd1e700a1be02a02f373adbcb5604b48 -size 10976 +oid sha256:8e455a78983e6e8f26920549181999cffeaf4daa7bdcd4f5774fb7419a27b0da +size 11057 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_8_en.png index afa0af99d4..4c836e32d8 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c0c23f8cb90609cc1f6107f4d34efbc044de92286cb237487993953f5497e5e -size 6521 +oid sha256:c47a9d0c4eddd09c8ba7f1b2ae186031d617d5bffd6095a3c708cd887de99439 +size 6555 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_9_en.png index 4f6d627398..2ce27e9c08 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:543e5d99df73c97b6e1fcfa184e865568d9cea4d23c2ab92a9f64be66ae303d8 -size 38127 +oid sha256:60d163e2da18bab22303c7b896ebd6dce13b900b41d3d1ec8b2779ec171ec7ac +size 38163 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_0_en.png index 3f11692df2..edf7df7749 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6453fec836c6cef4f0434d61f09e643f771be1babc583eb8e92c1f8176f5844 -size 8563 +oid sha256:06fb99d011d4d2353d4d0c7149607e3aa32f2ac17d96046068db74777c35e12d +size 8638 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_1_en.png index 75c032223e..4841f7b5c0 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ab912aa9485f80c38fd57e7cb79f70db386155e98d8f7a71239e7efb435f0d79 -size 21987 +oid sha256:ad0fefb47520389e716e738d311a0fe5775eefc817dbb96cdc1475855527145b +size 22073 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_2_en.png index c002b74577..7b6434a90a 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11c23632578610a78a6700f9d103ff6b4b3da03887cfb1918b10f2c6052e6820 -size 7549 +oid sha256:f8a0acbe3d78cce73592534bd028fef6c5477e93977369b77069532b140de811 +size 7740 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_3_en.png index 775f637648..df5bfbc44f 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b838359a59cdc357f0ef80d701f6093ea45875c7915ba438901748f43ce9106b -size 6316 +oid sha256:ba84e8dce8c457afeb24d03c82ff95c9ce5f3b6633fc1c03914e50f9e9615deb +size 6369 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_4_en.png index 775f637648..df5bfbc44f 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b838359a59cdc357f0ef80d701f6093ea45875c7915ba438901748f43ce9106b -size 6316 +oid sha256:ba84e8dce8c457afeb24d03c82ff95c9ce5f3b6633fc1c03914e50f9e9615deb +size 6369 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_5_en.png index 3aa6cceb27..e9dbe6cd19 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de723755b90c8cacce16e27a16dcc9103e27bad86f492fd540745d90eabd7984 -size 39352 +oid sha256:4165b4fb98a9e10c9b4b47d6f90d578799ad84f15b2cfdcddeb705413eff52ba +size 39435 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_6_en.png index 9a5c16673a..38a17c8d2d 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ece00a0efbaaef3ffa2a6cd21542a4d9f37fd722ddad8f52a2b5c5b22afaec5e -size 54275 +oid sha256:51eb6665f0fcc83c9d740e46538ccd4625c276f63513c2229f87583c04a49a29 +size 54361 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_7_en.png index 8aa1b22c1d..bfd097d1fc 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ced65352d0aee02e92f19fc890a8fa92efabfb8255a9a58e36dc539e2d4d6009 -size 10664 +oid sha256:f6c2a5dbe58e76da9ffd1202605c73f769c47da3d9686f5c773e92cae77cb086 +size 10743 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_8_en.png index 775f637648..df5bfbc44f 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b838359a59cdc357f0ef80d701f6093ea45875c7915ba438901748f43ce9106b -size 6316 +oid sha256:ba84e8dce8c457afeb24d03c82ff95c9ce5f3b6633fc1c03914e50f9e9615deb +size 6369 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_9_en.png index e467ac0551..006a06d9f7 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.components_UserListView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe7d54ea6d6bd3f74ab93360042afdad0def7b704c023b896a427d4e5e038f82 -size 37831 +oid sha256:3a07e925429267ac01fedf8ee7d1cf2a8c3db867a2d97ad4f486cc3311203bbe +size 37912 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_0_en.png index 67be7b388e..6d0b806999 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2513e8f167803ed68807b3b4b7916ad41457ddda6e06b73f73e763873c3610ed -size 25857 +oid sha256:dcf2720472a299395a7446b4002f7171d1af42dc5946e4cec236a9b4fd9336ee +size 25877 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_1_en.png index b581fb7b5e..4b4406609c 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e7c8f6b2beaf11a388c1c1eea86882836a8dc992dda0a616718e28ea10e9218 -size 19831 +oid sha256:41e8c2615bf34e656b9443368ec0ca26e81600be917231d8e8b7d2f9ea2058d5 +size 19868 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_2_en.png index 98e770a0e3..01837fbc87 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a80c27eeeb0b6d7bcae6dce55c1b76e8339a87e12ff9e489e4b94f7f8cfad048 -size 26686 +oid sha256:6bb5b17082fc8a9d3a9a31dac2e5565755f33ef7690c3f4c04e169e44ba39b4e +size 26722 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_3_en.png index 8cba1edf39..83b2d91eeb 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d6ed05f8651e3a080a4faf8a77e8f80bc56cd52452e64e279af80098216b913 -size 50201 +oid sha256:de87402782f0895d1192d801266a7d2bee1b6e79395eb39c56aff23b36da8839 +size 50232 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_4_en.png index cc66665bb2..b39e40108a 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:360449e5163938c21518eba4de43a2ba5f071d94ea84df1caa914624c1a19d93 -size 41889 +oid sha256:d09b9d85ccfd65576165b0f918488e3ffa3af1ea5d244b104200bc8bdaaac5a4 +size 41942 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_5_en.png index 5a00949455..75de482fbc 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bdebd45554b623d17e0d9a1d0fed3983773fb2e911145f5740a1defa89886d9d -size 29336 +oid sha256:75eff686fb001b562a69e131a3b96d1818c1fc148dd3a86675d949e08b53b835 +size 29376 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_0_en.png index e10c3da7c0..311e260e17 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0dc22976dcc0f511acb8648557e39de9a1f6ad459fbd97e326f079f4d999e502 -size 24836 +oid sha256:79af7dbe73fa2f66b7feb6cb631417c9222a6f12d8ca197cc13ce6f7f4ebb634 +size 24901 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_1_en.png index 00a76e245b..035cf7bbb8 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c6313c54b31b1bb0d01d3d8a144ee42a9ad8e48be5e38546d8330b7c83c51fd -size 18729 +oid sha256:379de8fb86ff06daae9cb3ecc9f24533da65885eb3360ed499b6808274896668 +size 18747 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_2_en.png index c48b02266d..3db3027f93 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c494394f5d6485ebdea10c9aa04057eb9e5d05680be5a10eaa1cf13e08833cb -size 25000 +oid sha256:9d0969ed7978c0f86aab5770723ea62a58ba6a5f639211358dae3517c7395315 +size 25007 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_3_en.png index 1a33369536..8e5a7731e9 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bcf1370e3cd3bee3c2ae0607d3a4d21f1e6f4aa9f3558c63f918e4cc64f126a6 -size 49709 +oid sha256:7e8a340602a16adae67049fd1b647d524bbfcc7572484117c97ddd6b38b87f9b +size 49804 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_4_en.png index 4b82277195..a411f682a6 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4634c3331d259372552efc5cc664a9f6bdc866595c9be398510e288ec4dd90b -size 40509 +oid sha256:7f851d2cb9829e8217cd6841a6831e2643ecbfa5b1fab9dcfc3e3ad0e70f8ef8 +size 40558 diff --git a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_5_en.png index 43f7609ad9..d7dddd9f25 100644 --- a/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.startchat.impl.root_StartChatView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bfd632991fa9e332a9197a25ed4e1a43ccd1624096601425d4fe1799ba0f81c8 -size 28222 +oid sha256:6b9e258147897ea127ee00473c5d60f881985519b15a8ecb52a300a66651374b +size 28308 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en.png index c4953b4c85..46343e3a6f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bdca6338a1a730fcb3177220bc739d6e528169fc5287136cdaff320d15a4b973 -size 33506 +oid sha256:f156d3940bfd60b6edb2445f4a57b69a203c33375817ce38f9bcc6bcde0fa46e +size 32141 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en.png index 83816f92c1..960c3f7758 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:05537901af85652cb107574ff58f288f77da0187300c64be26f916e80f555b24 -size 7484 +oid sha256:4e3209a390865cade44def398116bdb1149f23fd2b716ce3f1a3aa00e603a147 +size 11715 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en.png index feede5b4b2..8b30d765ed 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:34b2560572a5f5e73b214852266b2564fb4b9dec0f772d69e49b3faac15794ce -size 23700 +oid sha256:13b2d8af57efa72eda91df6ea9c6648fb2fba0160de5cfecdbe0eafeb9125302 +size 43657 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en.png index 37132539bb..1ccfcd86ca 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f47bc964a03cd58dfa956ebf3c6f00f52ade114e58af3de41ebb2759fae50ec -size 9073 +oid sha256:459357b401eea08435011256f067174527e256b5cbf20787ba9e16b747ced48b +size 14606 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en.png index afba740f62..0ab7ea4f2f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:488b8a97fefa7b756c401bcea298fbe6c5320745b87a1890f8701e9fdc59e16d -size 6837 +oid sha256:f9accbad68c93b7de73bdb7452360efc721b35af49835864661b0e481355afaa +size 10005 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en.png index b03fa02885..b5f456f9aa 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a9bad17542efddc6c24ffc390ab5336bb31ee7d50921f6c604464af084b5250 -size 7150 +oid sha256:d22efa94c41ea6fefc87634aa3d576f80c90057c37a1f99bf69a6e0b35685707 +size 10666 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarInactive_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarInactive_Search_views_en.png index 82fadc5a8c..1d9f68e2a3 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarInactive_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarInactive_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bef9250dd682af6ff5b2e65f15367b038526db0a5d93afdd8d67b9fa5fb0aeef -size 13002 +oid sha256:3b681cf0d6af2ee5fbc4851f70c84f61a41fc07092eb7c85cf8a7a64284fd30c +size 13108 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_Sliders_Sliders_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_Sliders_Sliders_en.png index 868a0e24a7..88a8298dfe 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_Sliders_Sliders_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_Sliders_Sliders_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb1f983126179c04a73876c58642108f90a88fe628f21e14d309c0caade12ad0 -size 14109 +oid sha256:67e1704236a59267acdcd3b4882c01ea2eb251ce1f4f4a9e7d3aedbbd96f5fa9 +size 14112 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_0_en.png index 77a250e489..f6706eae10 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b6cac7bbbb14cc9d75e3f8180b4a4d34e9365714ca6d3dfe15fab8d738107b01 -size 13167 +oid sha256:84d3dd594c06c53ead7c6cad57f9d56fcb057f808aa1ce7a44647ac2de7eac0b +size 13178 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_1_en.png index 27fa3a5062..78526680e6 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:239a3ad7218ce5117a1a158510cd3d474d8e17971e77f887358d9ee0a602801f -size 11071 +oid sha256:dfacf0be8e017585a63cd3aeb2f6ce3acd9195265404a2cc6ee420dfe60a486a +size 11079 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_2_en.png index d16a74d850..250d8edc07 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4aefb55765326a372413c9116251c9d3b9c79b3dc08e0fb89113db71c9680e55 -size 31167 +oid sha256:823507454e39c241cde2ce6918a178bd96c3fe6f179d11005d7c92dcf6f306a6 +size 31187 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_3_en.png index 9f7d11fab4..e97d05a8b7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1401bc94a37b803bc6eb3111d983cfc6794cef10dbd2531ddf71aa26e1e75ff0 -size 29410 +oid sha256:de592becf90c553388ded840d09775a5817fb785ee91ab15f88776cb9299978d +size 29403 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_4_en.png index 878dca81a4..234909bb90 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0f4637434aace49f39cee3f4826cf7c8d3837e6a557d4f2c88755b57a0f81bf +oid sha256:bd72ff98b667a2693afdaaf0dcf583efee7f4f772a7db1576fc9344c3b0e8610 size 33773 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_5_en.png index 986a006347..73452063d9 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a02cc5f5e8c430dafab0eaaee7dec6f057793e7c965d80845ea1d30d3204953f -size 28851 +oid sha256:c3b0333a9fe1ecfd2db961cbcab70959252d25db3b3bb5433364d4e52ebb62f1 +size 28871 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_0_en.png index 98e26b4644..f612f0a3b2 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:197113e80e6c4f918400bb0088da9b09d67240726341a691e3a114077777c856 -size 12563 +oid sha256:6df05997df8049e9a6e2b8607cfbdb27e24d5bdf1515a4d4bde4943ccd8bc37b +size 12593 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_1_en.png index 821df0eb16..a86ad92906 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c099419a45d24298bb52ecf48f04ce8cff117fb2dee4be2f650704663b6432a -size 10817 +oid sha256:59aa2b4def89d50b3ef509d2eeb45c02924073b1d141da218c7381365086432c +size 10843 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_2_en.png index c9c6162ff8..146018e289 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b1d38c3fd31bcb741b2f9df0370d32a77987b884880cf6bb675cca94d3e8d20 -size 30424 +oid sha256:a04d96eb2d9186b49f44f2ce6c12f170567d7cbe4983441404d9a3edffe2721d +size 30460 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_3_en.png index 359cf2e995..5cdee95ac4 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:781d1c293cb0e42beef278a2bbcfc25529fbeffa4e589df117832f5a6731458c -size 28954 +oid sha256:476f7104e9115c37b30c72e2697ac6418f405c14b6352cb9987aaba60bb03f93 +size 28982 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_4_en.png index 7c25e4e36a..a9d01df8b3 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dbd681b53702e6ec59f55db0a0697670b9646789fa73c2ca29cb7d7210572f4f -size 33306 +oid sha256:e9b41aec852e53187d209837ce593a33a52df9a6a315722c33b9ecfb3ab3b850 +size 33337 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_5_en.png index fe96f8cbb5..6e8ceaba0f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:294693fcfaab59474b8be0dc96d86fa9a86b85854892b7fa71f2c4fbd325b570 -size 28069 +oid sha256:7bdb980672962a528ff01458bc60bdb708861e9723278248ddc4ec59aa15c6eb +size 28104 From 90d71f5e66f7825061a8b9d448df426e805cad8b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Dec 2025 10:36:23 +0100 Subject: [PATCH 159/347] Fix issue detected by lint. --- .../messages/impl/pinned/list/PinnedMessagesListNode.kt | 6 ++++-- .../android/features/messages/impl/timeline/TimelineView.kt | 5 +++-- .../android/features/roomdetails/impl/RoomDetailsView.kt | 5 +++-- .../securebackup/impl/setup/SecureBackupSetupView.kt | 5 +++-- .../android/features/viewfolder/impl/file/FileContent.kt | 3 ++- .../android/libraries/matrix/ui/model/InviteSender.kt | 3 +-- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListNode.kt index 57af770d5b..292a77ba6a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListNode.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.res.stringResource import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin @@ -100,6 +101,7 @@ class PinnedMessagesListNode( LocalTimelineItemPresenterFactories provides timelineItemPresenterFactories, ) { val context = LocalContext.current + val toastMessage = stringResource(CommonStrings.common_copied_to_clipboard) val view = LocalView.current val state = presenter.present() PinnedMessagesListView( @@ -113,8 +115,8 @@ class PinnedMessagesListNode( HapticFeedbackConstants.LONG_PRESS ) context.copyToClipboard( - it.url, - context.getString(CommonStrings.common_copied_to_clipboard) + text = it.url, + toastMessage = toastMessage, ) }, modifier = modifier 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 b3f69f0e2b..73a15b797f 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 @@ -123,6 +123,7 @@ fun TimelineView( } val context = LocalContext.current + val toastMessage = stringResource(CommonStrings.common_copied_to_clipboard) val view = LocalView.current // Disable reverse layout when TalkBack is enabled to avoid incorrect ordering issues seen in the current Compose UI version val useReverseLayout = !isTalkbackActive() @@ -136,8 +137,8 @@ fun TimelineView( HapticFeedbackConstants.LONG_PRESS ) context.copyToClipboard( - link.url, - context.getString(CommonStrings.common_copied_to_clipboard) + text = link.url, + toastMessage = toastMessage, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index de0a2cba1b..046c64d906 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -721,6 +721,7 @@ private fun DebugInfoSection( ) { val context = LocalContext.current PreferenceCategory(showTopDivider = true) { + val toastMessage = stringResource(CommonStrings.common_copied_to_clipboard) ListItem( headlineContent = { Text("Internal room ID") @@ -736,8 +737,8 @@ private fun DebugInfoSection( trailingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Copy())), onClick = { context.copyToClipboard( - roomId.value, - context.getString(CommonStrings.common_copied_to_clipboard) + text = roomId.value, + toastMessage = toastMessage, ) }, ) diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/SecureBackupSetupView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/SecureBackupSetupView.kt index 8a87fc8983..497c64f072 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/SecureBackupSetupView.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/SecureBackupSetupView.kt @@ -116,11 +116,12 @@ private fun Content( ) { val context = LocalContext.current val formattedRecoveryKey = state.recoveryKeyViewState.formattedRecoveryKey + val toastMessage = stringResource(R.string.screen_recovery_key_copied_to_clipboard) val clickLambda = if (formattedRecoveryKey != null) { { context.copyToClipboard( - formattedRecoveryKey, - context.getString(R.string.screen_recovery_key_copied_to_clipboard) + text = formattedRecoveryKey, + toastMessage = toastMessage, ) state.eventSink.invoke(SecureBackupSetupEvents.RecoveryKeyHasBeenSaved) } diff --git a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/FileContent.kt b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/FileContent.kt index 614e45a7b8..c68d630869 100644 --- a/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/FileContent.kt +++ b/features/viewfolder/impl/src/main/kotlin/io/element/android/features/viewfolder/impl/file/FileContent.kt @@ -73,13 +73,14 @@ private fun LineRow( colorationMode: ColorationMode, ) { val context = LocalContext.current + val toastMessage = stringResource(CommonStrings.common_line_copied_to_clipboard) Row( modifier = Modifier .fillMaxWidth() .clickable(onClick = { context.copyToClipboard( text = line, - toastMessage = context.getString(CommonStrings.common_line_copied_to_clipboard), + toastMessage = toastMessage, ) }) ) { diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/InviteSender.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/InviteSender.kt index 34e95f63dc..dd8655af26 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/InviteSender.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/InviteSender.kt @@ -9,7 +9,6 @@ package io.element.android.libraries.matrix.ui.model import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.SpanStyle @@ -30,7 +29,7 @@ data class InviteSender( @Composable fun annotatedString(): AnnotatedString { return stringResource(R.string.screen_invites_invited_you, displayName, userId.value).let { text -> - val senderNameStart = LocalContext.current.getString(R.string.screen_invites_invited_you).indexOf("%1\$s") + val senderNameStart = stringResource(R.string.screen_invites_invited_you).indexOf($$"%1$s") AnnotatedString( text = text, spanStyles = listOf( From 538a309a1a9d35728b63aa21c4e84ecbef4310b9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Dec 2025 11:59:16 +0100 Subject: [PATCH 160/347] Import Compound tokens from release v6.4.3 https://github.com/element-hq/compound-design-tokens/releases/tag/v6.4.3 --- .../tokens/generated/CompoundIcons.kt | 20 +++++++++++++++++++ .../res/drawable/ic_compound_backspace.xml | 13 ++++++++++++ .../drawable/ic_compound_backspace_solid.xml | 9 +++++++++ .../drawable/ic_compound_left_panel_open.xml | 9 +++++++++ .../main/res/drawable/ic_compound_sticker.xml | 10 ++++++++++ 5 files changed, 61 insertions(+) create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_backspace.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_backspace_solid.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_left_panel_open.xml create mode 100644 libraries/compound/src/main/res/drawable/ic_compound_sticker.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 2f634b529e..6c30eda7f9 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 @@ -52,6 +52,12 @@ object CompoundIcons { @Composable fun Audio(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_audio) } + @Composable fun Backspace(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_backspace) + } + @Composable fun BackspaceSolid(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_backspace_solid) + } @Composable fun Block(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_block) } @@ -301,6 +307,9 @@ object CompoundIcons { @Composable fun LeftPanelClose(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_left_panel_close) } + @Composable fun LeftPanelOpen(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_left_panel_open) + } @Composable fun Link(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_link) } @@ -523,6 +532,9 @@ object CompoundIcons { @Composable fun SpotlightView(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_spotlight_view) } + @Composable fun Sticker(): ImageVector { + return ImageVector.vectorResource(R.drawable.ic_compound_sticker) + } @Composable fun Strikethrough(): ImageVector { return ImageVector.vectorResource(R.drawable.ic_compound_strikethrough) } @@ -643,6 +655,8 @@ object CompoundIcons { AskToJoinSolid(), Attachment(), Audio(), + Backspace(), + BackspaceSolid(), Block(), Bold(), Calendar(), @@ -726,6 +740,7 @@ object CompoundIcons { Labs(), Leave(), LeftPanelClose(), + LeftPanelOpen(), Link(), Linux(), ListBulleted(), @@ -800,6 +815,7 @@ object CompoundIcons { Spinner(), Spotlight(), SpotlightView(), + Sticker(), Strikethrough(), SwitchCameraSolid(), TakePhoto(), @@ -849,6 +865,8 @@ object CompoundIcons { R.drawable.ic_compound_ask_to_join_solid, R.drawable.ic_compound_attachment, R.drawable.ic_compound_audio, + R.drawable.ic_compound_backspace, + R.drawable.ic_compound_backspace_solid, R.drawable.ic_compound_block, R.drawable.ic_compound_bold, R.drawable.ic_compound_calendar, @@ -932,6 +950,7 @@ object CompoundIcons { R.drawable.ic_compound_labs, R.drawable.ic_compound_leave, R.drawable.ic_compound_left_panel_close, + R.drawable.ic_compound_left_panel_open, R.drawable.ic_compound_link, R.drawable.ic_compound_linux, R.drawable.ic_compound_list_bulleted, @@ -1006,6 +1025,7 @@ object CompoundIcons { R.drawable.ic_compound_spinner, R.drawable.ic_compound_spotlight, R.drawable.ic_compound_spotlight_view, + R.drawable.ic_compound_sticker, R.drawable.ic_compound_strikethrough, R.drawable.ic_compound_switch_camera_solid, R.drawable.ic_compound_take_photo, diff --git a/libraries/compound/src/main/res/drawable/ic_compound_backspace.xml b/libraries/compound/src/main/res/drawable/ic_compound_backspace.xml new file mode 100644 index 0000000000..1f0ce988e4 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_backspace.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_backspace_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_backspace_solid.xml new file mode 100644 index 0000000000..9226bb8c7e --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_backspace_solid.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_left_panel_open.xml b/libraries/compound/src/main/res/drawable/ic_compound_left_panel_open.xml new file mode 100644 index 0000000000..78c21c0625 --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_left_panel_open.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/compound/src/main/res/drawable/ic_compound_sticker.xml b/libraries/compound/src/main/res/drawable/ic_compound_sticker.xml new file mode 100644 index 0000000000..c68fd65d7d --- /dev/null +++ b/libraries/compound/src/main/res/drawable/ic_compound_sticker.xml @@ -0,0 +1,10 @@ + + + From 095801af892fa73b5a53c4ea7dae367aaad0f589 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Dec 2025 12:03:04 +0100 Subject: [PATCH 161/347] Icon Backspace and BackspaceSolid must be auto-mirrored. --- .../compound/src/main/res/drawable/ic_compound_backspace.xml | 1 + .../src/main/res/drawable/ic_compound_backspace_solid.xml | 1 + tools/compound/addAutoMirrored.py | 2 ++ 3 files changed, 4 insertions(+) diff --git a/libraries/compound/src/main/res/drawable/ic_compound_backspace.xml b/libraries/compound/src/main/res/drawable/ic_compound_backspace.xml index 1f0ce988e4..90464cb595 100644 --- a/libraries/compound/src/main/res/drawable/ic_compound_backspace.xml +++ b/libraries/compound/src/main/res/drawable/ic_compound_backspace.xml @@ -1,6 +1,7 @@ diff --git a/libraries/compound/src/main/res/drawable/ic_compound_backspace_solid.xml b/libraries/compound/src/main/res/drawable/ic_compound_backspace_solid.xml index 9226bb8c7e..27d5805811 100644 --- a/libraries/compound/src/main/res/drawable/ic_compound_backspace_solid.xml +++ b/libraries/compound/src/main/res/drawable/ic_compound_backspace_solid.xml @@ -1,6 +1,7 @@ Date: Wed, 17 Dec 2025 12:07:23 +0100 Subject: [PATCH 162/347] Use BackspaceSolid Icon from Compound --- .../features/lockscreen/impl/unlock/keypad/PinKeypad.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/keypad/PinKeypad.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/keypad/PinKeypad.kt index 2131853e3e..093ad2f2b4 100644 --- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/keypad/PinKeypad.kt +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/keypad/PinKeypad.kt @@ -21,8 +21,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.Backspace import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -40,6 +38,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.times import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.text.toSp @@ -206,7 +205,8 @@ private fun PinKeypadBackButton( onClick = onClick, ) { Icon( - imageVector = Icons.AutoMirrored.Filled.Backspace, + modifier = Modifier.size(28.dp), + imageVector = CompoundIcons.BackspaceSolid(), contentDescription = stringResource(CommonStrings.a11y_delete), ) } From 9e23d9f451db68291e7d8372d66a824c162f8fd7 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 17 Dec 2025 11:26:22 +0000 Subject: [PATCH 163/347] 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 ++-- .../compound/screenshots/Compound Vector Icons - Dark.png | 4 ++-- .../compound/screenshots/Compound Vector Icons - Light.png | 4 ++-- ...tures.lockscreen.impl.unlock.keypad_PinKeypad_Day_0_en.png | 4 ++-- ...res.lockscreen.impl.unlock.keypad_PinKeypad_Night_0_en.png | 4 ++-- ...features.lockscreen.impl.unlock_PinUnlockView_Day_0_en.png | 4 ++-- ...features.lockscreen.impl.unlock_PinUnlockView_Day_1_en.png | 4 ++-- ...features.lockscreen.impl.unlock_PinUnlockView_Day_2_en.png | 4 ++-- ...features.lockscreen.impl.unlock_PinUnlockView_Day_3_en.png | 4 ++-- ...features.lockscreen.impl.unlock_PinUnlockView_Day_4_en.png | 4 ++-- ...features.lockscreen.impl.unlock_PinUnlockView_Day_5_en.png | 4 ++-- ...features.lockscreen.impl.unlock_PinUnlockView_Day_6_en.png | 4 ++-- ...features.lockscreen.impl.unlock_PinUnlockView_Day_7_en.png | 4 ++-- ...atures.lockscreen.impl.unlock_PinUnlockView_Night_0_en.png | 4 ++-- ...atures.lockscreen.impl.unlock_PinUnlockView_Night_1_en.png | 4 ++-- ...atures.lockscreen.impl.unlock_PinUnlockView_Night_2_en.png | 4 ++-- ...atures.lockscreen.impl.unlock_PinUnlockView_Night_3_en.png | 4 ++-- ...atures.lockscreen.impl.unlock_PinUnlockView_Night_4_en.png | 4 ++-- ...atures.lockscreen.impl.unlock_PinUnlockView_Night_5_en.png | 4 ++-- ...atures.lockscreen.impl.unlock_PinUnlockView_Night_6_en.png | 4 ++-- ...atures.lockscreen.impl.unlock_PinUnlockView_Night_7_en.png | 4 ++-- ...raries.designsystem.theme.components_AllIcons_Icons_en.png | 4 ++-- 24 files changed, 48 insertions(+), 48 deletions(-) diff --git a/libraries/compound/screenshots/Compound Icons - Dark.png b/libraries/compound/screenshots/Compound Icons - Dark.png index d3fb6dc294..c0d816a6b9 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:fc758c149db501d0ac5eb235cca1d63b67230aae40356e7ccca4c9d481a9ce17 -size 216981 +oid sha256:fa16f659aa3e7d05fa03a51d52faddc0c40c3ab52231687f8c6c8a4ba81ff6f0 +size 219813 diff --git a/libraries/compound/screenshots/Compound Icons - Light.png b/libraries/compound/screenshots/Compound Icons - Light.png index a6728d0947..fd105971e0 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:db230bfe3d51527959d2a4f7c64a8cc79209dcfb752f077f84c0f5058d94f0bd -size 228829 +oid sha256:72fb457dc50bf1a2261502fc1da15c01ab415344e9070354d38dc7b74234d790 +size 232095 diff --git a/libraries/compound/screenshots/Compound Icons - Rtl.png b/libraries/compound/screenshots/Compound Icons - Rtl.png index c3f0b5fb8c..50c98caee5 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:4c6cd3ad1978c6f4e07d62b1edd08c5f32b3c498934d25af43932c50ef309fe0 -size 230519 +oid sha256:24cfe760717881ee71f36fae1fb201e74b2c32a2f9a5aef71ef21dab69ea5366 +size 233212 diff --git a/libraries/compound/screenshots/Compound Vector Icons - Dark.png b/libraries/compound/screenshots/Compound Vector Icons - Dark.png index 290f09480a..638e4a5cba 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:1d4f46c82f1504a983885a7d177900cd6d6f7729dce6851520cd7e471870ad2d -size 84955 +oid sha256:a699170cabca6fb912d034a588b45961485afe6ef6d2c24f0ab79f10ae00c168 +size 85629 diff --git a/libraries/compound/screenshots/Compound Vector Icons - Light.png b/libraries/compound/screenshots/Compound Vector Icons - Light.png index 01cee66ad7..d60a3fdadb 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:e2c1a78a88fad99c1fd9bc29d802ee8c2bdefec89626cd700c73f4909738aeb5 -size 91022 +oid sha256:dd4b2a40fcf02d6db29cb0bc371d93236b4a0be6d4446bab86358692cddb53f5 +size 91692 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock.keypad_PinKeypad_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock.keypad_PinKeypad_Day_0_en.png index 21f8cfe6db..01603dc202 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock.keypad_PinKeypad_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock.keypad_PinKeypad_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:24ebbb52fb801813c07dc602f95917d8d7a386e019526c4e32c22ded17ae5f1c -size 27992 +oid sha256:3e041bd0f0506fbf4abfeb18fcbd9f84bdd0004d56ebb679e4c7606a6af5a253 +size 28009 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock.keypad_PinKeypad_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock.keypad_PinKeypad_Night_0_en.png index db5097080b..c4c2b61d59 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock.keypad_PinKeypad_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock.keypad_PinKeypad_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cac52c4f2ff9e5c35cc527a6e1dfaaa38ba724747f3eeb25b401ea857dc2e17 -size 26854 +oid sha256:cc2f12e5f13d92c2188c687c67be0dea1fb04420ade868674e2a75e93a664dd0 +size 26877 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_0_en.png index da67d1e708..592621be6f 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5d6f0ad82c8b790bce7044b61f70cade02a90d96a3cf0b70fc42461d78cdada -size 36052 +oid sha256:8f57aec639b101e318a50fbed53787ddeecaa36f132d45fccd815d8e44db2a17 +size 36120 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_1_en.png index 754ce31556..d35f9868d6 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d901fb7ed307f0375b66aeb2bfd10b087e7da54b741116410715957e78693ed2 -size 36456 +oid sha256:3aa45a9733f3b076b28b84675dbc70439c3271b4881eb73ff7ca73e338b2e1cd +size 36529 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_2_en.png index 6d33b0a788..9ece7bf627 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9306676d3b7cda6cd5633703d43cd7d676debd133df55e5f9b367cf483cca6d6 -size 37377 +oid sha256:8d84f2ab82c4fc7e32a039cbdee38de33188afe0381ed02eb9facd8a5c6e3fe5 +size 37448 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_3_en.png index 6b470e59b3..93fc3a9d4e 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d72404ba8feabc3136da770f3bb6089f3fb5491b9aa1c5430b3fe222582041ee -size 40727 +oid sha256:9d68eaab539ae2c98599808a22c6448f388bebb95e7f2b8130d77247e07ac6fc +size 40774 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_4_en.png index d68200d41e..6a79292cbb 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fc66e46453be2527b13576c0c823de41a577dbe25d9c5c3ceae7129fc38a27ff -size 33750 +oid sha256:d44c3ebbdebf8303f324f687ac667037033bd305294afe56d86094acf8d04467 +size 33817 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_5_en.png index b46d416460..1a0f15f598 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:501929bec8cb96c367c6d4e39b635accd010df8d51d8b5b811c393ba88e055f0 -size 38013 +oid sha256:971856e46c73fba7f667a3a5e3a11296d8468cd0fab1b011f14d9e63d7416689 +size 38058 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_6_en.png index d3a76fe71a..9e6a4d8ddc 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:148eac0a83edaf736bcc5bfd2ad6c49d2658460a0a0e233f6aec86db0ed576b4 -size 30198 +oid sha256:6eaab5049e84445db1e187558263279f55a51cd132b17a28adfaa81e9d6b1049 +size 30243 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_7_en.png index 8549995133..9bda9734ee 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ab36754fbbf897c817f5a38e98548492194f91aab482684f907451543ff5bff -size 30357 +oid sha256:0eafbb6bb63c629fb74cc26219d51dc7221935d0a0abc7a106bc63d248456427 +size 30401 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_0_en.png index 97abac1ae5..17d6639d45 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:730a61f81f4f2e1b9f3bd1767d8e7a4e6dd05453ff58ec895938df8270a3288a -size 34840 +oid sha256:d511220a0034d6ac1eacd16500170e380f4158dca76224814f042fed60cc5b4a +size 34878 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_1_en.png index ee1b1bf6d2..5b90bf360b 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5967fca9544fe9fd0db9c8837a1c4e4a819837b87c6ea21f9d79b337a8dc02e9 -size 35229 +oid sha256:ad01f3bc714511d54bc0110cac4bb069a6c5d2c4328976981bbe473f3dd30146 +size 35268 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_2_en.png index ed96d41781..f3d0be5deb 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:801536182916e33a93d8e2da80b4dbe5cdeeacd772f358796bfc6070d0137910 -size 36013 +oid sha256:dba083c2aecd51cd697e71feb812411ca5f818931a7977a49ff6e2e348ad6b31 +size 36050 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_3_en.png index de62234d4a..ed70a90127 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c86cc2691774d836e029bcfdd080c6db002aeb4c544cc9426755dd7670e8133 -size 37630 +oid sha256:3ad40bf331b6039ee7a9214bf95628898c590ecb655d7e4695f84d49ec3756ea +size 37675 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_4_en.png index f312909ce2..1d6978def6 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e80eb2fb94a97a947e2d83b1cd11bdd76c32c2266a382233f10911a00e456374 -size 32649 +oid sha256:d0cb1f24daf8204ee0e4168b7adbafdfd5ea005ce9e1381e3951c86c2d6803f9 +size 32689 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_5_en.png index 508eb4f752..aa0038e291 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbe5723853d3d495f54c33bfd63403a8ca76b76a44edec4cd135218462721567 -size 35178 +oid sha256:1c8f6a181d08773e96a500b979cfe6510b6522c1f1258d03d8e259ea638a1305 +size 35222 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_6_en.png index a56b58b7d3..6694b535c5 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee14cfd4edcdfd4aca7e455a1179549b2c7bf17d5686bc22d7e1fad049d21883 -size 27614 +oid sha256:1f28a59217041e6078c910ed3da4f21987dedd04c958acc666cba37682a4b5bc +size 27662 diff --git a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_7_en.png index a72b27ccd4..a62fcc0aaa 100644 --- a/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.lockscreen.impl.unlock_PinUnlockView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44fd8f19fd371f3c8127fd85eed867b73b234f32ce94b777b38dd04b29e97682 -size 27494 +oid sha256:267b09143f52c5fca826d87b969a1f10756e757d134bced4aeef25725bfadbcb +size 27552 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 f6d53a9aaa..27ebcf92ac 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:22f7a2f98e8a7deaacaaeb75233cf1cb006c79c8e108b3c000190ac7ab006083 -size 103743 +oid sha256:813b2ee132d7de92e384b185dea13b366a6760095e03c52a9f127bc21402c383 +size 105960 From 4ad568ecd6156459b5e18eae14f9e3145a03104e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 14:27:39 +0100 Subject: [PATCH 164/347] Update lifecycle to v2.10.0 (#5240) 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 ac59b8d913..c4121c7f9a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ core = "1.17.0" datastore = "1.2.0" constraintlayout = "2.2.1" constraintlayout_compose = "1.1.1" -lifecycle = "2.9.2" +lifecycle = "2.10.0" activity = "1.11.0" media3 = "1.8.0" camera = "1.5.2" From 5c4d11c21f0924030fb7a5676e1919efcd5cefcc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 14:39:10 +0100 Subject: [PATCH 165/347] fix(deps): update dependency io.nlopez.compose.rules:detekt to v0.5.2 (#5911) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4d657a5c72..03f5eb91a3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,7 +46,7 @@ allprojects { config.from(files("$rootDir/tools/detekt/detekt.yml")) } dependencies { - detektPlugins("io.nlopez.compose.rules:detekt:0.5.1") + detektPlugins("io.nlopez.compose.rules:detekt:0.5.2") detektPlugins(project(":tests:detekt-rules")) } From 0e6a0c7f2fcc53fcd8f960296ccc92bcaac27591 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Dec 2025 15:05:11 +0100 Subject: [PATCH 166/347] Fix how we compute screenshot files. `AttachmentsPreviewViewPreview` was wrongly converted to `AttachmentsView` instead of `AttachmentsPreviewView` --- tests/uitests/src/test/kotlin/base/ScreenshotTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/uitests/src/test/kotlin/base/ScreenshotTest.kt b/tests/uitests/src/test/kotlin/base/ScreenshotTest.kt index 5296060b63..0b088b5de0 100644 --- a/tests/uitests/src/test/kotlin/base/ScreenshotTest.kt +++ b/tests/uitests/src/test/kotlin/base/ScreenshotTest.kt @@ -83,7 +83,7 @@ private fun Paparazzi.fixScreenshotName(preview: ComposablePreview Date: Wed, 17 Dec 2025 14:12:42 +0000 Subject: [PATCH 167/347] fix(deps): update kotlin (#5417) * fix(deps): update kotlin * No need for compat. --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Benoit Marty --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c4121c7f9a..2a9c86e3f6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ android_gradle_plugin = "8.13.2" # When updateing this, please also update the version in the file ./idea/kotlinc.xml kotlin = "2.2.20" kotlinpoet = "2.2.0" -ksp = "2.2.20-2.0.2" +ksp = "2.2.20-2.0.4" firebaseAppDistribution = "5.2.0" # AndroidX @@ -62,7 +62,7 @@ detekt = "1.23.8" # See https://github.com/pinterest/ktlint/releases/ ktlint = "1.8.0" androidx-test-ext-junit = "1.3.0" -kover = "0.9.1" +kover = "0.9.2" [libraries] # Project From 1f7c6c86d248a7864cfb2d8ea5f69b630a130d10 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 17 Dec 2025 14:21:11 +0000 Subject: [PATCH 168/347] Update screenshots --- ...ages.impl.attachments.preview_AttachmentsPreviewView_0_en.png} | 0 ...ages.impl.attachments.preview_AttachmentsPreviewView_1_en.png} | 0 ...ages.impl.attachments.preview_AttachmentsPreviewView_2_en.png} | 0 ...ages.impl.attachments.preview_AttachmentsPreviewView_3_en.png} | 0 ...ages.impl.attachments.preview_AttachmentsPreviewView_4_en.png} | 0 ...ages.impl.attachments.preview_AttachmentsPreviewView_5_en.png} | 0 ...ages.impl.attachments.preview_AttachmentsPreviewView_6_en.png} | 0 ...ages.impl.attachments.preview_AttachmentsPreviewView_7_en.png} | 0 ...ages.impl.attachments.preview_AttachmentsPreviewView_8_en.png} | 0 ...ries.textcomposer.components_VoiceMessagePreview_Day_0_en.png} | 0 ...es.textcomposer.components_VoiceMessagePreview_Night_0_en.png} | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename tests/uitests/src/test/snapshots/images/{features.messages.impl.attachments.preview_AttachmentsView_0_en.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.messages.impl.attachments.preview_AttachmentsView_1_en.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.messages.impl.attachments.preview_AttachmentsView_2_en.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.messages.impl.attachments.preview_AttachmentsView_3_en.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.messages.impl.attachments.preview_AttachmentsView_4_en.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.messages.impl.attachments.preview_AttachmentsView_5_en.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.messages.impl.attachments.preview_AttachmentsView_6_en.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.messages.impl.attachments.preview_AttachmentsView_7_en.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.messages.impl.attachments.preview_AttachmentsView_8_en.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.textcomposer.components_VoiceMessage_Day_0_en.png => libraries.textcomposer.components_VoiceMessagePreview_Day_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.textcomposer.components_VoiceMessage_Night_0_en.png => libraries.textcomposer.components_VoiceMessagePreview_Night_0_en.png} (100%) diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_0_en.png rename to tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_1_en.png rename to tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png rename to tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png rename to tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_4_en.png rename to tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_5_en.png rename to tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_6_en.png rename to tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_7_en.png rename to tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_8_en.png rename to tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessage_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessagePreview_Day_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessage_Day_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessagePreview_Day_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessage_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessagePreview_Night_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessage_Night_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessagePreview_Night_0_en.png From 24e1514fc3903a68de5aae6519f4a0ca81b86ef5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 15:39:18 +0100 Subject: [PATCH 169/347] fix(deps): update activity to v1.12.1 (#5770) 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 2a9c86e3f6..55a24ebe33 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,7 +16,7 @@ datastore = "1.2.0" constraintlayout = "2.2.1" constraintlayout_compose = "1.1.1" lifecycle = "2.10.0" -activity = "1.11.0" +activity = "1.12.1" media3 = "1.8.0" camera = "1.5.2" work = "2.11.0" From 10b85ec1ffcbdc3f8ca3b610b5d740aeec3d1647 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 15:08:41 +0000 Subject: [PATCH 170/347] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.12.17 (#5912) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.12.17 * Fix changes in the SDK: `LatestEventValue.Local` doesn't have an `isSending` property anymore, now it has `state: LatestEventValueLocalState`. If this is `HAS_BEEN_SENT`, it's equivalent to a `LatestEventValue.Remote`, we just haven't received the updated value from the SDK yet. --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jorge Martín --- gradle/libs.versions.toml | 2 +- .../impl/roomlist/RoomSummaryFactory.kt | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 55a24ebe33..71c25351ae 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -177,7 +177,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.10" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.17" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt index 4872dc48e8..738c1f72ea 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt @@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.impl.timeline.item.event.TimelineEven import io.element.android.libraries.matrix.impl.timeline.item.event.map import org.matrix.rustcomponents.sdk.Room import org.matrix.rustcomponents.sdk.use +import uniffi.matrix_sdk_ui.LatestEventValueLocalState import org.matrix.rustcomponents.sdk.LatestEventValue as RustLatestEventValue class RoomSummaryFactory( @@ -27,13 +28,24 @@ class RoomSummaryFactory( val latestEvent = room.latestEvent().use { event -> when (event) { is RustLatestEventValue.None -> LatestEventValue.None - is RustLatestEventValue.Local -> LatestEventValue.Local( - timestamp = event.timestamp.toLong(), - content = contentMapper.map(event.content), - isSending = event.isSending, - senderId = UserId(event.sender), - senderProfile = event.profile.map(), - ) + is RustLatestEventValue.Local -> when (event.state) { + LatestEventValueLocalState.IS_SENDING, + LatestEventValueLocalState.CANNOT_BE_SENT -> LatestEventValue.Local( + timestamp = event.timestamp.toLong(), + content = contentMapper.map(event.content), + isSending = event.state == LatestEventValueLocalState.IS_SENDING, + senderId = UserId(event.sender), + senderProfile = event.profile.map(), + ) + // This is the same as a remote event, we just haven't received the local -> remote update yet + LatestEventValueLocalState.HAS_BEEN_SENT -> LatestEventValue.Remote( + timestamp = event.timestamp.toLong(), + content = contentMapper.map(event.content), + senderId = UserId(event.sender), + senderProfile = event.profile.map(), + isOwn = true, + ) + } is RustLatestEventValue.Remote -> LatestEventValue.Remote( timestamp = event.timestamp.toLong(), content = contentMapper.map(event.content), From e953ff31374a1fc50433d3417d27fc884329c2d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 16:40:17 +0100 Subject: [PATCH 171/347] fix(deps): update dependency io.sentry:sentry-android to v8.29.0 (#5918) 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 71c25351ae..f4c7aef92b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -217,7 +217,7 @@ color_picker = "io.mhssn:colorpicker:1.0.0" # Analytics posthog = "com.posthog:posthog-android:3.26.0" -sentry = "io.sentry:sentry-android:8.28.0" +sentry = "io.sentry:sentry-android:8.29.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.29.2" From 75022f4018b9ab0e881d5da5ebfbda97dc68c3f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 16:41:13 +0100 Subject: [PATCH 172/347] fix(deps): update dependency com.google.firebase:firebase-bom to v34.7.0 (#5915) 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 f4c7aef92b..83692039d7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -78,7 +78,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.6.0" +google_firebase_bom = "com.google.firebase:firebase-bom:34.7.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 690182ab90ff663418ffe02152c8921a29478573 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 15:43:02 +0000 Subject: [PATCH 173/347] fix(deps): update wysiwyg to v2.41.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 f4c7aef92b..b735e46843 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -44,7 +44,7 @@ coil = "3.3.0" showkase = "1.0.5" appyx = "1.7.1" sqldelight = "2.2.1" -wysiwyg = "2.40.0" +wysiwyg = "2.41.0" telephoto = "0.18.0" haze = "1.6.10" From 2ca981ddfa6f3bf426e76be1ec8bf6d6f96a74d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 17 Dec 2025 18:38:02 +0100 Subject: [PATCH 174/347] Reuse already parsed document instead of parsing it again --- .../TimelineItemContentMessageFactory.kt | 81 ++++++++++--------- .../TimelineItemContentMessageFactoryTest.kt | 8 +- .../timeline/FakeHtmlConverterProvider.kt | 6 ++ libraries/matrixui/build.gradle.kts | 2 +- .../matrix/ui/messages/ToHtmlDocument.kt | 6 +- 5 files changed, 59 insertions(+), 44 deletions(-) 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 a3c8a1bb26..3d8467729a 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 @@ -9,7 +9,6 @@ package io.element.android.features.messages.impl.timeline.factories.event import android.text.style.URLSpan -import androidx.core.text.buildSpannedString import androidx.core.text.getSpans import androidx.core.text.toSpannable import dev.zacsweers.metro.Inject @@ -35,11 +34,9 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkParser 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 -import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType 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.MessageFormat 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.StickerMessageType @@ -50,6 +47,7 @@ import io.element.android.libraries.matrix.ui.messages.toHtmlDocument import io.element.android.libraries.mediaviewer.api.util.FileExtensionExtractor import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList +import org.jsoup.nodes.Document import kotlin.time.Duration @Inject @@ -60,7 +58,7 @@ class TimelineItemContentMessageFactory( private val permalinkParser: PermalinkParser, private val textPillificationHelper: TextPillificationHelper, ) { - suspend fun create( + fun create( content: MessageContent, senderDisambiguatedDisplayName: String, eventId: EventId?, @@ -68,26 +66,29 @@ class TimelineItemContentMessageFactory( return when (val messageType = content.type) { is EmoteMessageType -> { val emoteBody = "* $senderDisambiguatedDisplayName ${messageType.body.trimEnd()}" - val formattedBody = parseHtml(messageType.formatted, prefix = "* $senderDisambiguatedDisplayName") ?: textPillificationHelper.pillify( - emoteBody - ).safeLinkify() + val dom = messageType.formatted?.toHtmlDocument( + permalinkParser = permalinkParser, + prefix = "* $senderDisambiguatedDisplayName", + ) + val formattedBody = dom?.let(::parseHtml) + ?: textPillificationHelper.pillify(emoteBody).safeLinkify() TimelineItemEmoteContent( body = emoteBody, - htmlDocument = messageType.formatted?.toHtmlDocument( - permalinkParser = permalinkParser, - prefix = "* $senderDisambiguatedDisplayName", - ), + htmlDocument = dom, formattedBody = formattedBody, isEdited = content.isEdited, ) } is ImageMessageType -> { + val dom = messageType.formattedCaption?.toHtmlDocument(permalinkParser = permalinkParser) + val formattedCaption = dom?.let(::parseHtml) + ?: messageType.caption?.withLinks() val aspectRatio = aspectRatioOf(messageType.info?.width, messageType.info?.height) TimelineItemImageContent( filename = messageType.filename, fileSize = messageType.info?.size ?: 0, caption = messageType.caption?.trimEnd(), - formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + formattedCaption = formattedCaption, isEdited = content.isEdited, mediaSource = messageType.source, thumbnailSource = messageType.info?.thumbnailSource, @@ -103,12 +104,15 @@ class TimelineItemContentMessageFactory( ) } is StickerMessageType -> { + val dom = messageType.formattedCaption?.toHtmlDocument(permalinkParser = permalinkParser) + val formattedCaption = dom?.let(::parseHtml) + ?: messageType.caption?.withLinks() val aspectRatio = aspectRatioOf(messageType.info?.width, messageType.info?.height) TimelineItemStickerContent( filename = messageType.filename, fileSize = messageType.info?.size ?: 0, caption = messageType.caption?.trimEnd(), - formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + formattedCaption = formattedCaption, isEdited = content.isEdited, mediaSource = messageType.source, thumbnailSource = messageType.info?.thumbnailSource, @@ -140,12 +144,15 @@ class TimelineItemContentMessageFactory( } } is VideoMessageType -> { + val dom = messageType.formattedCaption?.toHtmlDocument(permalinkParser = permalinkParser) + val formattedCaption = dom?.let(::parseHtml) + ?: messageType.caption?.withLinks() val aspectRatio = aspectRatioOf(messageType.info?.width, messageType.info?.height) TimelineItemVideoContent( filename = messageType.filename, fileSize = messageType.info?.size ?: 0, caption = messageType.caption?.trimEnd(), - formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + formattedCaption = formattedCaption, isEdited = content.isEdited, thumbnailSource = messageType.info?.thumbnailSource, mediaSource = messageType.source, @@ -162,11 +169,14 @@ class TimelineItemContentMessageFactory( ) } is AudioMessageType -> { + val dom = messageType.formattedCaption?.toHtmlDocument(permalinkParser = permalinkParser) + val formattedCaption = dom?.let(::parseHtml) + ?: messageType.caption?.withLinks() TimelineItemAudioContent( filename = messageType.filename, fileSize = messageType.info?.size ?: 0, caption = messageType.caption?.trimEnd(), - formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + formattedCaption = formattedCaption, isEdited = content.isEdited, mediaSource = messageType.source, duration = messageType.info?.duration ?: Duration.ZERO, @@ -176,12 +186,15 @@ class TimelineItemContentMessageFactory( ) } is VoiceMessageType -> { + val dom = messageType.formattedCaption?.toHtmlDocument(permalinkParser = permalinkParser) + val formattedCaption = dom?.let(::parseHtml) + ?: messageType.caption?.withLinks() TimelineItemVoiceContent( eventId = eventId, filename = messageType.filename, fileSize = messageType.info?.size ?: 0, caption = messageType.caption?.trimEnd(), - formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + formattedCaption = formattedCaption, isEdited = content.isEdited, mediaSource = messageType.source, duration = messageType.info?.duration ?: Duration.ZERO, @@ -192,12 +205,15 @@ class TimelineItemContentMessageFactory( ) } is FileMessageType -> { + val dom = messageType.formattedCaption?.toHtmlDocument(permalinkParser = permalinkParser) + val formattedCaption = dom?.let(::parseHtml) + ?: messageType.caption?.withLinks() val fileExtension = fileExtensionExtractor.extractFromName(messageType.filename) TimelineItemFileContent( filename = messageType.filename, fileSize = messageType.info?.size ?: 0, caption = messageType.caption?.trimEnd(), - formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + formattedCaption = formattedCaption, isEdited = content.isEdited, thumbnailSource = messageType.info?.thumbnailSource, mediaSource = messageType.source, @@ -208,9 +224,9 @@ class TimelineItemContentMessageFactory( } is NoticeMessageType -> { val body = messageType.body.trimEnd() - val formattedBody = parseHtml(messageType.formatted) ?: textPillificationHelper.pillify( - body - ).safeLinkify() + val dom = messageType.formatted?.toHtmlDocument(permalinkParser = permalinkParser) + val formattedBody = dom?.let(::parseHtml) + ?: textPillificationHelper.pillify(body).safeLinkify() val htmlDocument = messageType.formatted?.toHtmlDocument(permalinkParser = permalinkParser) TimelineItemNoticeContent( body = body, @@ -221,12 +237,13 @@ class TimelineItemContentMessageFactory( } is TextMessageType -> { val body = messageType.body.trimEnd() - val formattedBody = parseHtml(messageType.formatted) ?: textPillificationHelper.pillify( - body - ).safeLinkify() + val dom = messageType.formatted?.toHtmlDocument(permalinkParser = permalinkParser) + val formattedBody = dom?.let(::parseHtml) + ?: textPillificationHelper.pillify(body).safeLinkify() + val htmlDocument = messageType.formatted?.toHtmlDocument(permalinkParser = permalinkParser) TimelineItemTextContent( body = body, - htmlDocument = messageType.formatted?.toHtmlDocument(permalinkParser = permalinkParser), + htmlDocument = htmlDocument, formattedBody = formattedBody, isEdited = content.isEdited, ) @@ -253,21 +270,11 @@ class TimelineItemContentMessageFactory( return result?.takeIf { it.isFinite() } } - private fun parseHtml(formattedBody: FormattedBody?, prefix: String? = null): CharSequence? { - if (formattedBody == null || formattedBody.format != MessageFormat.HTML) return null - val result = htmlConverterProvider.provide() - .fromHtmlToSpans(formattedBody.body.trimEnd()) + private fun parseHtml(document: Document): CharSequence? { + return htmlConverterProvider.provide() + .fromDocumentToSpans(document) .let { textPillificationHelper.pillify(it) } .safeLinkify() - return if (prefix != null) { - buildSpannedString { - append(prefix) - append(" ") - append(result) - } - } else { - result - } } } 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 160e368916..9f23388ecb 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 @@ -67,6 +67,7 @@ import io.element.android.libraries.mediaviewer.test.util.FileExtensionExtractor import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.test.runTest +import org.jsoup.nodes.Document import org.junit.Assert.fail import org.junit.Test import org.junit.runner.RunWith @@ -187,7 +188,7 @@ class TimelineItemContentMessageFactoryTest { } }.toSpannable() val sut = createTimelineItemContentMessageFactory( - htmlConverterTransform = { expected } + domConverterTransform = { expected } ) val result = sut.create( content = createMessageContent( @@ -679,7 +680,7 @@ class TimelineItemContentMessageFactoryTest { } }.toSpannable() val sut = createTimelineItemContentMessageFactory( - htmlConverterTransform = { expectedSpanned }, + domConverterTransform = { expectedSpanned }, permalinkParser = FakePermalinkParser { PermalinkData.FallbackLink(Uri.EMPTY) } ) val result = sut.create( @@ -765,11 +766,12 @@ class TimelineItemContentMessageFactoryTest { private fun createTimelineItemContentMessageFactory( htmlConverterTransform: (String) -> CharSequence = { it }, + domConverterTransform: (Document) -> CharSequence = { it.body().html() }, permalinkParser: FakePermalinkParser = FakePermalinkParser(), ) = TimelineItemContentMessageFactory( fileSizeFormatter = FakeFileSizeFormatter(), fileExtensionExtractor = FileExtensionExtractorWithoutValidation(), - htmlConverterProvider = FakeHtmlConverterProvider(htmlConverterTransform), + htmlConverterProvider = FakeHtmlConverterProvider(htmlConverterTransform, domConverterTransform), permalinkParser = permalinkParser, textPillificationHelper = FakeTextPillificationHelper(), ) diff --git a/features/messages/test/src/main/kotlin/io/element/android/features/messages/test/timeline/FakeHtmlConverterProvider.kt b/features/messages/test/src/main/kotlin/io/element/android/features/messages/test/timeline/FakeHtmlConverterProvider.kt index 75b700b58d..1277783f6a 100644 --- a/features/messages/test/src/main/kotlin/io/element/android/features/messages/test/timeline/FakeHtmlConverterProvider.kt +++ b/features/messages/test/src/main/kotlin/io/element/android/features/messages/test/timeline/FakeHtmlConverterProvider.kt @@ -11,9 +11,11 @@ package io.element.android.features.messages.test.timeline import androidx.compose.runtime.Composable import io.element.android.features.messages.api.timeline.HtmlConverterProvider import io.element.android.wysiwyg.utils.HtmlConverter +import org.jsoup.nodes.Document class FakeHtmlConverterProvider( private val transform: (String) -> CharSequence = { it }, + private val transformDom: (Document) -> CharSequence = { it.html() }, ) : HtmlConverterProvider { @Composable override fun Update() = Unit @@ -23,6 +25,10 @@ class FakeHtmlConverterProvider( override fun fromHtmlToSpans(html: String): CharSequence { return transform(html) } + + override fun fromDocumentToSpans(dom: Document): CharSequence { + return transformDom(dom) + } } } } diff --git a/libraries/matrixui/build.gradle.kts b/libraries/matrixui/build.gradle.kts index 94aa388c0c..5513dc240e 100644 --- a/libraries/matrixui/build.gradle.kts +++ b/libraries/matrixui/build.gradle.kts @@ -36,7 +36,7 @@ dependencies { implementation(projects.libraries.uiStrings) implementation(projects.libraries.testtags) implementation(libs.coil.compose) - implementation(libs.jsoup) + implementation(libs.matrix.richtexteditor) implementation(projects.libraries.previewutils) testCommonDependencies(libs, true) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToHtmlDocument.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToHtmlDocument.kt index 5a2297ec1f..ee9de51681 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToHtmlDocument.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToHtmlDocument.kt @@ -12,7 +12,7 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.permalink.PermalinkParser import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody import io.element.android.libraries.matrix.api.timeline.item.event.MessageFormat -import org.jsoup.Jsoup +import io.element.android.wysiwyg.utils.HtmlToDomParser import org.jsoup.nodes.Document /** @@ -34,9 +34,9 @@ fun FormattedBody.toHtmlDocument( ?.trimEnd() ?.let { formattedBody -> val dom = if (prefix != null) { - Jsoup.parse("$prefix $formattedBody") + HtmlToDomParser.document("$prefix $formattedBody") } else { - Jsoup.parse(formattedBody) + HtmlToDomParser.document(formattedBody) } // Prepend `@` to mentions From 1b4cf477c7c9ad09fc8e76ed22a7139ef008112d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Aug 2025 01:57:31 +0000 Subject: [PATCH 175/347] Update dependency org.robolectric:robolectric to v4.16 --- 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 83692039d7..7e30fa3653 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -165,7 +165,7 @@ test_konsist = "com.lemonappdev:konsist:0.17.3" test_turbine = "app.cash.turbine:turbine:1.2.1" test_truth = "com.google.truth:truth:1.4.5" test_parameter_injector = "com.google.testparameterinjector:test-parameter-injector:1.20" -test_robolectric = "org.robolectric:robolectric:4.15.1" +test_robolectric = "org.robolectric:robolectric:4.16" test_appyx_junit = { module = "com.bumble.appyx:testing-junit4", version.ref = "appyx" } test_composable_preview_scanner = "io.github.sergio-sastre.ComposablePreviewScanner:android:0.7.2" test_detekt_api = { module = "io.gitlab.arturbosch.detekt:detekt-api", version.ref = "detekt" } From 9e00ca323d94632f9fdc0735c595d3eb52d77596 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Dec 2025 16:14:11 +0100 Subject: [PATCH 176/347] Fix file size formatter output on API 26+ --- .../filesize/AndroidFileSizeFormatter.kt | 7 ++- .../filesize/AndroidFileSizeFormatterTest.kt | 50 ++++++++++++------- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/filesize/AndroidFileSizeFormatter.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/filesize/AndroidFileSizeFormatter.kt index 100fdcdfdc..6854d099fa 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/filesize/AndroidFileSizeFormatter.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/filesize/AndroidFileSizeFormatter.kt @@ -24,12 +24,15 @@ class AndroidFileSizeFormatter( override fun format(fileSize: Long, useShortFormat: Boolean): String { // Since Android O, the system considers that 1kB = 1000 bytes instead of 1024 bytes. // We want to avoid that. + // Sadly we do not have access to the flags values Formatter.FLAG_IEC_UNITS and Formatter.FLAG_SHORTER + // nor the method Formatter.formatFileSize with the flags parameter. + // So for Android 0 and more, first convert the fileSize to MB/GB/TB ourselves val normalizedSize = if (sdkIntProvider.get() <= Build.VERSION_CODES.N) { fileSize } else { // First convert the size when { - fileSize < 1024 -> fileSize + fileSize <= 1 -> fileSize fileSize < 1024 * 1024 -> fileSize * 1000 / 1024 fileSize < 1024 * 1024 * 1024 -> fileSize * 1000 / 1024 * 1000 / 1024 else -> fileSize * 1000 / 1024 * 1000 / 1024 * 1000 / 1024 @@ -40,6 +43,6 @@ class AndroidFileSizeFormatter( Formatter.formatShortFileSize(context, normalizedSize) } else { Formatter.formatFileSize(context, normalizedSize) - } + }.replace("kB", "KB") } } diff --git a/libraries/androidutils/src/test/kotlin/io/element/android/libraries/androidutils/filesize/AndroidFileSizeFormatterTest.kt b/libraries/androidutils/src/test/kotlin/io/element/android/libraries/androidutils/filesize/AndroidFileSizeFormatterTest.kt index 37260006b8..a83aa7d69f 100644 --- a/libraries/androidutils/src/test/kotlin/io/element/android/libraries/androidutils/filesize/AndroidFileSizeFormatterTest.kt +++ b/libraries/androidutils/src/test/kotlin/io/element/android/libraries/androidutils/filesize/AndroidFileSizeFormatterTest.kt @@ -15,45 +15,59 @@ import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) class AndroidFileSizeFormatterTest { + @Config(sdk = [Build.VERSION_CODES.N]) @Test fun `test api 24 long format`() { val sut = createAndroidFileSizeFormatter(sdkLevel = Build.VERSION_CODES.N) - assertThat(sut.format(1, useShortFormat = false)).isEqualTo("1.00B") - assertThat(sut.format(1000, useShortFormat = false)).isEqualTo("0.98KB") - assertThat(sut.format(1024, useShortFormat = false)).isEqualTo("1.00KB") - assertThat(sut.format(1024 * 1024, useShortFormat = false)).isEqualTo("1.00MB") - assertThat(sut.format(1024 * 1024 * 1024, useShortFormat = false)).isEqualTo("1.00GB") + assertThat(sut.format(1, useShortFormat = false)).isEqualTo("1 B") + assertThat(sut.format(1000, useShortFormat = false)).isEqualTo("0.98 KB") + assertThat(sut.format(1024, useShortFormat = false)).isEqualTo("1.00 KB") + assertThat(sut.format(1024 * 500, useShortFormat = false)).isEqualTo("500 KB") + assertThat(sut.format(1024 * 1024, useShortFormat = false)).isEqualTo("1.00 MB") + assertThat(sut.format(1024 * 1024 * 500, useShortFormat = false)).isEqualTo("500 MB") + assertThat(sut.format(1024 * 1024 * 1024, useShortFormat = false)).isEqualTo("1.00 GB") } + @Config(sdk = [Build.VERSION_CODES.O]) @Test fun `test api 26 long format`() { val sut = createAndroidFileSizeFormatter(sdkLevel = Build.VERSION_CODES.O) - assertThat(sut.format(1, useShortFormat = false)).isEqualTo("1.00B") - assertThat(sut.format(1000, useShortFormat = false)).isEqualTo("0.98KB") - assertThat(sut.format(1024 * 1024, useShortFormat = false)).isEqualTo("0.95MB") - assertThat(sut.format(1024 * 1024 * 1024, useShortFormat = false)).isEqualTo("0.93GB") + assertThat(sut.format(1, useShortFormat = false)).isEqualTo("1 B") + assertThat(sut.format(1000, useShortFormat = false)).isEqualTo("0.98 KB") + assertThat(sut.format(1024, useShortFormat = false)).isEqualTo("1.00 KB") + assertThat(sut.format(1024 * 500, useShortFormat = false)).isEqualTo("500 KB") + assertThat(sut.format(1024 * 1024, useShortFormat = false)).isEqualTo("1.00 MB") + assertThat(sut.format(1024 * 1024 * 500, useShortFormat = false)).isEqualTo("500 MB") + assertThat(sut.format(1024 * 1024 * 1024, useShortFormat = false)).isEqualTo("1.00 GB") } + @Config(sdk = [Build.VERSION_CODES.N]) @Test fun `test api 24 short format`() { val sut = createAndroidFileSizeFormatter(sdkLevel = Build.VERSION_CODES.N) - assertThat(sut.format(1, useShortFormat = true)).isEqualTo("1.0B") - assertThat(sut.format(1000, useShortFormat = true)).isEqualTo("0.98KB") - assertThat(sut.format(1024, useShortFormat = true)).isEqualTo("1.0KB") - assertThat(sut.format(1024 * 1024, useShortFormat = true)).isEqualTo("1.0MB") - assertThat(sut.format(1024 * 1024 * 1024, useShortFormat = true)).isEqualTo("1.0GB") + assertThat(sut.format(1, useShortFormat = true)).isEqualTo("1 B") + assertThat(sut.format(1000, useShortFormat = true)).isEqualTo("0.98 KB") + assertThat(sut.format(1024, useShortFormat = true)).isEqualTo("1.0 KB") + assertThat(sut.format(1024 * 500, useShortFormat = true)).isEqualTo("500 KB") + assertThat(sut.format(1024 * 1024, useShortFormat = true)).isEqualTo("1.0 MB") + assertThat(sut.format(1024 * 1024 * 500, useShortFormat = true)).isEqualTo("500 MB") + assertThat(sut.format(1024 * 1024 * 1024, useShortFormat = true)).isEqualTo("1.0 GB") } + @Config(sdk = [Build.VERSION_CODES.O]) @Test fun `test api 26 short format`() { val sut = createAndroidFileSizeFormatter(sdkLevel = Build.VERSION_CODES.O) - assertThat(sut.format(1, useShortFormat = true)).isEqualTo("1.0B") - assertThat(sut.format(1000, useShortFormat = true)).isEqualTo("0.98KB") - assertThat(sut.format(1024 * 1024, useShortFormat = true)).isEqualTo("0.95MB") - assertThat(sut.format(1024 * 1024 * 1024, useShortFormat = true)).isEqualTo("0.93GB") + assertThat(sut.format(1, useShortFormat = true)).isEqualTo("1 B") + assertThat(sut.format(1000, useShortFormat = true)).isEqualTo("0.98 KB") + assertThat(sut.format(1024, useShortFormat = true)).isEqualTo("1.0 KB") + assertThat(sut.format(1024 * 500, useShortFormat = true)).isEqualTo("500 KB") + assertThat(sut.format(1024 * 1024, useShortFormat = true)).isEqualTo("1.0 MB") + assertThat(sut.format(1024 * 1024 * 1024, useShortFormat = true)).isEqualTo("1.0 GB") } private fun createAndroidFileSizeFormatter(sdkLevel: Int) = AndroidFileSizeFormatter( From 07f8f878d2e61e96a84e9107b7be527bd752e369 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Dec 2025 16:48:21 +0100 Subject: [PATCH 177/347] Use more realistic value for maxUploadSize --- .../impl/attachments/preview/AttachmentsPreviewStateProvider.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewStateProvider.kt index 6823aead3f..70d7ab006e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewStateProvider.kt @@ -95,7 +95,7 @@ fun aMediaUploadInfo( ) fun aMediaOptimisationSelectorState( - maxUploadSize: Long = 100, + maxUploadSize: Long = 100 * 1024 * 1024, videoSizeEstimations: AsyncData> = AsyncData.Success(persistentListOf()), isImageOptimizationEnabled: Boolean = true, selectedVideoPreset: VideoCompressionPreset = VideoCompressionPreset.STANDARD, From 8ddbc6ff39468dcef269d2fb323a58e487307e44 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 17 Dec 2025 16:08:40 +0000 Subject: [PATCH 178/347] Update screenshots --- ...s.impl.attachments.preview_AttachmentsPreviewView_6_en.png | 4 ++-- ...s.impl.attachments.preview_AttachmentsPreviewView_8_en.png | 4 ++-- ...ttachments.preview_VideoQualitySelectorDialog_Day_0_en.png | 4 ++-- ...achments.preview_VideoQualitySelectorDialog_Night_0_en.png | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en.png index 47c4d55b5f..14f96e6874 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d3f18250226a6d8eb034b1de50531ad5b09c3da3020090a04d6064156d5aac35 -size 72811 +oid sha256:267c22669a6b79d3f2cf39307bab2bc9192c7d5426cd8967400ccb6422d3afee +size 73059 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en.png index eb5f1dd827..b09cb621a6 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:787675a64260b3557948840d252836cd561814117e93dda41332af57ad54953a -size 83474 +oid sha256:88539a3267facb99fdff7e49f6d554aca83d7fafa4896c27b1d5f5ab0dedfb32 +size 83677 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en.png index 7be6eb15ee..a15633ae9f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:521262df440dc94729863544f131f3b025057aa854f7b5d40490bbb24aafe45b -size 56605 +oid sha256:17b4bfbf75f7999c39e32245ecfeb209524865a47d0d79b9249a2833d0988ffe +size 56663 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en.png index f2dc0e0579..3395ea1c12 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:72132b0490257da50ca1a55599eff7f5c4bfdc0266d9d01c0822d51c728423f5 -size 54345 +oid sha256:724455c16cb39e9b532a57286c2a1a22d74930b5b06ff3e5b13771327545fa8f +size 54404 From 2b12e22cdd298c1d7e2d68a02f21145d5bfaf005 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 18 Dec 2025 11:42:07 +0100 Subject: [PATCH 179/347] change(room permissions): remove change settings permissions --- .../impl/permissions/ChangeRoomPermissionsPresenter.kt | 2 -- .../impl/permissions/ChangeRoomPermissionsState.kt | 2 -- .../impl/permissions/ChangeRoomPermissionsView.kt | 1 - 3 files changed, 5 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt index d085be5920..0032af6b01 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt @@ -52,7 +52,6 @@ class ChangeRoomPermissionsPresenter( ) RoomPermissionsSection.ManageSpace -> persistentListOf( RoomPermissionType.SPACE_MANAGE_ROOMS, - RoomPermissionType.CHANGE_SETTINGS, ) } @@ -108,7 +107,6 @@ class ChangeRoomPermissionsPresenter( RoomPermissionType.ROOM_AVATAR -> currentPermissions?.copy(roomAvatar = powerLevel) RoomPermissionType.ROOM_TOPIC -> currentPermissions?.copy(roomTopic = powerLevel) RoomPermissionType.SPACE_MANAGE_ROOMS -> currentPermissions?.copy(spaceChild = powerLevel) - RoomPermissionType.CHANGE_SETTINGS -> currentPermissions?.copy(stateDefault = powerLevel) } } is ChangeRoomPermissionsEvent.Save -> coroutineScope.save() diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt index 88309ea023..f538e0a36f 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt @@ -38,7 +38,6 @@ data class ChangeRoomPermissionsState( RoomPermissionType.ROOM_AVATAR -> RoomMember.Role.forPowerLevel(currentPermissions.roomAvatar) RoomPermissionType.ROOM_TOPIC -> RoomMember.Role.forPowerLevel(currentPermissions.roomTopic) RoomPermissionType.SPACE_MANAGE_ROOMS -> RoomMember.Role.forPowerLevel(currentPermissions.spaceChild) - RoomPermissionType.CHANGE_SETTINGS -> RoomMember.Role.forPowerLevel(currentPermissions.stateDefault) } return when (role) { is RoomMember.Role.Owner, @@ -84,5 +83,4 @@ enum class RoomPermissionType { ROOM_AVATAR, ROOM_TOPIC, SPACE_MANAGE_ROOMS, - CHANGE_SETTINGS, } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt index 5dea091be4..c9d9ed435f 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt @@ -127,7 +127,6 @@ private fun titleForType(type: RoomPermissionType): String = when (type) { RoomPermissionType.ROOM_AVATAR -> stringResource(R.string.screen_room_change_permissions_room_avatar) RoomPermissionType.ROOM_TOPIC -> stringResource(R.string.screen_room_change_permissions_room_topic) RoomPermissionType.SPACE_MANAGE_ROOMS -> stringResource(R.string.screen_room_change_permissions_manage_space_rooms) - RoomPermissionType.CHANGE_SETTINGS -> stringResource(R.string.screen_room_change_permissions_change_settings) } @PreviewsDayNight From 6b64f865d741ac1346a5c5f5f6764b01e0f896d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:45:16 +0100 Subject: [PATCH 180/347] fix(deps): update haze to v1.7.1 (#5712) 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 83692039d7..7c4bf18d53 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,7 +46,7 @@ appyx = "1.7.1" sqldelight = "2.2.1" wysiwyg = "2.40.0" telephoto = "0.18.0" -haze = "1.6.10" +haze = "1.7.1" # Dependency analysis dependencyAnalysis = "3.5.1" From c3f4b092702f151d12a94134c58210c4ec0a2eda Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:45:58 +0100 Subject: [PATCH 181/347] chore(deps): update peter-evans/create-pull-request action to v8 (#5878) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/sync-localazy.yml | 2 +- .github/workflows/sync-sas-strings.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sync-localazy.yml b/.github/workflows/sync-localazy.yml index c928434b73..2086eab3aa 100644 --- a/.github/workflows/sync-localazy.yml +++ b/.github/workflows/sync-localazy.yml @@ -36,7 +36,7 @@ jobs: ./tools/localazy/importSupportedLocalesFromLocalazy.py ./tools/test/generateAllScreenshots.py - name: Create Pull Request for Strings - uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 + uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 with: token: ${{ secrets.DANGER_GITHUB_API_TOKEN }} commit-message: Sync Strings from Localazy diff --git a/.github/workflows/sync-sas-strings.yml b/.github/workflows/sync-sas-strings.yml index b603049a04..2f5f22a2d5 100644 --- a/.github/workflows/sync-sas-strings.yml +++ b/.github/workflows/sync-sas-strings.yml @@ -23,7 +23,7 @@ jobs: - name: Run SAS String script run: ./tools/sas/import_sas_strings.py - name: Create Pull Request for SAS Strings - uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 + uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 with: commit-message: Sync SAS Strings title: Sync SAS Strings From 2bd6730e903a6b697306a7b9315820d04bb4eddc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:46:45 +0100 Subject: [PATCH 182/347] fix(deps): update dependency com.posthog:posthog-android to v3.27.2 (#5871) 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 7c4bf18d53..ec68978286 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -216,7 +216,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.26.0" +posthog = "com.posthog:posthog-android:3.27.2" sentry = "io.sentry:sentry-android:8.29.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.29.2" From d362e338215e2fba5eaedd6d74a1d540b596a87f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:48:12 +0100 Subject: [PATCH 183/347] chore(deps): update plugin sonarqube to v7.2.1.6560 (#5905) 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 ec68978286..df4ddc52eb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -264,7 +264,7 @@ roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" } sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" } knit = { id = "org.jetbrains.kotlinx.knit", version = "0.5.0" } -sonarqube = "org.sonarqube:7.2.0.6526" +sonarqube = "org.sonarqube:7.2.1.6560" licensee = "app.cash.licensee:1.14.1" compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } gms_google_services = { id = "com.google.gms.google-services", version = "4.4.4" } From 432b7b8cd7f9b3bfa2f2fe16d6c1f29466532120 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:00:20 +0100 Subject: [PATCH 184/347] fix(deps): update metro to v0.9.1 (#5920) 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 df4ddc52eb..a68e130fb8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -52,7 +52,7 @@ haze = "1.7.1" dependencyAnalysis = "3.5.1" # DI -metro = "0.8.2" +metro = "0.9.1" # Auto service autoservice = "1.1.1" From 8057bda97769e90aec6d876db822ed2e989cb828 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:21:39 +0000 Subject: [PATCH 185/347] fix(deps): update activity to v1.12.2 (#5924) 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 a68e130fb8..c2d2ef02cc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,7 +16,7 @@ datastore = "1.2.0" constraintlayout = "2.2.1" constraintlayout_compose = "1.1.1" lifecycle = "2.10.0" -activity = "1.12.1" +activity = "1.12.2" media3 = "1.8.0" camera = "1.5.2" work = "2.11.0" From 367bbc7e4bea10881fb40b3e81025910d70e232a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 16:31:51 +0100 Subject: [PATCH 186/347] Create `addUserData` method in the analytics providers This allows us to globally add arbitrary data to the events and transactions --- .../services/analytics/impl/DefaultAnalyticsService.kt | 6 ++++++ .../analyticsproviders/api/trackers/AnalyticsTracker.kt | 5 +++++ .../analyticsproviders/sentry/SentryAnalyticsProvider.kt | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt index df26766506..764d2e9796 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt @@ -149,6 +149,12 @@ class DefaultAnalyticsService( } } + override fun addUserData(key: String, value: String) { + if (userConsent.get()) { + analyticsProviders.onEach { it.addUserData(key, value) } + } + } + override fun startTransaction(name: String, operation: String?): AnalyticsTransaction { return if (userConsent.get()) { analyticsProviders.firstNotNullOfOrNull { it.startTransaction(name, operation) } diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/trackers/AnalyticsTracker.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/trackers/AnalyticsTracker.kt index 4ada0cbdaa..9ac7d13f2a 100644 --- a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/trackers/AnalyticsTracker.kt +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/trackers/AnalyticsTracker.kt @@ -35,6 +35,11 @@ interface AnalyticsTracker { * Super properties are added to any tracked event automatically. */ fun updateSuperProperties(updatedProperties: SuperProperties) + + /** + * Adds user data that will be sent with every event. + */ + fun addUserData(key: String, value: String) {} } fun AnalyticsTracker.captureInteraction(name: Interaction.Name, type: Interaction.InteractionType? = null) { diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index 8c2566946a..84167b52c3 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -86,6 +86,10 @@ class SentryAnalyticsProvider( override fun updateSuperProperties(updatedProperties: SuperProperties) { } + override fun addUserData(key: String, value: String) { + Sentry.setExtra(key, value) + } + override fun trackError(throwable: Throwable) { Sentry.captureException(throwable) } From 18482a99e3f844217fbadd7c6c0be9a251e32d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 16:45:54 +0100 Subject: [PATCH 187/347] Add `AnalyticsUserData`, with keys for several extras we want to upload to Sentry. Add the `HOMESERVER` extra, with a hashed homeserver value. This is only so we can identify devices using a problematic HS (like matrix.org under heavy load). --- .../android/appnav/di/MatrixSessionCache.kt | 9 +++++++++ .../analyticsproviders/api/AnalyticsUserData.kt | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsUserData.kt diff --git a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt index 4af64cba34..c639a9abd7 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt @@ -14,10 +14,13 @@ import com.bumble.appyx.core.state.SavedStateMap import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.SingleIn +import io.element.android.libraries.androidutils.hash.hash import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analyticsproviders.api.AnalyticsUserData import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock @@ -36,6 +39,7 @@ private const val SAVE_INSTANCE_KEY = "io.element.android.x.di.MatrixClientsHold class MatrixSessionCache( private val authenticationService: MatrixAuthenticationService, private val syncOrchestratorFactory: SyncOrchestrator.Factory, + private val analyticsService: AnalyticsService, ) : MatrixClientProvider { private val sessionIdsToMatrixSession = ConcurrentHashMap() private val restoreMutex = Mutex() @@ -100,6 +104,11 @@ class MatrixSessionCache( Timber.d("Restore matrix session: $sessionId") return authenticationService.restoreSession(sessionId) .onSuccess { matrixClient -> + // Add the current homeserver (hashed) to the extra info + // This may not play well with multiple sessions, but it should work for now + analyticsService.addUserData(AnalyticsUserData.HOMESERVER, matrixClient.userIdServerName().hash()) + + // Add the new client to the in-memory cache onNewMatrixClient(matrixClient) } .onFailure { diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsUserData.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsUserData.kt new file mode 100644 index 0000000000..44080f824d --- /dev/null +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsUserData.kt @@ -0,0 +1,17 @@ +/* + * 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.services.analyticsproviders.api + +object AnalyticsUserData { + const val HOMESERVER = "homeserver" + + const val STATE_STORE_SIZE = "state_store_size" + const val EVENT_CACHE_SIZE = "event_cache_size" + const val CRYPTO_STORE_SIZE = "crypto_store_size" + const val MEDIA_STORE_SIZE = "media_store_size" +} From dc0b508b089ca9ae84f4f0935cb125eb548e91b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 16:48:01 +0100 Subject: [PATCH 188/347] Add `MatrixClient.getDatabaseSizes` This returns a `SdkStoreSizes` object, with the possible SDK database sizes. --- .../libraries/matrix/api/MatrixClient.kt | 2 ++ .../matrix/api/analytics/SdkStoreSizes.kt | 20 +++++++++++++++++++ .../libraries/matrix/impl/RustMatrixClient.kt | 13 ++++++++++++ .../libraries/matrix/test/FakeMatrixClient.kt | 6 ++++++ 4 files changed, 41 insertions(+) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/SdkStoreSizes.kt diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index ae803110d5..de6257094b 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.matrix.api import io.element.android.libraries.core.data.tryOrNull +import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes import io.element.android.libraries.matrix.api.core.DeviceId import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.MatrixPatterns @@ -81,6 +82,7 @@ interface MatrixClient { suspend fun joinRoomByIdOrAlias(roomIdOrAlias: RoomIdOrAlias, serverNames: List): Result suspend fun knockRoom(roomIdOrAlias: RoomIdOrAlias, message: String, serverNames: List): Result suspend fun getCacheSize(): Long + suspend fun getDatabaseSizes(): Result /** * Will close the client and delete the cache data. diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/SdkStoreSizes.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/SdkStoreSizes.kt new file mode 100644 index 0000000000..62b68b8fdb --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/SdkStoreSizes.kt @@ -0,0 +1,20 @@ +/* + * 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.analytics + +import io.element.android.libraries.core.data.ByteSize + +/** + * The sizes of the different stores (DBs) in the SDK. + */ +data class SdkStoreSizes( + val stateStore: ByteSize?, + val eventCacheStore: ByteSize?, + val mediaStore: ByteSize?, + val cryptoStore: ByteSize?, +) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 8784a69d7c..739a14a533 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -12,11 +12,13 @@ import io.element.android.libraries.androidutils.file.getSizeOfFiles import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.coroutine.childScope +import io.element.android.libraries.core.data.bytes import io.element.android.libraries.core.data.tryOrNull import io.element.android.libraries.core.extensions.mapFailure import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes import io.element.android.libraries.matrix.api.core.DeviceId import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomAlias @@ -566,6 +568,17 @@ class RustMatrixClient( return getCacheSize(includeCryptoDb = false) } + override suspend fun getDatabaseSizes(): Result = runCatchingExceptions { + innerClient.getStoreSizes().run { + SdkStoreSizes( + stateStore = stateStore?.bytes, + eventCacheStore = eventCacheStore?.bytes, + mediaStore = mediaStore?.bytes, + cryptoStore = cryptoStore?.bytes, + ) + } + } + override suspend fun clearCache() { innerClient.clearCaches(innerSyncService) destroy() diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 38d4d1aefe..a2088713a7 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.matrix.test import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes import io.element.android.libraries.matrix.api.core.DeviceId import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomAlias @@ -105,6 +106,7 @@ class FakeMatrixClient( private val addRecentEmojiLambda: (String) -> Result = { Result.success(Unit) }, private val markRoomAsFullyReadResult: (RoomId, EventId) -> Result = { _, _ -> lambdaError() }, private val performDatabaseVacuumLambda: () -> Result = { lambdaError() }, + private val getDatabaseSizesLambda: () -> Result = { lambdaError() }, ) : MatrixClient { var setDisplayNameCalled: Boolean = false private set @@ -184,6 +186,10 @@ class FakeMatrixClient( return 0 } + override suspend fun getDatabaseSizes(): Result { + return getDatabaseSizesLambda() + } + override suspend fun clearCache() = simulateLongTask { clearCacheLambda() } From b4d2f322adead16d58048fe8f2c32aa517e41e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 16:50:11 +0100 Subject: [PATCH 189/347] Rename `ByteSize.to` to `ByteSize.into` This method could clash the the `a to b` operator. --- .../android/libraries/core/data/ByteSize.kt | 8 +++- .../libraries/core/data/ByteSizeTest.kt | 38 +++++++++---------- .../matrix/impl/RustMatrixClientFactory.kt | 4 +- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/data/ByteSize.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/data/ByteSize.kt index fe72866d7e..c91dc96a4a 100644 --- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/data/ByteSize.kt +++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/data/ByteSize.kt @@ -15,7 +15,7 @@ enum class ByteUnit(val bitShift: Int) { } class ByteSize internal constructor(val value: Long, val unit: ByteUnit) { - fun to(dest: ByteUnit): Long { + fun into(dest: ByteUnit): Long { if (unit == dest) return value return value shl unit.bitShift shr dest.bitShift } @@ -25,3 +25,9 @@ val Number.gigaBytes get() = ByteSize(toLong(), ByteUnit.GB) val Number.megaBytes get() = ByteSize(toLong(), ByteUnit.MB) val Number.kiloBytes get() = ByteSize(toLong(), ByteUnit.KB) val Number.bytes get() = ByteSize(toLong(), ByteUnit.BYTES) + +// For the SDK values +val ULong.gigaBytes get() = ByteSize(toLong(), ByteUnit.GB) +val ULong.megaBytes get() = ByteSize(toLong(), ByteUnit.MB) +val ULong.kiloBytes get() = ByteSize(toLong(), ByteUnit.KB) +val ULong.bytes get() = ByteSize(toLong(), ByteUnit.BYTES) diff --git a/libraries/core/src/test/kotlin/io/element/android/libraries/core/data/ByteSizeTest.kt b/libraries/core/src/test/kotlin/io/element/android/libraries/core/data/ByteSizeTest.kt index 0d1ec87b63..ad0191da0c 100644 --- a/libraries/core/src/test/kotlin/io/element/android/libraries/core/data/ByteSizeTest.kt +++ b/libraries/core/src/test/kotlin/io/element/android/libraries/core/data/ByteSizeTest.kt @@ -15,35 +15,35 @@ class ByteSizeTest { fun testSizeConversions() { // Check bytes to other units val bytes = 10_000_000.bytes - assertThat(bytes.to(ByteUnit.BYTES)).isEqualTo(bytes.value) - assertThat(bytes.to(ByteUnit.KB)).isEqualTo(bytes.value / 1024L) - assertThat(bytes.to(ByteUnit.MB)).isEqualTo(bytes.value / 1024L / 1024L) - assertThat(bytes.to(ByteUnit.GB)).isEqualTo(bytes.value / 1024L / 1024L / 1024L) + assertThat(bytes.into(ByteUnit.BYTES)).isEqualTo(bytes.value) + assertThat(bytes.into(ByteUnit.KB)).isEqualTo(bytes.value / 1024L) + assertThat(bytes.into(ByteUnit.MB)).isEqualTo(bytes.value / 1024L / 1024L) + assertThat(bytes.into(ByteUnit.GB)).isEqualTo(bytes.value / 1024L / 1024L / 1024L) // Now check for values too small to be converted - assertThat(100.bytes.to(ByteUnit.KB)).isEqualTo(0) - assertThat(100.bytes.to(ByteUnit.MB)).isEqualTo(0) - assertThat(100.bytes.to(ByteUnit.GB)).isEqualTo(0) + assertThat(100.bytes.into(ByteUnit.KB)).isEqualTo(0) + assertThat(100.bytes.into(ByteUnit.MB)).isEqualTo(0) + assertThat(100.bytes.into(ByteUnit.GB)).isEqualTo(0) // Check for KBs val kiloBytes = 10_000.kiloBytes - assertThat(kiloBytes.to(ByteUnit.BYTES)).isEqualTo(kiloBytes.value * 1024L) - assertThat(kiloBytes.to(ByteUnit.KB)).isEqualTo(kiloBytes.value) - assertThat(kiloBytes.to(ByteUnit.MB)).isEqualTo(kiloBytes.value / 1024L) - assertThat(kiloBytes.to(ByteUnit.GB)).isEqualTo(kiloBytes.value / 1024L / 1024L) + assertThat(kiloBytes.into(ByteUnit.BYTES)).isEqualTo(kiloBytes.value * 1024L) + assertThat(kiloBytes.into(ByteUnit.KB)).isEqualTo(kiloBytes.value) + assertThat(kiloBytes.into(ByteUnit.MB)).isEqualTo(kiloBytes.value / 1024L) + assertThat(kiloBytes.into(ByteUnit.GB)).isEqualTo(kiloBytes.value / 1024L / 1024L) // Check for MBs val megaBytes = 10_000.megaBytes - assertThat(megaBytes.to(ByteUnit.BYTES)).isEqualTo(megaBytes.value * 1024L * 1024L) - assertThat(megaBytes.to(ByteUnit.KB)).isEqualTo(megaBytes.value * 1024L) - assertThat(megaBytes.to(ByteUnit.MB)).isEqualTo(megaBytes.value) - assertThat(megaBytes.to(ByteUnit.GB)).isEqualTo(megaBytes.value / 1024L) + assertThat(megaBytes.into(ByteUnit.BYTES)).isEqualTo(megaBytes.value * 1024L * 1024L) + assertThat(megaBytes.into(ByteUnit.KB)).isEqualTo(megaBytes.value * 1024L) + assertThat(megaBytes.into(ByteUnit.MB)).isEqualTo(megaBytes.value) + assertThat(megaBytes.into(ByteUnit.GB)).isEqualTo(megaBytes.value / 1024L) // Check for GBs val gigaBytes = 10.gigaBytes - assertThat(gigaBytes.to(ByteUnit.BYTES)).isEqualTo(gigaBytes.value * 1024L * 1024L * 1024L) - assertThat(gigaBytes.to(ByteUnit.KB)).isEqualTo(gigaBytes.value * 1024L * 1024L) - assertThat(gigaBytes.to(ByteUnit.MB)).isEqualTo(gigaBytes.value * 1024L) - assertThat(gigaBytes.to(ByteUnit.GB)).isEqualTo(gigaBytes.value) + assertThat(gigaBytes.into(ByteUnit.BYTES)).isEqualTo(gigaBytes.value * 1024L * 1024L * 1024L) + assertThat(gigaBytes.into(ByteUnit.KB)).isEqualTo(gigaBytes.value * 1024L * 1024L) + assertThat(gigaBytes.into(ByteUnit.MB)).isEqualTo(gigaBytes.value * 1024L) + assertThat(gigaBytes.into(ByteUnit.GB)).isEqualTo(gigaBytes.value) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index 3d94f7554d..88207049d2 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -81,9 +81,9 @@ class RustMatrixClientFactory( client.setMediaRetentionPolicy( MediaRetentionPolicy( // Make this 500MB instead of 400MB - maxCacheSize = 500.megaBytes.to(ByteUnit.BYTES).toULong(), + maxCacheSize = 500.megaBytes.into(ByteUnit.BYTES).toULong(), // This is the default value, but let's make it explicit - maxFileSize = 20.megaBytes.to(ByteUnit.BYTES).toULong(), + maxFileSize = 20.megaBytes.into(ByteUnit.BYTES).toULong(), // Use 30 days instead of 60 lastAccessExpiry = 30.days.toJavaDuration(), // This is the default value, but let's make it explicit From b064b35c93d783991a68242f80db0f2bc0a3a75c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 16:51:05 +0100 Subject: [PATCH 190/347] Create `GetDatabaseSizesUseCase` so we don't have to expose the while `MatrixClient` to get these values --- .../api/analytics/GetDatabaseSizesUseCase.kt | 14 ++++++++++ .../DefaultGetDatabaseSizesUseCase.kt | 27 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/GetDatabaseSizesUseCase.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultGetDatabaseSizesUseCase.kt diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/GetDatabaseSizesUseCase.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/GetDatabaseSizesUseCase.kt new file mode 100644 index 0000000000..ab11374116 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/GetDatabaseSizesUseCase.kt @@ -0,0 +1,14 @@ +/* + * 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.analytics + +import io.element.android.libraries.matrix.api.core.SessionId + +fun interface GetDatabaseSizesUseCase { + suspend operator fun invoke(sessionId: SessionId): Result +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultGetDatabaseSizesUseCase.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultGetDatabaseSizesUseCase.kt new file mode 100644 index 0000000000..8973483132 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultGetDatabaseSizesUseCase.kt @@ -0,0 +1,27 @@ +/* + * 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.analytics + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.matrix.api.MatrixClientProvider +import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase +import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes +import io.element.android.libraries.matrix.api.core.SessionId + +@ContributesBinding(AppScope::class) +class DefaultGetDatabaseSizesUseCase( + private val clientProvider: Lazy, +) : GetDatabaseSizesUseCase { + override suspend fun invoke(sessionId: SessionId): Result { + val client = clientProvider.value.getOrNull(sessionId) + ?: return Result.failure(IllegalArgumentException("No MatrixClient for session $sessionId")) + + return client.getDatabaseSizes() + } +} From a4b908bc181b0e1f7a58c868ebad3e09eaa115c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 16:52:08 +0100 Subject: [PATCH 191/347] Integrate the new use case with Sentry We'll upload the store sizes as different fields so we can later use them to filter transaction/issues --- libraries/core/build.gradle.kts | 1 + .../sentry/build.gradle.kts | 2 ++ .../sentry/SentryAnalyticsProvider.kt | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/libraries/core/build.gradle.kts b/libraries/core/build.gradle.kts index e25ae62c95..d04efaa40e 100644 --- a/libraries/core/build.gradle.kts +++ b/libraries/core/build.gradle.kts @@ -24,6 +24,7 @@ kotlin { dependencies { implementation(libs.coroutines.core) + implementation(libs.coroutines.test) testImplementation(libs.test.junit) testImplementation(libs.test.truth) } diff --git a/services/analyticsproviders/sentry/build.gradle.kts b/services/analyticsproviders/sentry/build.gradle.kts index 780e97a2d5..5f8ec01996 100644 --- a/services/analyticsproviders/sentry/build.gradle.kts +++ b/services/analyticsproviders/sentry/build.gradle.kts @@ -51,5 +51,7 @@ dependencies { implementation(libs.sentry) implementation(projects.libraries.core) implementation(projects.libraries.di) + implementation(projects.libraries.matrix.api) implementation(projects.services.analyticsproviders.api) + implementation(projects.services.appnavstate.api) } diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index 84167b52c3..395e2eab25 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -16,16 +16,22 @@ import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsScreen import im.vector.app.features.analytics.plan.SuperProperties import im.vector.app.features.analytics.plan.UserProperties +import io.element.android.libraries.core.data.ByteUnit import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.di.annotations.ApplicationContext +import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase import io.element.android.services.analyticsproviders.api.AnalyticsProvider import io.element.android.services.analyticsproviders.api.AnalyticsTransaction +import io.element.android.services.analyticsproviders.api.AnalyticsUserData import io.element.android.services.analyticsproviders.sentry.log.analyticsTag +import io.element.android.services.appnavstate.api.AppNavigationStateService +import io.element.android.services.appnavstate.api.currentSessionId import io.sentry.Breadcrumb import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.android.core.SentryAndroid +import kotlinx.coroutines.runBlocking import timber.log.Timber @ContributesIntoSet(AppScope::class) @@ -33,6 +39,8 @@ import timber.log.Timber class SentryAnalyticsProvider( @ApplicationContext private val context: Context, private val buildMeta: BuildMeta, + private val getDatabaseSizesUseCase: GetDatabaseSizesUseCase, + private val appNavigationStateService: AppNavigationStateService, ) : AnalyticsProvider { override val name = SentryConfig.NAME @@ -48,6 +56,20 @@ class SentryAnalyticsProvider( SentryAndroid.init(context) { options -> options.dsn = dsn options.beforeSend = SentryOptions.BeforeSendCallback { event, _ -> event } + options.beforeSendTransaction = SentryOptions.BeforeSendTransactionCallback { transaction, _ -> + val sessionId = appNavigationStateService.appNavigationState.value.navigationState.currentSessionId() + if (sessionId != null) { + // This runs in a separate thread, so although using `runBlocking` is not great, at least it shouldn't freeze the app + // Also, the method is fairly quick, so the blocking shouldn't take longer than a few ms + val databaseSizes = runBlocking { getDatabaseSizesUseCase(sessionId) }.getOrNull() + + databaseSizes?.stateStore?.let { transaction.setExtra(AnalyticsUserData.STATE_STORE_SIZE, it.into(ByteUnit.MB)) } + databaseSizes?.eventCacheStore?.let { transaction.setExtra(AnalyticsUserData.EVENT_CACHE_SIZE, it.into(ByteUnit.MB)) } + databaseSizes?.mediaStore?.let { transaction.setExtra(AnalyticsUserData.MEDIA_STORE_SIZE, it.into(ByteUnit.MB)) } + databaseSizes?.cryptoStore?.let { transaction.setExtra(AnalyticsUserData.CRYPTO_STORE_SIZE, it.into(ByteUnit.MB)) } + } + transaction + } options.tracesSampleRate = 1.0 options.isEnableUserInteractionTracing = true options.environment = buildMeta.buildType.toSentryEnv() From 20c0d0190ef659a9e89135b1e1225f1694fcc37c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 16:52:48 +0100 Subject: [PATCH 192/347] Add extra code to make sure we can't upload a session/user id as an extra by mistake --- .../analyticsproviders/sentry/SentryAnalyticsProvider.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index 395e2eab25..e7f49079a4 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -55,8 +55,13 @@ class SentryAnalyticsProvider( SentryAndroid.init(context) { options -> options.dsn = dsn - options.beforeSend = SentryOptions.BeforeSendCallback { event, _ -> event } options.beforeSendTransaction = SentryOptions.BeforeSendTransactionCallback { transaction, _ -> + // Ensure we'll never upload any session ids + val possibleSessionIds = transaction.extras?.filter { (it.value as? String)?.startsWith("@") == true }.orEmpty() + for (invalidExtra in possibleSessionIds) { + transaction.extras?.remove(invalidExtra.key) + } + val sessionId = appNavigationStateService.appNavigationState.value.navigationState.currentSessionId() if (sessionId != null) { // This runs in a separate thread, so although using `runBlocking` is not great, at least it shouldn't freeze the app From b201b40639763cac927289619e45b05fb1118cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 16:53:16 +0100 Subject: [PATCH 193/347] Add a new entry in the developer settings to check the store sizes --- .../developer/DeveloperSettingsPresenter.kt | 33 +++++++++++++++++++ .../impl/developer/DeveloperSettingsState.kt | 2 ++ .../DeveloperSettingsStateProvider.kt | 2 ++ .../impl/developer/DeveloperSettingsView.kt | 20 +++++++++++ .../DeveloperSettingsPresenterTest.kt | 5 +++ 5 files changed, 62 insertions(+) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt index db35a1dc83..a0d96be540 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt @@ -31,21 +31,26 @@ import io.element.android.features.preferences.impl.tasks.ClearCacheUseCase import io.element.android.features.preferences.impl.tasks.ComputeCacheSizeUseCase import io.element.android.features.preferences.impl.tasks.VacuumStoresUseCase import io.element.android.features.rageshake.api.preferences.RageshakePreferencesState +import io.element.android.libraries.androidutils.filesize.FileSizeFormatter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState +import io.element.android.libraries.core.data.ByteUnit import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.ui.model.FeatureUiModel +import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.preferences.api.store.AppPreferencesStore import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toImmutableMap import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.map @@ -63,6 +68,8 @@ class DeveloperSettingsPresenter( private val buildMeta: BuildMeta, private val enterpriseService: EnterpriseService, private val vacuumStoresUseCase: VacuumStoresUseCase, + private val databaseSizesUseCase: GetDatabaseSizesUseCase, + private val fileSizeFormatter: FileSizeFormatter, ) : Presenter { @Composable override fun present(): DeveloperSettingsState { @@ -73,6 +80,9 @@ class DeveloperSettingsPresenter( val cacheSize = remember { mutableStateOf>(AsyncData.Uninitialized) } + val databaseSizes = remember { + mutableStateOf>>(AsyncData.Uninitialized) + } val clearCacheAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } @@ -96,6 +106,7 @@ class DeveloperSettingsPresenter( } LaunchedEffect(Unit) { + computeDatabaseSizes(databaseSizes) featureFlagService.getAvailableFeatures() .run { // Never display room directory search in release builds for Play Store @@ -162,6 +173,7 @@ class DeveloperSettingsPresenter( return DeveloperSettingsState( features = featureUiModels, cacheSize = cacheSize.value, + databaseSizes = databaseSizes.value, clearCacheAction = clearCacheAction.value, rageshakeState = rageshakeState, customElementCallBaseUrlState = CustomElementCallBaseUrlState( @@ -214,6 +226,27 @@ class DeveloperSettingsPresenter( }.runCatchingUpdatingState(cacheSize) } + private fun CoroutineScope.computeDatabaseSizes(databaseSizes: MutableState>>) = launch { + suspend { + databaseSizesUseCase(sessionId).getOrThrow().let { sizes -> + buildMap { + sizes.stateStore?.let { stateStoreSize -> + put("State store", fileSizeFormatter.format(stateStoreSize.into(ByteUnit.BYTES), useShortFormat = true)) + } + sizes.eventCacheStore?.let { eventCacheStoreSize -> + put("Event cache store", fileSizeFormatter.format(eventCacheStoreSize.into(ByteUnit.BYTES), useShortFormat = true)) + } + sizes.mediaStore?.let { mediaStoreSize -> + put("Media store", fileSizeFormatter.format(mediaStoreSize.into(ByteUnit.BYTES), useShortFormat = true)) + } + sizes.cryptoStore?.let { cryptoStoreSize -> + put("Crypto store", fileSizeFormatter.format(cryptoStoreSize.into(ByteUnit.BYTES), useShortFormat = true)) + } + } + }.toImmutableMap() + }.runCatchingUpdatingState(databaseSizes) + } + private fun CoroutineScope.clearCache(clearCacheAction: MutableState>) = launch { suspend { clearCacheUseCase() diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt index f97270dc7a..920c8ec95c 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt @@ -15,10 +15,12 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.featureflag.ui.model.FeatureUiModel import io.element.android.libraries.matrix.api.tracing.TraceLogPack import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.ImmutableMap data class DeveloperSettingsState( val features: ImmutableList, val cacheSize: AsyncData, + val databaseSizes: AsyncData>, val rageshakeState: RageshakePreferencesState, val clearCacheAction: AsyncAction, val customElementCallBaseUrlState: CustomElementCallBaseUrlState, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt index ea16ed9f0f..9ac4fdfcc8 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt @@ -15,6 +15,7 @@ import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.featureflag.ui.model.aFeatureUiModelList import io.element.android.libraries.matrix.api.tracing.TraceLogPack +import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toImmutableList open class DeveloperSettingsStateProvider : PreviewParameterProvider { @@ -47,6 +48,7 @@ fun aDeveloperSettingsState( features = aFeatureUiModelList(), rageshakeState = aRageshakePreferencesState(), cacheSize = AsyncData.Success("1.2 MB"), + databaseSizes = AsyncData.Success(persistentMapOf("state_store" to "1.2MB")), clearCacheAction = clearCacheAction, customElementCallBaseUrlState = customElementCallBaseUrlState, tracingLogLevel = AsyncData.Success(LogLevelItem.INFO), diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt index 2bfb2f086a..444a391d43 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt @@ -9,6 +9,7 @@ package io.element.android.features.preferences.impl.developer import androidx.activity.compose.BackHandler +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.progressSemantics @@ -146,6 +147,25 @@ fun DeveloperSettingsView( } val cache = state.cacheSize PreferenceCategory(title = "Cache") { + ListItem( + headlineContent = { Text("Database sizes") }, + supportingContent = { + if (state.databaseSizes.isLoading()) { + Text("Computing...") + } else { + val dbSizes = state.databaseSizes.dataOrNull() + if (dbSizes != null && dbSizes.isNotEmpty()) { + Column { + for ((dbName, size) in dbSizes) { + Text("$dbName: $size") + } + } + } else { + Text("Unknown") + } + } + } + ) ListItem( headlineContent = { Text("Vacuum stores") diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt index 75ae12b714..fa5f5fd0f6 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt @@ -19,6 +19,7 @@ import io.element.android.features.preferences.impl.tasks.FakeClearCacheUseCase import io.element.android.features.preferences.impl.tasks.FakeComputeCacheSizeUseCase import io.element.android.features.preferences.impl.tasks.VacuumStoresUseCase import io.element.android.features.rageshake.api.preferences.aRageshakePreferencesState +import io.element.android.libraries.androidutils.filesize.FakeFileSizeFormatter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.core.meta.BuildMeta @@ -27,6 +28,7 @@ import io.element.android.libraries.featureflag.api.Feature import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeature import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.core.aBuildMeta @@ -249,6 +251,7 @@ class DeveloperSettingsPresenterTest { buildMeta: BuildMeta = aBuildMeta(), enterpriseService: EnterpriseService = FakeEnterpriseService(), vacuumStoresUseCase: VacuumStoresUseCase = VacuumStoresUseCase {}, + datbaseSizesUseCase: GetDatabaseSizesUseCase = GetDatabaseSizesUseCase { Result.success(emptyMap()) }, ): DeveloperSettingsPresenter { return DeveloperSettingsPresenter( sessionId = sessionId, @@ -260,6 +263,8 @@ class DeveloperSettingsPresenterTest { buildMeta = buildMeta, enterpriseService = enterpriseService, vacuumStoresUseCase = vacuumStoresUseCase, + databaseSizesUseCase = datbaseSizesUseCase, + fileSizeFormatter = FakeFileSizeFormatter(), ) } } From 5c6fee08fd3b8495397584a44cb72cb393a826b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 16:53:24 +0100 Subject: [PATCH 194/347] Fix tests --- .../appnav/di/MatrixSessionCacheTest.kt | 72 ++++++++++++------- .../libraries/core/coroutine/ChildScopeOf.kt | 10 ++- .../matrix/impl/room/RustBaseRoomTest.kt | 2 +- 3 files changed, 54 insertions(+), 30 deletions(-) diff --git a/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixSessionCacheTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixSessionCacheTest.kt index 56c20f7a1d..36fa471dd0 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixSessionCacheTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/di/MatrixSessionCacheTest.kt @@ -19,29 +19,31 @@ import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.appnavstate.test.FakeAppForegroundStateService import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Test +@OptIn(ExperimentalCoroutinesApi::class) class MatrixSessionCacheTest { @Test fun `test getOrNull`() = runTest { - val fakeAuthenticationService = FakeMatrixAuthenticationService() - val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) + val matrixSessionCache = createMatrixSessionCache() assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull() } @Test fun `test getSyncOrchestratorOrNull`() = runTest { val fakeAuthenticationService = FakeMatrixAuthenticationService() - val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) + val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService) // With no matrix client there is no sync orchestrator assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull() assertThat(matrixSessionCache.getSyncOrchestrator(A_SESSION_ID)).isNull() // But as soon as we receive a client, we can get the sync orchestrator - val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) + val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value }) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixSessionCache.getSyncOrchestrator(A_SESSION_ID)).isNotNull() @@ -50,8 +52,8 @@ class MatrixSessionCacheTest { @Test fun `test getOrRestore`() = runTest { val fakeAuthenticationService = FakeMatrixAuthenticationService() - val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) - val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) + val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService) + val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value }) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull() assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) @@ -63,8 +65,8 @@ class MatrixSessionCacheTest { @Test fun `test remove`() = runTest { val fakeAuthenticationService = FakeMatrixAuthenticationService() - val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) - val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) + val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService) + val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value }) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isEqualTo(fakeMatrixClient) @@ -76,8 +78,8 @@ class MatrixSessionCacheTest { @Test fun `test remove all`() = runTest { val fakeAuthenticationService = FakeMatrixAuthenticationService() - val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) - val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) + val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService) + val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value }) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isEqualTo(fakeMatrixClient) @@ -89,8 +91,8 @@ class MatrixSessionCacheTest { @Test fun `test save and restore`() = runTest { val fakeAuthenticationService = FakeMatrixAuthenticationService() - val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) - val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) + val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService) + val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value }) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) matrixSessionCache.getOrRestore(A_SESSION_ID) val savedStateMap = MutableSavedStateMapImpl { true } @@ -109,29 +111,45 @@ class MatrixSessionCacheTest { @Test fun `test AuthenticationService listenToNewMatrixClients emits a Client value and we save it`() = runTest { val fakeAuthenticationService = FakeMatrixAuthenticationService() - val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) + val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull() - fakeAuthenticationService.givenMatrixClient(FakeMatrixClient(sessionId = A_SESSION_ID, sessionCoroutineScope = backgroundScope)) val loginSucceeded = fakeAuthenticationService.login("user", "pass") assertThat(loginSucceeded.isSuccess).isTrue() + + runCurrent() + assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNotNull() } - private fun TestScope.createSyncOrchestratorFactory() = object : SyncOrchestrator.Factory { - override fun create( - syncService: SyncService, - sessionCoroutineScope: CoroutineScope, - ): SyncOrchestrator { - return SyncOrchestrator( - syncService = syncService, - sessionCoroutineScope = sessionCoroutineScope, - appForegroundStateService = FakeAppForegroundStateService(), - networkMonitor = FakeNetworkMonitor(), - dispatchers = testCoroutineDispatchers(), - analyticsService = FakeAnalyticsService(), - ) + private fun TestScope.createMatrixSessionCache( + authenticationService: FakeMatrixAuthenticationService = FakeMatrixAuthenticationService(), + syncOrchestratorFactory: SyncOrchestrator.Factory = createSyncOrchestratorFactory(), + analyticsService: FakeAnalyticsService = FakeAnalyticsService(), + ) = MatrixSessionCache( + authenticationService = authenticationService, + syncOrchestratorFactory = syncOrchestratorFactory, + analyticsService = analyticsService, + ) + + private fun TestScope.createSyncOrchestratorFactory(): SyncOrchestrator.Factory { + val dispatchers = testCoroutineDispatchers() + + return object : SyncOrchestrator.Factory { + override fun create( + syncService: SyncService, + sessionCoroutineScope: CoroutineScope, + ): SyncOrchestrator { + return SyncOrchestrator( + syncService = syncService, + sessionCoroutineScope = sessionCoroutineScope, + appForegroundStateService = FakeAppForegroundStateService(), + networkMonitor = FakeNetworkMonitor(), + dispatchers = dispatchers, + analyticsService = FakeAnalyticsService(), + ) + } } } } diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/ChildScopeOf.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/ChildScopeOf.kt index 1fba021530..46831a2698 100644 --- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/ChildScopeOf.kt +++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/ChildScopeOf.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.job import kotlinx.coroutines.plus +import kotlinx.coroutines.test.TestScope /** * Create a child scope of the current scope. @@ -28,6 +29,11 @@ fun CoroutineScope.childScope( dispatcher: CoroutineDispatcher, name: String, ): CoroutineScope = run { - val supervisorJob = SupervisorJob(parent = coroutineContext.job) - this + dispatcher + supervisorJob + CoroutineName(name) + if (this is TestScope) { + // Special case for tests: we can't start a coroutine with a different SupervisorJob + this + } else { + val supervisorJob = SupervisorJob(parent = coroutineContext.job) + this + dispatcher + supervisorJob + CoroutineName(name) + } } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt index 9c8feef2dc..851f64c230 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt @@ -175,7 +175,7 @@ class RustBaseRoomTest { ), roomMembershipObserver = roomMembershipObserver, // Not using backgroundScope here, but the test scope - sessionCoroutineScope = this, + sessionCoroutineScope = backgroundScope, roomInfoMapper = RoomInfoMapper(), initialRoomInfo = initialRoomInfo, ) From 7fe3b18699e9df3dc7a67d0a487ce48615fc0192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 17:45:56 +0100 Subject: [PATCH 195/347] Distinguish between indexable and non-indexable extra data --- .../android/appnav/di/MatrixSessionCache.kt | 2 +- .../android/appnav/di/SyncOrchestrator.kt | 3 +- .../impl/timeline/TimelinePresenter.kt | 3 +- .../analytics/api/NoopAnalyticsTransaction.kt | 3 +- .../analytics/impl/DefaultAnalyticsService.kt | 10 ++++-- .../api/AnalyticsTransaction.kt | 35 ++++++++++++++++++- .../api/AnalyticsUserData.kt | 3 ++ .../api/trackers/AnalyticsTracker.kt | 11 ++++-- .../sentry/SentryAnalyticsProvider.kt | 6 +++- .../sentry/SentryAnalyticsTransaction.kt | 4 ++- 10 files changed, 69 insertions(+), 11 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt index c639a9abd7..c6a031921f 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/di/MatrixSessionCache.kt @@ -106,7 +106,7 @@ class MatrixSessionCache( .onSuccess { matrixClient -> // Add the current homeserver (hashed) to the extra info // This may not play well with multiple sessions, but it should work for now - analyticsService.addUserData(AnalyticsUserData.HOMESERVER, matrixClient.userIdServerName().hash()) + analyticsService.addIndexableData(AnalyticsUserData.HOMESERVER, matrixClient.userIdServerName().hash()) // Add the new client to the in-memory cache onNewMatrixClient(matrixClient) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/di/SyncOrchestrator.kt b/appnav/src/main/kotlin/io/element/android/appnav/di/SyncOrchestrator.kt index 53ce50a788..9b1bbd1b81 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/di/SyncOrchestrator.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/di/SyncOrchestrator.kt @@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.recordTransaction +import io.element.android.services.analyticsproviders.api.AnalyticsUserData import io.element.android.services.appnavstate.api.AppForegroundStateService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.FlowPreview @@ -77,7 +78,7 @@ class SyncOrchestrator( // Wait until the sync service is not idle, either it will be running or in error/offline state val firstState = syncService.syncState.first { it != SyncState.Idle } - transaction.setData("first_sync_state", firstState.name) + transaction.putIndexableData(AnalyticsUserData.FIRST_SYNC_STATE, firstState.name) } observeStates() 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 289ec2924d..a953c6e349 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 @@ -60,6 +60,7 @@ import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.finishLongRunningTransaction +import io.element.android.services.analyticsproviders.api.AnalyticsUserData import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.CoroutineScope @@ -249,7 +250,7 @@ class TimelinePresenter( combine(timelineController.timelineItems(), room.membersStateFlow) { items, membersState -> val parent = analyticsService.getLongRunningTransaction(DisplayFirstTimelineItems) val transaction = parent?.startChild("timelineItemsFactory.replaceWith", "Processing timeline items") - transaction?.setData("items", items.count()) + transaction?.putExtraData(AnalyticsUserData.TIMELINE_ITEM_COUNT, items.count().toString()) timelineItemsFactory.replaceWith( timelineItems = items, roomMembers = membersState.roomMembers().orEmpty() diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt index e6f69ae99b..914fac1b12 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/NoopAnalyticsTransaction.kt @@ -11,7 +11,8 @@ import io.element.android.services.analyticsproviders.api.AnalyticsTransaction object NoopAnalyticsTransaction : AnalyticsTransaction { override fun startChild(operation: String, description: String?): AnalyticsTransaction = NoopAnalyticsTransaction - override fun setData(key: String, value: Any) {} + override fun putExtraData(key: String, value: String) {} + override fun putIndexableData(key: String, value: String) {} override fun isFinished(): Boolean = true override fun traceId(): String? = null override fun attachError(throwable: Throwable) {} diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt index 764d2e9796..5db1eb1b31 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt @@ -149,9 +149,15 @@ class DefaultAnalyticsService( } } - override fun addUserData(key: String, value: String) { + override fun addExtraData(key: String, value: String) { if (userConsent.get()) { - analyticsProviders.onEach { it.addUserData(key, value) } + analyticsProviders.onEach { it.addExtraData(key, value) } + } + } + + override fun addIndexableData(key: String, value: String) { + if (userConsent.get()) { + analyticsProviders.onEach { it.addIndexableData(key, value) } } } diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt index 84575d5dd0..b5f81ac67e 100644 --- a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransaction.kt @@ -8,14 +8,47 @@ package io.element.android.services.analyticsproviders.api interface AnalyticsTransaction { + /** + * Start a child span from this transaction. + */ fun startChild(operation: String, description: String? = null): AnalyticsTransaction - fun setData(key: String, value: Any) + + /** + * Adds extra data to the transaction. This data is not indexed, it's just listed. + */ + fun putExtraData(key: String, value: String) + + /** + * Similar to [putExtraData], adds extra data that *will be indexed* and can be used for filtering in the analytics portal. + * + * **Do not add numerical values using this function, use [putExtraData] instead.** + */ + fun putIndexableData(key: String, value: String) + + /** + * Whether the transaction has finished. + */ fun isFinished(): Boolean + + /** + * The optional trace id which can be used for distributed tracing. + */ fun traceId(): String? + + /** + * Attach a throwable to the transaction, so we can know it failed. + */ fun attachError(throwable: Throwable) + + /** + * Finish the transaction. This will schedule an upload of the data. + */ fun finish() } +/** + * Records a child span from this transaction. + */ inline fun AnalyticsTransaction.recordChildTransaction(operation: String, description: String? = null, block: (AnalyticsTransaction) -> T): T { val child = startChild(operation, description) try { diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsUserData.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsUserData.kt index 44080f824d..28ae4a5668 100644 --- a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsUserData.kt +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsUserData.kt @@ -14,4 +14,7 @@ object AnalyticsUserData { const val EVENT_CACHE_SIZE = "event_cache_size" const val CRYPTO_STORE_SIZE = "crypto_store_size" const val MEDIA_STORE_SIZE = "media_store_size" + + const val FIRST_SYNC_STATE = "first_sync_state" + const val TIMELINE_ITEM_COUNT = "timeline_item_count" } diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/trackers/AnalyticsTracker.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/trackers/AnalyticsTracker.kt index 9ac7d13f2a..5bb63338a8 100644 --- a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/trackers/AnalyticsTracker.kt +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/trackers/AnalyticsTracker.kt @@ -37,9 +37,16 @@ interface AnalyticsTracker { fun updateSuperProperties(updatedProperties: SuperProperties) /** - * Adds user data that will be sent with every event. + * Adds extra data that will be sent with every event. */ - fun addUserData(key: String, value: String) {} + fun addExtraData(key: String, value: String) {} + + /** + * Similar to [addExtraData], adds data that will be indexed in the analytics portal. + * + * **Do not add numerical values using this, use [addExtraData] instead.** + */ + fun addIndexableData(key: String, value: String) {} } fun AnalyticsTracker.captureInteraction(name: Interaction.Name, type: Interaction.InteractionType? = null) { diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index e7f49079a4..629426d6c2 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -113,10 +113,14 @@ class SentryAnalyticsProvider( override fun updateSuperProperties(updatedProperties: SuperProperties) { } - override fun addUserData(key: String, value: String) { + override fun addExtraData(key: String, value: String) { Sentry.setExtra(key, value) } + override fun addIndexableData(key: String, value: String) { + Sentry.setTag(key, value) + } + override fun trackError(throwable: Throwable) { Sentry.captureException(throwable) } diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt index 77a008b0a4..84314ee35f 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt @@ -20,7 +20,9 @@ class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTra override fun startChild(operation: String, description: String?): AnalyticsTransaction = SentryAnalyticsTransaction( inner.startChild(operation, description) ) - override fun setData(key: String, value: Any) = inner.setData(key, value) + + override fun putIndexableData(key: String, value: String) = inner.setTag(key, value) + override fun putExtraData(key: String, value: String) = inner.setData(key, value) override fun traceId(): String? = inner.toSentryTrace().value override fun isFinished(): Boolean = inner.isFinished override fun attachError(throwable: Throwable) { From 88f45517ca1cbd56c35d3226596f4f244265fba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 18:08:54 +0100 Subject: [PATCH 196/347] Fix test --- .../impl/developer/DeveloperSettingsPresenterTest.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt index fa5f5fd0f6..a2d7b2c18a 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt @@ -29,6 +29,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeature import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase +import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.core.aBuildMeta @@ -251,7 +252,7 @@ class DeveloperSettingsPresenterTest { buildMeta: BuildMeta = aBuildMeta(), enterpriseService: EnterpriseService = FakeEnterpriseService(), vacuumStoresUseCase: VacuumStoresUseCase = VacuumStoresUseCase {}, - datbaseSizesUseCase: GetDatabaseSizesUseCase = GetDatabaseSizesUseCase { Result.success(emptyMap()) }, + databaseSizesUseCase: GetDatabaseSizesUseCase = GetDatabaseSizesUseCase { Result.success(SdkStoreSizes(null, null, null, null)) }, ): DeveloperSettingsPresenter { return DeveloperSettingsPresenter( sessionId = sessionId, @@ -263,7 +264,7 @@ class DeveloperSettingsPresenterTest { buildMeta = buildMeta, enterpriseService = enterpriseService, vacuumStoresUseCase = vacuumStoresUseCase, - databaseSizesUseCase = datbaseSizesUseCase, + databaseSizesUseCase = databaseSizesUseCase, fileSizeFormatter = FakeFileSizeFormatter(), ) } From 4ef0dfed8cba84bb5b8c1d7c771635bb6a0a7a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 16 Dec 2025 18:30:35 +0100 Subject: [PATCH 197/347] Try fixing UI test (it works locally) --- .../preferences/impl/developer/DeveloperSettingsViewTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsViewTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsViewTest.kt index e812bf650d..3854e3f4a1 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsViewTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsViewTest.kt @@ -113,7 +113,7 @@ class DeveloperSettingsViewTest { eventsRecorder.assertSingle(DeveloperSettingsEvents.SetTracingLogLevel(LogLevelItem.DEBUG)) } - @Config(qualifiers = "h2000dp") + @Config(qualifiers = "h2200dp") @Test fun `clicking on clear cache emits the expected event`() { val eventsRecorder = EventsRecorder() From 9a9e84f6c86ef5e96e0214fad984cb94b61f0fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 17 Dec 2025 08:53:01 +0100 Subject: [PATCH 198/347] Add tests for `SentryAnalyticsProvider` --- .../sentry/build.gradle.kts | 5 + .../sentry/SentryAnalyticsProvider.kt | 43 +++-- .../sentry/SentryAnalyticsProviderTest.kt | 173 ++++++++++++++++++ 3 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt diff --git a/services/analyticsproviders/sentry/build.gradle.kts b/services/analyticsproviders/sentry/build.gradle.kts index 5f8ec01996..02dde35ef4 100644 --- a/services/analyticsproviders/sentry/build.gradle.kts +++ b/services/analyticsproviders/sentry/build.gradle.kts @@ -2,6 +2,7 @@ import config.BuildTimeConfig import extension.buildConfigFieldStr import extension.readLocalProperty import extension.setupDependencyInjection +import extension.testCommonDependencies /* * Copyright (c) 2025 Element Creations Ltd. @@ -54,4 +55,8 @@ dependencies { implementation(projects.libraries.matrix.api) implementation(projects.services.analyticsproviders.api) implementation(projects.services.appnavstate.api) + + testCommonDependencies(libs, false) + testImplementation(projects.libraries.matrix.test) + testImplementation(projects.services.appnavstate.test) } diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index 629426d6c2..3cea95bcae 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -9,6 +9,7 @@ package io.element.android.services.analyticsproviders.sentry import android.content.Context +import androidx.annotation.VisibleForTesting import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesIntoSet import dev.zacsweers.metro.Inject @@ -31,6 +32,7 @@ import io.sentry.Breadcrumb import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.android.core.SentryAndroid +import io.sentry.protocol.SentryTransaction import kotlinx.coroutines.runBlocking import timber.log.Timber @@ -56,24 +58,7 @@ class SentryAnalyticsProvider( SentryAndroid.init(context) { options -> options.dsn = dsn options.beforeSendTransaction = SentryOptions.BeforeSendTransactionCallback { transaction, _ -> - // Ensure we'll never upload any session ids - val possibleSessionIds = transaction.extras?.filter { (it.value as? String)?.startsWith("@") == true }.orEmpty() - for (invalidExtra in possibleSessionIds) { - transaction.extras?.remove(invalidExtra.key) - } - - val sessionId = appNavigationStateService.appNavigationState.value.navigationState.currentSessionId() - if (sessionId != null) { - // This runs in a separate thread, so although using `runBlocking` is not great, at least it shouldn't freeze the app - // Also, the method is fairly quick, so the blocking shouldn't take longer than a few ms - val databaseSizes = runBlocking { getDatabaseSizesUseCase(sessionId) }.getOrNull() - - databaseSizes?.stateStore?.let { transaction.setExtra(AnalyticsUserData.STATE_STORE_SIZE, it.into(ByteUnit.MB)) } - databaseSizes?.eventCacheStore?.let { transaction.setExtra(AnalyticsUserData.EVENT_CACHE_SIZE, it.into(ByteUnit.MB)) } - databaseSizes?.mediaStore?.let { transaction.setExtra(AnalyticsUserData.MEDIA_STORE_SIZE, it.into(ByteUnit.MB)) } - databaseSizes?.cryptoStore?.let { transaction.setExtra(AnalyticsUserData.CRYPTO_STORE_SIZE, it.into(ByteUnit.MB)) } - } - transaction + prepareTransactionBeforeSend(transaction) } options.tracesSampleRate = 1.0 options.isEnableUserInteractionTracing = true @@ -128,6 +113,28 @@ class SentryAnalyticsProvider( override fun startTransaction(name: String, operation: String?): AnalyticsTransaction? { return SentryAnalyticsTransaction(name, operation) } + + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + internal fun prepareTransactionBeforeSend(transaction: SentryTransaction): SentryTransaction { + // Ensure we'll never upload any session ids + val possibleSessionIds = transaction.extras?.filter { (it.value as? String)?.startsWith("@") == true }.orEmpty() + for (invalidExtra in possibleSessionIds) { + transaction.removeExtra(invalidExtra.key) + } + + val sessionId = appNavigationStateService.appNavigationState.value.navigationState.currentSessionId() + if (sessionId != null) { + // This runs in a separate thread, so although using `runBlocking` is not great, at least it shouldn't freeze the app + // Also, the method is fairly quick, so the blocking shouldn't take longer than a few ms + val databaseSizes = runBlocking { getDatabaseSizesUseCase(sessionId) }.getOrNull() + + databaseSizes?.stateStore?.let { transaction.setExtra(AnalyticsUserData.STATE_STORE_SIZE, it.into(ByteUnit.MB)) } + databaseSizes?.eventCacheStore?.let { transaction.setExtra(AnalyticsUserData.EVENT_CACHE_SIZE, it.into(ByteUnit.MB)) } + databaseSizes?.mediaStore?.let { transaction.setExtra(AnalyticsUserData.MEDIA_STORE_SIZE, it.into(ByteUnit.MB)) } + databaseSizes?.cryptoStore?.let { transaction.setExtra(AnalyticsUserData.CRYPTO_STORE_SIZE, it.into(ByteUnit.MB)) } + } + return transaction + } } private fun BuildType.toSentryEnv() = when (this) { diff --git a/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt b/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt new file mode 100644 index 0000000000..da496cb612 --- /dev/null +++ b/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt @@ -0,0 +1,173 @@ +/* + * 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.services.analyticsproviders.sentry + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import com.google.common.truth.Truth.assertThat +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent +import im.vector.app.features.analytics.itf.VectorAnalyticsScreen +import im.vector.app.features.analytics.plan.SuperProperties +import im.vector.app.features.analytics.plan.UserProperties +import io.element.android.libraries.core.data.megaBytes +import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase +import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes +import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.matrix.test.core.aBuildMeta +import io.element.android.services.analyticsproviders.api.AnalyticsUserData +import io.element.android.services.appnavstate.api.AppNavigationState +import io.element.android.services.appnavstate.api.NavigationState +import io.element.android.services.appnavstate.test.FakeAppNavigationStateService +import io.sentry.Sentry +import io.sentry.SentryTracer +import io.sentry.protocol.SentryId +import io.sentry.protocol.SentryTransaction +import kotlinx.coroutines.flow.MutableStateFlow +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SentryAnalyticsProviderTest { + @Test + fun `init enables Sentry`() { + createSentryAnalyticsProvider().run { + init() + } + assertThat(Sentry.isEnabled()).isTrue() + } + + @Test + fun `stop disables Sentry`() { + createSentryAnalyticsProvider().run { + init() + stop() + } + assertThat(Sentry.isEnabled()).isFalse() + } + + @Test + fun `capture adds a breadcrumb`() { + createSentryAnalyticsProvider().run { + init() + capture(object : VectorAnalyticsEvent { + override fun getName(): String = "Test" + override fun getProperties(): Map? = null + }) + } + assertThat(Sentry.getCurrentScopes().scope.breadcrumbs.isNotEmpty()).isTrue() + } + + @Test + fun `screen adds a breadcrumb`() { + createSentryAnalyticsProvider().run { + init() + screen(object : VectorAnalyticsScreen { + override fun getName(): String = "Test" + override fun getProperties(): Map? = null + }) + } + assertThat(Sentry.getCurrentScopes().scope.breadcrumbs.isNotEmpty()).isTrue() + } + + @Test + fun `updateUserProperties and updateSuperProperties do nothing`() { + createSentryAnalyticsProvider().run { + init() + updateUserProperties(UserProperties()) + updateSuperProperties(SuperProperties()) + } + val scope = Sentry.getCurrentScopes().scope + assertThat(scope.extras.isEmpty()).isTrue() + assertThat(scope.tags.isEmpty()).isTrue() + assertThat(scope.contexts.isEmpty()).isTrue() + } + + @Test + fun `addExtraData adds a global extra`() { + createSentryAnalyticsProvider().run { + init() + addExtraData("foo", "bar") + } + val scope = Sentry.getCurrentScopes().scope + assertThat(scope.extras.get("foo")).isEqualTo("bar") + } + + @Test + fun `addIndexableData adds a global tag`() { + createSentryAnalyticsProvider().run { + init() + addIndexableData("foo", "bar") + } + val scope = Sentry.getCurrentScopes().scope + assertThat(scope.tags.get("foo")).isEqualTo("bar") + } + + @Test + fun `trackError adds a throwable to the global scope`() { + var initialLastId: SentryId? = null + createSentryAnalyticsProvider().run { + init() + initialLastId = Sentry.getLastEventId() + trackError(IllegalStateException("foo")) + } + assertThat(Sentry.getLastEventId()).isNotEqualTo(initialLastId) + } + + @Test + fun `startTransaction starts a SentryAnalyticsTransaction`() { + val transaction = createSentryAnalyticsProvider().run { + init() + startTransaction("foo") + } + assertThat(transaction).isNotNull() + assertThat(transaction).isInstanceOf(SentryAnalyticsTransaction::class.java) + } + + @Test + fun `prepareTransactionBeforeSend removes unwanted data and adds DB size extras`() { + createSentryAnalyticsProvider( + getDatabaseSizesUseCase = GetDatabaseSizesUseCase { + Result.success( + SdkStoreSizes(stateStore = 10.megaBytes, eventCacheStore = 11.megaBytes, mediaStore = 12.megaBytes, cryptoStore = 13.megaBytes) + ) + }, + appNavigationStateService = FakeAppNavigationStateService( + MutableStateFlow(AppNavigationState(navigationState = NavigationState.Session("owner", A_SESSION_ID), isInForeground = true)) + ) + ).run { + init() + + val transaction = SentryTransaction(Sentry.startTransaction("foo", "bar") as SentryTracer) + // Add a user id value + transaction.setExtra("user", "@some:user") + + val result = prepareTransactionBeforeSend(transaction) + + // The user id value should have been removed + assertThat(result.getExtra("user")).isNull() + + // The DB sizes should be included + assertThat(result.getExtra(AnalyticsUserData.STATE_STORE_SIZE)).isEqualTo(10) + assertThat(result.getExtra(AnalyticsUserData.EVENT_CACHE_SIZE)).isEqualTo(11) + assertThat(result.getExtra(AnalyticsUserData.MEDIA_STORE_SIZE)).isEqualTo(12) + assertThat(result.getExtra(AnalyticsUserData.CRYPTO_STORE_SIZE)).isEqualTo(13) + } + } + + private fun createSentryAnalyticsProvider( + buildMeta: BuildMeta = aBuildMeta(), + getDatabaseSizesUseCase: GetDatabaseSizesUseCase = GetDatabaseSizesUseCase { Result.success(SdkStoreSizes(null, null, null, null)) }, + appNavigationStateService: FakeAppNavigationStateService = FakeAppNavigationStateService(), + ) = SentryAnalyticsProvider( + context = InstrumentationRegistry.getInstrumentation().targetContext, + buildMeta = buildMeta, + getDatabaseSizesUseCase = getDatabaseSizesUseCase, + appNavigationStateService = appNavigationStateService, + ) +} From de694cecdbdb778618bf99f473d0fb58e876cf1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 17 Dec 2025 09:01:35 +0100 Subject: [PATCH 199/347] Add tests for `RustMatrixClient.getDatabaseSizes()` --- .../android/libraries/core/data/ByteSize.kt | 17 +++++++++++++++++ .../matrix/impl/RustMatrixClientTest.kt | 16 ++++++++++++++++ .../matrix/impl/fixtures/fakes/FakeFfiClient.kt | 6 ++++++ 3 files changed, 39 insertions(+) diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/data/ByteSize.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/data/ByteSize.kt index c91dc96a4a..f4daf85011 100644 --- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/data/ByteSize.kt +++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/data/ByteSize.kt @@ -19,6 +19,23 @@ class ByteSize internal constructor(val value: Long, val unit: ByteUnit) { if (unit == dest) return value return value shl unit.bitShift shr dest.bitShift } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is ByteSize) return false + + return value == other.value && unit == other.unit + } + + override fun hashCode(): Int { + var result = value.hashCode() + result = 31 * result + unit.hashCode() + return result + } + + override fun toString(): String { + return "$value $unit" + } } val Number.gigaBytes get() = ByteSize(toLong(), ByteUnit.GB) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt index 3c8619ed72..fc459dba86 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt @@ -11,6 +11,7 @@ package io.element.android.libraries.matrix.impl import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.core.data.bytes import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClient import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiSyncService @@ -34,6 +35,7 @@ import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import org.junit.Test import org.matrix.rustcomponents.sdk.Client +import org.matrix.rustcomponents.sdk.StoreSizes import org.matrix.rustcomponents.sdk.UserProfile import java.io.File @@ -98,6 +100,20 @@ class RustMatrixClientTest { client.destroy() } + @Test + fun `getDatabaseSizes returns the database sizes`() = runTest { + val client = createRustMatrixClient( + client = FakeFfiClient(getStoreSizesResult = { StoreSizes(null, 10uL, 11uL, 12uL) }) + ) + + client.getDatabaseSizes().getOrThrow().run { + assertThat(cryptoStore).isNull() + assertThat(stateStore).isEqualTo(10.bytes) + assertThat(eventCacheStore).isEqualTo(11.bytes) + assertThat(mediaStore).isEqualTo(12.bytes) + } + } + private fun TestScope.createRustMatrixClient( client: Client = FakeFfiClient(), sessionStore: SessionStore = InMemorySessionStore( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt index 3196cd1173..db33393ac2 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt @@ -28,6 +28,7 @@ import org.matrix.rustcomponents.sdk.RoomDirectorySearch import org.matrix.rustcomponents.sdk.Session import org.matrix.rustcomponents.sdk.SessionVerificationController import org.matrix.rustcomponents.sdk.SpaceService +import org.matrix.rustcomponents.sdk.StoreSizes import org.matrix.rustcomponents.sdk.SyncService import org.matrix.rustcomponents.sdk.SyncServiceBuilder import org.matrix.rustcomponents.sdk.TaskHandle @@ -46,6 +47,7 @@ class FakeFfiClient( private val withUtdHook: (UnableToDecryptDelegate) -> Unit = { lambdaError() }, private val getProfileResult: (String) -> UserProfile = { UserProfile(userId = userId, displayName = null, avatarUrl = null) }, private val homeserverLoginDetailsResult: () -> HomeserverLoginDetails = { lambdaError() }, + private val getStoreSizesResult: () -> StoreSizes = { lambdaError() }, private val closeResult: () -> Unit = {}, ) : Client(NoHandle) { override fun userId(): String = userId @@ -91,5 +93,9 @@ class FakeFfiClient( override suspend fun setMediaRetentionPolicy(policy: MediaRetentionPolicy) {} + override suspend fun getStoreSizes(): StoreSizes { + return getStoreSizesResult() + } + override fun close() = closeResult() } From b5d68437254a6d5490ce775da8f25afe4e3ba5f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 17 Dec 2025 10:16:17 +0100 Subject: [PATCH 200/347] Inject `SentryDsn` the same way we do with `SentrySdkDsn` so we can fake it for tests --- .../kotlin/io/element/android/x/di/AppBindings.kt | 2 +- .../android/libraries/di/identifiers/SentryDsn.kt | 11 +++++++++++ .../di/{annotations => identifiers}/SentrySdkDsn.kt | 2 +- .../services/analytics/noop/di/NoopAnalyticsModule.kt | 2 +- .../sentry/SentryAnalyticsProvider.kt | 4 +++- .../analyticsproviders/sentry/di/SentryModule.kt | 8 ++++++-- .../sentry/SentryAnalyticsProviderTest.kt | 3 +++ 7 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 libraries/di/src/main/kotlin/io/element/android/libraries/di/identifiers/SentryDsn.kt rename libraries/di/src/main/kotlin/io/element/android/libraries/di/{annotations => identifiers}/SentrySdkDsn.kt (83%) diff --git a/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt b/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt index d7bfda93a6..6768d0d8db 100644 --- a/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt +++ b/app/src/main/kotlin/io/element/android/x/di/AppBindings.kt @@ -17,7 +17,7 @@ import io.element.android.features.lockscreen.api.LockScreenService import io.element.android.features.rageshake.api.reporter.BugReporter import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher -import io.element.android.libraries.di.annotations.SentrySdkDsn +import io.element.android.libraries.di.identifiers.SentrySdkDsn import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.matrix.api.platform.InitPlatformService import io.element.android.libraries.matrix.api.tracing.TracingService diff --git a/libraries/di/src/main/kotlin/io/element/android/libraries/di/identifiers/SentryDsn.kt b/libraries/di/src/main/kotlin/io/element/android/libraries/di/identifiers/SentryDsn.kt new file mode 100644 index 0000000000..264af2e6e1 --- /dev/null +++ b/libraries/di/src/main/kotlin/io/element/android/libraries/di/identifiers/SentryDsn.kt @@ -0,0 +1,11 @@ +/* + * 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.di.identifiers + +@JvmInline +value class SentryDsn(val value: String) diff --git a/libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt b/libraries/di/src/main/kotlin/io/element/android/libraries/di/identifiers/SentrySdkDsn.kt similarity index 83% rename from libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt rename to libraries/di/src/main/kotlin/io/element/android/libraries/di/identifiers/SentrySdkDsn.kt index 19a0eac017..f1ebe2e5c2 100644 --- a/libraries/di/src/main/kotlin/io/element/android/libraries/di/annotations/SentrySdkDsn.kt +++ b/libraries/di/src/main/kotlin/io/element/android/libraries/di/identifiers/SentrySdkDsn.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.di.annotations +package io.element.android.libraries.di.identifiers @JvmInline value class SentrySdkDsn(val value: String) diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt index 26e4f16b37..3c4b00c7a0 100644 --- a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/di/NoopAnalyticsModule.kt @@ -11,7 +11,7 @@ import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.BindingContainer import dev.zacsweers.metro.ContributesTo import dev.zacsweers.metro.Provides -import io.element.android.libraries.di.annotations.SentrySdkDsn +import io.element.android.libraries.di.identifiers.SentrySdkDsn @BindingContainer @ContributesTo(AppScope::class) diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index 3cea95bcae..df4f3a68a1 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -21,6 +21,7 @@ import io.element.android.libraries.core.data.ByteUnit import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.di.annotations.ApplicationContext +import io.element.android.libraries.di.identifiers.SentryDsn import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase import io.element.android.services.analyticsproviders.api.AnalyticsProvider import io.element.android.services.analyticsproviders.api.AnalyticsTransaction @@ -40,6 +41,7 @@ import timber.log.Timber @Inject class SentryAnalyticsProvider( @ApplicationContext private val context: Context, + private val sentryDsn: SentryDsn?, private val buildMeta: BuildMeta, private val getDatabaseSizesUseCase: GetDatabaseSizesUseCase, private val appNavigationStateService: AppNavigationStateService, @@ -50,7 +52,7 @@ class SentryAnalyticsProvider( Timber.tag(analyticsTag.value).d("Initializing Sentry") if (Sentry.isEnabled()) return - val dsn = SentryConfig.DSN.ifBlank { + val dsn = sentryDsn?.value ?: run { Timber.w("No Sentry DSN provided, Sentry will not be initialized") return } diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt index 1887ed829b..74b7d56683 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/di/SentryModule.kt @@ -11,12 +11,16 @@ import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.BindingContainer import dev.zacsweers.metro.ContributesTo import dev.zacsweers.metro.Provides -import io.element.android.libraries.di.annotations.SentrySdkDsn +import io.element.android.libraries.di.identifiers.SentryDsn +import io.element.android.libraries.di.identifiers.SentrySdkDsn import io.element.android.services.analyticsproviders.sentry.SentryConfig @BindingContainer @ContributesTo(AppScope::class) object SentryModule { @Provides - fun provideSentrySdkDsn(): SentrySdkDsn? = SentrySdkDsn(SentryConfig.SDK_DSN) + fun provideSentryDsn(): SentryDsn? = SentryConfig.DSN.takeIf { it.isNotBlank() }?.let(::SentryDsn) + + @Provides + fun provideSentrySdkDsn(): SentrySdkDsn? = SentryConfig.SDK_DSN.takeIf { it.isNotBlank() }?.let(::SentrySdkDsn) } diff --git a/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt b/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt index da496cb612..057cd972af 100644 --- a/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt +++ b/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt @@ -16,6 +16,7 @@ import im.vector.app.features.analytics.plan.SuperProperties import im.vector.app.features.analytics.plan.UserProperties import io.element.android.libraries.core.data.megaBytes import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.di.identifiers.SentryDsn import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes import io.element.android.libraries.matrix.test.A_SESSION_ID @@ -161,11 +162,13 @@ class SentryAnalyticsProviderTest { } private fun createSentryAnalyticsProvider( + sentryDsn: SentryDsn? = SentryDsn("https://1234@sentry.com/a"), buildMeta: BuildMeta = aBuildMeta(), getDatabaseSizesUseCase: GetDatabaseSizesUseCase = GetDatabaseSizesUseCase { Result.success(SdkStoreSizes(null, null, null, null)) }, appNavigationStateService: FakeAppNavigationStateService = FakeAppNavigationStateService(), ) = SentryAnalyticsProvider( context = InstrumentationRegistry.getInstrumentation().targetContext, + sentryDsn = sentryDsn, buildMeta = buildMeta, getDatabaseSizesUseCase = getDatabaseSizesUseCase, appNavigationStateService = appNavigationStateService, From 69eda26235bed67d0bab619cb31d0b8f30417d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 17 Dec 2025 10:55:52 +0100 Subject: [PATCH 201/347] Check `computeCacheSize` function in `DeveloperSettingsPresenterTest` --- .../developer/DeveloperSettingsPresenterTest.kt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt index a2d7b2c18a..1fcf9bff70 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt @@ -22,6 +22,7 @@ import io.element.android.features.rageshake.api.preferences.aRageshakePreferenc import io.element.android.libraries.androidutils.filesize.FakeFileSizeFormatter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.core.data.megaBytes import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.featureflag.api.Feature @@ -38,6 +39,7 @@ 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.collections.immutable.persistentMapOf import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Rule @@ -59,7 +61,12 @@ class DeveloperSettingsPresenterTest { ) } val presenter = createDeveloperSettingsPresenter( - featureFlagService = FakeFeatureFlagService(getAvailableFeaturesResult = getAvailableFeaturesResult) + featureFlagService = FakeFeatureFlagService(getAvailableFeaturesResult = getAvailableFeaturesResult), + databaseSizesUseCase = GetDatabaseSizesUseCase { + Result.success( + SdkStoreSizes(stateStore = 10.megaBytes, eventCacheStore = 10.megaBytes, mediaStore = 10.megaBytes, cryptoStore = 10.megaBytes) + ) + } ) presenter.test { awaitItem().also { state -> @@ -82,6 +89,14 @@ class DeveloperSettingsPresenterTest { } awaitItem().also { state -> assertThat(state.cacheSize).isInstanceOf(AsyncData.Success::class.java) + assertThat(state.databaseSizes.dataOrNull()).isEqualTo( + persistentMapOf( + "State store" to "10485760 Bytes", + "Event cache store" to "10485760 Bytes", + "Media store" to "10485760 Bytes", + "Crypto store" to "10485760 Bytes" + ) + ) } getAvailableFeaturesResult.assertions().isCalledOnce() .with(value(false), value(false)) From 515f7f494648996eb4d08707da66a47f712de859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 17 Dec 2025 11:03:51 +0100 Subject: [PATCH 202/347] Add more tests to `SentryAnalyticsProviderTest` --- .../sentry/SentryAnalyticsProviderTest.kt | 76 ++++++++++++++++++- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt b/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt index 057cd972af..c98439dddd 100644 --- a/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt +++ b/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt @@ -5,6 +5,8 @@ * Please see LICENSE files in the repository root for full details. */ +@file:Suppress("UnstableApiUsage") + package io.element.android.services.analyticsproviders.sentry import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -36,13 +38,21 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class SentryAnalyticsProviderTest { @Test - fun `init enables Sentry`() { + fun `init enables Sentry if DSN is present`() { createSentryAnalyticsProvider().run { init() } assertThat(Sentry.isEnabled()).isTrue() } + @Test + fun `init does nothing if DSN is not present`() { + createSentryAnalyticsProvider(sentryDsn = null).run { + init() + } + assertThat(Sentry.isEnabled()).isTrue() + } + @Test fun `stop disables Sentry`() { createSentryAnalyticsProvider().run { @@ -58,7 +68,7 @@ class SentryAnalyticsProviderTest { init() capture(object : VectorAnalyticsEvent { override fun getName(): String = "Test" - override fun getProperties(): Map? = null + override fun getProperties(): Map? = mapOf("foo" to "bar") }) } assertThat(Sentry.getCurrentScopes().scope.breadcrumbs.isNotEmpty()).isTrue() @@ -70,7 +80,7 @@ class SentryAnalyticsProviderTest { init() screen(object : VectorAnalyticsScreen { override fun getName(): String = "Test" - override fun getProperties(): Map? = null + override fun getProperties(): Map? = mapOf("foo" to "bar") }) } assertThat(Sentry.getCurrentScopes().scope.breadcrumbs.isNotEmpty()).isTrue() @@ -161,11 +171,69 @@ class SentryAnalyticsProviderTest { } } + @Test + fun `prepareTransactionBeforeSend removes unwanted data and doesn't add anything if no session id is provided`() { + createSentryAnalyticsProvider( + getDatabaseSizesUseCase = GetDatabaseSizesUseCase { + Result.success( + SdkStoreSizes(stateStore = 10.megaBytes, eventCacheStore = 11.megaBytes, mediaStore = 12.megaBytes, cryptoStore = 13.megaBytes) + ) + }, + appNavigationStateService = FakeAppNavigationStateService( + MutableStateFlow(AppNavigationState(navigationState = NavigationState.Root, isInForeground = true)) + ) + ).run { + init() + + val transaction = SentryTransaction(Sentry.startTransaction("foo", "bar") as SentryTracer) + // Add a user id value + transaction.setExtra("user", "@some:user") + + val result = prepareTransactionBeforeSend(transaction) + + // The user id value should have been removed + assertThat(result.getExtra("user")).isNull() + + // The DB sizes are missing since there was no session id to query them + assertThat(result.extras).isEmpty() + } + } + + @Test + fun `prepareTransactionBeforeSend removes unwanted data and doesn't add anything if no store sizes are available`() { + createSentryAnalyticsProvider( + getDatabaseSizesUseCase = GetDatabaseSizesUseCase { + Result.success( + SdkStoreSizes(stateStore = null, eventCacheStore = null, mediaStore = null, cryptoStore = null) + ) + }, + appNavigationStateService = FakeAppNavigationStateService( + MutableStateFlow(AppNavigationState(navigationState = NavigationState.Session("owner", A_SESSION_ID), isInForeground = true)) + ) + ).run { + init() + + val transaction = SentryTransaction(Sentry.startTransaction("foo", "bar") as SentryTracer) + // Add a user id value + transaction.setExtra("user", "@some:user") + + val result = prepareTransactionBeforeSend(transaction) + + // The user id value should have been removed + assertThat(result.getExtra("user")).isNull() + + // The DB sizes are missing since there was no session id to query them + assertThat(result.extras).isEmpty() + } + } + private fun createSentryAnalyticsProvider( sentryDsn: SentryDsn? = SentryDsn("https://1234@sentry.com/a"), buildMeta: BuildMeta = aBuildMeta(), getDatabaseSizesUseCase: GetDatabaseSizesUseCase = GetDatabaseSizesUseCase { Result.success(SdkStoreSizes(null, null, null, null)) }, - appNavigationStateService: FakeAppNavigationStateService = FakeAppNavigationStateService(), + appNavigationStateService: FakeAppNavigationStateService = FakeAppNavigationStateService( + MutableStateFlow(AppNavigationState(navigationState = NavigationState.Session("owner", A_SESSION_ID), isInForeground = true)) + ) ) = SentryAnalyticsProvider( context = InstrumentationRegistry.getInstrumentation().targetContext, sentryDsn = sentryDsn, From 165032ea027fd93605bcdea0908bfa8a750f4d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 17 Dec 2025 13:09:23 +0100 Subject: [PATCH 203/347] Make sure we don't upload any user ids in tags either --- .../sentry/SentryAnalyticsProvider.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index df4f3a68a1..2a0677ed20 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -118,11 +118,15 @@ class SentryAnalyticsProvider( @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal fun prepareTransactionBeforeSend(transaction: SentryTransaction): SentryTransaction { - // Ensure we'll never upload any session ids - val possibleSessionIds = transaction.extras?.filter { (it.value as? String)?.startsWith("@") == true }.orEmpty() - for (invalidExtra in possibleSessionIds) { + // Ensure we'll never upload any session ids in extras or tags + val invalidExtras = transaction.extras?.filter { (it.value as? String)?.startsWith("@") == true }.orEmpty() + for (invalidExtra in invalidExtras) { transaction.removeExtra(invalidExtra.key) } + val invalidTags = transaction.tags?.filter { it.value.startsWith("@") }.orEmpty() + for (invalidTag in invalidExtras) { + transaction.removeTag(invalidTag.key) + } val sessionId = appNavigationStateService.appNavigationState.value.navigationState.currentSessionId() if (sessionId != null) { From dd7649414d003fe4b3cf0cc06fb2e8c0ec6dab62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 17 Dec 2025 13:31:51 +0100 Subject: [PATCH 204/347] Fix wrong variable being used, improve tests --- .../sentry/SentryAnalyticsProvider.kt | 2 +- .../sentry/SentryAnalyticsProviderTest.kt | 23 +++++-------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index 2a0677ed20..7545563736 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -124,7 +124,7 @@ class SentryAnalyticsProvider( transaction.removeExtra(invalidExtra.key) } val invalidTags = transaction.tags?.filter { it.value.startsWith("@") }.orEmpty() - for (invalidTag in invalidExtras) { + for (invalidTag in invalidTags) { transaction.removeTag(invalidTag.key) } diff --git a/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt b/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt index c98439dddd..24b938d9a5 100644 --- a/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt +++ b/services/analyticsproviders/sentry/src/test/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProviderTest.kt @@ -157,11 +157,13 @@ class SentryAnalyticsProviderTest { val transaction = SentryTransaction(Sentry.startTransaction("foo", "bar") as SentryTracer) // Add a user id value transaction.setExtra("user", "@some:user") + transaction.setTag("user", "@some:user") val result = prepareTransactionBeforeSend(transaction) // The user id value should have been removed assertThat(result.getExtra("user")).isNull() + assertThat(result.getTag("user")).isNull() // The DB sizes should be included assertThat(result.getExtra(AnalyticsUserData.STATE_STORE_SIZE)).isEqualTo(10) @@ -172,7 +174,7 @@ class SentryAnalyticsProviderTest { } @Test - fun `prepareTransactionBeforeSend removes unwanted data and doesn't add anything if no session id is provided`() { + fun `prepareTransactionBeforeSend doesn't add DB info if no session id is provided`() { createSentryAnalyticsProvider( getDatabaseSizesUseCase = GetDatabaseSizesUseCase { Result.success( @@ -186,21 +188,14 @@ class SentryAnalyticsProviderTest { init() val transaction = SentryTransaction(Sentry.startTransaction("foo", "bar") as SentryTracer) - // Add a user id value - transaction.setExtra("user", "@some:user") - val result = prepareTransactionBeforeSend(transaction) - - // The user id value should have been removed - assertThat(result.getExtra("user")).isNull() - // The DB sizes are missing since there was no session id to query them - assertThat(result.extras).isEmpty() + assertThat(result.extras).isNull() } } @Test - fun `prepareTransactionBeforeSend removes unwanted data and doesn't add anything if no store sizes are available`() { + fun `prepareTransactionBeforeSend doesn't add DB info if no store sizes are available`() { createSentryAnalyticsProvider( getDatabaseSizesUseCase = GetDatabaseSizesUseCase { Result.success( @@ -214,16 +209,10 @@ class SentryAnalyticsProviderTest { init() val transaction = SentryTransaction(Sentry.startTransaction("foo", "bar") as SentryTracer) - // Add a user id value - transaction.setExtra("user", "@some:user") - val result = prepareTransactionBeforeSend(transaction) - // The user id value should have been removed - assertThat(result.getExtra("user")).isNull() - // The DB sizes are missing since there was no session id to query them - assertThat(result.extras).isEmpty() + assertThat(result.extras).isNull() } } From 37d81fd4d1eec0e3cbaf020419dc19de477ba2a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 18 Dec 2025 13:34:08 +0100 Subject: [PATCH 205/347] Remove comment that was no longer valid --- .../android/libraries/matrix/impl/room/RustBaseRoomTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt index 851f64c230..6508c04112 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/RustBaseRoomTest.kt @@ -174,7 +174,6 @@ class RustBaseRoomTest { dispatchers = dispatchers, ), roomMembershipObserver = roomMembershipObserver, - // Not using backgroundScope here, but the test scope sessionCoroutineScope = backgroundScope, roomInfoMapper = RoomInfoMapper(), initialRoomInfo = initialRoomInfo, From e8198b246dc59ad5ee4be662dbd8cd5735841fdf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:23:21 +0100 Subject: [PATCH 206/347] chore(deps): update plugin sonarqube to v7.2.2.6593 (#5927) 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 c2d2ef02cc..e41d29813f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -264,7 +264,7 @@ roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" } sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" } knit = { id = "org.jetbrains.kotlinx.knit", version = "0.5.0" } -sonarqube = "org.sonarqube:7.2.1.6560" +sonarqube = "org.sonarqube:7.2.2.6593" licensee = "app.cash.licensee:1.14.1" compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } gms_google_services = { id = "com.google.gms.google-services", version = "4.4.4" } From 8f6a12f1e6561b8579b0a2622fa5198f1034c23b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 18 Dec 2025 14:48:23 +0100 Subject: [PATCH 207/347] Rename vars. --- .../linknewdevice/impl/LinkNewDeviceFlowNode.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt index 3294476c44..e3b1d06cf0 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt @@ -78,21 +78,21 @@ class LinkNewDeviceFlowNode( override fun onBuilt() { super.onBuilt() - var job1: Job? = null - var job2: Job? = null + var linkMobileHandlerJob: Job? = null + var linkDesktopHandlerJob: Job? = null lifecycle.subscribe( onCreate = { linkNewMobileHandler.reset() linkNewDesktopHandler.reset() @Suppress("AssignedValueIsNeverRead") - job1 = observeLinkNewMobileHandler() + linkMobileHandlerJob = observeLinkNewMobileHandler() @Suppress("AssignedValueIsNeverRead") - job2 = observeLinkNewDesktopHandler() + linkDesktopHandlerJob = observeLinkNewDesktopHandler() }, onDestroy = { - job1?.cancel() - job2?.cancel() + linkMobileHandlerJob?.cancel() + linkDesktopHandlerJob?.cancel() } ) } From b449d4d1306a7b7ad2183b0e7cc8d02adaa472f8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 18 Dec 2025 15:06:44 +0100 Subject: [PATCH 208/347] Reset the handlers when starting over after an error. --- .../features/linknewdevice/impl/LinkNewDeviceFlowNode.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt index e3b1d06cf0..97d73bbc05 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt @@ -258,6 +258,8 @@ class LinkNewDeviceFlowNode( is NavTarget.Error -> { val callback = object : ErrorNode.Callback { override fun onRetry() { + linkNewMobileHandler.reset() + linkNewDesktopHandler.reset() backstack.newRoot(NavTarget.Root) } } From 6ccbc88ef52fb5e28acc002f4f8574b1618dadfb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 18 Dec 2025 15:07:08 +0100 Subject: [PATCH 209/347] Reset the handlers when coming back from ShowQrCode screen. --- .../android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt index 97d73bbc05..23c6b6ab2d 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewDeviceFlowNode.kt @@ -247,6 +247,7 @@ class LinkNewDeviceFlowNode( is NavTarget.MobileShowQrCode -> { val callback = object : ShowQrCodeNode.Callback { override fun navigateBack() { + linkNewMobileHandler.reset() backstack.pop() } } From 999eca42d72f44db14e857a971ede17c2df4bf7a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 18 Dec 2025 15:33:08 +0100 Subject: [PATCH 210/347] Remove translations Translations are not located in the current module. They will be imported in the correct module once the current PR with the Localazy config has been merged. --- .../src/main/res/values-et/translations.xml | 26 ------------------- .../src/main/res/values-hr/translations.xml | 26 ------------------- .../src/main/res/values-ro/translations.xml | 26 ------------------- 3 files changed, 78 deletions(-) diff --git a/libraries/ui-strings/src/main/res/values-et/translations.xml b/libraries/ui-strings/src/main/res/values-et/translations.xml index 593fc9af11..b1ffe755d6 100644 --- a/libraries/ui-strings/src/main/res/values-et/translations.xml +++ b/libraries/ui-strings/src/main/res/values-et/translations.xml @@ -434,32 +434,6 @@ Kas sa oled kindel, et soovid jätkata?" "Valikud" "Kustuta: %1$s" "Seadistused" - "Skaneeri QR-koodi" - "Ava %1$s kas oma süle- või lauaarvutis" - "Skaneeri QR-koodi selle seadmega" - "Skaneerimiseks valmis" - "QR-koodi laadimiseks ava %1$s süle- või lauaarvutis" - "Numbrid ei klapi" - "Sisesta kahekohaline kood" - "Sellega verifitseerime, et ühendus sinu teise seadmega on turvaline." - "Sisesta teises seadmes kuvatud number" - "Sinu teenusepakkuja ei toeta rakendust %1$s." - "%1$s pole toetatud" - "Sinu kasutajakonto teenusepakkuja ei toeta võimalust logida sisse QR-koodi abil." - "QR-kood pole toetatud" - "Sisselogimine katkestati teises seadmes." - "Sisselogimispäring on tühistatud" - "Sisselogimine aegus. Palun proovi uuesti." - "Sisselogimine jäi etteantud aja jooksul tegemata" - "Ava %1$s teises seadmes" - "Vali %1$s" - "„Logi sisse QR-koodiga“" - "Skaneeri siin näidatud QR-koodi teise seadmega" - "Ava %1$s teises seadmes" - "Lauaarvuti" - "Laadin QR-koodi…" - "Nutiseade" - "Mis tüüpi seadet soovid siduda?" "Kogukonnad, milles on võimalik jututoaga liituda ilma kutseta." "Halda kogukondi" "(Tundmatu kogukond)" diff --git a/libraries/ui-strings/src/main/res/values-hr/translations.xml b/libraries/ui-strings/src/main/res/values-hr/translations.xml index e350ab9f73..18c3de72b9 100644 --- a/libraries/ui-strings/src/main/res/values-hr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hr/translations.xml @@ -442,32 +442,6 @@ Jeste li sigurni da želite nastaviti?" "Mogućnosti" "Ukloni %1$s" "Postavke" - "Skeniraj QR kod" - "Otvorite %1$s na prijenosnom ili stolnom računalu" - "Skenirajte QR kod ovim uređajem" - "Spremno za skeniranje" - "Otvorite %1$s na stolnom računalu kako biste dobili QR kod" - "Brojevi se ne podudaraju" - "Unesite dvoznamenkasti kod" - "Time ćete potvrditi da je veza s vašim drugim uređajem sigurna." - "Unesite broj prikazan na vašem drugom uređaju" - "Vaš davatelj usluga računa ne podržava %1$s." - "%1$s nije podržan" - "Vaš davatelj usluga računa ne podržava prijavu na novi uređaj pomoću QR koda." - "QR kod nije podržan" - "Prijava je otkazana na drugom uređaju." - "Zahtjev za prijavu je otkazan" - "Prijava je istekla. Pokušajte ponovno." - "Prijava nije dovršena na vrijeme" - "Otvorite %1$s na drugom uređaju" - "Odaberi %1$s" - "“Prijavi se pomoću QR koda”" - "Skenirajte ovdje prikazani QR kod drugim uređajem" - "Otvorite %1$s na drugom uređaju" - "Stolno računalo" - "Učitavanje QR koda…" - "Mobilni uređaj" - "Koju vrstu uređaja želite povezati?" "Prostori u kojima se članovi mogu pridružiti sobi bez pozivnice." "Upravljaj prostorima" "(nepoznati prostor)" diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index 203f2f893a..d65e57a219 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -442,32 +442,6 @@ Sunteți sigur că doriți să continuați?" "Opțiuni" "Ștergeți %1$s" "Setări" - "Scanați codul QR" - "Deschide %1$s pe un laptop sau un computer desktop" - "Scanați codul QR cu acest dispozitiv" - "Gata de scanare" - "Deschide %1$s pe un computer desktop pentru a obține codul QR" - "Numerele nu se potrivesc" - "Introduceți codul de 2 cifre" - "Aceasta va verifica dacă conexiunea cu celălalt dispozitiv este sigură." - "Introduceți numărul afișat pe celălalt dispozitiv" - "Furnizorul contului dumneavoastră nu acceptă %1$s." - "%1$s nu este acceptat" - "Furnizorul contului dumneavoastră nu acceptă conectarea la un dispozitiv nou cu un cod QR." - "Codul QR nu este acceptat" - "Autentificarea a fost anulată de pe celălalt dispozitiv." - "Cererea de autentificare a fost anulată" - "Conectarea a expirat. Vă rugăm să încercați din nou." - "Conectarea nu a fost finalizată la timp" - "Deschideți %1$s pe celălalt dispozitiv" - "Selectați %1$s" - "“Conectați-vă cu un cod QR”" - "Scanați codul QR afișat aici cu celălalt dispozitiv." - "Deschideți %1$s pe celălalt dispozitiv" - "Calculator desktop" - "Se încarcă codul QR…" - "Dispozitiv mobil" - "Ce tip de dispozitiv doriți să conectați?" "Spațile din care membrii se pot alătura camerei fără invitație." "Gestionați spațiile" "(Spațiu necunoscut)" From b3c4a2ba92004815805c04aef189da51c514d0cd Mon Sep 17 00:00:00 2001 From: Skye Elliot Date: Thu, 18 Dec 2025 16:05:22 +0000 Subject: [PATCH 211/347] fix: Show history visibiliy banner for `shared`, not `invited`. --- .../historyvisible/HistoryVisibleStatePresenter.kt | 8 ++++---- .../HistoryVisibleStatePresenterTest.kt | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt index d76e567b3c..71aa9fcc33 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt @@ -20,7 +20,6 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch @Inject @@ -35,11 +34,12 @@ class HistoryVisibleStatePresenter( val roomInfo by room.roomInfoFlow.collectAsState() // Implicitly assume the alert is initially acknowledged to avoid flashes in UI. val acknowledged by repository.hasAcknowledged(room.roomId).collectAsState(initial = true) + val isHistoryVisible = roomInfo.historyVisibility == RoomHistoryVisibility.Shared || roomInfo.historyVisibility == RoomHistoryVisibility.WorldReadable val coroutineScope = rememberCoroutineScope() - LaunchedEffect(roomInfo.historyVisibility, acknowledged) { - if (roomInfo.historyVisibility == RoomHistoryVisibility.Joined && acknowledged) { + LaunchedEffect(isHistoryVisible, acknowledged) { + if (!isHistoryVisible && acknowledged) { repository.setAcknowledged(room.roomId, false) } } @@ -51,7 +51,7 @@ class HistoryVisibleStatePresenter( } return HistoryVisibleState( - showAlert = isFeatureEnabled && roomInfo.historyVisibility != RoomHistoryVisibility.Joined && roomInfo.isEncrypted == true && !acknowledged, + showAlert = isFeatureEnabled && isHistoryVisible && roomInfo.isEncrypted == true && !acknowledged, eventSink = ::handleEvent, ) } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenterTest.kt index b6619851e6..afa1992cac 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenterTest.kt @@ -28,7 +28,7 @@ class HistoryVisibleStatePresenterTest { @Test fun `present - not visible if feature disabled`() = runTest { val room = FakeJoinedRoom() - room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Joined, isEncrypted = true)) + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Shared, isEncrypted = true)) val presenter = createHistoryVisibleStatePresenter(room, enabled = false, acknowledged = false) presenter.test { assertThat(awaitLastSequentialItem().showAlert).isFalse() @@ -48,7 +48,17 @@ class HistoryVisibleStatePresenterTest { @Test fun `present - initial with room joined, encrypted`() = runTest { val room = FakeJoinedRoom() - room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Joined, isEncrypted = false)) + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Joined, isEncrypted = true)) + val presenter = createHistoryVisibleStatePresenter(room) + presenter.test { + assertThat(awaitLastSequentialItem().showAlert).isFalse() + } + } + + @Test + fun `present - initial with room invited, encrypted`() = runTest { + val room = FakeJoinedRoom() + room.givenRoomInfo(aRoomInfo(historyVisibility = RoomHistoryVisibility.Invited, isEncrypted = true)) val presenter = createHistoryVisibleStatePresenter(room) presenter.test { assertThat(awaitLastSequentialItem().showAlert).isFalse() From a0d6fddf73286ac22467ac6b1a41d513b0cd94fb Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 18 Dec 2025 21:36:55 +0100 Subject: [PATCH 212/347] change(member moderation): fix available moderation actions --- .../impl/RoomMemberModerationPresenter.kt | 28 ++++++++------- .../matrix/ui/model/RoomInfoExtension.kt | 21 +++++++++--- .../matrix/ui/room/MatrixRoomState.kt | 34 ------------------- 3 files changed, 32 insertions(+), 51 deletions(-) delete mode 100644 libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt index 16a11aee96..cfb9412394 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt @@ -28,6 +28,7 @@ import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runUpdatingState import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.core.coroutine.mapState import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMember @@ -35,7 +36,7 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipState import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.matrix.ui.room.userPowerLevelAsState +import io.element.android.libraries.matrix.ui.model.powerLevelOf import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -56,11 +57,14 @@ class RoomMemberModerationPresenter( @Composable override fun present(): RoomMemberModerationState { val coroutineScope = rememberCoroutineScope() - val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val permissions by room.permissionsAsState(RoomMemberModerationPermissions.DEFAULT) { perms -> perms.roomMemberModerationPermissions() } - val currentUserMemberPowerLevel = room.userPowerLevelAsState(syncUpdateFlow.value) + val currentUserPowerLevel by remember { + room.roomInfoFlow.mapState { info -> + info.powerLevelOf(room.sessionId) + } + }.collectAsState() val kickUserAsyncAction = remember { mutableStateOf(AsyncAction.Uninitialized as AsyncAction) } @@ -83,7 +87,7 @@ class RoomMemberModerationPresenter( moderationActions.value = computeModerationActions( member = member, permissions = permissions, - currentUserMemberPowerLevel = currentUserMemberPowerLevel.value, + currentUserPowerLevel = currentUserPowerLevel, ) } is RoomMemberModerationEvents.ProcessAction -> { @@ -148,26 +152,26 @@ class RoomMemberModerationPresenter( private fun computeModerationActions( member: RoomMember?, permissions: RoomMemberModerationPermissions, - currentUserMemberPowerLevel: Long, + currentUserPowerLevel: Long, ): ImmutableList { return buildList { add(ModerationActionState(action = ModerationAction.DisplayProfile, isEnabled = true)) // Assume the member is a regular user when it's unknown val targetMemberPowerLevel = member?.powerLevel ?: 0 - val canModerateThisUser = currentUserMemberPowerLevel > targetMemberPowerLevel + val canModerateThisUser = currentUserPowerLevel > targetMemberPowerLevel // Assume the member is joined when it's unknown val membership = member?.membership ?: RoomMembershipState.JOIN if (permissions.canKick) { - val isKickEnabled = canModerateThisUser && membership.isActive() - add(ModerationActionState(action = ModerationAction.KickUser, isEnabled = isKickEnabled)) - } - if (permissions.canBan) { + // Unban requires kick permission instead of a dedicated unban permission if (membership == RoomMembershipState.BAN) { add(ModerationActionState(action = ModerationAction.UnbanUser, isEnabled = canModerateThisUser)) - } else { - add(ModerationActionState(action = ModerationAction.BanUser, isEnabled = canModerateThisUser)) + } else if (membership != RoomMembershipState.LEAVE) { + add(ModerationActionState(action = ModerationAction.KickUser, isEnabled = canModerateThisUser)) } } + if (permissions.canBan && membership != RoomMembershipState.BAN) { + add(ModerationActionState(action = ModerationAction.BanUser, isEnabled = canModerateThisUser)) + } }.toImmutableList() } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtension.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtension.kt index f9a86c9bd7..3a03d8329b 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtension.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtension.kt @@ -21,6 +21,20 @@ fun RoomInfo.getAvatarData(size: AvatarSize) = AvatarData( size = size, ) +/** + * Returns the power level of the user in the room. + * If the user is a creator and [RoomInfo.privilegedCreatorRole] is true, returns the power level of [RoomMember.Role.Owner]. + * Otherwise, checks the room's power levels for the user's power level. + * If no specific power level is set for the user, defaults to 0. + */ +fun RoomInfo.powerLevelOf(userId: UserId): Long { + return if (privilegedCreatorRole && creators.contains(userId)) { + RoomMember.Role.Owner(isCreator = true).powerLevel + } else { + roomPowerLevels?.powerLevelOf(userId = userId) ?: 0L + } +} + /** * Returns the role of the user in the room. * If the user is a creator and [RoomInfo.privilegedCreatorRole] is true, returns [RoomMember.Role.Owner]. @@ -28,9 +42,6 @@ fun RoomInfo.getAvatarData(size: AvatarSize) = AvatarData( * If no specific power level is set for the user, defaults to [RoomMember.Role.User]. */ fun RoomInfo.roleOf(userId: UserId): RoomMember.Role { - return if (privilegedCreatorRole && creators.contains(userId)) { - RoomMember.Role.Owner(isCreator = true) - } else { - roomPowerLevels?.roleOf(userId) ?: RoomMember.Role.User - } + val powerLevel = powerLevelOf(userId = userId) + return RoomMember.Role.forPowerLevel(powerLevel) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt deleted file mode 100644 index d4e6127b69..0000000000 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt +++ /dev/null @@ -1,34 +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.matrix.ui.room - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.State -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.produceState -import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.ui.model.roleOf - -@Composable -fun BaseRoom.userPowerLevelAsState(updateKey: Long): State { - return produceState(initialValue = 0, key1 = updateKey) { - value = userRole(sessionId) - .getOrDefault(RoomMember.Role.User) - .powerLevel - } -} - -@Composable -fun BaseRoom.isOwnUserAdmin(): Boolean { - val roomInfo by roomInfoFlow.collectAsState() - val role = roomInfo.roleOf(sessionId) - return role == RoomMember.Role.Admin || role is RoomMember.Role.Owner -} From 4c2aa0ba33c3f564fd7490c1fb8579fc459a5b90 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 18 Dec 2025 21:37:56 +0100 Subject: [PATCH 213/347] change(room permissions): fix some role&permissions inconsistencies after last changes --- .../impl/roles/ChangeRolesPresenter.kt | 8 +++-- .../impl/root/RolesAndPermissionsPresenter.kt | 14 ++++++-- .../impl/root/RolesAndPermissionsState.kt | 14 ++++++-- .../root/RolesAndPermissionsStateProvider.kt | 7 ++-- .../impl/root/RolesAndPermissionsView.kt | 33 ++++++++----------- 5 files changed, 47 insertions(+), 29 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt index 4181fb6e2e..3989a76df3 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt @@ -36,6 +36,7 @@ import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.room.powerlevels.usersWithRole import io.element.android.libraries.matrix.api.room.toMatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.ui.model.powerLevelOf import io.element.android.libraries.matrix.ui.model.roleOf import io.element.android.libraries.matrix.ui.room.PowerLevelRoomMemberComparator import io.element.android.services.analytics.api.AnalyticsService @@ -124,9 +125,10 @@ class ChangeRolesPresenter( val roomInfo by room.roomInfoFlow.collectAsState() fun canChangeMemberRole(userId: UserId): Boolean { - val currentUserRole = roomInfo.roleOf(room.sessionId) - val otherUserRole = roomInfo.roleOf(userId) - return currentUserRole.powerLevel > otherUserRole.powerLevel + val currentUserPowerLevel = roomInfo.powerLevelOf(room.sessionId) + val otherUserPowerLevel = roomInfo.powerLevelOf(userId) + return currentUserPowerLevel > otherUserPowerLevel && + currentUserPowerLevel >= role.powerLevel } fun handleEvent(event: ChangeRolesEvent) { diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt index bde20affd8..f80899fc0f 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt @@ -28,6 +28,7 @@ import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.room.powerlevels.userCountWithRole import io.element.android.libraries.matrix.ui.model.roleOf import io.element.android.services.analytics.api.AnalyticsService +import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -49,7 +50,16 @@ class RolesAndPermissionsPresenter( room.userCountWithRole { role -> role is RoomMember.Role.Admin || role is RoomMember.Role.Owner } }.collectAsState(null) - val canDemoteSelf = remember { derivedStateOf { roomInfo.roleOf(room.sessionId) !is RoomMember.Role.Owner } } + val availableDemoteActions by remember { + derivedStateOf { + val currentRole = roomInfo.roleOf(room.sessionId) + when (currentRole) { + is RoomMember.Role.Admin -> persistentListOf(DemoteActions.ToModerator, DemoteActions.ToMember) + is RoomMember.Role.Moderator -> persistentListOf(DemoteActions.ToMember) + else -> persistentListOf() + } + } + } val changeOwnRoleAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } val resetPermissionsAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } @@ -78,7 +88,7 @@ class RolesAndPermissionsPresenter( roomSupportsOwnerRole = roomInfo.privilegedCreatorRole, adminCount = adminCount, moderatorCount = moderatorCount, - canDemoteSelf = canDemoteSelf.value, + availableDemoteActions = availableDemoteActions, changeOwnRoleAction = changeOwnRoleAction.value, resetPermissionsAction = resetPermissionsAction.value, eventSink = ::handleEvent, diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt index 90785d1b38..9064f559c6 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt @@ -8,14 +8,24 @@ package io.element.android.features.rolesandpermissions.impl.root +import io.element.android.features.rolesandpermissions.impl.R import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.matrix.api.room.RoomMember +import kotlinx.collections.immutable.ImmutableList data class RolesAndPermissionsState( val roomSupportsOwnerRole: Boolean, val adminCount: Int?, val moderatorCount: Int?, - val canDemoteSelf: Boolean, + val availableDemoteActions: ImmutableList, val changeOwnRoleAction: AsyncAction, val resetPermissionsAction: AsyncAction, val eventSink: (RolesAndPermissionsEvents) -> Unit, -) +) { + val canDemoteSelf = availableDemoteActions.isNotEmpty() +} + +enum class DemoteActions(val role: RoomMember.Role, val titleRes: Int) { + ToModerator(RoomMember.Role.Moderator, R.string.screen_room_roles_and_permissions_change_role_demote_to_moderator), + ToMember(RoomMember.Role.User, R.string.screen_room_roles_and_permissions_change_role_demote_to_member) +} diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsStateProvider.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsStateProvider.kt index 23448c0351..cf0163d0ba 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsStateProvider.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsStateProvider.kt @@ -10,6 +10,7 @@ package io.element.android.features.rolesandpermissions.impl.root import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.architecture.AsyncAction +import kotlinx.collections.immutable.toImmutableList class RolesAndPermissionsStateProvider : PreviewParameterProvider { override val values: Sequence @@ -46,7 +47,7 @@ class RolesAndPermissionsStateProvider : PreviewParameterProvider = listOf(DemoteActions.ToModerator, DemoteActions.ToMember), changeOwnRoleAction: AsyncAction = AsyncAction.Uninitialized, resetPermissionsAction: AsyncAction = AsyncAction.Uninitialized, eventSink: (RolesAndPermissionsEvents) -> Unit = {}, ) = RolesAndPermissionsState( roomSupportsOwnerRole = roomSupportsOwners, adminCount = adminCount, - canDemoteSelf = canDemoteSelf, + availableDemoteActions = availableDemoteActions.toImmutableList(), moderatorCount = moderatorCount, changeOwnRoleAction = changeOwnRoleAction, resetPermissionsAction = resetPermissionsAction, diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt index c0cb15983c..82b49f0d81 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt @@ -39,8 +39,8 @@ import io.element.android.libraries.designsystem.theme.components.ListSectionHea import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.hide -import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.ImmutableList @Composable fun RolesAndPermissionsView( @@ -117,6 +117,7 @@ fun RolesAndPermissionsView( when (state.changeOwnRoleAction) { is AsyncAction.Confirming -> { ChangeOwnRoleBottomSheet( + availableDemoteActions = state.availableDemoteActions, eventSink = state.eventSink, ) } @@ -136,6 +137,7 @@ fun RolesAndPermissionsView( @OptIn(ExperimentalMaterial3Api::class) @Composable private fun ChangeOwnRoleBottomSheet( + availableDemoteActions: ImmutableList, eventSink: (RolesAndPermissionsEvents) -> Unit, ) { val coroutineScope = rememberCoroutineScope() @@ -164,24 +166,17 @@ private fun ChangeOwnRoleBottomSheet( style = ElementTheme.typography.fontBodyLgRegular, color = ElementTheme.colors.textPrimary, ) - ListItem( - headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_change_role_demote_to_moderator)) }, - onClick = { - sheetState.hide(coroutineScope) { - eventSink(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.Moderator)) - } - }, - style = ListItemStyle.Destructive, - ) - ListItem( - headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_change_role_demote_to_member)) }, - onClick = { - sheetState.hide(coroutineScope) { - eventSink(RolesAndPermissionsEvents.DemoteSelfTo(RoomMember.Role.User)) - } - }, - style = ListItemStyle.Destructive, - ) + for (demoteAction in availableDemoteActions) { + ListItem( + headlineContent = { Text(stringResource(demoteAction.titleRes)) }, + onClick = { + sheetState.hide(coroutineScope) { + eventSink(RolesAndPermissionsEvents.DemoteSelfTo(demoteAction.role)) + } + }, + style = ListItemStyle.Destructive, + ) + } ListItem( headlineContent = { Text(stringResource(CommonStrings.action_cancel)) }, onClick = ::dismiss, From 74dd3f381e1e55a6c84bbe99f292665c82d24474 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 18 Dec 2025 21:45:49 +0100 Subject: [PATCH 214/347] quality: fix tests after changes --- .../impl/RoomMemberModerationPresenterTest.kt | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt b/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt index 3f59151eea..3397f3a40a 100644 --- a/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt +++ b/features/roommembermoderation/impl/src/test/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenterTest.kt @@ -21,11 +21,14 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom +import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomMember +import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService @@ -33,6 +36,7 @@ import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest @@ -161,7 +165,6 @@ class RoomMemberModerationPresenterTest { assertThat(updatedState.selectedUser).isEqualTo(targetUser) assertThat(updatedState.actions).containsExactly( ModerationActionState(action = ModerationAction.DisplayProfile, isEnabled = true), - ModerationActionState(action = ModerationAction.KickUser, isEnabled = false), ModerationActionState(action = ModerationAction.UnbanUser, isEnabled = true), ) } @@ -223,9 +226,11 @@ class RoomMemberModerationPresenterTest { val room = aJoinedRoom() room.baseRoom.givenUpdateMembersResult { // Simulate the member list being updated - room.givenRoomMembersState(RoomMembersState.Ready( - persistentListOf(aRoomMember()) - )) + room.givenRoomMembersState( + RoomMembersState.Ready( + persistentListOf(aRoomMember()) + ) + ) } createRoomMemberModerationPresenter(room = room).test { val initialState = awaitState() @@ -251,9 +256,11 @@ class RoomMemberModerationPresenterTest { val room = aJoinedRoom() room.baseRoom.givenUpdateMembersResult { // Simulate the member list being updated - room.givenRoomMembersState(RoomMembersState.Ready( - persistentListOf(aRoomMember()) - )) + room.givenRoomMembersState( + RoomMembersState.Ready( + persistentListOf(aRoomMember()) + ) + ) } createRoomMemberModerationPresenter(room = room).test { val initialState = awaitState() @@ -279,9 +286,11 @@ class RoomMemberModerationPresenterTest { val room = aJoinedRoom() room.baseRoom.givenUpdateMembersResult { // Simulate the member list being updated - room.givenRoomMembersState(RoomMembersState.Ready( - persistentListOf(aRoomMember()) - )) + room.givenRoomMembersState( + RoomMembersState.Ready( + persistentListOf(aRoomMember()) + ) + ) } createRoomMemberModerationPresenter(room = room).test { val initialState = awaitState() @@ -361,7 +370,13 @@ class RoomMemberModerationPresenterTest { canKick = canKick ), userRoleResult = { Result.success(myUserRole) }, - updateMembersResult = { Result.success(Unit) } + updateMembersResult = { Result.success(Unit) }, + initialRoomInfo = aRoomInfo( + roomPowerLevels = RoomPowerLevels( + values = defaultRoomPowerLevelValues(), + users = persistentMapOf(A_USER_ID to myUserRole.powerLevel) + ) + ) ), ).apply { val roomMembers = listOfNotNull(targetRoomMember).toImmutableList() From bd46ce97750ce028c668d630a4b1d56c01ccb7fc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Dec 2025 09:22:58 +0100 Subject: [PATCH 215/347] Fix test issue: "java.security.KeyStoreException: AndroidKeyStore not found" --- .../DefaultRegisterUnifiedPushUseCaseTest.kt | 7 ++ .../testutils/fake/FakeAndroidKeyStore.kt | 71 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/testutils/src/main/kotlin/io/element/android/tests/testutils/fake/FakeAndroidKeyStore.kt diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultRegisterUnifiedPushUseCaseTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultRegisterUnifiedPushUseCaseTest.kt index a2304bfd24..1e77df79a2 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultRegisterUnifiedPushUseCaseTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/DefaultRegisterUnifiedPushUseCaseTest.kt @@ -15,16 +15,23 @@ import io.element.android.libraries.matrix.test.A_SECRET import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.unifiedpush.registration.EndpointRegistrationHandler import io.element.android.libraries.pushproviders.unifiedpush.registration.RegistrationResult +import io.element.android.tests.testutils.fake.FakeAndroidKeyStore import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) class DefaultRegisterUnifiedPushUseCaseTest { + @Before + fun setup() { + FakeAndroidKeyStore.setup + } + @Test fun `test registration successful`() = runTest { val endpointRegistrationHandler = EndpointRegistrationHandler() diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/fake/FakeAndroidKeyStore.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/fake/FakeAndroidKeyStore.kt new file mode 100644 index 0000000000..9edbec9795 --- /dev/null +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/fake/FakeAndroidKeyStore.kt @@ -0,0 +1,71 @@ +/* + * 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.tests.testutils.fake + +import java.io.InputStream +import java.io.OutputStream +import java.security.Key +import java.security.KeyStore +import java.security.KeyStoreSpi +import java.security.Provider +import java.security.SecureRandom +import java.security.Security +import java.security.cert.Certificate +import java.security.spec.AlgorithmParameterSpec +import java.util.Date +import java.util.Enumeration +import javax.crypto.KeyGenerator +import javax.crypto.KeyGeneratorSpi +import javax.crypto.SecretKey + +// Source - https://stackoverflow.com/questions/38213748/using-the-android-keystore-in-robolectric-tests/75763240#75763240 +// Posted by Victor Oliveira +// Retrieved 2025-12-19, License - CC BY-SA 4.0 + +object FakeAndroidKeyStore { + val setup by lazy { + Security.addProvider(object : Provider("AndroidKeyStore", 1.0, "") { + init { + put("KeyStore.AndroidKeyStore", FakeKeyStore::class.java.name) + put("KeyGenerator.AES", FakeAesKeyGenerator::class.java.name) + } + }) + } + + class FakeKeyStore : KeyStoreSpi() { + private val wrapped = KeyStore.getInstance(KeyStore.getDefaultType()) + + override fun engineIsKeyEntry(alias: String?): Boolean = wrapped.isKeyEntry(alias) + override fun engineIsCertificateEntry(alias: String?): Boolean = wrapped.isCertificateEntry(alias) + override fun engineGetCertificate(alias: String?): Certificate = wrapped.getCertificate(alias) + override fun engineGetCreationDate(alias: String?): Date = wrapped.getCreationDate(alias) + override fun engineDeleteEntry(alias: String?) = wrapped.deleteEntry(alias) + override fun engineSetKeyEntry(alias: String?, key: Key?, password: CharArray?, chain: Array?) = + wrapped.setKeyEntry(alias, key, password, chain) + + override fun engineSetKeyEntry(alias: String?, key: ByteArray?, chain: Array?) = wrapped.setKeyEntry(alias, key, chain) + override fun engineStore(stream: OutputStream?, password: CharArray?) = wrapped.store(stream, password) + override fun engineSize(): Int = wrapped.size() + override fun engineAliases(): Enumeration = wrapped.aliases() + override fun engineContainsAlias(alias: String?): Boolean = wrapped.containsAlias(alias) + override fun engineLoad(stream: InputStream?, password: CharArray?) = wrapped.load(stream, password) + override fun engineGetCertificateChain(alias: String?): Array = wrapped.getCertificateChain(alias) + override fun engineSetCertificateEntry(alias: String?, cert: Certificate?) = wrapped.setCertificateEntry(alias, cert) + override fun engineGetCertificateAlias(cert: Certificate?): String = wrapped.getCertificateAlias(cert) + override fun engineGetKey(alias: String?, password: CharArray?): Key = wrapped.getKey(alias, password) + } + + class FakeAesKeyGenerator : KeyGeneratorSpi() { + private val wrapped = KeyGenerator.getInstance("AES") + + override fun engineInit(random: SecureRandom?) = Unit + override fun engineInit(params: AlgorithmParameterSpec?, random: SecureRandom?) = Unit + override fun engineInit(keysize: Int, random: SecureRandom?) = Unit + override fun engineGenerateKey(): SecretKey = wrapped.generateKey() + } +} From dd4537ae4c917767674354c27aa1ac30be52569c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 09:39:35 +0100 Subject: [PATCH 216/347] fix(deps): update media3 to v1.9.0 (#5931) * Update media3 to v1.9.0 * Fix compilation issue. --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Benoit Marty --- gradle/libs.versions.toml | 2 +- .../impl/local/player/ExoPlayerForPreview.kt | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 108504ae75..ee97570ed9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -17,7 +17,7 @@ constraintlayout = "2.2.1" constraintlayout_compose = "1.1.1" lifecycle = "2.10.0" activity = "1.12.2" -media3 = "1.8.0" +media3 = "1.9.0" camera = "1.5.2" work = "2.11.0" diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/player/ExoPlayerForPreview.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/player/ExoPlayerForPreview.kt index 4cb05ee6d1..51a44d49fb 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/player/ExoPlayerForPreview.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/local/player/ExoPlayerForPreview.kt @@ -38,6 +38,8 @@ import androidx.media3.common.VideoSize import androidx.media3.common.text.CueGroup import androidx.media3.common.util.Clock import androidx.media3.common.util.Size +import androidx.media3.exoplayer.CodecParameters +import androidx.media3.exoplayer.CodecParametersChangeListener import androidx.media3.exoplayer.DecoderCounters import androidx.media3.exoplayer.ExoPlaybackException import androidx.media3.exoplayer.ExoPlayer @@ -160,6 +162,8 @@ class ExoPlayerForPreview( override fun getAudioAttributes(): AudioAttributes = throw NotImplementedError() override fun setVolume(volume: Float) = throw NotImplementedError() override fun getVolume(): Float = throw NotImplementedError() + override fun mute() {} + override fun unmute() {} override fun clearVideoSurface() {} override fun clearVideoSurface(surface: Surface?) {} override fun setVideoSurface(surface: Surface?) {} @@ -192,6 +196,7 @@ class ExoPlayerForPreview( override fun getRendererCount(): Int = throw NotImplementedError() override fun getRendererType(index: Int): Int = throw NotImplementedError() override fun getRenderer(index: Int): Renderer = throw NotImplementedError() + override fun getSecondaryRenderer(index: Int): Renderer? = throw NotImplementedError() override fun getTrackSelector(): TrackSelector? = throw NotImplementedError() override fun getCurrentTrackGroups(): TrackGroupArray = throw NotImplementedError() override fun getCurrentTrackSelections(): TrackSelectionArray = throw NotImplementedError() @@ -216,6 +221,7 @@ class ExoPlayerForPreview( override fun setAuxEffectInfo(auxEffectInfo: AuxEffectInfo) {} override fun clearAuxEffectInfo() {} override fun setPreferredAudioDevice(audioDeviceInfo: AudioDeviceInfo?) {} + override fun setVirtualDeviceId(virtualDeviceId: Int) {} override fun setSkipSilenceEnabled(skipSilenceEnabled: Boolean) {} override fun getSkipSilenceEnabled(): Boolean = throw NotImplementedError() override fun setScrubbingModeEnabled(scrubbingModeEnabled: Boolean) {} @@ -234,6 +240,9 @@ class ExoPlayerForPreview( override fun createMessage(target: PlayerMessage.Target): PlayerMessage = throw NotImplementedError() override fun setSeekParameters(seekParameters: SeekParameters?) {} override fun getSeekParameters(): SeekParameters = throw NotImplementedError() + override fun setSeekBackIncrementMs(seekBackIncrementMs: Long) {} + override fun setSeekForwardIncrementMs(seekForwardIncrementMs: Long) {} + override fun setMaxSeekToPreviousPositionMs(maxSeekToPreviousPositionMs: Long) {} override fun setForegroundMode(foregroundMode: Boolean) {} override fun setPauseAtEndOfMediaItems(pauseAtEndOfMediaItems: Boolean) {} override fun getPauseAtEndOfMediaItems(): Boolean = throw NotImplementedError() @@ -249,4 +258,10 @@ class ExoPlayerForPreview( override fun isTunnelingEnabled(): Boolean = throw NotImplementedError() override fun isReleased(): Boolean = throw NotImplementedError() override fun setImageOutput(imageOutput: ImageOutput?) {} + override fun setAudioCodecParameters(codecParameters: CodecParameters) {} + override fun addAudioCodecParametersChangeListener(listener: CodecParametersChangeListener, keys: List) {} + override fun removeAudioCodecParametersChangeListener(listener: CodecParametersChangeListener) {} + override fun setVideoCodecParameters(codecParameters: CodecParameters) {} + override fun addVideoCodecParametersChangeListener(listener: CodecParametersChangeListener, keys: List) {} + override fun removeVideoCodecParametersChangeListener(listener: CodecParametersChangeListener) {} } From 1f2b7eb6417f9e02c9a631f68fb1f12050720462 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Dec 2025 09:44:58 +0100 Subject: [PATCH 217/347] Add exceptions. --- .../io/element/android/tests/konsist/KonsistClassNameTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt index 07f375cfb6..631def9f75 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt @@ -99,8 +99,10 @@ class KonsistClassNameTest { .classes() .withNameContaining("Fake") .withoutName( + "FakeAesKeyGenerator", "FakeFileSystem", "FakeImageLoader", + "FakeKeyStore", "FakeListenableFuture", ) .assertTrue { From 602498a36b1b8b3ac95ba82cbe2c12899b6312b9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 09:18:02 +0000 Subject: [PATCH 218/347] fix(deps): update metro to v0.9.2 (#5940) 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 ee97570ed9..bd8bdf19ae 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -52,7 +52,7 @@ haze = "1.7.1" dependencyAnalysis = "3.5.1" # DI -metro = "0.9.1" +metro = "0.9.2" # Auto service autoservice = "1.1.1" From 0b5c4fc8bb04b4f109bd1919b465d927730f4618 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Fri, 19 Dec 2025 10:43:40 +0100 Subject: [PATCH 219/347] Add `threadInfo` field to message like timeline events (#5930) * Add `threadInfo` field to message like timeline events: - Polls - Stickers - UTDs * Add missing cases for `EventTimeline.threadInfo()` --- .../PollContentStateFactoryTest.kt | 1 + ...efaultPinnedMessagesBannerFormatterTest.kt | 6 +- .../DefaultRoomLatestEventFormatterTest.kt | 6 +- .../api/timeline/item/event/EventContent.kt | 7 +- .../timeline/item/event/EventTimelineItem.kt | 8 +- .../item/event/TimelineEventContentMapper.kt | 79 +++++++++++-------- .../matrix/test/timeline/TimelineFixture.kt | 4 + .../reply/InReplyToDetailsProvider.kt | 3 +- .../messages/reply/InReplyToMetadataKtTest.kt | 11 ++- .../datasource/DefaultEventItemFactoryTest.kt | 6 +- 10 files changed, 87 insertions(+), 44 deletions(-) diff --git a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/pollcontent/PollContentStateFactoryTest.kt b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/pollcontent/PollContentStateFactoryTest.kt index 438d451199..277508681e 100644 --- a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/pollcontent/PollContentStateFactoryTest.kt +++ b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/pollcontent/PollContentStateFactoryTest.kt @@ -220,6 +220,7 @@ class PollContentStateFactoryTest { votes = votes, endTime = endTime, isEdited = false, + threadInfo = null, ) private fun aPollContentState( 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 10c09ad41d..b58bbb4b25 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 @@ -103,7 +103,11 @@ class DefaultPinnedMessagesBannerFormatterTest { fun `Unable to decrypt content`() { val expected = "Waiting for this message" val senderName = "Someone" - val message = createRoomEvent(false, senderName, UnableToDecryptContent(UnableToDecryptContent.Data.Unknown)) + val message = createRoomEvent( + sentByYou = false, + senderDisplayName = senderName, + content = UnableToDecryptContent(data = UnableToDecryptContent.Data.Unknown, threadInfo = null) + ) val result = formatter.format(message) assertThat(result).isEqualTo(expected) } 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 c06b79ead9..0da3134098 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 @@ -112,7 +112,11 @@ class DefaultRoomLatestEventFormatterTest { val expected = "Waiting for this message" val senderName = "Someone" sequenceOf(false, true).forEach { isDm -> - val message = createLatestEvent(false, senderName, UnableToDecryptContent(UnableToDecryptContent.Data.Unknown)) + val message = createLatestEvent( + sentByYou = false, + senderDisplayName = senderName, + content = UnableToDecryptContent(data = UnableToDecryptContent.Data.Unknown, threadInfo = null), + ) val result = formatter.format(message, isDm) if (isDm) { assertThat(result).isEqualTo(expected) 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 c6272e8f52..b6ed7dc602 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 @@ -26,7 +26,7 @@ data class MessageContent( val inReplyTo: InReplyTo?, val isEdited: Boolean, val threadInfo: EventThreadInfo?, - val type: MessageType + val type: MessageType, ) : EventContent data object RedactedContent : EventContent @@ -36,6 +36,7 @@ data class StickerContent( val body: String?, val info: ImageInfo, val source: MediaSource, + val threadInfo: EventThreadInfo?, ) : EventContent { val bestDescription: String get() = body ?: filename @@ -49,10 +50,12 @@ data class PollContent( val votes: ImmutableMap>, val endTime: ULong?, val isEdited: Boolean, + val threadInfo: EventThreadInfo?, ) : EventContent data class UnableToDecryptContent( - val data: Data + val data: Data, + val threadInfo: EventThreadInfo?, ) : EventContent { @Immutable sealed interface Data { diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt index 8294b78c24..401240f927 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt @@ -39,7 +39,13 @@ data class EventTimelineItem( return (content as? MessageContent)?.inReplyTo } - fun threadInfo(): EventThreadInfo? = (content as? MessageContent)?.threadInfo + fun threadInfo(): EventThreadInfo? = when (content) { + is MessageContent -> content.threadInfo + is PollContent -> content.threadInfo + is StickerContent -> content.threadInfo + is UnableToDecryptContent -> content.threadInfo + else -> null + } fun hasNotLoadedInReplyTo(): Boolean { val details = inReplyTo() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt index d0545d3f0a..b1758fb734 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt @@ -36,6 +36,7 @@ import io.element.android.libraries.matrix.impl.room.join.map import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableMap import org.matrix.rustcomponents.sdk.EmbeddedEventDetails +import org.matrix.rustcomponents.sdk.MsgLikeContent import org.matrix.rustcomponents.sdk.MsgLikeKind import org.matrix.rustcomponents.sdk.TimelineItemContent import org.matrix.rustcomponents.sdk.use @@ -68,37 +69,11 @@ class TimelineEventContentMapper( when (val kind = it.content.kind) { is MsgLikeKind.Message -> { val inReplyTo = it.content.inReplyTo - val threadSummary = it.content.threadSummary?.use { summary -> - val numberOfReplies = summary.numReplies().toLong() - val latestEvent = summary.latestEvent() - val details = when (latestEvent) { - is EmbeddedEventDetails.Unavailable -> AsyncData.Uninitialized - is EmbeddedEventDetails.Pending -> AsyncData.Loading() - is EmbeddedEventDetails.Error -> AsyncData.Failure(IllegalStateException(latestEvent.message)) - is EmbeddedEventDetails.Ready -> { - AsyncData.Success( - EmbeddedEventInfo( - eventOrTransactionId = latestEvent.eventOrTransactionId.map(), - content = map(latestEvent.content), - senderId = UserId(latestEvent.sender), - senderProfile = latestEvent.senderProfile.map(), - timestamp = latestEvent.timestamp.toLong(), - ) - ) - } - } - ThreadSummary( - latestEvent = details, - numberOfReplies = numberOfReplies, - ) - } - val threadRootId = it.content.threadRoot?.let(::ThreadId) - val threadInfo = when { - threadSummary != null -> EventThreadInfo.ThreadRoot(threadSummary) - threadRootId != null -> EventThreadInfo.ThreadResponse(threadRootId) - else -> null - } - eventMessageMapper.map(kind, inReplyTo, threadInfo) + eventMessageMapper.map( + message = kind, + inReplyTo = inReplyTo, + threadInfo = extractThreadInfo(it.content) + ) } is MsgLikeKind.Redacted -> { RedactedContent @@ -114,11 +89,13 @@ class TimelineEventContentMapper( }.toImmutableMap(), endTime = kind.endTime, isEdited = kind.hasBeenEdited, + threadInfo = extractThreadInfo(it.content), ) } is MsgLikeKind.UnableToDecrypt -> { UnableToDecryptContent( - data = kind.msg.map() + data = kind.msg.map(), + threadInfo = extractThreadInfo(it.content), ) } is MsgLikeKind.Sticker -> { @@ -127,6 +104,7 @@ class TimelineEventContentMapper( body = null, info = kind.info.map(), source = kind.source.map(), + threadInfo = extractThreadInfo(it.content), ) } is MsgLikeKind.Other -> UnknownContent @@ -159,6 +137,43 @@ class TimelineEventContentMapper( } } } + + private fun extractThreadInfo(content: MsgLikeContent): EventThreadInfo? { + val threadSummary = extractThreadSummary(content.threadSummary) + val threadRootId = content.threadRoot?.let(::ThreadId) + return when { + threadSummary != null -> EventThreadInfo.ThreadRoot(threadSummary) + threadRootId != null -> EventThreadInfo.ThreadResponse(threadRootId) + else -> null + } + } + + private fun extractThreadSummary(threadSummary: org.matrix.rustcomponents.sdk.ThreadSummary?): ThreadSummary? { + return threadSummary?.use { summary -> + val numberOfReplies = summary.numReplies().toLong() + val latestEvent = summary.latestEvent() + val details = when (latestEvent) { + is EmbeddedEventDetails.Unavailable -> AsyncData.Uninitialized + is EmbeddedEventDetails.Pending -> AsyncData.Loading() + is EmbeddedEventDetails.Error -> AsyncData.Failure(IllegalStateException(latestEvent.message)) + is EmbeddedEventDetails.Ready -> { + AsyncData.Success( + EmbeddedEventInfo( + eventOrTransactionId = latestEvent.eventOrTransactionId.map(), + content = map(latestEvent.content), + senderId = UserId(latestEvent.sender), + senderProfile = latestEvent.senderProfile.map(), + timestamp = latestEvent.timestamp.toLong(), + ) + ) + } + } + ThreadSummary( + latestEvent = details, + numberOfReplies = numberOfReplies, + ) + } + } } private fun RustMembershipChange.map(): MembershipChange { diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt index c8d8ff6015..24c26a6734 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt @@ -123,11 +123,13 @@ fun aStickerContent( info: ImageInfo, mediaSource: MediaSource, body: String? = null, + threadInfo: EventThreadInfo? = null, ) = StickerContent( filename = filename, body = body, info = info, source = mediaSource, + threadInfo = threadInfo, ) fun aTimelineItemDebugInfo( @@ -148,6 +150,7 @@ fun aPollContent( votes: ImmutableMap> = persistentMapOf(), endTime: ULong? = null, isEdited: Boolean = false, + threadInfo: EventThreadInfo? = null, ) = PollContent( question = question, kind = kind, @@ -156,4 +159,5 @@ fun aPollContent( votes = votes, endTime = endTime, isEdited = isEdited, + threadInfo = threadInfo, ) 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 ac545ed8ea..0727b0b7ec 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 @@ -89,6 +89,7 @@ open class InReplyToDetailsProvider : PreviewParameterProvider votes = persistentMapOf(), endTime = null, isEdited = false, + threadInfo = null, ), ).map { aInReplyToDetails( @@ -116,7 +117,7 @@ class InReplyToDetailsInformativeProvider : InReplyToDetailsProvider() { override val values: Sequence get() = sequenceOf( RedactedContent, - UnableToDecryptContent(UnableToDecryptContent.Data.Unknown), + UnableToDecryptContent(data = UnableToDecryptContent.Data.Unknown, threadInfo = null), ).map { aInReplyToDetails( eventContent = it, 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 e7cae1151b..004e622211 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 @@ -134,7 +134,8 @@ class InReplyToMetadataKtTest { filename = "filename", body = "body", info = anImageInfo(), - source = aMediaSource(url = "url") + source = aMediaSource(url = "url"), + threadInfo = null, ) ).metadata(hideImage = false) }.test { @@ -161,7 +162,8 @@ class InReplyToMetadataKtTest { filename = "filename", body = "body", info = anImageInfo(), - source = aMediaSource(url = "url") + source = aMediaSource(url = "url"), + threadInfo = null, ) ).metadata(hideImage = true) }.test { @@ -445,7 +447,10 @@ class InReplyToMetadataKtTest { fun `unable to decrypt content`() = runTest { moleculeFlow(RecompositionMode.Immediate) { anInReplyToDetailsReady( - eventContent = UnableToDecryptContent(UnableToDecryptContent.Data.Unknown) + eventContent = UnableToDecryptContent( + data = UnableToDecryptContent.Data.Unknown, + threadInfo = null, + ), ).metadata(hideImage = false) }.test { awaitItem().let { 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 68d6564d12..c70d658418 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 @@ -84,7 +84,7 @@ class DefaultEventItemFactoryTest { ), mediaSource = MediaSource("") ), - UnableToDecryptContent(UnableToDecryptContent.Data.Unknown), + UnableToDecryptContent(data = UnableToDecryptContent.Data.Unknown, threadInfo = null), UnknownContent, ) contents.forEach { @@ -397,8 +397,8 @@ class DefaultEventItemFactoryTest { height = 1L, width = 2L, blurhash = null, - ) - ) + ), + ), ) ) ) From fd883049be9a7f8f5bc52b735b2e5844f0558c95 Mon Sep 17 00:00:00 2001 From: Skye Elliot Date: Fri, 19 Dec 2025 11:09:19 +0000 Subject: [PATCH 220/347] docs: Clarify purpose of `LaunchedEffect` as part of algorithm. --- .../impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt index 71aa9fcc33..e79681cd5c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStatePresenter.kt @@ -40,6 +40,8 @@ class HistoryVisibleStatePresenter( LaunchedEffect(isHistoryVisible, acknowledged) { if (!isHistoryVisible && acknowledged) { + // Clear the dismissed flag, if it is set to ensure that if a room is changed public -> private -> public, + // we show the banner again when it is set back to public. repository.setAcknowledged(room.roomId, false) } } From 98f43f24020591f39ac28c316896131f1eda22cf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 Dec 2025 17:20:00 +0100 Subject: [PATCH 221/347] Sync strings. --- features/roomdetails/impl/src/main/res/values/localazy.xml | 7 ++++--- .../impl/src/main/res/values/localazy.xml | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index 4ed7d0c242..cd90edf709 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -157,10 +157,11 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Allow for this room to be found by searching %1$s public room directory" "Allow to be found by searching the public directory." "Visible in public directory" - "Anyone" + "Anyone (history is public)" + "Changes won\'t affect past messages, only new ones. %1$s" "Who can read history" - "Members only since they were invited" - "Members only since selecting this option" + "Members since invited" + "Members (full history)" "Room addresses are ways to find and access rooms. This also ensures you can easily share your room with others. You can choose to publish your room in your homeserver public room directory." "Room publishing" diff --git a/features/securityandprivacy/impl/src/main/res/values/localazy.xml b/features/securityandprivacy/impl/src/main/res/values/localazy.xml index 374cf94870..acf4b04e71 100644 --- a/features/securityandprivacy/impl/src/main/res/values/localazy.xml +++ b/features/securityandprivacy/impl/src/main/res/values/localazy.xml @@ -31,10 +31,11 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Allow for this room to be found by searching %1$s public room directory" "Allow to be found by searching the public directory." "Visible in public directory" - "Anyone" + "Anyone (history is public)" + "Changes won\'t affect past messages, only new ones. %1$s" "Who can read history" - "Members only since they were invited" - "Members only since selecting this option" + "Members since invited" + "Members (full history)" "Room addresses are ways to find and access rooms. This also ensures you can easily share your room with others. You can choose to publish your room in your homeserver public room directory." "Room publishing" From 83eae74488b8c5ede6df3bd9a7bafe132342989a Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Fri, 19 Dec 2025 12:55:34 +0100 Subject: [PATCH 222/347] Fix unverified account after account creation (#5914) * Fix unverified account after account creation: When we create an account either using OIDC or by importing a login and password one, we need to wait until the verification state is known (either verified or unverified). The problem is the verification service will return incorrect values until the E2EE tasks are initialized in the SDK, even if we add the state listeners after doing so. So what we can do is initialize the E2EE setup, discard any invalid verification state received while it's not initialized, and take only those received after it's initialized. * Actually restore the `Client` in `RustMatrixAuthenticationService.importCreatedSession` so we don't need to use `clear` and have the navigation restore the client later: This standarizes the way the login/registration flow works, always restoring/reusing the existing client instance --- .../createaccount/CreateAccountPresenter.kt | 12 ---- .../CreateAccountPresenterTest.kt | 7 --- .../matrix/impl/RustMatrixClientFactory.kt | 2 +- .../auth/RustMatrixAuthenticationService.kt | 32 +++++++++- .../RustSessionVerificationService.kt | 59 ++++++++++++------- 5 files changed, 68 insertions(+), 44 deletions(-) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenter.kt index f7a23df7d1..bf7af111f4 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenter.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenter.kt @@ -19,24 +19,18 @@ import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.core.data.tryOrNull import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.meta.BuildMeta -import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.core.SessionId import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch -import kotlinx.coroutines.withTimeout -import kotlin.time.Duration.Companion.seconds @AssistedInject class CreateAccountPresenter( @Assisted private val url: String, private val authenticationService: MatrixAuthenticationService, - private val clientProvider: MatrixClientProvider, private val messageParser: MessageParser, private val buildMeta: BuildMeta, ) : Presenter { @@ -80,12 +74,6 @@ class CreateAccountPresenter( }.flatMap { externalSession -> authenticationService.importCreatedSession(externalSession) }.onSuccess { sessionId -> - tryOrNull { - // Wait until the session is verified - val client = clientProvider.getOrRestore(sessionId).getOrThrow() - val sessionVerificationService = client.sessionVerificationService - withTimeout(10.seconds) { sessionVerificationService.sessionVerifiedStatus.first { it.isVerified() } } - } loggedInState.value = AsyncAction.Success(sessionId) }.onFailure { failure -> loggedInState.value = AsyncAction.Failure(failure) diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenterTest.kt index a9d3c02368..c70a5c9a9a 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountPresenterTest.kt @@ -16,8 +16,6 @@ import io.element.android.libraries.matrix.api.auth.external.ExternalSession import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_SESSION_ID -import io.element.android.libraries.matrix.test.FakeMatrixClient -import io.element.android.libraries.matrix.test.FakeMatrixClientProvider import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService @@ -80,14 +78,11 @@ class CreateAccountPresenterTest { fun `present - receiving a message able to be parsed change the state to success`() = runTest { val lambda = lambdaRecorder { _ -> anExternalSession() } val sessionVerificationService = FakeSessionVerificationService() - val client = FakeMatrixClient(sessionVerificationService = sessionVerificationService) - val clientProvider = FakeMatrixClientProvider(getClient = { Result.success(client) }) val presenter = createPresenter( authenticationService = FakeMatrixAuthenticationService( importCreatedSessionLambda = { Result.success(A_SESSION_ID) } ), messageParser = FakeMessageParser(lambda), - clientProvider = clientProvider, ) presenter.test { val initialState = awaitItem() @@ -120,12 +115,10 @@ class CreateAccountPresenterTest { authenticationService: MatrixAuthenticationService = FakeMatrixAuthenticationService(), messageParser: MessageParser = FakeMessageParser(), buildMeta: BuildMeta = aBuildMeta(), - clientProvider: FakeMatrixClientProvider = FakeMatrixClientProvider(), ) = CreateAccountPresenter( url = url, authenticationService = authenticationService, messageParser = messageParser, buildMeta = buildMeta, - clientProvider = clientProvider, ) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index 88207049d2..5932acec20 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -193,7 +193,7 @@ sealed interface ClientBuilderSlidingSync { data object Native : ClientBuilderSlidingSync } -private fun SessionData.toSession() = Session( +fun SessionData.toSession() = Session( accessToken = accessToken, refreshToken = refreshToken, userId = userId, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt index 97719bed36..7cd9fbedf5 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.api.auth.external.ExternalSession import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus import io.element.android.libraries.matrix.impl.ClientBuilderSlidingSync import io.element.android.libraries.matrix.impl.RustMatrixClientFactory import io.element.android.libraries.matrix.impl.auth.qrlogin.QrErrorMapper @@ -35,10 +36,13 @@ import io.element.android.libraries.matrix.impl.keys.PassphraseGenerator import io.element.android.libraries.matrix.impl.mapper.toSessionData import io.element.android.libraries.matrix.impl.paths.SessionPaths import io.element.android.libraries.matrix.impl.paths.SessionPathsFactory +import io.element.android.libraries.matrix.impl.toSession import io.element.android.libraries.sessionstorage.api.LoginType import io.element.android.libraries.sessionstorage.api.SessionStore import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.flow.first import kotlinx.coroutines.withContext +import kotlinx.coroutines.withTimeoutOrNull import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.ClientBuilder import org.matrix.rustcomponents.sdk.HumanQrLoginException @@ -48,6 +52,7 @@ import org.matrix.rustcomponents.sdk.QrLoginProgress import org.matrix.rustcomponents.sdk.QrLoginProgressListener import timber.log.Timber import uniffi.matrix_sdk.OAuthAuthorizationData +import kotlin.time.Duration.Companion.seconds @ContributesBinding(AppScope::class) @SingleIn(AppScope::class) @@ -160,7 +165,7 @@ class RustMatrixAuthenticationService( override suspend fun importCreatedSession(externalSession: ExternalSession): Result = withContext(coroutineDispatchers.io) { runCatchingExceptions { - currentClient ?: error("You need to call `setHomeserver()` first") + val client = currentClient ?: error("You need to call `setHomeserver()` first") val currentSessionPaths = sessionPaths ?: error("You need to call `setHomeserver()` first") val sessionData = externalSession.toSessionData( isTokenValid = true, @@ -168,8 +173,21 @@ class RustMatrixAuthenticationService( passphrase = pendingPassphrase, sessionPaths = currentSessionPaths, ) - clear() + + // We restore the client using the just retrieved session data + client.restoreSession(sessionData.toSession()) + val matrixClient = rustMatrixClientFactory.create(client) + + // We wait for the verification state to be known + matrixClient.waitForKnownVerificationState() + + // And once it's ready we share it and save the actual session data + newMatrixClientObservers.forEach { it.invoke(matrixClient) } sessionStore.addSession(sessionData) + + // Clean up the strong reference held here since it's no longer necessary + currentClient = null + SessionId(sessionData.userId) } } @@ -238,6 +256,8 @@ class RustMatrixAuthenticationService( sessionPaths = currentSessionPaths, ) val matrixClient = rustMatrixClientFactory.create(client) + matrixClient.waitForKnownVerificationState() + newMatrixClientObservers.forEach { it.invoke(matrixClient) } sessionStore.addSession(sessionData) @@ -356,4 +376,12 @@ class RustMatrixAuthenticationService( currentClient?.close() currentClient = null } + + private suspend fun MatrixClient.waitForKnownVerificationState() { + withTimeoutOrNull(10.seconds) { + Timber.d("Waiting for a known verification status...") + val status = sessionVerificationService.sessionVerifiedStatus.first { it != SessionVerifiedStatus.Unknown } + Timber.d("Finished waiting for a known verification status: $status") + } ?: Timber.w("Timed out waiting for a known verification status") + } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt index 3014618b9d..f613ce8dff 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt @@ -44,6 +44,7 @@ import org.matrix.rustcomponents.sdk.VerificationState import org.matrix.rustcomponents.sdk.VerificationStateListener import org.matrix.rustcomponents.sdk.use import timber.log.Timber +import java.util.concurrent.atomic.AtomicBoolean import kotlin.time.Duration.Companion.seconds import org.matrix.rustcomponents.sdk.SessionVerificationData as RustSessionVerificationData import org.matrix.rustcomponents.sdk.SessionVerificationRequestDetails as RustSessionVerificationRequestDetails @@ -66,9 +67,16 @@ class RustSessionVerificationService( private val recoveryState = MutableStateFlow(RecoveryState.UNKNOWN) + private val isInitialized = AtomicBoolean(false) + // Listen for changes in verification status and update accordingly private val verificationStateListenerTaskHandle = encryptionService.verificationStateListener(object : VerificationStateListener { override fun onUpdate(status: VerificationState) { + if (!isInitialized.get()) { + Timber.d("Discarding new verifications state: $status. E2EE is not initialised yet") + return + } + Timber.d("New verification state: $status") _sessionVerifiedStatus.value = status.map() } @@ -77,6 +85,11 @@ class RustSessionVerificationService( // In case we enter the recovery key instead we check changes in the recovery state, since the listener above won't be triggered private val recoveryStateListenerTaskHandle = encryptionService.recoveryStateListener(object : RecoveryStateListener { override fun onUpdate(status: RecoveryState) { + if (!isInitialized.get()) { + Timber.d("Discarding new recovery state: $status. E2EE is not initialised yet") + return + } + Timber.d("New recovery state: $status") // We could check the `RecoveryState`, but it's easier to just use the verification state directly recoveryState.value = status @@ -87,7 +100,7 @@ class RustSessionVerificationService( * The internal service that checks verification can only run after the initial sync. * This [StateFlow] will notify consumers when the service is ready to be used. */ - private val isReady = isSyncServiceReady.stateIn(sessionCoroutineScope, SharingStarted.Eagerly, false) + private val canVerify = isSyncServiceReady.stateIn(sessionCoroutineScope, SharingStarted.Eagerly, false) override val needsSessionVerification = sessionVerifiedStatus.map { verificationStatus -> verificationStatus == SessionVerifiedStatus.NotVerified @@ -99,14 +112,11 @@ class RustSessionVerificationService( private var listener: SessionVerificationServiceListener? = null + private val initializationMutex = Mutex() + init { // Instantiate the verification controller when possible, this is needed to get incoming verification requests - sessionCoroutineScope.launch { - tryOrNull { - encryptionService.waitForE2eeInitializationTasks() - initVerificationControllerIfNeeded() - } - } + sessionCoroutineScope.launch { ensureEncryptionIsInitialized() } } override fun setListener(listener: SessionVerificationServiceListener?) { @@ -114,13 +124,13 @@ class RustSessionVerificationService( } override suspend fun requestCurrentSessionVerification() = tryOrFail { - initVerificationControllerIfNeeded() + ensureEncryptionIsInitialized() verificationController.requestDeviceVerification() currentVerificationRequest = VerificationRequest.Outgoing.CurrentSession } override suspend fun requestUserVerification(userId: UserId) = tryOrFail { - initVerificationControllerIfNeeded() + ensureEncryptionIsInitialized() verificationController.requestUserVerification(userId.value) currentVerificationRequest = VerificationRequest.Outgoing.User(userId) } @@ -140,7 +150,7 @@ class RustSessionVerificationService( } override suspend fun acknowledgeVerificationRequest(verificationRequest: VerificationRequest.Incoming) = tryOrFail { - initVerificationControllerIfNeeded() + ensureEncryptionIsInitialized() verificationController.acknowledgeVerificationRequest( senderId = verificationRequest.details.senderProfile.userId.value, flowId = verificationRequest.details.flowId.value, @@ -225,7 +235,7 @@ class RustSessionVerificationService( override suspend fun reset(cancelAnyPendingVerificationAttempt: Boolean) { currentVerificationRequest = null - if (isReady.value && cancelAnyPendingVerificationAttempt) { + if (canVerify.value && cancelAnyPendingVerificationAttempt) { // Cancel any pending verification attempt tryOrNull { verificationController.cancelVerification() } } @@ -241,23 +251,28 @@ class RustSessionVerificationService( } } - private var initControllerMutex = Mutex() - - private suspend fun initVerificationControllerIfNeeded() = initControllerMutex.withLock { - if (!this::verificationController.isInitialized) { - tryOrFail { - verificationController = client.getSessionVerificationController() - verificationController.setDelegate(this) - } - } - } - private fun updateVerificationStatus() { runCatchingExceptions { _sessionVerifiedStatus.value = encryptionService.verificationState().map() Timber.d("New verification status: ${_sessionVerifiedStatus.value}") } } + + private suspend fun ensureEncryptionIsInitialized() = initializationMutex.withLock { + // We're keeping the separate checks instead of unconditionally calling the suspend methods + // so we can skip crossing the FFI layer when it's not needed + tryOrFail { + if (!isInitialized.get()) { + encryptionService.waitForE2eeInitializationTasks() + isInitialized.set(true) + } + + if (!this::verificationController.isInitialized) { + verificationController = client.getSessionVerificationController() + verificationController.setDelegate(this) + } + } + } } private fun VerificationState.map() = when (this) { From f0ff97e4cf49610e9acd2527efcef18390615903 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 13:13:54 +0100 Subject: [PATCH 223/347] fix(deps): update dependency io.nlopez.compose.rules:detekt to v0.5.3 (#5939) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 03f5eb91a3..61e17c149c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,7 +46,7 @@ allprojects { config.from(files("$rootDir/tools/detekt/detekt.yml")) } dependencies { - detektPlugins("io.nlopez.compose.rules:detekt:0.5.2") + detektPlugins("io.nlopez.compose.rules:detekt:0.5.3") detektPlugins(project(":tests:detekt-rules")) } From 96b67cefa4c61a4f7e1e93ebd00f496898eb2dd7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 14:15:55 +0100 Subject: [PATCH 224/347] fix(deps): update dependency com.google.zxing:core to v3.5.4 (#5935) * fix(deps): update dependency com.google.zxing:core to v3.5.4 * We are not targetting API 24+ so it should be fine to use the last version * Update screenshots --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Benoit Marty Co-authored-by: ElementBot --- gradle/libs.versions.toml | 3 +-- .../test/snapshots/images/libraries.qrcode_QrCodeView_en.png | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bd8bdf19ae..95c8bb6b89 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -211,8 +211,7 @@ maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2" maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2" opusencoder = "io.element.android:opusencoder:1.2.0" zxing_cpp = "io.github.zxing-cpp:android:2.3.0" -# Stick to 3.3.3 because of https://github.com/zxing/zxing/issues/1170 -google_zxing = "com.google.zxing:core:3.3.3" +google_zxing = "com.google.zxing:core:3.5.4" haze = { module = "dev.chrisbanes.haze:haze", version.ref = "haze" } haze_materials = { module = "dev.chrisbanes.haze:haze-materials", version.ref = "haze" } diff --git a/tests/uitests/src/test/snapshots/images/libraries.qrcode_QrCodeView_en.png b/tests/uitests/src/test/snapshots/images/libraries.qrcode_QrCodeView_en.png index bca09dbeb2..beec069b37 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.qrcode_QrCodeView_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.qrcode_QrCodeView_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6aea8452a990307184b9d3f3ceef60e3c09de4ac8128362cafd23ab64a1fe8d7 -size 10600 +oid sha256:c07e9a4ec69a889b003bee4293a610c9fe0fd0f83c10c0da01322e076e9c980d +size 10750 From d04ebe880bfe3016fbf79c4dfad0147d03510222 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 18 Dec 2025 11:00:10 +0100 Subject: [PATCH 225/347] Simplify the copy of the history visibility settings Closes #5898 --- .../historyvisible/HistoryVisibleStateView.kt | 38 +++----------- .../securityandprivacy/impl/build.gradle.kts | 2 + .../impl/root/SecurityAndPrivacyNode.kt | 13 +++++ .../impl/root/SecurityAndPrivacyPresenter.kt | 16 +++--- .../impl/root/SecurityAndPrivacyState.kt | 30 ++++++----- .../root/SecurityAndPrivacyStateProvider.kt | 2 +- .../impl/root/SecurityAndPrivacyView.kt | 32 ++++++++++-- .../impl/SecurityAndPrivacyPresenterTest.kt | 20 ++++---- .../impl/SecurityAndPrivacyViewTest.kt | 9 ++-- .../designsystem/text/StringWithLink.kt | 51 +++++++++++++++++++ 10 files changed, 142 insertions(+), 71 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/StringWithLink.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateView.kt index 9c08c9d101..d0655f695d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/historyvisible/HistoryVisibleStateView.kt @@ -10,18 +10,13 @@ package io.element.android.features.messages.impl.crypto.historyvisible import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.LinkAnnotation -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.appconfig.LearnMoreConfig -import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.atomic.molecules.ComposerAlertLevel import io.element.android.libraries.designsystem.atomic.molecules.ComposerAlertMolecule import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.text.stringWithLink import io.element.android.libraries.ui.strings.CommonStrings @Composable @@ -33,37 +28,16 @@ fun HistoryVisibleStateView( if (!state.showAlert) { return } - ComposerAlertMolecule( modifier = modifier, avatar = null, showIcon = true, level = ComposerAlertLevel.Info, - content = buildAnnotatedString { - val learnMoreStr = stringResource(CommonStrings.action_learn_more) - val fullText = stringResource(CommonStrings.crypto_history_visible, learnMoreStr) - append(fullText) - val learnMoreStartIndex = fullText.lastIndexOf(learnMoreStr) - addStyle( - style = SpanStyle( - textDecoration = TextDecoration.Underline, - fontWeight = FontWeight.Bold, - color = ElementTheme.colors.textPrimary - ), - start = learnMoreStartIndex, - end = learnMoreStartIndex + learnMoreStr.length, - ) - addLink( - url = LinkAnnotation.Url( - url = LearnMoreConfig.HISTORY_VISIBLE_URL, - linkInteractionListener = { - onLinkClick(LearnMoreConfig.HISTORY_VISIBLE_URL, true) - } - ), - start = learnMoreStartIndex, - end = learnMoreStartIndex + learnMoreStr.length, - ) - }, + content = stringWithLink( + textRes = CommonStrings.crypto_history_visible, + url = LearnMoreConfig.HISTORY_VISIBLE_URL, + onLinkClick = { url -> onLinkClick(url, true) }, + ), submitText = stringResource(CommonStrings.action_dismiss), onSubmitClick = { state.eventSink(HistoryVisibleEvent.Acknowledge) }, ) diff --git a/features/securityandprivacy/impl/build.gradle.kts b/features/securityandprivacy/impl/build.gradle.kts index 5a83cebd8c..bb9764eb60 100644 --- a/features/securityandprivacy/impl/build.gradle.kts +++ b/features/securityandprivacy/impl/build.gradle.kts @@ -28,7 +28,9 @@ setupDependencyInjection() dependencies { api(projects.features.securityandprivacy.api) + implementation(projects.appconfig) implementation(projects.appnav) + implementation(projects.libraries.androidutils) implementation(projects.libraries.architecture) implementation(projects.libraries.core) implementation(projects.libraries.designsystem) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt index e173117431..d5fb72e72e 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt @@ -8,6 +8,8 @@ package io.element.android.features.securityandprivacy.impl.root +import android.app.Activity +import androidx.activity.compose.LocalActivity import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -19,7 +21,9 @@ import com.bumble.appyx.core.plugin.plugins import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode +import io.element.android.compound.theme.ElementTheme import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator +import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab import io.element.android.libraries.architecture.appyx.launchMolecule import io.element.android.libraries.di.RoomScope @@ -35,11 +39,20 @@ class SecurityAndPrivacyNode( private val stateFlow = launchMolecule { presenter.present() } + private fun onOpenExternalUrl(activity: Activity, darkTheme: Boolean, url: String) { + activity.openUrlInChromeCustomTab(null, darkTheme, url) + } + @Composable override fun View(modifier: Modifier) { + val activity = requireNotNull(LocalActivity.current) + val isDark = ElementTheme.isLightTheme.not() val state by stateFlow.collectAsState() SecurityAndPrivacyView( state = state, + onLinkClick = { url -> + onOpenExternalUrl(activity, isDark, url) + }, modifier = modifier ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index 472f71ddfb..e627fef40c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -301,21 +301,21 @@ private fun SecurityAndPrivacyRoomAccess.map(): JoinRule? { private fun RoomHistoryVisibility?.map(): SecurityAndPrivacyHistoryVisibility { return when (this) { - RoomHistoryVisibility.WorldReadable -> SecurityAndPrivacyHistoryVisibility.Anyone RoomHistoryVisibility.Joined, - RoomHistoryVisibility.Invited -> SecurityAndPrivacyHistoryVisibility.SinceInvite - RoomHistoryVisibility.Shared -> SecurityAndPrivacyHistoryVisibility.SinceSelection - // All other cases are not supported so we default to SinceSelection + RoomHistoryVisibility.Invited -> SecurityAndPrivacyHistoryVisibility.Invited + RoomHistoryVisibility.Shared -> SecurityAndPrivacyHistoryVisibility.Shared + RoomHistoryVisibility.WorldReadable -> SecurityAndPrivacyHistoryVisibility.WorldReadable + // All other cases are not supported so we default to Shared is RoomHistoryVisibility.Custom, - null -> SecurityAndPrivacyHistoryVisibility.SinceSelection + null -> SecurityAndPrivacyHistoryVisibility.Shared } } private fun SecurityAndPrivacyHistoryVisibility.map(): RoomHistoryVisibility { return when (this) { - SecurityAndPrivacyHistoryVisibility.SinceSelection -> RoomHistoryVisibility.Shared - SecurityAndPrivacyHistoryVisibility.SinceInvite -> RoomHistoryVisibility.Invited - SecurityAndPrivacyHistoryVisibility.Anyone -> RoomHistoryVisibility.WorldReadable + SecurityAndPrivacyHistoryVisibility.Invited -> RoomHistoryVisibility.Invited + SecurityAndPrivacyHistoryVisibility.Shared -> RoomHistoryVisibility.Shared + SecurityAndPrivacyHistoryVisibility.WorldReadable -> RoomHistoryVisibility.WorldReadable } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index 2c6bd59e12..7f43d4e94a 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -11,7 +11,7 @@ package io.element.android.features.securityandprivacy.impl.root import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData -import kotlinx.collections.immutable.toImmutableSet +import kotlinx.collections.immutable.toImmutableList data class SecurityAndPrivacyState( // the settings that are currently applied on the room. @@ -23,19 +23,24 @@ data class SecurityAndPrivacyState( val isKnockEnabled: Boolean, val saveAction: AsyncAction, val isSpace: Boolean, + private val permissions: SecurityAndPrivacyPermissions, val eventSink: (SecurityAndPrivacyEvent) -> Unit ) { val canBeSaved = savedSettings != editedSettings - val availableHistoryVisibilities = buildSet { - add(SecurityAndPrivacyHistoryVisibility.SinceSelection) + // Logic is in https://github.com/element-hq/element-meta/issues/3029 + val availableHistoryVisibilities = buildList { + // Shared is always available + add(SecurityAndPrivacyHistoryVisibility.Shared) if (editedSettings.roomAccess == SecurityAndPrivacyRoomAccess.Anyone && !editedSettings.isEncrypted) { - add(SecurityAndPrivacyHistoryVisibility.Anyone) + add(SecurityAndPrivacyHistoryVisibility.WorldReadable) } else { - add(SecurityAndPrivacyHistoryVisibility.SinceInvite) + add(SecurityAndPrivacyHistoryVisibility.Invited) } - }.toImmutableSet() + } + .sorted() + .toImmutableList() val showRoomAccessSection = permissions.canChangeRoomAccess @@ -55,18 +60,19 @@ data class SecurityAndPrivacySettings( ) enum class SecurityAndPrivacyHistoryVisibility { - SinceSelection, - SinceInvite, - Anyone; + // Order matters, and is from the most to the least restrictive + Invited, + Shared, + WorldReadable; /** * Returns the fallback visibility when the current visibility is not available. */ fun fallback(): SecurityAndPrivacyHistoryVisibility { return when (this) { - SinceSelection, - SinceInvite -> SinceSelection - Anyone -> SinceInvite + Invited, + Shared -> Shared + WorldReadable -> Invited } } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index b5347a753f..223d524ca3 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -93,7 +93,7 @@ fun aSecurityAndPrivacySettings( roomAccess: SecurityAndPrivacyRoomAccess = SecurityAndPrivacyRoomAccess.InviteOnly, isEncrypted: Boolean = true, address: String? = null, - historyVisibility: SecurityAndPrivacyHistoryVisibility = SecurityAndPrivacyHistoryVisibility.SinceSelection, + historyVisibility: SecurityAndPrivacyHistoryVisibility = SecurityAndPrivacyHistoryVisibility.Shared, isVisibleInRoomDirectory: AsyncData = AsyncData.Uninitialized, ) = SecurityAndPrivacySettings( roomAccess = roomAccess, diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 125d84c84d..bf6a5ffdf2 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -27,8 +27,10 @@ import androidx.compose.material3.ListItemDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp +import io.element.android.appconfig.LearnMoreConfig import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.securityandprivacy.impl.R @@ -44,6 +46,7 @@ import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight +import io.element.android.libraries.designsystem.text.stringWithLink import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.IconSource import io.element.android.libraries.designsystem.theme.components.ListItem @@ -52,11 +55,12 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.ui.strings.CommonStrings -import kotlinx.collections.immutable.ImmutableSet +import kotlinx.collections.immutable.ImmutableList @Composable fun SecurityAndPrivacyView( state: SecurityAndPrivacyState, + onLinkClick: (String) -> Unit, modifier: Modifier = Modifier, ) { BackHandler { @@ -122,6 +126,7 @@ fun SecurityAndPrivacyView( savedOptions = state.savedSettings.historyVisibility, availableOptions = state.availableHistoryVisibilities, onSelectOption = { state.eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(it)) }, + onLinkClick = onLinkClick, ) } } @@ -176,6 +181,7 @@ private fun SecurityAndPrivacyToolbar( private fun SecurityAndPrivacySection( title: String, modifier: Modifier = Modifier, + subtitle: AnnotatedString? = null, content: @Composable ColumnScope.() -> Unit, ) { Column( @@ -187,6 +193,15 @@ private fun SecurityAndPrivacySection( color = ElementTheme.colors.textPrimary, modifier = Modifier.padding(horizontal = 16.dp), ) + if (subtitle != null) { + Spacer(Modifier.height(8.dp)) + Text( + text = subtitle, + style = ElementTheme.typography.fontBodyMdRegular, + color = ElementTheme.colors.textSecondary, + modifier = Modifier.padding(horizontal = 16.dp), + ) + } content() } } @@ -359,12 +374,18 @@ private fun EncryptionSection( private fun HistoryVisibilitySection( editedOption: SecurityAndPrivacyHistoryVisibility?, savedOptions: SecurityAndPrivacyHistoryVisibility?, - availableOptions: ImmutableSet, + availableOptions: ImmutableList, onSelectOption: (SecurityAndPrivacyHistoryVisibility) -> Unit, + onLinkClick: (String) -> Unit, modifier: Modifier = Modifier, ) { SecurityAndPrivacySection( title = stringResource(R.string.screen_security_and_privacy_room_history_section_header), + subtitle = stringWithLink( + textRes = R.string.screen_security_and_privacy_room_history_section_footer, + url = LearnMoreConfig.HISTORY_VISIBLE_URL, + onLinkClick = onLinkClick, + ), modifier = modifier, ) { for (availableOption in availableOptions) { @@ -396,9 +417,9 @@ private fun HistoryVisibilityItem( isEnabled: Boolean = true, ) { val headlineText = when (option) { - SecurityAndPrivacyHistoryVisibility.SinceSelection -> stringResource(R.string.screen_security_and_privacy_room_history_since_selecting_option_title) - SecurityAndPrivacyHistoryVisibility.SinceInvite -> stringResource(R.string.screen_security_and_privacy_room_history_since_invite_option_title) - SecurityAndPrivacyHistoryVisibility.Anyone -> stringResource(R.string.screen_security_and_privacy_room_history_anyone_option_title) + SecurityAndPrivacyHistoryVisibility.Invited -> stringResource(R.string.screen_security_and_privacy_room_history_since_invite_option_title) + SecurityAndPrivacyHistoryVisibility.Shared -> stringResource(R.string.screen_security_and_privacy_room_history_since_selecting_option_title) + SecurityAndPrivacyHistoryVisibility.WorldReadable -> stringResource(R.string.screen_security_and_privacy_room_history_anyone_option_title) } ListItem( headlineContent = { Text(text = headlineText) }, @@ -424,5 +445,6 @@ internal fun SecurityAndPrivacyViewDarkPreview(@PreviewParameter(SecurityAndPriv private fun ContentToPreview(state: SecurityAndPrivacyState) { SecurityAndPrivacyView( state = state, + onLinkClick = {}, ) } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index 5f3d14958c..25331470b6 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -84,7 +84,7 @@ class SecurityAndPrivacyPresenterTest { with(awaitItem()) { assertThat(editedSettings).isEqualTo(savedSettings) assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.Anyone) - assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Anyone) + assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Shared) assertThat(editedSettings.address).isEqualTo(A_ROOM_ALIAS.value) assertThat(canBeSaved).isFalse() } @@ -122,16 +122,16 @@ class SecurityAndPrivacyPresenterTest { presenter.test { skipItems(1) with(awaitItem()) { - assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.SinceSelection) - eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.SinceInvite)) + assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Shared) + eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Invited)) } with(awaitItem()) { - assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.SinceInvite) + assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Invited) assertThat(canBeSaved).isTrue() - eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.SinceSelection)) + eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.WorldReadable)) } with(awaitItem()) { - assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.SinceSelection) + assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.WorldReadable) assertThat(canBeSaved).isFalse() } } @@ -250,10 +250,10 @@ class SecurityAndPrivacyPresenterTest { eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) } with(awaitItem()) { - eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Anyone)) + eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.WorldReadable)) } with(awaitItem()) { - assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Anyone) + assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.WorldReadable) eventSink(SecurityAndPrivacyEvent.ConfirmEnableEncryption) } skipItems(1) @@ -318,10 +318,10 @@ class SecurityAndPrivacyPresenterTest { eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.Anyone)) } with(awaitItem()) { - eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Anyone)) + eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.WorldReadable)) } with(awaitItem()) { - assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Anyone) + assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.WorldReadable) eventSink(SecurityAndPrivacyEvent.ConfirmEnableEncryption) } skipItems(1) diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt index 6b429c04ea..66178878f5 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt @@ -24,6 +24,7 @@ import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPriv import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.tests.testutils.EnsureNeverCalledWithParam import io.element.android.tests.testutils.EventsRecorder import io.element.android.tests.testutils.clickOn import io.element.android.tests.testutils.pressBack @@ -146,12 +147,12 @@ class SecurityAndPrivacyViewTest { val state = aSecurityAndPrivacyState( eventSink = recorder, editedSettings = aSecurityAndPrivacySettings( - historyVisibility = SecurityAndPrivacyHistoryVisibility.SinceSelection, + historyVisibility = SecurityAndPrivacyHistoryVisibility.Invited, ), ) rule.setSecurityAndPrivacyView(state) - rule.clickOn(R.string.screen_security_and_privacy_room_history_since_selecting_option_title) - recorder.assertSingle(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.SinceSelection)) + rule.clickOn(R.string.screen_security_and_privacy_room_history_since_invite_option_title) + recorder.assertSingle(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Invited)) } @Test @@ -184,10 +185,12 @@ private fun AndroidComposeTestRule.setSecur state: SecurityAndPrivacyState = aSecurityAndPrivacyState( eventSink = EventsRecorder(expectEvents = false), ), + onLinkClick: (String) -> Unit = EnsureNeverCalledWithParam(), ) { setContent { SecurityAndPrivacyView( state = state, + onLinkClick = onLinkClick, ) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/StringWithLink.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/StringWithLink.kt new file mode 100644 index 0000000000..d82ea9e817 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/StringWithLink.kt @@ -0,0 +1,51 @@ +/* + * 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.designsystem.text + +import androidx.annotation.StringRes +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.LinkAnnotation +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextDecoration +import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +fun stringWithLink( + @StringRes textRes: Int, + url: String, + onLinkClick: (String) -> Unit, + @StringRes linkTextRes: Int = CommonStrings.action_learn_more, +) = buildAnnotatedString { + val learnMoreStr = stringResource(linkTextRes) + val fullText = stringResource(textRes, learnMoreStr) + append(fullText) + val learnMoreStartIndex = fullText.lastIndexOf(learnMoreStr) + addStyle( + style = SpanStyle( + textDecoration = TextDecoration.Underline, + fontWeight = FontWeight.Bold, + color = ElementTheme.colors.textPrimary + ), + start = learnMoreStartIndex, + end = learnMoreStartIndex + learnMoreStr.length, + ) + addLink( + url = LinkAnnotation.Url( + url = url, + linkInteractionListener = { + onLinkClick(url) + } + ), + start = learnMoreStartIndex, + end = learnMoreStartIndex + learnMoreStr.length, + ) +} From 5e21f179cc2a53fc2873886c78f29d4727889b2c Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 19 Dec 2025 14:08:00 +0000 Subject: [PATCH 226/347] Update screenshots --- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png | 4 ++-- 24 files changed, 48 insertions(+), 48 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png index a52b20decc..840ed2ce67 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71acb17375db16b8777221e3a09c85ce821920dfaf7853c456493371e4778b9d -size 37050 +oid sha256:85a7f1e86ee77355ada16764c0cdaa96193237e1e0936188b00b99247b67f272 +size 39232 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png index e8b0f4f2a3..81ed09d87e 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b03d25813c75712a0b9e23622132bd63e07ca9ec593a1842dacf751347c06ea1 -size 32023 +oid sha256:507eec1e5125056ca4980ae67f904dd30bcb88ef6d66d5968aafbb3c1449e4b8 +size 33779 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png index 16b13d8a4f..14683ef0b0 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3aaf6da43b5f2882da986ae766d0057421b1f39f7f0bb467bd32f2a957608045 -size 31478 +oid sha256:d300a9854096634ea0e6722db487607a75f6e0c46d7341f044a190a212d95307 +size 32373 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png index f642f7050b..810bb5531a 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:72be11ed273a790b0ab8e5023c1e21384c020e1b0fc0e3950de8f041c4004e64 -size 33758 +oid sha256:b42e3df9fec259210b63431e295e8c7d1a7640149c9616b572b90c0b40392a60 +size 34637 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png index 82cba49c78..0bd3c0413d 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5343bc348bc1be7430243ce6fceeb7c81bbf2d5692486733221cb6c615d9aeea -size 41544 +oid sha256:3bb107a37b14dcbc6aa530a8d47f58c809df7719a0c8a416a268ffd2df165681 +size 41602 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png index 53e3694e7b..08e21cdeb5 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9cf6cd1f914a4f31608edceefde79632ebed0c8983d83d8a63c4408bcc2d4ff3 -size 56743 +oid sha256:6a2d21173c63d0b9b3a558d23acd380c9d15fe5c4dc1b62f31644817318e049f +size 56061 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png index aa9712b151..74531a6a2d 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00a667f59cd097021a6d363d0e4f578cba6acc405aaaa74bddfa9a3286cfd26e -size 56408 +oid sha256:89598f3f1149cec915196f1abb1998855c3dd161d6f05f32bccc7bb85cd1938a +size 55715 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png index 680b550efa..d71baf5a13 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5bdcf84378968b8e37cc50a300ff19b1917354de764a9f81448e6ca3d4050386 -size 54711 +oid sha256:8ae448a2c6f5da0b563873a683884d75a74ded6157edc56e91507a1857ff87ee +size 56298 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png index d2603fba50..beeea22486 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:577eac69d32648070d896788474104fdf143c040e058f182d6b832e5ea83fad8 -size 37242 +oid sha256:b67ebf4536e36571b0867e71533b2fe1953ca2b88f15fe3531f3ddb9043f69ec +size 39418 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png index cad3e46f71..b39a2f040c 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:745a270883c79932fdde14d11785d9e27d1ec0eee03999af5e494b5c6e30c309 -size 57329 +oid sha256:e5fb16ef839b9f93caddbc984c8be260846e7fd7d68ae3b31dcc97c7644b41b4 +size 56670 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png index f918b5ff28..f29bc630f1 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:451eee79c5ca4b61902044c58f99069065fcd11a9fa7d469d2568cd20ea134a3 -size 56743 +oid sha256:9402ad99b181b99083abff78d078e9fbb010144e07f80ff995db7884a61fa853 +size 56060 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png index 7f77181ea9..e5fda5dfd7 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:023b2870f5a4291ad8b521dc177db22972a47e5e965458c81cb8688da0cbe6b8 -size 57097 +oid sha256:cadacec9344f3ca2c029006c620cd8c309bb7f4b38cbb7b47c7c336ca265a141 +size 56424 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png index 80b8aeb70e..f366177df5 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1463d9c6b2d968c0a5f375e5135b31e31b32f2d35525e0be1c264d90ff4e723c -size 38652 +oid sha256:cc24db5d5659ddee2787ffc6a3371351478c9ccd7cfb909ede6a06f1e72a907a +size 40756 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png index 7458fc24fa..0ba776c5fd 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09a88867a2f10ce346df8d683d614970f9aad8e8ec7bf06bddf27352dc0e5476 -size 33520 +oid sha256:548950d915f6fbfdf1a17b81619d3d4cbefe93b79091d259bcec41ae6bbbc652 +size 35422 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png index eeac763a63..5932151ec4 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:81162b1f086e45797db0678eff6bc41ad35eb09a7ac436d540fd3b7e1feffbc6 -size 33534 +oid sha256:6b47bcab08cded6e857fe213ab2c90602e557a36feebb45b2b8d4d18115ac68b +size 34582 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png index 5e318df2ca..8919639fe0 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1cbcce698faad80969cd00d2680afd7cd61b6ba649f0b67e8c7fb2fe0dbe746 -size 35884 +oid sha256:5cd5de47e285702bf3d2ee325fc83a1168a0367d9c6b54018565daa0ed503a77 +size 36876 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png index af2072ede6..bce9a377e8 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0ce43031e71ffadc53388a66a9ceb66b1c9bb33014a912161ec6006a303050b -size 43544 +oid sha256:59b6d7d5e484b34e1ce7814432144df34b1cd3323d31c90db439cbb5d9f8dc83 +size 43588 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png index c9a99e421a..663a88741f 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a906ec0c412892a241eab241836d4238c1883ec1d27f27b8a012de75894fdaf7 -size 58785 +oid sha256:01cab7fd5a8b4e10a4ecca8a31b0f659fb9f2db9260272b0f6c96c4e126050aa +size 57895 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png index 4a47f17a41..7535035974 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e4ccb39f3024e3a98be3bc0f94ce769e412b891ed988dad4cf1457aab3cea72 -size 58442 +oid sha256:18e03a178666b24e95a9cd0ae5d95d0fe57db49d11b1b1f3cae5ed472e94b6d7 +size 57550 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png index 5176122680..dadc0c2de8 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8b10af4e5006f45e2fe738a3a8a589551378ee9106c09f10b9de81fdbf12e61 -size 56716 +oid sha256:f4aee340402c5fa0cdcaf2603ae5999f353eec734a1ab928c242889a1d5d2425 +size 58272 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png index db1c3dd777..a3ddf8b354 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc82d2ab3bc9d73726bcc0cdc5dc27b628d00db330cfcc7a78f177af029a7803 -size 38810 +oid sha256:a3bebec99f2b870e7a38333590f5cb776b30f4f9b976d99601a7fb3bfd05a71f +size 40913 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png index 766e81c18a..085ac47033 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aef64f63cb176feea3ee1e48de98f7bf6ed104370f84e377c963a2f26ba0fa49 -size 59387 +oid sha256:853218e7ddc4d18b260f6ab047beb82778284851e230babc14113c6cb329d29a +size 58504 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png index 55d3916eb4..0914a151e4 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6f46d940ee39961ea128fc7fc607dd6156d827121def3516ef62ff5f617e249 -size 58785 +oid sha256:e7caee4430244e294b75e3b6a5830088dd25397b1c272666eb2bec47ecd1f382 +size 57895 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png index 2c37ae11f9..c9a3183eea 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ea58c892886c9de971fd22a5a72340775cb0f973cdfb697d7f517100ce8b65d -size 59205 +oid sha256:bbb4224047c88d838de227e61332775e5efe0ce1380a7446c701f0db5b2d2dcc +size 58323 From ec61c065621d7178a90ca59ae511824225b94c40 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 15:38:08 +0100 Subject: [PATCH 227/347] fix(deps): update dependency androidx.webkit:webkit to v1.15.0 (#5925) 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 956855912e..e77dab102c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -115,7 +115,7 @@ androidx_activity_activity = { module = "androidx.activity:activity", version.re androidx_activity_compose = { module = "androidx.activity:activity-compose", version.ref = "activity" } androidx_startup = "androidx.startup:startup-runtime:1.2.0" androidx_preference = "androidx.preference:preference:1.2.1" -androidx_webkit = "androidx.webkit:webkit:1.14.0" +androidx_webkit = "androidx.webkit:webkit:1.15.0" androidx_compose_bom = { module = "androidx.compose:compose-bom", version.ref = "compose_bom" } androidx_compose_material3 = { module = "androidx.compose.material3:material3" } From 861ee714b43c53ed4a59f4b51d8bb37d10e02f4e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 15:38:26 +0100 Subject: [PATCH 228/347] Update GitHub Artifact Actions (#5932) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/build_enterprise.yml | 2 +- .github/workflows/maestro-local.yml | 6 +++--- .github/workflows/nightlyReports.yml | 4 ++-- .github/workflows/quality.yml | 10 +++++----- .github/workflows/release.yml | 6 +++--- .github/workflows/tests.yml | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bbd057c9b0..aa62b83e36 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,7 +54,7 @@ jobs: run: ./gradlew :app:assembleGplayDebug app:assembleFDroidDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES - name: Upload debug APKs if: ${{ matrix.variant == 'debug' }} - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: elementx-debug path: | @@ -62,7 +62,7 @@ jobs: app/build/outputs/apk/fdroid/debug/*-universal-debug.apk - name: Upload x86_64 APK for Maestro if: ${{ matrix.variant == 'debug' }} - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: elementx-apk-maestro path: | diff --git a/.github/workflows/build_enterprise.yml b/.github/workflows/build_enterprise.yml index 66bff7ce51..1d416ffe42 100644 --- a/.github/workflows/build_enterprise.yml +++ b/.github/workflows/build_enterprise.yml @@ -62,7 +62,7 @@ jobs: run: ./gradlew :app:assembleGplayDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES - name: Upload debug Enterprise APKs if: ${{ matrix.variant == 'debug' }} - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: elementx-enterprise-debug path: | diff --git a/.github/workflows/maestro-local.yml b/.github/workflows/maestro-local.yml index 460fdcf6c2..4fd42534b7 100644 --- a/.github/workflows/maestro-local.yml +++ b/.github/workflows/maestro-local.yml @@ -44,7 +44,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} - name: Upload APK as artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: elementx-apk-maestro path: | @@ -69,7 +69,7 @@ jobs: # https://github.com/actions/checkout/issues/881 ref: ${{ github.ref }} - name: Download APK artifact from previous job - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: name: elementx-apk-maestro - name: Enable KVM group perms @@ -102,7 +102,7 @@ jobs: script: | .github/workflows/scripts/maestro/maestro-local-with-screen-recording.sh app-gplay-x86_64-debug.apk - name: Upload test results - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: test-results path: | diff --git a/.github/workflows/nightlyReports.yml b/.github/workflows/nightlyReports.yml index 46818a1749..b7119c7036 100644 --- a/.github/workflows/nightlyReports.yml +++ b/.github/workflows/nightlyReports.yml @@ -42,7 +42,7 @@ jobs: - name: ✅ Upload kover report if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: kover-results path: | @@ -74,7 +74,7 @@ jobs: run: ./gradlew dependencyCheckAnalyze $CI_GRADLE_ARG_PROPERTIES - name: Upload dependency analysis if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: dependency-analysis path: build/reports/dependency-check-report.html diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index cc4b9db7e1..2084c7648a 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -97,7 +97,7 @@ jobs: run: ./gradlew :tests:konsist:testDebugUnitTest $CI_GRADLE_ARG_PROPERTIES --no-daemon - name: Upload reports if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: konsist-report path: | @@ -174,7 +174,7 @@ jobs: run: ./gradlew :app:lintGplayDebug :app:lintFdroidDebug lintDebug $CI_GRADLE_ARG_PROPERTIES --continue - name: Upload reports if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: linting-report path: | @@ -214,7 +214,7 @@ jobs: run: ./gradlew detekt $CI_GRADLE_ARG_PROPERTIES --no-daemon - name: Upload reports if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: detekt-report path: | @@ -254,7 +254,7 @@ jobs: run: ./gradlew ktlintCheck $CI_GRADLE_ARG_PROPERTIES - name: Upload reports if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: ktlint-report path: | @@ -317,7 +317,7 @@ jobs: # https://github.com/actions/checkout/issues/881 ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }} - name: Download reports from previous jobs - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 - name: Prepare Danger if: always() run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 79b2d3de6e..439b97ba8c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,7 +39,7 @@ jobs: ELEMENT_CALL_RAGESHAKE_URL: ${{ secrets.ELEMENT_CALL_RAGESHAKE_URL }} run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES - name: Upload bundle as artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: elementx-app-gplay-bundle-unsigned path: | @@ -75,7 +75,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES - name: Upload bundle as artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: elementx-enterprise-app-gplay-bundle-unsigned path: | @@ -103,7 +103,7 @@ jobs: ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} run: ./gradlew assembleFdroidRelease $CI_GRADLE_ARG_PROPERTIES - name: Upload apks as artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: elementx-app-fdroid-apks-unsigned path: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b412eb4a49..aa11a433f4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -61,7 +61,7 @@ jobs: - name: 🚫 Upload kover failed coverage reports if: failure() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: kover-error-report path: | @@ -73,7 +73,7 @@ jobs: - name: 🚫 Upload test results on error if: failure() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: tests-and-screenshot-tests-results path: | From 59409fb9eaf113fe0e1746131fbd3a431af784bb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 15:39:17 +0100 Subject: [PATCH 229/347] fix(deps): update dependency org.maplibre.gl:android-sdk to v12.3.1 (#5883) 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 e77dab102c..1183f3687f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -206,7 +206,7 @@ vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0" telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" } telephoto_flick = { module = "me.saket.telephoto:flick-android", version.ref = "telephoto" } statemachine = "com.freeletics.flowredux:compose:1.2.2" -maplibre = "org.maplibre.gl:android-sdk:12.2.2" +maplibre = "org.maplibre.gl:android-sdk:12.3.1" maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2" maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2" opusencoder = "io.element.android:opusencoder:1.2.0" From 15585536e0f7bb67e886ddb3b1003bcb57c79c14 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Dec 2025 15:53:43 +0100 Subject: [PATCH 230/347] Remove empty line. --- .../securityandprivacy/impl/root/SecurityAndPrivacyState.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index 7f43d4e94a..e64cf633a8 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -23,7 +23,6 @@ data class SecurityAndPrivacyState( val isKnockEnabled: Boolean, val saveAction: AsyncAction, val isSpace: Boolean, - private val permissions: SecurityAndPrivacyPermissions, val eventSink: (SecurityAndPrivacyEvent) -> Unit ) { From 02b6a90a95aaf5a1284237442abf732e8c899bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 19 Dec 2025 16:15:51 +0100 Subject: [PATCH 231/347] Fix `toPlainText` representation with formatting spans --- .../libraries/matrix/ui/messages/ToPlainText.kt | 11 +++++++++-- .../libraries/matrix/ui/messages/ToPlainTextTest.kt | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToPlainText.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToPlainText.kt index 2fc371c71b..d58d12b785 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToPlainText.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToPlainText.kt @@ -55,8 +55,15 @@ private class PlainTextNodeVisitor : NodeVisitor { private val builder = StringBuilder() override fun head(node: Node, depth: Int) { - if (node is TextNode && node.text().isNotBlank()) { - builder.append(node.text()) + if (node is TextNode) { + // If the text node is blank, only add a single whitespace char if there wasn't already one + if (node.text().isBlank()) { + if (builder.lastOrNull()?.isWhitespace() == false) { + builder.append(" ") + } + } else { + builder.append(node.text()) + } } else if (node is Element && node.tagName() == "li") { val index = node.elementSiblingIndex() + 1 val isOrdered = node.parent()?.nodeName()?.lowercase() == "ol" diff --git a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/ToPlainTextTest.kt b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/ToPlainTextTest.kt index 5345113dc2..607f825401 100644 --- a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/ToPlainTextTest.kt +++ b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/ToPlainTextTest.kt @@ -45,7 +45,7 @@ class ToPlainTextTest { val formattedBody = FormattedBody( format = MessageFormat.HTML, body = """ - Hello world + Hello formatted world
  • This is an unordered list.
  1. This is an ordered list.

@@ -53,7 +53,7 @@ class ToPlainTextTest { ) assertThat(formattedBody.toPlainText(permalinkParser = FakePermalinkParser())).isEqualTo( """ - Hello world + Hello formatted world • This is an unordered list. 1. This is an ordered list. """.trimIndent() From f13d9259c5baff59515769967deb6d55918f3405 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 19 Dec 2025 17:10:28 +0100 Subject: [PATCH 232/347] change(room permissions): user can edit only roles <= to his own role --- .../ChangeRoomPermissionsPresenter.kt | 8 ++++ .../permissions/ChangeRoomPermissionsState.kt | 47 ++++++++++++++----- .../ChangeRoomPermissionsStateProvider.kt | 3 ++ .../permissions/ChangeRoomPermissionsView.kt | 3 +- .../ChangeRoomPermissionsPresenterTest.kt | 38 ++++++++++++++- 5 files changed, 84 insertions(+), 15 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt index 0032af6b01..552f1d0ec6 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenter.kt @@ -10,6 +10,7 @@ package io.element.android.features.rolesandpermissions.impl.permissions 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 @@ -20,9 +21,11 @@ import dev.zacsweers.metro.Inject import io.element.android.features.rolesandpermissions.impl.analytics.trackPermissionChangeAnalytics import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.core.coroutine.mapState import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues +import io.element.android.libraries.matrix.ui.model.powerLevelOf import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableMap @@ -89,6 +92,10 @@ class ChangeRoomPermissionsPresenter( derivedStateOf { initialPermissions != currentPermissions } } + val ownPowerLevel by remember { + room.roomInfoFlow.mapState { it.powerLevelOf(room.sessionId) } + }.collectAsState() + fun handleEvent(event: ChangeRoomPermissionsEvent) { when (event) { is ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction -> { @@ -123,6 +130,7 @@ class ChangeRoomPermissionsPresenter( } } return ChangeRoomPermissionsState( + ownPowerLevel = ownPowerLevel, currentPermissions = currentPermissions, itemsBySection = itemsBySection, hasChanges = hasChanges, diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt index f538e0a36f..535f2b4a71 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsState.kt @@ -18,34 +18,55 @@ import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap +import kotlinx.collections.immutable.persistentListOf data class ChangeRoomPermissionsState( + private val ownPowerLevel: Long, val currentPermissions: RoomPowerLevelsValues?, val itemsBySection: ImmutableMap>, val hasChanges: Boolean, val saveAction: AsyncAction, val eventSink: (ChangeRoomPermissionsEvent) -> Unit, ) { + private val ownRole = RoomMember.Role.forPowerLevel(ownPowerLevel) + + // Roles that the user can select based on their own role + val selectableRoles: ImmutableList = when (ownRole) { + is RoomMember.Role.Owner, + RoomMember.Role.Admin -> persistentListOf(SelectableRole.Admin, SelectableRole.Moderator, SelectableRole.Everyone) + RoomMember.Role.Moderator -> persistentListOf(SelectableRole.Moderator, SelectableRole.Everyone) + RoomMember.Role.User -> persistentListOf(SelectableRole.Everyone) + } + fun selectedRoleForType(type: RoomPermissionType): SelectableRole? { - if (currentPermissions == null) return null - val role = when (type) { - RoomPermissionType.BAN -> RoomMember.Role.forPowerLevel(currentPermissions.ban) - RoomPermissionType.INVITE -> RoomMember.Role.forPowerLevel(currentPermissions.invite) - RoomPermissionType.KICK -> RoomMember.Role.forPowerLevel(currentPermissions.kick) - RoomPermissionType.SEND_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.eventsDefault) - RoomPermissionType.REDACT_EVENTS -> RoomMember.Role.forPowerLevel(currentPermissions.redactEvents) - RoomPermissionType.ROOM_NAME -> RoomMember.Role.forPowerLevel(currentPermissions.roomName) - RoomPermissionType.ROOM_AVATAR -> RoomMember.Role.forPowerLevel(currentPermissions.roomAvatar) - RoomPermissionType.ROOM_TOPIC -> RoomMember.Role.forPowerLevel(currentPermissions.roomTopic) - RoomPermissionType.SPACE_MANAGE_ROOMS -> RoomMember.Role.forPowerLevel(currentPermissions.spaceChild) - } - return when (role) { + val powerLevel = currentPowerLevelForType(type = type) ?: return null + return when (RoomMember.Role.forPowerLevel(powerLevel)) { is RoomMember.Role.Owner, RoomMember.Role.Admin -> SelectableRole.Admin RoomMember.Role.Moderator -> SelectableRole.Moderator RoomMember.Role.User -> SelectableRole.Everyone } } + + fun canChangePermission(type: RoomPermissionType): Boolean { + val currentPowerLevel = currentPowerLevelForType(type) ?: return false + return ownPowerLevel >= currentPowerLevel + } + + private fun currentPowerLevelForType(type: RoomPermissionType): Long? { + if (currentPermissions == null) return null + return when (type) { + RoomPermissionType.BAN -> currentPermissions.ban + RoomPermissionType.INVITE -> currentPermissions.invite + RoomPermissionType.KICK -> currentPermissions.kick + RoomPermissionType.SEND_EVENTS -> currentPermissions.eventsDefault + RoomPermissionType.REDACT_EVENTS -> currentPermissions.redactEvents + RoomPermissionType.ROOM_NAME -> currentPermissions.roomName + RoomPermissionType.ROOM_AVATAR -> currentPermissions.roomAvatar + RoomPermissionType.ROOM_TOPIC -> currentPermissions.roomTopic + RoomPermissionType.SPACE_MANAGE_ROOMS -> currentPermissions.spaceChild + } + } } enum class RoomPermissionsSection { diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt index 6c4e5aa379..2760272d8a 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsStateProvider.kt @@ -19,6 +19,7 @@ class ChangeRoomPermissionsStateProvider : PreviewParameterProvider get() = sequenceOf( aChangeRoomPermissionsState(), + aChangeRoomPermissionsState(ownPowerLevel = RoomMember.Role.Moderator.powerLevel), aChangeRoomPermissionsState(hasChanges = true), aChangeRoomPermissionsState(hasChanges = true, saveAction = AsyncAction.Loading), aChangeRoomPermissionsState( @@ -31,12 +32,14 @@ class ChangeRoomPermissionsStateProvider : PreviewParameterProvider> = ChangeRoomPermissionsPresenter.buildItems(false), hasChanges: Boolean = false, saveAction: AsyncAction = AsyncAction.Uninitialized, eventSink: (ChangeRoomPermissionsEvent) -> Unit = {}, ) = ChangeRoomPermissionsState( + ownPowerLevel = ownPowerLevel, currentPermissions = currentPermissions, itemsBySection = itemsBySection.toImmutableMap(), hasChanges = hasChanges, diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt index c9d9ed435f..b7084acf57 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt @@ -74,7 +74,8 @@ fun ChangeRoomPermissionsView( PreferenceDropdown( title = titleForType(permissionType), selectedOption = state.selectedRoleForType(permissionType), - options = SelectableRole.entries.toImmutableList(), + options = state.selectableRoles, + enabled = state.canChangePermission(permissionType), onSelectOption = { role -> state.eventSink( ChangeRoomPermissionsEvent.ChangeMinimumRoleForAction( diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt index 9d94c4831e..34b1ac0da5 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt @@ -16,13 +16,18 @@ import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.RoomModeration import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMember.Role.Admin import io.element.android.libraries.matrix.api.room.RoomMember.Role.Moderator +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues +import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom +import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues import io.element.android.services.analytics.test.FakeAnalyticsService +import kotlinx.collections.immutable.persistentMapOf import kotlinx.coroutines.test.runTest import org.junit.Test @@ -70,6 +75,28 @@ class ChangeRoomPermissionsPresenterTest { } } + @Test + fun `present - check canChangePermissions and selectableOptions for moderator`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + initialRoomInfo = initialRoomInfo(role = Moderator), + powerLevelsResult = { Result.success(defaultPermissions()) } + ), + ) + val presenter = createChangeRoomPermissionsPresenter(room = room) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val state = awaitUpdatedItem() + assertThat(state.selectableRoles).containsExactly(SelectableRole.Moderator, SelectableRole.Everyone) + for (sectionItems in state.itemsBySection.values) { + for (permissionType in sectionItems) { + assertThat(state.canChangePermission(permissionType)).isTrue() + } + } + } + } + @Test fun `present - ChangeMinimumRoleForAction updates the current permissions and hasChanges`() = runTest { val presenter = createChangeRoomPermissionsPresenter() @@ -266,7 +293,9 @@ class ChangeRoomPermissionsPresenterTest { private fun createChangeRoomPermissionsPresenter( room: FakeJoinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom(powerLevelsResult = { Result.success(defaultPermissions()) }), + baseRoom = FakeBaseRoom( + initialRoomInfo = initialRoomInfo(), + powerLevelsResult = { Result.success(defaultPermissions()) }), ), analyticsService: FakeAnalyticsService = FakeAnalyticsService(), ) = ChangeRoomPermissionsPresenter( @@ -274,6 +303,13 @@ class ChangeRoomPermissionsPresenterTest { analyticsService = analyticsService, ) + private fun initialRoomInfo(role: RoomMember.Role = Admin) = aRoomInfo( + roomPowerLevels = RoomPowerLevels( + values = defaultPermissions(), + users = persistentMapOf(A_SESSION_ID to role.powerLevel), + ) + ) + private fun defaultPermissions() = defaultRoomPowerLevelValues() private suspend fun TurbineTestContext.awaitUpdatedItem(): ChangeRoomPermissionsState { From 044d027488fe26169e27f96d8a386217e046b1d0 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 19 Dec 2025 17:35:22 +0100 Subject: [PATCH 233/347] quality: format code --- .../impl/permissions/ChangeRoomPermissionsView.kt | 1 - .../impl/permissions/ChangeRoomPermissionsPresenterTest.kt | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt index b7084acf57..529df0d50d 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsView.kt @@ -30,7 +30,6 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.ui.strings.CommonStrings -import kotlinx.collections.immutable.toImmutableList @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt index 34b1ac0da5..ba7d47adb2 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/permissions/ChangeRoomPermissionsPresenterTest.kt @@ -295,7 +295,8 @@ class ChangeRoomPermissionsPresenterTest { room: FakeJoinedRoom = FakeJoinedRoom( baseRoom = FakeBaseRoom( initialRoomInfo = initialRoomInfo(), - powerLevelsResult = { Result.success(defaultPermissions()) }), + powerLevelsResult = { Result.success(defaultPermissions()) } + ), ), analyticsService: FakeAnalyticsService = FakeAnalyticsService(), ) = ChangeRoomPermissionsPresenter( From 95372d9cfb7d83069ac90095c118473b4f2f021c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Dec 2025 18:05:56 +0100 Subject: [PATCH 234/347] Fix tests --- .../impl/SecurityAndPrivacyPresenterTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index 25331470b6..bf26a36ef3 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -84,7 +84,7 @@ class SecurityAndPrivacyPresenterTest { with(awaitItem()) { assertThat(editedSettings).isEqualTo(savedSettings) assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.Anyone) - assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Shared) + assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.WorldReadable) assertThat(editedSettings.address).isEqualTo(A_ROOM_ALIAS.value) assertThat(canBeSaved).isFalse() } @@ -128,10 +128,10 @@ class SecurityAndPrivacyPresenterTest { with(awaitItem()) { assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Invited) assertThat(canBeSaved).isTrue() - eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.WorldReadable)) + eventSink(SecurityAndPrivacyEvent.ChangeHistoryVisibility(SecurityAndPrivacyHistoryVisibility.Shared)) } with(awaitItem()) { - assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.WorldReadable) + assertThat(editedSettings.historyVisibility).isEqualTo(SecurityAndPrivacyHistoryVisibility.Shared) assertThat(canBeSaved).isFalse() } } From ecc57ab9a946e1ed6f2720c626003ea66463ec9d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Sat, 20 Dec 2025 16:26:34 +0100 Subject: [PATCH 235/347] Fix tests --- .../securityandprivacy/impl/SecurityAndPrivacyViewTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt index 66178878f5..b15bc2fe37 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt @@ -141,7 +141,7 @@ class SecurityAndPrivacyViewTest { } @Test - @Config(qualifiers = "h640dp") + @Config(qualifiers = "h1024dp") fun `click on history visibility item emits the expected event`() { val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( @@ -156,7 +156,7 @@ class SecurityAndPrivacyViewTest { } @Test - @Config(qualifiers = "h640dp") + @Config(qualifiers = "h1024dp") fun `click on encryption item emits the expected event`() { val recorder = EventsRecorder() val state = aSecurityAndPrivacyState( From 4402585a52b119b4c69cf17b5b9d0aca06e82bd0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Dec 2025 16:10:25 +0100 Subject: [PATCH 236/347] Use typography instead of materialTypography. --- .../impl/attachments/preview/AttachmentsPreviewView.kt | 4 ++-- .../preferences/impl/advanced/AdvancedSettingsView.kt | 2 +- .../components/dialogs/ErrorDialogWithDoNotShowAgain.kt | 4 ++-- .../designsystem/components/dialogs/TextFieldDialog.kt | 2 +- .../designsystem/theme/components/AlertDialogContent.kt | 2 +- .../libraries/designsystem/theme/components/ListItem.kt | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewView.kt index 7c9ffdaf89..8f55957e32 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewView.kt @@ -231,7 +231,7 @@ private fun ImageOptimizationSelector(state: MediaOptimizationSelectorState) { Text( modifier = Modifier.weight(1f).align(Alignment.CenterVertically), text = stringResource(R.string.screen_media_upload_preview_optimize_image_quality_title), - style = ElementTheme.materialTypography.bodyLarge, + style = ElementTheme.typography.fontBodyLgRegular, ) Switch( modifier = Modifier.height(32.dp), @@ -337,7 +337,7 @@ private fun VideoQualitySelectorDialog( supportingContent = { Text( text = preset.subtitle(), - style = ElementTheme.materialTypography.bodyMedium, + style = ElementTheme.typography.fontBodyMdRegular, color = ElementTheme.colors.textSecondary, ) }, diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt index b518dae4d1..c2b51973d0 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt @@ -234,7 +234,7 @@ private fun VideoQualitySelectorDialog( supportingContent = { Text( text = subtitle, - style = ElementTheme.materialTypography.bodyMedium, + style = ElementTheme.typography.fontBodyMdRegular, color = ElementTheme.colors.textSecondary, ) }, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ErrorDialogWithDoNotShowAgain.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ErrorDialogWithDoNotShowAgain.kt index 37c9dae87e..e85725cfc0 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ErrorDialogWithDoNotShowAgain.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ErrorDialogWithDoNotShowAgain.kt @@ -57,14 +57,14 @@ fun ErrorDialogWithDoNotShowAgain( Column { Text( text = content, - style = ElementTheme.materialTypography.bodyMedium, + style = ElementTheme.typography.fontBodyMdRegular, ) Spacer(modifier = Modifier.height(8.dp)) Row(verticalAlignment = Alignment.CenterVertically) { Checkbox(checked = doNotShowAgain, onCheckedChange = { doNotShowAgain = it }) Text( text = stringResource(id = CommonStrings.common_do_not_show_this_again), - style = ElementTheme.materialTypography.bodyMedium, + style = ElementTheme.typography.fontBodyMdRegular, ) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/TextFieldDialog.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/TextFieldDialog.kt index aeaaa9f040..1ce241d5d9 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/TextFieldDialog.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/TextFieldDialog.kt @@ -76,7 +76,7 @@ fun TextFieldDialog( item { Text( text = content, - style = ElementTheme.materialTypography.bodyMedium, + style = ElementTheme.typography.fontBodyMdRegular, ) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt index ddc235bc9e..c9c553b7b9 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt @@ -65,7 +65,7 @@ internal fun SimpleAlertDialogContent( content = { Text( text = content, - style = ElementTheme.materialTypography.bodyMedium, + style = ElementTheme.typography.fontBodyMdRegular, ) }, submitText = submitText, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ListItem.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ListItem.kt index 8bc09ceaa4..0da086725d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ListItem.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ListItem.kt @@ -114,7 +114,7 @@ fun ListItem( val decoratedHeadlineContent: @Composable () -> Unit = { CompositionLocalProvider( - LocalTextStyle provides ElementTheme.materialTypography.bodyLarge, + LocalTextStyle provides ElementTheme.typography.fontBodyLgRegular, LocalContentColor provides headlineColor, ) { headlineContent() @@ -123,7 +123,7 @@ fun ListItem( val decoratedSupportingContent: (@Composable () -> Unit)? = supportingContent?.let { content -> { CompositionLocalProvider( - LocalTextStyle provides ElementTheme.materialTypography.bodyMedium, + LocalTextStyle provides ElementTheme.typography.fontBodyMdRegular, LocalContentColor provides supportingColor, ) { content() From d92ac247c19654142b8bfbf3ba3c0a1dd1303195 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Dec 2025 16:12:31 +0100 Subject: [PATCH 237/347] Remove `materialTypography` val from ElementTheme. We should only use `typography`. --- .../io/element/android/compound/theme/ElementTheme.kt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt index 0f8e77a4b6..bb2ae2b62e 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/theme/ElementTheme.kt @@ -62,14 +62,6 @@ object ElementTheme { */ val typography: TypographyTokens = TypographyTokens - /** - * Material 3 [Typography] tokens. In Figma, these have the `M3 Typography/` prefix. - */ - val materialTypography: Typography - @Composable - @ReadOnlyComposable - get() = MaterialTheme.typography - /** * Returns whether the theme version used is the light or the dark one. */ From 8d2a683fbcfba227319366015219e3ac76854ccb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Sat, 20 Dec 2025 18:23:50 +0100 Subject: [PATCH 238/347] Add preview for ElementTheme.typography values. --- .../android/compound/previews/Typography.kt | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt index 761bf12cdf..2f2ef942a7 100644 --- a/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt +++ b/libraries/compound/src/main/kotlin/io/element/android/compound/previews/Typography.kt @@ -17,13 +17,14 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.compoundTypography @Preview @Composable internal fun TypographyPreview() = ElementTheme { Surface { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - with(ElementTheme.materialTypography) { + with(compoundTypography) { TypographyTokenPreview(displayLarge, "Display large") TypographyTokenPreview(displayMedium, "Display medium") TypographyTokenPreview(displaySmall, "Display small") @@ -44,6 +45,33 @@ internal fun TypographyPreview() = ElementTheme { } } +@Preview +@Composable +internal fun CompoundTypographyPreview() = ElementTheme { + Surface { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + with(ElementTheme.typography) { + TypographyTokenPreview(fontHeadingXlBold, "fontHeadingXlBold") + TypographyTokenPreview(fontHeadingXlRegular, "fontHeadingXlRegular") + TypographyTokenPreview(fontHeadingLgBold, "fontHeadingLgBold") + TypographyTokenPreview(fontHeadingLgRegular, "fontHeadingLgRegular") + TypographyTokenPreview(fontHeadingMdBold, "fontHeadingMdBold") + TypographyTokenPreview(fontHeadingMdRegular, "fontHeadingMdRegular") + TypographyTokenPreview(fontHeadingSmMedium, "fontHeadingSmMedium") + TypographyTokenPreview(fontHeadingSmRegular, "fontHeadingSmRegular") + TypographyTokenPreview(fontBodyLgMedium, "fontBodyLgMedium") + TypographyTokenPreview(fontBodyLgRegular, "fontBodyLgRegular") + TypographyTokenPreview(fontBodyMdMedium, "fontBodyMdMedium") + TypographyTokenPreview(fontBodyMdRegular, "fontBodyMdRegular") + TypographyTokenPreview(fontBodySmMedium, "fontBodySmMedium") + TypographyTokenPreview(fontBodySmRegular, "fontBodySmRegular") + TypographyTokenPreview(fontBodyXsMedium, "fontBodyXsMedium") + TypographyTokenPreview(fontBodyXsRegular, "fontBodyXsRegular") + } + } + } +} + @Composable private fun TypographyTokenPreview(style: TextStyle, text: String) { Text(text = text, style = style) From 6c0caab13256869d82239410d009136ba0fb2e13 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Sun, 21 Dec 2025 11:33:07 +0100 Subject: [PATCH 239/347] Use existing preview. --- .../screenshot/CompoundTypographyTest.kt | 40 +------------------ 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundTypographyTest.kt b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundTypographyTest.kt index 902bab6872..c4822f680e 100644 --- a/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundTypographyTest.kt +++ b/libraries/compound/src/test/kotlin/io/element/android/compound/screenshot/CompoundTypographyTest.kt @@ -8,18 +8,10 @@ package io.element.android.compound.screenshot -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.dp import androidx.test.ext.junit.runners.AndroidJUnit4 import com.github.takahirom.roborazzi.captureRoboImage +import io.element.android.compound.previews.CompoundTypographyPreview import io.element.android.compound.screenshot.utils.screenshotFile -import io.element.android.compound.theme.ElementTheme -import io.element.android.compound.tokens.generated.TypographyTokens import org.junit.Test import org.junit.runner.RunWith import org.robolectric.annotation.Config @@ -32,35 +24,7 @@ class CompoundTypographyTest { @Config(sdk = [35], qualifiers = "h2048dp-xxhdpi") fun screenshots() { captureRoboImage(file = screenshotFile("Compound Typography.png")) { - ElementTheme { - Surface { - Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - with(TypographyTokens) { - TypographyTokenPreview(fontHeadingXlBold, "Heading XL Bold") - TypographyTokenPreview(fontHeadingXlRegular, "Heading XL Regular") - TypographyTokenPreview(fontHeadingLgBold, "Heading LG Bold") - TypographyTokenPreview(fontHeadingLgRegular, "Heading LG Regular") - TypographyTokenPreview(fontHeadingMdBold, "Heading MD Bold") - TypographyTokenPreview(fontHeadingMdRegular, "Heading MD Regular") - TypographyTokenPreview(fontHeadingSmMedium, "Heading SM Medium") - TypographyTokenPreview(fontHeadingSmRegular, "Heading SM Regular") - TypographyTokenPreview(fontBodyLgMedium, "Body LG Medium") - TypographyTokenPreview(fontBodyLgRegular, "Body LG Regular") - TypographyTokenPreview(fontBodyMdMedium, "Body MD Medium") - TypographyTokenPreview(fontBodyMdRegular, "Body MD Regular") - TypographyTokenPreview(fontBodySmMedium, "Body SM Medium") - TypographyTokenPreview(fontBodySmRegular, "Body SM Regular") - TypographyTokenPreview(fontBodyXsMedium, "Body XS Medium") - TypographyTokenPreview(fontBodyXsRegular, "Body XS Regular") - } - } - } - } + CompoundTypographyPreview() } } - - @Composable - private fun TypographyTokenPreview(style: TextStyle, text: String) { - Text(text = text, style = style) - } } From e5c6f1fada0bba6a92258e049f5467f52bdd8e96 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Sun, 21 Dec 2025 10:46:34 +0000 Subject: [PATCH 240/347] Update screenshots --- libraries/compound/screenshots/Compound Typography.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/compound/screenshots/Compound Typography.png b/libraries/compound/screenshots/Compound Typography.png index 095ad6c71d..22e2d92ebb 100644 --- a/libraries/compound/screenshots/Compound Typography.png +++ b/libraries/compound/screenshots/Compound Typography.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ac84a7175c4a4897aa28eddcf722b7997c6576f612eb38fa09ffabcf7be11e00 -size 119496 +oid sha256:32b12d0b26cd016a632a4cb87b71d5efcb2c0d816bf565bc90aee9963ce2d5df +size 134117 From 20a1e7fdcfbf9e37ce4253e929b53237812840f1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 19 Dec 2025 20:12:52 +0100 Subject: [PATCH 241/347] change(space) : add "settings" entry menu --- .../features/space/impl/root/SpaceNode.kt | 2 +- .../features/space/impl/root/SpaceView.kt | 99 +++++++++++-------- .../features/space/impl/root/SpaceViewTest.kt | 2 +- 3 files changed, 59 insertions(+), 44 deletions(-) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceNode.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceNode.kt index 40fa1273e1..240bc89990 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceNode.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceNode.kt @@ -80,7 +80,7 @@ class SpaceNode( onRoomClick = { spaceRoom -> callback.navigateToRoom(spaceRoom.roomId, spaceRoom.via) }, - onDetailsClick = { + onSettingsClick = { callback.navigateToSpaceSettings() }, onShareSpace = { diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt index 862b9882d2..769b608e8e 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt @@ -8,6 +8,7 @@ package io.element.android.features.space.impl.root +import androidx.annotation.StringRes import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box @@ -29,6 +30,7 @@ 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.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics @@ -78,7 +80,7 @@ fun SpaceView( onRoomClick: (spaceRoom: SpaceRoom) -> Unit, onShareSpace: () -> Unit, onLeaveSpaceClick: () -> Unit, - onDetailsClick: () -> Unit, + onSettingsClick: () -> Unit, onViewMembersClick: () -> Unit, modifier: Modifier = Modifier, acceptDeclineInviteView: @Composable () -> Unit, @@ -92,7 +94,7 @@ fun SpaceView( onBackClick = onBackClick, onLeaveSpaceClick = onLeaveSpaceClick, onShareSpace = onShareSpace, - onDetailsClick = onDetailsClick, + onSettingsClick = onSettingsClick, onViewMembersClick = onViewMembersClick, ) }, @@ -259,7 +261,7 @@ private fun SpaceViewTopBar( canAccessSpaceSettings: Boolean, onBackClick: () -> Unit, onLeaveSpaceClick: () -> Unit, - onDetailsClick: () -> Unit, + onSettingsClick: () -> Unit, onShareSpace: () -> Unit, onViewMembersClick: () -> Unit, modifier: Modifier = Modifier, @@ -277,7 +279,7 @@ private fun SpaceViewTopBar( avatarData = currentSpace.getAvatarData(AvatarSize.TimelineRoom), modifier = Modifier .clip(roundedCornerShape) - .clickable(enabled = canAccessSpaceSettings, onClick = onDetailsClick) + .clickable(enabled = canAccessSpaceSettings, onClick = onSettingsClick) ) } }, @@ -295,51 +297,39 @@ private fun SpaceViewTopBar( expanded = showMenu, onDismissRequest = { showMenu = false } ) { - DropdownMenuItem( - onClick = { - showMenu = false - onShareSpace() - }, - text = { Text(stringResource(id = CommonStrings.action_share)) }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.ShareAndroid(), - tint = ElementTheme.colors.iconSecondary, - contentDescription = null, - ) - } - ) - DropdownMenuItem( + SpaceMenuItem( + titleRes = CommonStrings.screen_space_menu_action_members, + icon = CompoundIcons.User(), onClick = { showMenu = false onViewMembersClick() - }, - text = { Text(stringResource(id = CommonStrings.screen_space_menu_action_members)) }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.User(), - tint = ElementTheme.colors.iconSecondary, - contentDescription = null, - ) } ) - DropdownMenuItem( + SpaceMenuItem( + titleRes = CommonStrings.action_share, + icon = CompoundIcons.ShareAndroid(), + onClick = { + showMenu = false + onShareSpace() + } + ) + if (canAccessSpaceSettings) { + SpaceMenuItem( + titleRes = CommonStrings.common_settings, + icon = CompoundIcons.Settings(), + onClick = { + showMenu = false + onSettingsClick() + } + ) + } + SpaceMenuItem( + titleRes = CommonStrings.action_leave_space, + icon = CompoundIcons.Leave(), + isCritical = true, onClick = { showMenu = false onLeaveSpaceClick() - }, - text = { - Text( - text = stringResource(id = CommonStrings.action_leave_space), - color = ElementTheme.colors.textCriticalPrimary, - ) - }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.Leave(), - tint = ElementTheme.colors.iconCriticalPrimary, - contentDescription = null, - ) } ) } @@ -347,6 +337,31 @@ private fun SpaceViewTopBar( ) } +@Composable +private fun SpaceMenuItem( + @StringRes titleRes: Int, + icon: ImageVector, + onClick: () -> Unit, + isCritical: Boolean = false, +) { + DropdownMenuItem( + onClick = onClick, + text = { + Text( + text = stringResource(titleRes), + color = if (isCritical) ElementTheme.colors.textCriticalPrimary else ElementTheme.colors.textPrimary, + ) + }, + leadingIcon = { + Icon( + imageVector = icon, + tint = if (isCritical) ElementTheme.colors.iconCriticalPrimary else ElementTheme.colors.iconSecondary, + contentDescription = null, + ) + } + ) +} + @Composable private fun SpaceAvatarAndNameRow( name: String?, @@ -421,7 +436,7 @@ internal fun SpaceViewPreview( onShareSpace = {}, onLeaveSpaceClick = {}, acceptDeclineInviteView = {}, - onDetailsClick = {}, + onSettingsClick = {}, onViewMembersClick = {}, onBackClick = {}, ) diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt index 59e323af7c..defac3406a 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt @@ -151,7 +151,7 @@ private fun AndroidComposeTestRule.setSpace onRoomClick = onRoomClick, onShareSpace = onShareSpace, onLeaveSpaceClick = onLeaveSpaceClick, - onDetailsClick = onDetailsClick, + onSettingsClick = onDetailsClick, onViewMembersClick = onViewMembersClick, acceptDeclineInviteView = acceptDeclineInviteView, ) From 940e96a76ae9c344ff8ebbdb383919e8b7cbbc7a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 11:01:38 +0100 Subject: [PATCH 242/347] fix(deps): update dependency io.github.sergio-sastre.composablepreviewscanner:android to v0.8.1 (#5916) 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 1183f3687f..2633bf3579 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -167,7 +167,7 @@ test_truth = "com.google.truth:truth:1.4.5" test_parameter_injector = "com.google.testparameterinjector:test-parameter-injector:1.20" test_robolectric = "org.robolectric:robolectric:4.16" test_appyx_junit = { module = "com.bumble.appyx:testing-junit4", version.ref = "appyx" } -test_composable_preview_scanner = "io.github.sergio-sastre.ComposablePreviewScanner:android:0.7.2" +test_composable_preview_scanner = "io.github.sergio-sastre.ComposablePreviewScanner:android:0.8.1" test_detekt_api = { module = "io.gitlab.arturbosch.detekt:detekt-api", version.ref = "detekt" } test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version.ref = "detekt" } From 806126462985a9c841b5d62c0a7dda17afdfe007 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 17:11:26 +0000 Subject: [PATCH 243/347] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.12.19 --- 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 2633bf3579..343748537e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -177,7 +177,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.17" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.19" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } From 63d205f8aa429f4c632b0e373a40f2cc8559837b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 22 Dec 2025 10:04:04 +0100 Subject: [PATCH 244/347] Replace some usages of `TimelineEventType` in `EventType` with `TimelineEventContent` --- .../TimelineEventToNotificationContentMapper.kt | 12 ++++++------ .../impl/fixtures/factories/TimelineEventType.kt | 8 ++++---- .../impl/fixtures/fakes/FakeFfiTimelineEvent.kt | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventToNotificationContentMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventToNotificationContentMapper.kt index b38ad719a9..450216b452 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventToNotificationContentMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventToNotificationContentMapper.kt @@ -18,7 +18,7 @@ import io.element.android.libraries.matrix.impl.timeline.item.event.EventMessage import org.matrix.rustcomponents.sdk.MessageLikeEventContent import org.matrix.rustcomponents.sdk.StateEventContent import org.matrix.rustcomponents.sdk.TimelineEvent -import org.matrix.rustcomponents.sdk.TimelineEventType +import org.matrix.rustcomponents.sdk.TimelineEventContent import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.RtcNotificationType as SdkRtcNotificationType @@ -27,18 +27,18 @@ class TimelineEventToNotificationContentMapper { return runCatchingExceptions { timelineEvent.use { val senderId = UserId(timelineEvent.senderId()) - timelineEvent.eventType().use { eventType -> - eventType.toContent(senderId = senderId) + timelineEvent.content().use { eventContent -> + eventContent.toContent(senderId = senderId) } } } } } -private fun TimelineEventType.toContent(senderId: UserId): NotificationContent { +private fun TimelineEventContent.toContent(senderId: UserId): NotificationContent { return when (this) { - is TimelineEventType.MessageLike -> content.toContent(senderId) - is TimelineEventType.State -> content.toContent() + is TimelineEventContent.MessageLike -> content.toContent(senderId) + is TimelineEventContent.State -> content.toContent() } } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventType.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventType.kt index 395b2aefe2..8d87afb4e7 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventType.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventType.kt @@ -13,12 +13,12 @@ import org.matrix.rustcomponents.sdk.FormattedBody import org.matrix.rustcomponents.sdk.MessageLikeEventContent import org.matrix.rustcomponents.sdk.MessageType import org.matrix.rustcomponents.sdk.TextMessageContent -import org.matrix.rustcomponents.sdk.TimelineEventType +import org.matrix.rustcomponents.sdk.TimelineEventContent -fun aRustTimelineEventTypeMessageLike( +fun aRustTimelineEventContentMessageLike( content: MessageLikeEventContent = aRustMessageLikeEventContentRoomMessage(), -): TimelineEventType.MessageLike { - return TimelineEventType.MessageLike( +): TimelineEventContent.MessageLike { + return TimelineEventContent.MessageLike( content = content, ) } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiTimelineEvent.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiTimelineEvent.kt index f364ca635a..80eec5efe7 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiTimelineEvent.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiTimelineEvent.kt @@ -8,19 +8,19 @@ package io.element.android.libraries.matrix.impl.fixtures.fakes -import io.element.android.libraries.matrix.impl.fixtures.factories.aRustTimelineEventTypeMessageLike +import io.element.android.libraries.matrix.impl.fixtures.factories.aRustTimelineEventContentMessageLike import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.services.toolbox.test.systemclock.A_FAKE_TIMESTAMP import org.matrix.rustcomponents.sdk.NoHandle import org.matrix.rustcomponents.sdk.TimelineEvent -import org.matrix.rustcomponents.sdk.TimelineEventType +import org.matrix.rustcomponents.sdk.TimelineEventContent open class FakeFfiTimelineEvent( val timestamp: ULong = A_FAKE_TIMESTAMP.toULong(), - val timelineEventType: TimelineEventType = aRustTimelineEventTypeMessageLike(), + val timelineEventContent: TimelineEventContent = aRustTimelineEventContentMessageLike(), val senderId: String = A_USER_ID_2.value, ) : TimelineEvent(NoHandle) { override fun timestamp(): ULong = timestamp - override fun eventType(): TimelineEventType = timelineEventType + override fun content(): TimelineEventContent = timelineEventContent override fun senderId(): String = senderId } From 75f8c4f594ac154754e2c879bcbb5d70db47f4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 22 Dec 2025 10:09:37 +0100 Subject: [PATCH 245/347] Transform `MessageEventType` and `StateEventType` into sealed interfaces to handle the `Custom` variant, also add missing variants --- .../android/appconfig/TimelineConfig.kt | 28 +++--- .../messages/impl/MessagesPresenterTest.kt | 2 +- .../impl/RoomCallStatePresenterTest.kt | 2 +- .../impl/RoomDetailsPresenterTest.kt | 16 +-- .../api/RoomDetailsEditPermissions.kt | 6 +- .../impl/RoomDetailsEditPresenterTest.kt | 18 ++-- .../api/SecurityAndPrivacyPermissions.kt | 8 +- .../impl/SecurityAndPrivacyPresenterTest.kt | 8 +- .../impl/UserProfilePresenterTest.kt | 2 +- .../matrix/api/room/MessageEventType.kt | 18 +++- .../matrix/api/room/StateEventType.kt | 52 +++++----- .../api/room/powerlevels/RoomPermissions.kt | 4 +- .../matrix/impl/room/MessageEventType.kt | 36 ++++++- .../matrix/impl/room/StateEventType.kt | 98 ++++++++++--------- .../RustNotificationServiceTest.kt | 6 +- .../matrix/impl/room/StateEventTypeTest.kt | 90 ++++++++--------- 16 files changed, 230 insertions(+), 164 deletions(-) diff --git a/appconfig/src/main/kotlin/io/element/android/appconfig/TimelineConfig.kt b/appconfig/src/main/kotlin/io/element/android/appconfig/TimelineConfig.kt index 539b67825d..d4fe7d1fc5 100644 --- a/appconfig/src/main/kotlin/io/element/android/appconfig/TimelineConfig.kt +++ b/appconfig/src/main/kotlin/io/element/android/appconfig/TimelineConfig.kt @@ -17,19 +17,19 @@ object TimelineConfig { * Event types that will be filtered out from the timeline (i.e. not displayed). */ val excludedEvents = listOf( - StateEventType.CALL_MEMBER, - StateEventType.ROOM_ALIASES, - StateEventType.ROOM_CANONICAL_ALIAS, - StateEventType.ROOM_GUEST_ACCESS, - StateEventType.ROOM_HISTORY_VISIBILITY, - StateEventType.ROOM_JOIN_RULES, - StateEventType.ROOM_POWER_LEVELS, - StateEventType.ROOM_SERVER_ACL, - StateEventType.ROOM_TOMBSTONE, - StateEventType.SPACE_CHILD, - StateEventType.SPACE_PARENT, - StateEventType.POLICY_RULE_ROOM, - StateEventType.POLICY_RULE_SERVER, - StateEventType.POLICY_RULE_USER, + StateEventType.CallMember, + StateEventType.RoomAliases, + StateEventType.RoomCanonicalAlias, + StateEventType.RoomGuestAccess, + StateEventType.RoomHistoryVisibility, + StateEventType.RoomJoinRules, + StateEventType.RoomPowerLevels, + StateEventType.RoomServerAcl, + StateEventType.RoomTombstone, + StateEventType.SpaceChild, + StateEventType.SpaceParent, + StateEventType.PolicyRuleRoom, + StateEventType.PolicyRuleServer, + StateEventType.PolicyRuleUser, ) } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index cd5bcf8a6d..bdf84e9eec 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -1236,7 +1236,7 @@ class MessagesPresenterTest { ) = FakeRoomPermissions( canSendState = { type -> when (type) { - StateEventType.CALL_MEMBER -> canStartCall + StateEventType.CallMember -> canStartCall else -> lambdaError() } }, diff --git a/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt b/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt index bb0dc04c18..bdececf584 100644 --- a/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt +++ b/features/roomcall/impl/src/test/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenterTest.kt @@ -230,7 +230,7 @@ class RoomCallStatePresenterTest { return FakeRoomPermissions( canSendState = { stateEvent -> when (stateEvent) { - StateEventType.CALL_MEMBER -> canJoinCall + StateEventType.CallMember -> canJoinCall else -> lambdaError() } } diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt index 7d6219004e..5b1fd9474f 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenterTest.kt @@ -643,14 +643,14 @@ class RoomDetailsPresenterTest { canRedactOwn = canRedactOwn, canSendState = { eventType -> when (eventType) { - StateEventType.ROOM_JOIN_RULES -> canChangeRoomAccess - StateEventType.ROOM_HISTORY_VISIBILITY -> canChangeHistoryVisibility - StateEventType.ROOM_ENCRYPTION -> canChangeEncryption - StateEventType.ROOM_CANONICAL_ALIAS -> canChangeRoomVisibility - StateEventType.ROOM_AVATAR -> canChangeAvatar - StateEventType.ROOM_NAME -> canChangeName - StateEventType.ROOM_TOPIC -> canChangeTopic - StateEventType.ROOM_POWER_LEVELS -> canChangePowerLevels + StateEventType.RoomJoinRules -> canChangeRoomAccess + StateEventType.RoomHistoryVisibility -> canChangeHistoryVisibility + StateEventType.RoomEncryption -> canChangeEncryption + StateEventType.RoomCanonicalAlias -> canChangeRoomVisibility + StateEventType.RoomAvatar -> canChangeAvatar + StateEventType.RoomName -> canChangeName + StateEventType.RoomTopic -> canChangeTopic + StateEventType.RoomPowerLevels -> canChangePowerLevels else -> lambdaError() } } diff --git a/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt index c400ec1220..8ac2ea5022 100644 --- a/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt +++ b/features/roomdetailsedit/api/src/main/kotlin/io/element/android/features/roomdetailsedit/api/RoomDetailsEditPermissions.kt @@ -30,8 +30,8 @@ data class RoomDetailsEditPermissions( fun RoomPermissions.roomDetailsEditPermissions(): RoomDetailsEditPermissions { return RoomDetailsEditPermissions( - canEditName = canOwnUserSendState(StateEventType.ROOM_NAME), - canEditTopic = canOwnUserSendState(StateEventType.ROOM_TOPIC), - canEditAvatar = canOwnUserSendState(StateEventType.ROOM_AVATAR), + canEditName = canOwnUserSendState(StateEventType.RoomName), + canEditTopic = canOwnUserSendState(StateEventType.RoomTopic), + canEditAvatar = canOwnUserSendState(StateEventType.RoomAvatar), ) } diff --git a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt index 9c7f840af2..00dcb961ec 100644 --- a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt +++ b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt @@ -129,9 +129,9 @@ class RoomDetailsEditPresenterTest { val room = aJoinedRoom( canSendState = { stateEventType -> when (stateEventType) { - StateEventType.ROOM_NAME -> true - StateEventType.ROOM_AVATAR -> false - StateEventType.ROOM_TOPIC -> false + StateEventType.RoomName -> true + StateEventType.RoomAvatar -> false + StateEventType.RoomTopic -> false else -> lambdaError() } } @@ -162,9 +162,9 @@ class RoomDetailsEditPresenterTest { avatarUrl = AN_AVATAR_URL, canSendState = { stateEventType -> when (stateEventType) { - StateEventType.ROOM_NAME -> false - StateEventType.ROOM_AVATAR -> true - StateEventType.ROOM_TOPIC -> false + StateEventType.RoomName -> false + StateEventType.RoomAvatar -> true + StateEventType.RoomTopic -> false else -> lambdaError() } } @@ -194,9 +194,9 @@ class RoomDetailsEditPresenterTest { avatarUrl = AN_AVATAR_URL, canSendState = { stateEventType -> when (stateEventType) { - StateEventType.ROOM_NAME -> false - StateEventType.ROOM_AVATAR -> false - StateEventType.ROOM_TOPIC -> true + StateEventType.RoomName -> false + StateEventType.RoomAvatar -> false + StateEventType.RoomTopic -> true else -> lambdaError() } } diff --git a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt index 3601f2c4e6..f42d792b6f 100644 --- a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt +++ b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt @@ -44,9 +44,9 @@ data class SecurityAndPrivacyPermissions( fun RoomPermissions.securityAndPrivacyPermissions(): SecurityAndPrivacyPermissions { return SecurityAndPrivacyPermissions( - canChangeRoomAccess = canOwnUserSendState(StateEventType.ROOM_JOIN_RULES), - canChangeHistoryVisibility = canOwnUserSendState(StateEventType.ROOM_HISTORY_VISIBILITY), - canChangeEncryption = canOwnUserSendState(StateEventType.ROOM_ENCRYPTION), - canChangeRoomVisibility = canOwnUserSendState(StateEventType.ROOM_CANONICAL_ALIAS), + canChangeRoomAccess = canOwnUserSendState(StateEventType.RoomJoinRules), + canChangeHistoryVisibility = canOwnUserSendState(StateEventType.RoomHistoryVisibility), + canChangeEncryption = canOwnUserSendState(StateEventType.RoomEncryption), + canChangeRoomVisibility = canOwnUserSendState(StateEventType.RoomCanonicalAlias), ) } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index bf26a36ef3..c035b5510d 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -387,10 +387,10 @@ class SecurityAndPrivacyPresenterTest { return FakeRoomPermissions( canSendState = { eventType -> when (eventType) { - StateEventType.ROOM_JOIN_RULES -> canChangeRoomAccess - StateEventType.ROOM_HISTORY_VISIBILITY -> canChangeHistoryVisibility - StateEventType.ROOM_ENCRYPTION -> canChangeEncryption - StateEventType.ROOM_CANONICAL_ALIAS -> canChangeRoomVisibility + StateEventType.RoomJoinRules -> canChangeRoomAccess + StateEventType.RoomHistoryVisibility -> canChangeHistoryVisibility + StateEventType.RoomEncryption -> canChangeEncryption + StateEventType.RoomCanonicalAlias -> canChangeRoomVisibility else -> lambdaError() } } diff --git a/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt b/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt index b10cf3e48d..511effe750 100644 --- a/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt +++ b/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt @@ -134,7 +134,7 @@ class UserProfilePresenterTest { roomPermissions = FakeRoomPermissions( canSendState = { type -> when (type) { - StateEventType.CALL_MEMBER -> canUserJoinCall + StateEventType.CallMember -> canUserJoinCall else -> lambdaError() } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MessageEventType.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MessageEventType.kt index adf8ebfed1..1341378b90 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MessageEventType.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MessageEventType.kt @@ -12,10 +12,21 @@ import androidx.compose.runtime.Immutable @Immutable sealed interface MessageEventType { + data object Audio : MessageEventType + data object Beacon : MessageEventType data object CallAnswer : MessageEventType + data object CallCandidates : MessageEventType data object CallInvite : MessageEventType data object CallHangup : MessageEventType - data object CallCandidates : MessageEventType + data object CallNegotiate : MessageEventType + data object CallNotify : MessageEventType + data object CallReject : MessageEventType + data object CallSdpStreamMetadataChanged : MessageEventType + data object CallSelectAnswer : MessageEventType + data object Emote : MessageEventType + data object Encrypted : MessageEventType + data object File : MessageEventType + data object Image : MessageEventType data object RtcNotification : MessageEventType data object KeyVerificationReady : MessageEventType data object KeyVerificationStart : MessageEventType @@ -24,10 +35,13 @@ sealed interface MessageEventType { data object KeyVerificationKey : MessageEventType data object KeyVerificationMac : MessageEventType data object KeyVerificationDone : MessageEventType + data object Location : MessageEventType + data object Message : MessageEventType data object Reaction : MessageEventType data object RoomEncrypted : MessageEventType data object RoomMessage : MessageEventType data object RoomRedaction : MessageEventType + data object RtcDecline : MessageEventType data object Sticker : MessageEventType data object PollEnd : MessageEventType data object PollResponse : MessageEventType @@ -35,5 +49,7 @@ sealed interface MessageEventType { data object UnstablePollEnd : MessageEventType data object UnstablePollResponse : MessageEventType data object UnstablePollStart : MessageEventType + data object Video : MessageEventType + data object Voice : MessageEventType data class Other(val type: String) : MessageEventType } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/StateEventType.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/StateEventType.kt index 452d934212..41d64afff1 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/StateEventType.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/StateEventType.kt @@ -8,27 +8,33 @@ package io.element.android.libraries.matrix.api.room -enum class StateEventType { - POLICY_RULE_ROOM, - POLICY_RULE_SERVER, - POLICY_RULE_USER, - CALL_MEMBER, - ROOM_ALIASES, - ROOM_AVATAR, - ROOM_CANONICAL_ALIAS, - ROOM_CREATE, - ROOM_ENCRYPTION, - ROOM_GUEST_ACCESS, - ROOM_HISTORY_VISIBILITY, - ROOM_JOIN_RULES, - ROOM_MEMBER_EVENT, - ROOM_NAME, - ROOM_PINNED_EVENTS, - ROOM_POWER_LEVELS, - ROOM_SERVER_ACL, - ROOM_THIRD_PARTY_INVITE, - ROOM_TOMBSTONE, - ROOM_TOPIC, - SPACE_CHILD, - SPACE_PARENT +sealed interface StateEventType { + data object PolicyRuleRoom : StateEventType + data object PolicyRuleServer : StateEventType + data object PolicyRuleUser : StateEventType + data object CallMember : StateEventType + data object RoomAliases : StateEventType + data object RoomAvatar : StateEventType + data object RoomCanonicalAlias : StateEventType + data object RoomCreate : StateEventType + data object RoomEncryption : StateEventType + data object RoomGuestAccess : StateEventType + data object RoomHistoryVisibility : StateEventType + data object RoomJoinRules : StateEventType + data object RoomMemberEvent : StateEventType + data object RoomName : StateEventType + data object RoomPinnedEvents : StateEventType + data object RoomPowerLevels : StateEventType + data object RoomServerAcl : StateEventType + data object RoomThirdPartyInvite : StateEventType + data object RoomTombstone : StateEventType + data object RoomTopic : StateEventType + data object SpaceChild : StateEventType + data object SpaceParent : StateEventType + data object BeaconInfo : StateEventType + data object MemberHints : StateEventType + data object RoomImagePack : StateEventType + data object RoomLanguage : StateEventType + + data class Custom(val type: String) : StateEventType } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt index 6b9815d6c9..a12f7d9606 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/RoomPermissions.kt @@ -136,7 +136,7 @@ interface RoomPermissions : AutoCloseable { * a power levels state event. */ fun RoomPermissions.canEditRolesAndPermissions(): Boolean { - return canOwnUserSendState(StateEventType.ROOM_POWER_LEVELS) + return canOwnUserSendState(StateEventType.RoomPowerLevels) } /** @@ -144,7 +144,7 @@ fun RoomPermissions.canEditRolesAndPermissions(): Boolean { * a call member state event. */ fun RoomPermissions.canCall(): Boolean { - return canOwnUserSendState(StateEventType.CALL_MEMBER) + return canOwnUserSendState(StateEventType.CallMember) } fun Result.use(default: T, block: (RoomPermissions) -> T): T { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MessageEventType.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MessageEventType.kt index dffa5c1acb..47b37b7923 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MessageEventType.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MessageEventType.kt @@ -12,11 +12,21 @@ import io.element.android.libraries.matrix.api.room.MessageEventType import org.matrix.rustcomponents.sdk.MessageLikeEventType fun MessageEventType.map(): MessageLikeEventType = when (this) { + MessageEventType.Audio -> MessageLikeEventType.Audio + MessageEventType.Beacon -> MessageLikeEventType.Beacon MessageEventType.CallAnswer -> MessageLikeEventType.CallAnswer + MessageEventType.CallCandidates -> MessageLikeEventType.CallCandidates MessageEventType.CallInvite -> MessageLikeEventType.CallInvite MessageEventType.CallHangup -> MessageLikeEventType.CallHangup - MessageEventType.CallCandidates -> MessageLikeEventType.CallCandidates - MessageEventType.RtcNotification -> MessageLikeEventType.RtcNotification + MessageEventType.CallNegotiate -> MessageLikeEventType.CallNegotiate + MessageEventType.CallNotify -> MessageLikeEventType.CallNotify + MessageEventType.CallReject -> MessageLikeEventType.CallReject + MessageEventType.CallSdpStreamMetadataChanged -> MessageLikeEventType.CallSdpStreamMetadataChanged + MessageEventType.CallSelectAnswer -> MessageLikeEventType.CallSelectAnswer + MessageEventType.Emote -> MessageLikeEventType.Emote + MessageEventType.Encrypted -> MessageLikeEventType.Encrypted + MessageEventType.File -> MessageLikeEventType.File + MessageEventType.Image -> MessageLikeEventType.Image MessageEventType.KeyVerificationReady -> MessageLikeEventType.KeyVerificationReady MessageEventType.KeyVerificationStart -> MessageLikeEventType.KeyVerificationStart MessageEventType.KeyVerificationCancel -> MessageLikeEventType.KeyVerificationCancel @@ -24,17 +34,23 @@ fun MessageEventType.map(): MessageLikeEventType = when (this) { MessageEventType.KeyVerificationKey -> MessageLikeEventType.KeyVerificationKey MessageEventType.KeyVerificationMac -> MessageLikeEventType.KeyVerificationMac MessageEventType.KeyVerificationDone -> MessageLikeEventType.KeyVerificationDone + MessageEventType.Location -> MessageLikeEventType.Location + MessageEventType.Message -> MessageLikeEventType.Message MessageEventType.Reaction -> MessageLikeEventType.Reaction MessageEventType.RoomEncrypted -> MessageLikeEventType.RoomEncrypted MessageEventType.RoomMessage -> MessageLikeEventType.RoomMessage MessageEventType.RoomRedaction -> MessageLikeEventType.RoomRedaction + MessageEventType.RtcDecline -> MessageLikeEventType.RtcDecline MessageEventType.Sticker -> MessageLikeEventType.Sticker MessageEventType.PollEnd -> MessageLikeEventType.PollEnd MessageEventType.PollResponse -> MessageLikeEventType.PollResponse MessageEventType.PollStart -> MessageLikeEventType.PollStart + MessageEventType.RtcNotification -> MessageLikeEventType.RtcNotification MessageEventType.UnstablePollEnd -> MessageLikeEventType.UnstablePollEnd MessageEventType.UnstablePollResponse -> MessageLikeEventType.UnstablePollResponse MessageEventType.UnstablePollStart -> MessageLikeEventType.UnstablePollStart + MessageEventType.Video -> MessageLikeEventType.Video + MessageEventType.Voice -> MessageLikeEventType.Voice is MessageEventType.Other -> MessageLikeEventType.Other(type) } @@ -62,5 +78,21 @@ fun MessageLikeEventType.map(): MessageEventType = when (this) { MessageLikeEventType.UnstablePollEnd -> MessageEventType.UnstablePollEnd MessageLikeEventType.UnstablePollResponse -> MessageEventType.UnstablePollResponse MessageLikeEventType.UnstablePollStart -> MessageEventType.UnstablePollStart + MessageLikeEventType.Audio -> MessageEventType.Audio + MessageLikeEventType.Beacon -> MessageEventType.Beacon + MessageLikeEventType.CallNegotiate -> MessageEventType.CallNegotiate + MessageLikeEventType.CallNotify -> MessageEventType.CallNotify + MessageLikeEventType.CallReject -> MessageEventType.CallReject + MessageLikeEventType.CallSdpStreamMetadataChanged -> MessageEventType.CallSdpStreamMetadataChanged + MessageLikeEventType.CallSelectAnswer -> MessageEventType.CallSelectAnswer + MessageLikeEventType.Emote -> MessageEventType.Emote + MessageLikeEventType.Encrypted -> MessageEventType.Encrypted + MessageLikeEventType.File -> MessageEventType.File + MessageLikeEventType.Image -> MessageEventType.Image + MessageLikeEventType.Location -> MessageEventType.Location + MessageLikeEventType.Message -> MessageEventType.Message + MessageLikeEventType.RtcDecline -> MessageEventType.RtcDecline + MessageLikeEventType.Video -> MessageEventType.Video + MessageLikeEventType.Voice -> MessageEventType.Voice is MessageLikeEventType.Other -> MessageEventType.Other(v1) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/StateEventType.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/StateEventType.kt index c1ba8c9728..76fea0beef 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/StateEventType.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/StateEventType.kt @@ -12,51 +12,61 @@ import io.element.android.libraries.matrix.api.room.StateEventType import org.matrix.rustcomponents.sdk.StateEventType as RustStateEventType fun StateEventType.map(): RustStateEventType = when (this) { - StateEventType.POLICY_RULE_ROOM -> RustStateEventType.POLICY_RULE_ROOM - StateEventType.POLICY_RULE_SERVER -> RustStateEventType.POLICY_RULE_SERVER - StateEventType.POLICY_RULE_USER -> RustStateEventType.POLICY_RULE_USER - StateEventType.CALL_MEMBER -> RustStateEventType.CALL_MEMBER - StateEventType.ROOM_ALIASES -> RustStateEventType.ROOM_ALIASES - StateEventType.ROOM_AVATAR -> RustStateEventType.ROOM_AVATAR - StateEventType.ROOM_CANONICAL_ALIAS -> RustStateEventType.ROOM_CANONICAL_ALIAS - StateEventType.ROOM_CREATE -> RustStateEventType.ROOM_CREATE - StateEventType.ROOM_ENCRYPTION -> RustStateEventType.ROOM_ENCRYPTION - StateEventType.ROOM_GUEST_ACCESS -> RustStateEventType.ROOM_GUEST_ACCESS - StateEventType.ROOM_HISTORY_VISIBILITY -> RustStateEventType.ROOM_HISTORY_VISIBILITY - StateEventType.ROOM_JOIN_RULES -> RustStateEventType.ROOM_JOIN_RULES - StateEventType.ROOM_MEMBER_EVENT -> RustStateEventType.ROOM_MEMBER_EVENT - StateEventType.ROOM_NAME -> RustStateEventType.ROOM_NAME - StateEventType.ROOM_PINNED_EVENTS -> RustStateEventType.ROOM_PINNED_EVENTS - StateEventType.ROOM_POWER_LEVELS -> RustStateEventType.ROOM_POWER_LEVELS - StateEventType.ROOM_SERVER_ACL -> RustStateEventType.ROOM_SERVER_ACL - StateEventType.ROOM_THIRD_PARTY_INVITE -> RustStateEventType.ROOM_THIRD_PARTY_INVITE - StateEventType.ROOM_TOMBSTONE -> RustStateEventType.ROOM_TOMBSTONE - StateEventType.ROOM_TOPIC -> RustStateEventType.ROOM_TOPIC - StateEventType.SPACE_CHILD -> RustStateEventType.SPACE_CHILD - StateEventType.SPACE_PARENT -> RustStateEventType.SPACE_PARENT + StateEventType.PolicyRuleRoom -> RustStateEventType.PolicyRuleRoom + StateEventType.PolicyRuleServer -> RustStateEventType.PolicyRuleServer + StateEventType.PolicyRuleUser -> RustStateEventType.PolicyRuleUser + StateEventType.CallMember -> RustStateEventType.CallMember + StateEventType.RoomAliases -> RustStateEventType.RoomAliases + StateEventType.RoomAvatar -> RustStateEventType.RoomAvatar + StateEventType.RoomCanonicalAlias -> RustStateEventType.RoomCanonicalAlias + StateEventType.RoomCreate -> RustStateEventType.RoomCreate + StateEventType.RoomEncryption -> RustStateEventType.RoomEncryption + StateEventType.RoomGuestAccess -> RustStateEventType.RoomGuestAccess + StateEventType.RoomHistoryVisibility -> RustStateEventType.RoomHistoryVisibility + StateEventType.RoomJoinRules -> RustStateEventType.RoomJoinRules + StateEventType.RoomMemberEvent -> RustStateEventType.RoomMemberEvent + StateEventType.RoomName -> RustStateEventType.RoomName + StateEventType.RoomPinnedEvents -> RustStateEventType.RoomPinnedEvents + StateEventType.RoomPowerLevels -> RustStateEventType.RoomPowerLevels + StateEventType.RoomServerAcl -> RustStateEventType.RoomServerAcl + StateEventType.RoomThirdPartyInvite -> RustStateEventType.RoomThirdPartyInvite + StateEventType.RoomTombstone -> RustStateEventType.RoomTombstone + StateEventType.RoomTopic -> RustStateEventType.RoomTopic + StateEventType.SpaceChild -> RustStateEventType.SpaceChild + StateEventType.SpaceParent -> RustStateEventType.SpaceParent + StateEventType.BeaconInfo -> RustStateEventType.BeaconInfo + StateEventType.MemberHints -> RustStateEventType.MemberHints + StateEventType.RoomImagePack -> RustStateEventType.RoomImagePack + StateEventType.RoomLanguage -> RustStateEventType.RoomLanguage + is StateEventType.Custom -> RustStateEventType.Custom(type) } fun RustStateEventType.map(): StateEventType = when (this) { - RustStateEventType.POLICY_RULE_ROOM -> StateEventType.POLICY_RULE_ROOM - RustStateEventType.POLICY_RULE_SERVER -> StateEventType.POLICY_RULE_SERVER - RustStateEventType.POLICY_RULE_USER -> StateEventType.POLICY_RULE_USER - RustStateEventType.CALL_MEMBER -> StateEventType.CALL_MEMBER - RustStateEventType.ROOM_ALIASES -> StateEventType.ROOM_ALIASES - RustStateEventType.ROOM_AVATAR -> StateEventType.ROOM_AVATAR - RustStateEventType.ROOM_CANONICAL_ALIAS -> StateEventType.ROOM_CANONICAL_ALIAS - RustStateEventType.ROOM_CREATE -> StateEventType.ROOM_CREATE - RustStateEventType.ROOM_ENCRYPTION -> StateEventType.ROOM_ENCRYPTION - RustStateEventType.ROOM_GUEST_ACCESS -> StateEventType.ROOM_GUEST_ACCESS - RustStateEventType.ROOM_HISTORY_VISIBILITY -> StateEventType.ROOM_HISTORY_VISIBILITY - RustStateEventType.ROOM_JOIN_RULES -> StateEventType.ROOM_JOIN_RULES - RustStateEventType.ROOM_MEMBER_EVENT -> StateEventType.ROOM_MEMBER_EVENT - RustStateEventType.ROOM_NAME -> StateEventType.ROOM_NAME - RustStateEventType.ROOM_PINNED_EVENTS -> StateEventType.ROOM_PINNED_EVENTS - RustStateEventType.ROOM_POWER_LEVELS -> StateEventType.ROOM_POWER_LEVELS - RustStateEventType.ROOM_SERVER_ACL -> StateEventType.ROOM_SERVER_ACL - RustStateEventType.ROOM_THIRD_PARTY_INVITE -> StateEventType.ROOM_THIRD_PARTY_INVITE - RustStateEventType.ROOM_TOMBSTONE -> StateEventType.ROOM_TOMBSTONE - RustStateEventType.ROOM_TOPIC -> StateEventType.ROOM_TOPIC - RustStateEventType.SPACE_CHILD -> StateEventType.SPACE_CHILD - RustStateEventType.SPACE_PARENT -> StateEventType.SPACE_PARENT + RustStateEventType.PolicyRuleRoom -> StateEventType.PolicyRuleRoom + RustStateEventType.PolicyRuleServer -> StateEventType.PolicyRuleServer + RustStateEventType.PolicyRuleUser -> StateEventType.PolicyRuleUser + RustStateEventType.CallMember -> StateEventType.CallMember + RustStateEventType.RoomAliases -> StateEventType.RoomAliases + RustStateEventType.RoomAvatar -> StateEventType.RoomAvatar + RustStateEventType.RoomCanonicalAlias -> StateEventType.RoomCanonicalAlias + RustStateEventType.RoomCreate -> StateEventType.RoomCreate + RustStateEventType.RoomEncryption -> StateEventType.RoomEncryption + RustStateEventType.RoomGuestAccess -> StateEventType.RoomGuestAccess + RustStateEventType.RoomHistoryVisibility -> StateEventType.RoomHistoryVisibility + RustStateEventType.RoomJoinRules -> StateEventType.RoomJoinRules + RustStateEventType.RoomMemberEvent -> StateEventType.RoomMemberEvent + RustStateEventType.RoomName -> StateEventType.RoomName + RustStateEventType.RoomPinnedEvents -> StateEventType.RoomPinnedEvents + RustStateEventType.RoomPowerLevels -> StateEventType.RoomPowerLevels + RustStateEventType.RoomServerAcl -> StateEventType.RoomServerAcl + RustStateEventType.RoomThirdPartyInvite -> StateEventType.RoomThirdPartyInvite + RustStateEventType.RoomTombstone -> StateEventType.RoomTombstone + RustStateEventType.RoomTopic -> StateEventType.RoomTopic + RustStateEventType.SpaceChild -> StateEventType.SpaceChild + RustStateEventType.SpaceParent -> StateEventType.SpaceParent + RustStateEventType.BeaconInfo -> StateEventType.BeaconInfo + RustStateEventType.MemberHints -> StateEventType.MemberHints + RustStateEventType.RoomImagePack -> StateEventType.RoomImagePack + RustStateEventType.RoomLanguage -> StateEventType.RoomLanguage + is RustStateEventType.Custom -> StateEventType.Custom(value) } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt index df10c163a1..a50fa4c45b 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt @@ -32,7 +32,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Test import org.matrix.rustcomponents.sdk.NotificationClient import org.matrix.rustcomponents.sdk.NotificationStatus -import org.matrix.rustcomponents.sdk.TimelineEventType +import org.matrix.rustcomponents.sdk.TimelineEventContent class RustNotificationServiceTest { @Test @@ -58,9 +58,9 @@ class RustNotificationServiceTest { @Test fun `test mapping invalid item only drops that item`() = runTest { - val error = IllegalStateException("This event type is not supported") + val error = IllegalStateException("This event content is not supported") val faultyEvent = object : FakeFfiTimelineEvent() { - override fun eventType(): TimelineEventType { + override fun content(): TimelineEventContent { throw error } } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/StateEventTypeTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/StateEventTypeTest.kt index 245a321c65..428bb7db7a 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/StateEventTypeTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/StateEventTypeTest.kt @@ -16,53 +16,55 @@ import org.matrix.rustcomponents.sdk.StateEventType as RustStateEventType class StateEventTypeTest { @Test fun `mapping Rust type should work`() { - assertThat(RustStateEventType.CALL_MEMBER.map()).isEqualTo(StateEventType.CALL_MEMBER) - assertThat(RustStateEventType.POLICY_RULE_ROOM.map()).isEqualTo(StateEventType.POLICY_RULE_ROOM) - assertThat(RustStateEventType.POLICY_RULE_SERVER.map()).isEqualTo(StateEventType.POLICY_RULE_SERVER) - assertThat(RustStateEventType.POLICY_RULE_USER.map()).isEqualTo(StateEventType.POLICY_RULE_USER) - assertThat(RustStateEventType.ROOM_ALIASES.map()).isEqualTo(StateEventType.ROOM_ALIASES) - assertThat(RustStateEventType.ROOM_AVATAR.map()).isEqualTo(StateEventType.ROOM_AVATAR) - assertThat(RustStateEventType.ROOM_CANONICAL_ALIAS.map()).isEqualTo(StateEventType.ROOM_CANONICAL_ALIAS) - assertThat(RustStateEventType.ROOM_CREATE.map()).isEqualTo(StateEventType.ROOM_CREATE) - assertThat(RustStateEventType.ROOM_ENCRYPTION.map()).isEqualTo(StateEventType.ROOM_ENCRYPTION) - assertThat(RustStateEventType.ROOM_GUEST_ACCESS.map()).isEqualTo(StateEventType.ROOM_GUEST_ACCESS) - assertThat(RustStateEventType.ROOM_HISTORY_VISIBILITY.map()).isEqualTo(StateEventType.ROOM_HISTORY_VISIBILITY) - assertThat(RustStateEventType.ROOM_JOIN_RULES.map()).isEqualTo(StateEventType.ROOM_JOIN_RULES) - assertThat(RustStateEventType.ROOM_MEMBER_EVENT.map()).isEqualTo(StateEventType.ROOM_MEMBER_EVENT) - assertThat(RustStateEventType.ROOM_NAME.map()).isEqualTo(StateEventType.ROOM_NAME) - assertThat(RustStateEventType.ROOM_PINNED_EVENTS.map()).isEqualTo(StateEventType.ROOM_PINNED_EVENTS) - assertThat(RustStateEventType.ROOM_POWER_LEVELS.map()).isEqualTo(StateEventType.ROOM_POWER_LEVELS) - assertThat(RustStateEventType.ROOM_SERVER_ACL.map()).isEqualTo(StateEventType.ROOM_SERVER_ACL) - assertThat(RustStateEventType.ROOM_THIRD_PARTY_INVITE.map()).isEqualTo(StateEventType.ROOM_THIRD_PARTY_INVITE) - assertThat(RustStateEventType.ROOM_TOMBSTONE.map()).isEqualTo(StateEventType.ROOM_TOMBSTONE) - assertThat(RustStateEventType.ROOM_TOPIC.map()).isEqualTo(StateEventType.ROOM_TOPIC) - assertThat(RustStateEventType.SPACE_CHILD.map()).isEqualTo(StateEventType.SPACE_CHILD) - assertThat(RustStateEventType.SPACE_PARENT.map()).isEqualTo(StateEventType.SPACE_PARENT) + assertThat(RustStateEventType.CallMember.map()).isEqualTo(StateEventType.CallMember) + assertThat(RustStateEventType.PolicyRuleRoom.map()).isEqualTo(StateEventType.PolicyRuleRoom) + assertThat(RustStateEventType.PolicyRuleServer.map()).isEqualTo(StateEventType.PolicyRuleServer) + assertThat(RustStateEventType.PolicyRuleUser.map()).isEqualTo(StateEventType.PolicyRuleUser) + assertThat(RustStateEventType.RoomAliases.map()).isEqualTo(StateEventType.RoomAliases) + assertThat(RustStateEventType.RoomAvatar.map()).isEqualTo(StateEventType.RoomAvatar) + assertThat(RustStateEventType.RoomCanonicalAlias.map()).isEqualTo(StateEventType.RoomCanonicalAlias) + assertThat(RustStateEventType.RoomCreate.map()).isEqualTo(StateEventType.RoomCreate) + assertThat(RustStateEventType.RoomEncryption.map()).isEqualTo(StateEventType.RoomEncryption) + assertThat(RustStateEventType.RoomGuestAccess.map()).isEqualTo(StateEventType.RoomGuestAccess) + assertThat(RustStateEventType.RoomHistoryVisibility.map()).isEqualTo(StateEventType.RoomHistoryVisibility) + assertThat(RustStateEventType.RoomJoinRules.map()).isEqualTo(StateEventType.RoomJoinRules) + assertThat(RustStateEventType.RoomMemberEvent.map()).isEqualTo(StateEventType.RoomMemberEvent) + assertThat(RustStateEventType.RoomName.map()).isEqualTo(StateEventType.RoomName) + assertThat(RustStateEventType.RoomPinnedEvents.map()).isEqualTo(StateEventType.RoomPinnedEvents) + assertThat(RustStateEventType.RoomPowerLevels.map()).isEqualTo(StateEventType.RoomPowerLevels) + assertThat(RustStateEventType.RoomServerAcl.map()).isEqualTo(StateEventType.RoomServerAcl) + assertThat(RustStateEventType.RoomThirdPartyInvite.map()).isEqualTo(StateEventType.RoomThirdPartyInvite) + assertThat(RustStateEventType.RoomTombstone.map()).isEqualTo(StateEventType.RoomTombstone) + assertThat(RustStateEventType.RoomTopic.map()).isEqualTo(StateEventType.RoomTopic) + assertThat(RustStateEventType.SpaceChild.map()).isEqualTo(StateEventType.SpaceChild) + assertThat(RustStateEventType.SpaceParent.map()).isEqualTo(StateEventType.SpaceParent) + assertThat(RustStateEventType.Custom("foo").map()).isEqualTo(StateEventType.Custom("foo")) } @Test fun `mapping Kotlin type should work`() { - assertThat(StateEventType.CALL_MEMBER.map()).isEqualTo(RustStateEventType.CALL_MEMBER) - assertThat(StateEventType.POLICY_RULE_ROOM.map()).isEqualTo(RustStateEventType.POLICY_RULE_ROOM) - assertThat(StateEventType.POLICY_RULE_SERVER.map()).isEqualTo(RustStateEventType.POLICY_RULE_SERVER) - assertThat(StateEventType.POLICY_RULE_USER.map()).isEqualTo(RustStateEventType.POLICY_RULE_USER) - assertThat(StateEventType.ROOM_ALIASES.map()).isEqualTo(RustStateEventType.ROOM_ALIASES) - assertThat(StateEventType.ROOM_AVATAR.map()).isEqualTo(RustStateEventType.ROOM_AVATAR) - assertThat(StateEventType.ROOM_CANONICAL_ALIAS.map()).isEqualTo(RustStateEventType.ROOM_CANONICAL_ALIAS) - assertThat(StateEventType.ROOM_CREATE.map()).isEqualTo(RustStateEventType.ROOM_CREATE) - assertThat(StateEventType.ROOM_ENCRYPTION.map()).isEqualTo(RustStateEventType.ROOM_ENCRYPTION) - assertThat(StateEventType.ROOM_GUEST_ACCESS.map()).isEqualTo(RustStateEventType.ROOM_GUEST_ACCESS) - assertThat(StateEventType.ROOM_HISTORY_VISIBILITY.map()).isEqualTo(RustStateEventType.ROOM_HISTORY_VISIBILITY) - assertThat(StateEventType.ROOM_JOIN_RULES.map()).isEqualTo(RustStateEventType.ROOM_JOIN_RULES) - assertThat(StateEventType.ROOM_MEMBER_EVENT.map()).isEqualTo(RustStateEventType.ROOM_MEMBER_EVENT) - assertThat(StateEventType.ROOM_NAME.map()).isEqualTo(RustStateEventType.ROOM_NAME) - assertThat(StateEventType.ROOM_PINNED_EVENTS.map()).isEqualTo(RustStateEventType.ROOM_PINNED_EVENTS) - assertThat(StateEventType.ROOM_POWER_LEVELS.map()).isEqualTo(RustStateEventType.ROOM_POWER_LEVELS) - assertThat(StateEventType.ROOM_SERVER_ACL.map()).isEqualTo(RustStateEventType.ROOM_SERVER_ACL) - assertThat(StateEventType.ROOM_THIRD_PARTY_INVITE.map()).isEqualTo(RustStateEventType.ROOM_THIRD_PARTY_INVITE) - assertThat(StateEventType.ROOM_TOMBSTONE.map()).isEqualTo(RustStateEventType.ROOM_TOMBSTONE) - assertThat(StateEventType.ROOM_TOPIC.map()).isEqualTo(RustStateEventType.ROOM_TOPIC) - assertThat(StateEventType.SPACE_CHILD.map()).isEqualTo(RustStateEventType.SPACE_CHILD) - assertThat(StateEventType.SPACE_PARENT.map()).isEqualTo(RustStateEventType.SPACE_PARENT) + assertThat(StateEventType.CallMember.map()).isEqualTo(RustStateEventType.CallMember) + assertThat(StateEventType.PolicyRuleRoom.map()).isEqualTo(RustStateEventType.PolicyRuleRoom) + assertThat(StateEventType.PolicyRuleServer.map()).isEqualTo(RustStateEventType.PolicyRuleServer) + assertThat(StateEventType.PolicyRuleUser.map()).isEqualTo(RustStateEventType.PolicyRuleUser) + assertThat(StateEventType.RoomAliases.map()).isEqualTo(RustStateEventType.RoomAliases) + assertThat(StateEventType.RoomAvatar.map()).isEqualTo(RustStateEventType.RoomAvatar) + assertThat(StateEventType.RoomCanonicalAlias.map()).isEqualTo(RustStateEventType.RoomCanonicalAlias) + assertThat(StateEventType.RoomCreate.map()).isEqualTo(RustStateEventType.RoomCreate) + assertThat(StateEventType.RoomEncryption.map()).isEqualTo(RustStateEventType.RoomEncryption) + assertThat(StateEventType.RoomGuestAccess.map()).isEqualTo(RustStateEventType.RoomGuestAccess) + assertThat(StateEventType.RoomHistoryVisibility.map()).isEqualTo(RustStateEventType.RoomHistoryVisibility) + assertThat(StateEventType.RoomJoinRules.map()).isEqualTo(RustStateEventType.RoomJoinRules) + assertThat(StateEventType.RoomMemberEvent.map()).isEqualTo(RustStateEventType.RoomMemberEvent) + assertThat(StateEventType.RoomName.map()).isEqualTo(RustStateEventType.RoomName) + assertThat(StateEventType.RoomPinnedEvents.map()).isEqualTo(RustStateEventType.RoomPinnedEvents) + assertThat(StateEventType.RoomPowerLevels.map()).isEqualTo(RustStateEventType.RoomPowerLevels) + assertThat(StateEventType.RoomServerAcl.map()).isEqualTo(RustStateEventType.RoomServerAcl) + assertThat(StateEventType.RoomThirdPartyInvite.map()).isEqualTo(RustStateEventType.RoomThirdPartyInvite) + assertThat(StateEventType.RoomTombstone.map()).isEqualTo(RustStateEventType.RoomTombstone) + assertThat(StateEventType.RoomTopic.map()).isEqualTo(RustStateEventType.RoomTopic) + assertThat(StateEventType.SpaceChild.map()).isEqualTo(RustStateEventType.SpaceChild) + assertThat(StateEventType.SpaceParent.map()).isEqualTo(RustStateEventType.SpaceParent) + assertThat(StateEventType.Custom("foo").map()).isEqualTo(RustStateEventType.Custom("foo")) } } From cfa7d39966547fbbf2f51cc3385d3a95de368fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 22 Dec 2025 10:11:31 +0100 Subject: [PATCH 246/347] Instantiate the now suspending `innerClient.spaceService()` `RustMatrixClient` with `runBlocking` for now --- .../element/android/libraries/matrix/impl/RustMatrixClient.kt | 4 +++- .../libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index f3ceb1e425..4cb84abc03 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -151,7 +151,9 @@ class RustMatrixClient( private val sessionDispatcher = dispatchers.io.limitedParallelism(64) private val innerRoomListService = innerSyncService.roomListService() - private val innerSpaceService = innerClient.spaceService() + + // TODO refactor this and `innerNotificationClient` to be behind a suspend function instead + private val innerSpaceService = runBlocking { innerClient.spaceService() } override val roomMembershipObserver = RoomMembershipObserver() diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt index db33393ac2..dc9d21cddc 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt @@ -60,7 +60,7 @@ class FakeFfiClient( override suspend fun cachedAvatarUrl(): String? = null override suspend fun restoreSession(session: Session) = Unit override fun syncService(): SyncServiceBuilder = FakeFfiSyncServiceBuilder() - override fun spaceService(): SpaceService = FakeFfiSpaceService() + override suspend fun spaceService(): SpaceService = FakeFfiSpaceService() override fun roomDirectorySearch(): RoomDirectorySearch = FakeFfiRoomDirectorySearch() override suspend fun setPusher( identifiers: PusherIdentifiers, From 293d41f122728ce198a96c4e4b91c6ffd71068d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 22 Dec 2025 10:12:12 +0100 Subject: [PATCH 247/347] `RustSpaceService.joinedSpaces()` now points to the FFI method `SpaceService.topLevelJoinedSpaces()` --- .../android/libraries/matrix/impl/spaces/RustSpaceService.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt index 84da9f1b52..ba816c11c7 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt @@ -51,7 +51,7 @@ class RustSpaceService( override suspend fun joinedSpaces(): Result> = withContext(sessionDispatcher) { runCatchingExceptions { - innerSpaceService.joinedSpaces() + innerSpaceService.topLevelJoinedSpaces() .map { it.let(spaceRoomMapper::map) } @@ -97,7 +97,7 @@ internal fun SpaceServiceInterface.spaceListUpdate(): Flow } } Timber.d("Open spaceDiffFlow for SpaceServiceInterface ${this@spaceListUpdate}") - val taskHandle = subscribeToJoinedSpaces(listener) + val taskHandle = subscribeToTopLevelJoinedSpaces(listener) awaitClose { Timber.d("Close spaceDiffFlow for SpaceServiceInterface ${this@spaceListUpdate}") taskHandle.cancelAndDestroy() From 7de4b7d3af29cc669a5796b0ac135eeb04944836 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Mon, 22 Dec 2025 10:29:46 +0000 Subject: [PATCH 248/347] Update screenshots --- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png | 4 ++-- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_6_en.png | 3 +++ ....impl.permissions_ChangeRoomPermissionsView_Night_1_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_2_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_3_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_4_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_5_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_6_en.png | 3 +++ 12 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png index f3ef799045..a6d9a85284 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f82f648e9f5d67abfe2cf783df7e70568a74ff5dcae876e80b54995981a65886 -size 49650 +oid sha256:4eadce77750c8946f3d506a59925901fe3a44ac61ac08e4a23b6517f4596eece +size 48910 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png index 83b5995ef4..f3ef799045 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ebf86fc0ac80375edd1730caab4a669aa2cc545b2ea946981901fd360114320 -size 44555 +oid sha256:f82f648e9f5d67abfe2cf783df7e70568a74ff5dcae876e80b54995981a65886 +size 49650 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png index 0c1593bc85..83b5995ef4 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fae74539f53342110e50a077ad78b8422d08ba931b948b2b167d90f6cbe8ade6 -size 43535 +oid sha256:0ebf86fc0ac80375edd1730caab4a669aa2cc545b2ea946981901fd360114320 +size 44555 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png index 5a6d410ad7..0c1593bc85 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61bced1ea61f5952e83956b4c4447a0371fe99c874e2a20df431bc59e02dc838 -size 50316 +oid sha256:fae74539f53342110e50a077ad78b8422d08ba931b948b2b167d90f6cbe8ade6 +size 43535 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png index 16c2a363d8..5a6d410ad7 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73d9461a1d51964ba1a912376658e3e550e952821f7aa1d9bff765ed11deb920 -size 49123 +oid sha256:61bced1ea61f5952e83956b4c4447a0371fe99c874e2a20df431bc59e02dc838 +size 50316 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en.png new file mode 100644 index 0000000000..16c2a363d8 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73d9461a1d51964ba1a912376658e3e550e952821f7aa1d9bff765ed11deb920 +size 49123 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png index cb24aa2578..43f63ee7f9 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:192fce45ea8d83d8f7aa40f9337b2dd92c3b1194da611fed1c42fd771d74fe0a -size 48534 +oid sha256:009e04296b2dbeb127e6d3b9306dce996fa35bf4443d34abbdf2b8cc14126053 +size 47615 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png index b16e4b3ba3..cb24aa2578 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3ed16d04a1106b82183c4fe6ae741b598448050e2ddae2fa842b0b01d475e0a -size 43230 +oid sha256:192fce45ea8d83d8f7aa40f9337b2dd92c3b1194da611fed1c42fd771d74fe0a +size 48534 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png index 7ae9ff70b6..b16e4b3ba3 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0cb2f7d7cad98d111ed2c1c0b8120e5837f2586f845594e581b41b7cb96e00f2 -size 41555 +oid sha256:b3ed16d04a1106b82183c4fe6ae741b598448050e2ddae2fa842b0b01d475e0a +size 43230 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png index 1aa08a4e12..7ae9ff70b6 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0862da8d120e276afd6bdef6a9b247d3976ae70adab47077d8749600dd695884 -size 48280 +oid sha256:0cb2f7d7cad98d111ed2c1c0b8120e5837f2586f845594e581b41b7cb96e00f2 +size 41555 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en.png index 25c50a55cb..1aa08a4e12 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48e5f7460a13798d2f2963930e4e7a95c6a1ffa704d034ec21e33ba1bde6606c -size 48123 +oid sha256:0862da8d120e276afd6bdef6a9b247d3976ae70adab47077d8749600dd695884 +size 48280 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en.png new file mode 100644 index 0000000000..25c50a55cb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48e5f7460a13798d2f2963930e4e7a95c6a1ffa704d034ec21e33ba1bde6606c +size 48123 From 55791ad2ffc779991b5a27c8225b19058547838c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 22 Dec 2025 14:16:35 +0100 Subject: [PATCH 249/347] Make sure we don't obfuscate `Metro` classes --- app/proguard-rules.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index d915d67a25..9207e06edc 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -70,3 +70,6 @@ -keep class uniffi.** { *;} -keep class io.element.android.x.di.** { *; } -keepclasseswithmembernames,allowoptimization,allowshrinking class io.element.android.** { *; } + +# Keep Metro classes +-keep class dev.zacsweers.metro.** { *; } From 9127ce743d3aeb5a0a05aa93be5429258c1511b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 22 Dec 2025 14:17:08 +0100 Subject: [PATCH 250/347] Change `JsonProvider` from a parent interface to a typealias This fixes the error seen in the nightlies --- .../element/android/libraries/androidutils/json/JsonProvider.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt index 1876bbd3f5..fb92adddb9 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt @@ -17,7 +17,7 @@ import kotlinx.serialization.json.Json /** * Provides a Json instance configured to ignore unknown keys. */ -fun interface JsonProvider : Provider +typealias JsonProvider = Provider @ContributesBinding(AppScope::class) @SingleIn(AppScope::class) From 3a6e82a7f0ba5be6675388a7395ae230d6a54dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 22 Dec 2025 14:17:19 +0100 Subject: [PATCH 251/347] Do some cleanup in `VectorUnifiedPushMessagingReceiverBindings` --- .../VectorUnifiedPushMessagingReceiverBindings.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt index da13aa93d1..1d227b3b83 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverBindings.kt @@ -9,14 +9,9 @@ package io.element.android.libraries.pushproviders.unifiedpush import dev.zacsweers.metro.AppScope -import dev.zacsweers.metro.Binds import dev.zacsweers.metro.ContributesTo -import org.unifiedpush.android.connector.MessagingReceiver @ContributesTo(AppScope::class) interface VectorUnifiedPushMessagingReceiverBindings { fun inject(receiver: VectorUnifiedPushMessagingReceiver) - - @Binds - fun bindsMessagingReceiver(vectorUnifiedPushMessagingReceiver: VectorUnifiedPushMessagingReceiver): MessagingReceiver } From 7b3f082eb34d182b688193a8a83d8228f1f451b9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 14:28:15 +0100 Subject: [PATCH 252/347] fix(deps): update kotlin to 2.3.0 (#5917) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(deps): update kotlin to 2.3.0 * Cleanup - remove `datetime` compat version * Fix several lint issues caused by the Kotlin compiler inference working better (checks in nullables, vars, etc.) * Fix tests by removing mock in `File.readBytes`, it seems like it's no longer allowed. Using a tmp file works well enough. --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Benoit Marty Co-authored-by: Jorge Martín --- .idea/kotlinc.xml | 4 +- .../call/impl/utils/ActiveCallManager.kt | 8 +-- .../ConfigureRoomPresenterTest.kt | 45 +++++------- .../impl/timeline/TimelinePresenter.kt | 3 +- .../EditUserProfilePresenterTest.kt | 60 +++++++++------- .../impl/reporter/DefaultBugReporterTest.kt | 2 +- .../impl/RoomDetailsEditPresenterTest.kt | 71 +++++++++++-------- gradle/libs.versions.toml | 6 +- .../androidutils/diff/DiffCacheUpdater.kt | 2 +- .../androidutils/text/LinkifyHelper.kt | 1 + .../matrix/test/timeline/FakeTimeline.kt | 24 +++---- 11 files changed, 119 insertions(+), 107 deletions(-) diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index 3efb2d8dd4..dbbf81b44b 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - - \ No newline at end of file + diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/ActiveCallManager.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/ActiveCallManager.kt index 91fcc2593e..4183e22531 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/ActiveCallManager.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/ActiveCallManager.kt @@ -177,8 +177,8 @@ class DefaultActiveCallManager( suspend fun incomingCallTimedOut(displayMissedCallNotification: Boolean) = mutex.withLock { Timber.tag(tag).d("Incoming call timed out") - val previousActiveCall = activeCall.value ?: return - val notificationData = (previousActiveCall.callState as? CallState.Ringing)?.notificationData ?: return + val previousActiveCall = activeCall.value ?: return@withLock + val notificationData = (previousActiveCall.callState as? CallState.Ringing)?.notificationData ?: return@withLock activeCall.value = null if (activeWakeLock?.isHeld == true) { Timber.tag(tag).d("Releasing partial wakelock after timeout") @@ -196,11 +196,11 @@ class DefaultActiveCallManager( Timber.tag(tag).d("Hung up call: $callType") val currentActiveCall = activeCall.value ?: run { Timber.tag(tag).w("No active call, ignoring hang up") - return + return@withLock } if (currentActiveCall.callType != callType) { Timber.tag(tag).w("Call type $callType does not match the active call type, ignoring") - return + return@withLock } if (currentActiveCall.callState is CallState.Ringing) { // Decline the call diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt index c8a6c2bd8a..6de15904d7 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt @@ -51,15 +51,10 @@ import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.test -import io.mockk.every import io.mockk.mockk -import io.mockk.mockkStatic -import io.mockk.unmockkAll import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest -import org.junit.After -import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -76,17 +71,6 @@ class ConfigureRoomPresenterTest { @get:Rule val warmUpRule = WarmUpRule() - @Before - fun setup() { - mockkStatic(File::readBytes) - every { any().readBytes() } returns byteArrayOf() - } - - @After - fun tearDown() { - unmockkAll() - } - @Test fun `present - initial state`() = runTest { val presenter = createConfigureRoomPresenter() @@ -261,20 +245,25 @@ class ConfigureRoomPresenterTest { val initialState = initialState() dataStore.setAvatarUri(Uri.parse(AN_URI_FROM_GALLERY)) skipItems(1) - mediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(mockk(), mockk(), mockk()))) - matrixClient.givenUploadMediaResult(Result.failure(AN_EXCEPTION)) + val file = File.createTempFile("test", "jpg") + try { + mediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(file, mockk(), mockk()))) + matrixClient.givenUploadMediaResult(Result.failure(AN_EXCEPTION)) - initialState.eventSink(ConfigureRoomEvents.CreateRoom) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) - val stateAfterCreateRoom = awaitItem() - assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java) - assertThat(analyticsService.capturedEvents.filterIsInstance()).isEmpty() + initialState.eventSink(ConfigureRoomEvents.CreateRoom) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) + val stateAfterCreateRoom = awaitItem() + assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java) + assertThat(analyticsService.capturedEvents.filterIsInstance()).isEmpty() - matrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL)) - stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) - assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Success::class.java) + matrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL)) + stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Success::class.java) + } finally { + file.delete() + } } } 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 a953c6e349..5bafaf3e88 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 @@ -394,9 +394,8 @@ class TimelinePresenter( newMostRecentItemId != prevMostRecentItemIdValue if (hasNewEvent) { - val newMostRecentEvent = newMostRecentItem // Scroll to bottom if the new event is from me, even if sent from another device - val fromMe = newMostRecentEvent?.isMine == true + val fromMe = newMostRecentItem.isMine newEventState.value = if (fromMe) { NewEventState.FromMe } else { diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt index d69101cbba..0602709ec8 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt @@ -56,8 +56,6 @@ class EditUserProfilePresenterTest { private val userAvatarUri: Uri = mockk() private val anotherAvatarUri: Uri = mockk() - private val fakeFileContents = ByteArray(2) - @Before fun setup() { fakePickerProvider = FakePickerProvider() @@ -397,7 +395,7 @@ class EditUserProfilePresenterTest { fun `present - save processes and sets avatar when processor returns successfully`() = runTest { val matrixClient = FakeMatrixClient() val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL) - givenPickerReturnsFile() + val tmpFile = givenPickerReturnsFile() val presenter = createEditUserProfilePresenter( matrixClient = matrixClient, matrixUser = user, @@ -405,12 +403,16 @@ class EditUserProfilePresenterTest { deleteLambda = { assertThat(it).isEqualTo(userAvatarUri) } ), ) - presenter.test { - val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) - initialState.eventSink(EditUserProfileEvent.Save) - consumeItemsUntilPredicate { matrixClient.uploadAvatarCalled } - assertThat(matrixClient.uploadAvatarCalled).isTrue() + try { + presenter.test { + val initialState = awaitItem() + initialState.eventSink(EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(EditUserProfileEvent.Save) + consumeItemsUntilPredicate { matrixClient.uploadAvatarCalled } + assertThat(matrixClient.uploadAvatarCalled).isTrue() + } + } finally { + tmpFile.delete() } } @@ -457,30 +459,38 @@ class EditUserProfilePresenterTest { @Test fun `present - sets save action to failure if setting avatar fails`() = runTest { - givenPickerReturnsFile() + val tmpFile = givenPickerReturnsFile() val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL) val matrixClient = FakeMatrixClient().apply { givenUploadAvatarResult(Result.failure(RuntimeException("!"))) } - saveAndAssertFailure(user, matrixClient, EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) + try { + saveAndAssertFailure(user, matrixClient, EditUserProfileEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) + } finally { + tmpFile.delete() + } } @Test fun `present - CloseDialog resets save action state`() = runTest { - givenPickerReturnsFile() + val tmpFile = givenPickerReturnsFile() val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL) val matrixClient = FakeMatrixClient().apply { givenSetDisplayNameResult(Result.failure(RuntimeException("!"))) } val presenter = createEditUserProfilePresenter(matrixUser = user, matrixClient = matrixClient) - presenter.test { - val initialState = awaitItem() - initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("foo")) - initialState.eventSink(EditUserProfileEvent.Save) - skipItems(2) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) - initialState.eventSink(EditUserProfileEvent.CloseDialog) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) + try { + presenter.test { + val initialState = awaitItem() + initialState.eventSink(EditUserProfileEvent.UpdateDisplayName("foo")) + initialState.eventSink(EditUserProfileEvent.Save) + skipItems(2) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) + initialState.eventSink(EditUserProfileEvent.CloseDialog) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) + } + } finally { + tmpFile.delete() } } @@ -502,20 +512,18 @@ class EditUserProfilePresenterTest { } } - private fun givenPickerReturnsFile() { - mockkStatic(File::readBytes) - val processedFile: File = mockk { - every { readBytes() } returns fakeFileContents - } + private fun givenPickerReturnsFile(): File { + val file = File.createTempFile("test", "jpg") fakePickerProvider.givenResult(anotherAvatarUri) fakeMediaPreProcessor.givenResult( Result.success( MediaUploadInfo.AnyFile( - file = processedFile, + file = file, fileInfo = mockk(), ) ) ) + return file } companion object { diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt index f82c57889f..41e136a53e 100755 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt @@ -323,7 +323,7 @@ class DefaultBugReporterTest { while (part != null) { part.headers["Content-Disposition"]?.let { contentDisposition -> regex.find(contentDisposition)?.groupValues?.get(1)?.let { name -> - foundValues.put(name, part!!.body.readUtf8()) + foundValues.put(name, part.body.readUtf8()) } } part = multipartReader.nextPart() diff --git a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt index 00dcb961ec..656cc92265 100644 --- a/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt +++ b/features/roomdetailsedit/impl/src/test/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditPresenterTest.kt @@ -35,6 +35,7 @@ import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.fake.FakeTemporaryUriDeleter import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.matching import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test import io.mockk.every @@ -528,22 +529,29 @@ class RoomDetailsEditPresenterTest { avatarUrl = AN_AVATAR_URL, updateAvatarResult = updateAvatarResult, ) - givenPickerReturnsFile() + val tmpFile = givenPickerReturnsFile() val deleteCallback = lambdaRecorder {} val presenter = createRoomDetailsEditPresenter( room = room, temporaryUriDeleter = FakeTemporaryUriDeleter(deleteCallback), ) - presenter.test { - val initialState = awaitItem() - initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) - initialState.eventSink(RoomDetailsEditEvent.Save) - skipItems(4) - updateAvatarResult.assertions().isCalledOnce().with(value(MimeTypes.Jpeg), value(fakeFileContents)) - deleteCallback.assertions().isCalledExactly(2).withSequence( - listOf(value(null)), - listOf(value(roomAvatarUri)), - ) + try { + presenter.test { + val initialState = awaitItem() + initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto)) + initialState.eventSink(RoomDetailsEditEvent.Save) + skipItems(4) + updateAvatarResult.assertions().isCalledOnce().with( + value(MimeTypes.Jpeg), + matching { it.contentEquals(fakeFileContents) } + ) + deleteCallback.assertions().isCalledExactly(2).withSequence( + listOf(value(null)), + listOf(value(roomAvatarUri)), + ) + } + } finally { + tmpFile.delete() } } @@ -605,19 +613,23 @@ class RoomDetailsEditPresenterTest { @Test fun `present - sets save action to failure if setting avatar fails`() = runTest { - givenPickerReturnsFile() + val tmpFile = givenPickerReturnsFile() val room = aJoinedRoom( topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL, updateAvatarResult = { _, _ -> Result.failure(RuntimeException("!")) }, ) - saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto), deleteCallbackNumberOfInvocation = 2) + try { + saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto), deleteCallbackNumberOfInvocation = 2) + } finally { + tmpFile.delete() + } } @Test fun `present - CancelSaveChanges resets save action state`() = runTest { - givenPickerReturnsFile() + val tmpFile = givenPickerReturnsFile() val room = aJoinedRoom( topic = "My topic", displayName = "Name", @@ -629,14 +641,18 @@ class RoomDetailsEditPresenterTest { room = room, temporaryUriDeleter = FakeTemporaryUriDeleter(deleteCallback), ) - presenter.test { - val initialState = awaitItem() - initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("foo")) - initialState.eventSink(RoomDetailsEditEvent.Save) - skipItems(3) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) - initialState.eventSink(RoomDetailsEditEvent.CloseDialog) - assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) + try { + presenter.test { + val initialState = awaitItem() + initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("foo")) + initialState.eventSink(RoomDetailsEditEvent.Save) + skipItems(3) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) + initialState.eventSink(RoomDetailsEditEvent.CloseDialog) + assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) + } + } finally { + tmpFile.delete() } } @@ -736,20 +752,19 @@ class RoomDetailsEditPresenterTest { } } - private fun givenPickerReturnsFile() { - mockkStatic(File::readBytes) - val processedFile: File = mockk { - every { readBytes() } returns fakeFileContents - } + private fun givenPickerReturnsFile(): File { + val tmpFile = File.createTempFile("test", "jpg") + tmpFile.writeBytes(fakeFileContents) fakePickerProvider.givenResult(anotherAvatarUri) fakeMediaPreProcessor.givenResult( Result.success( MediaUploadInfo.AnyFile( - file = processedFile, + file = tmpFile, fileInfo = mockk(), ) ) ) + return tmpFile } private fun aJoinedRoom( diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 343748537e..5daa441233 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,9 +5,9 @@ # Project android_gradle_plugin = "8.13.2" # When updateing this, please also update the version in the file ./idea/kotlinc.xml -kotlin = "2.2.20" +kotlin = "2.3.0" kotlinpoet = "2.2.0" -ksp = "2.2.20-2.0.4" +ksp = "2.3.4" firebaseAppDistribution = "5.2.0" # AndroidX @@ -62,7 +62,7 @@ detekt = "1.23.8" # See https://github.com/pinterest/ktlint/releases/ ktlint = "1.8.0" androidx-test-ext-junit = "1.3.0" -kover = "0.9.2" +kover = "0.9.4" [libraries] # Project diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/diff/DiffCacheUpdater.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/diff/DiffCacheUpdater.kt index fce510f69c..fb3c610a01 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/diff/DiffCacheUpdater.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/diff/DiffCacheUpdater.kt @@ -28,7 +28,7 @@ class DiffCacheUpdater( private val cacheInvalidator: DiffCacheInvalidator = DefaultDiffCacheInvalidator(), private val areItemsTheSame: (oldItem: ListItem?, newItem: ListItem?) -> Boolean, ) { - private val lock = Object() + private val lock = Any() private var prevOriginalList: List = emptyList() private val listUpdateCallback = object : ListUpdateCallback { diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/text/LinkifyHelper.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/text/LinkifyHelper.kt index 916f365b28..b95dacc5a8 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/text/LinkifyHelper.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/text/LinkifyHelper.kt @@ -30,6 +30,7 @@ object LinkifyHelper { @LinkifyCompat.LinkifyMask linkifyMask: Int = Linkify.WEB_URLS or Linkify.PHONE_NUMBERS or Linkify.EMAIL_ADDRESSES, ): CharSequence { // Convert the text to a Spannable to be able to add URL spans, return the original text if it's not possible (in tests, i.e.) + @Suppress("USELESS_ELVIS") val spannable = text.toSpannable() ?: return text // Get all URL spans, as they will be removed by LinkifyCompat.addLinks diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt index 6115dd2345..4451de6276 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt @@ -158,7 +158,7 @@ class FakeTimeline( imageInfo: ImageInfo, body: String?, formattedBody: String?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ) -> Result = { _, _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } @@ -169,7 +169,7 @@ class FakeTimeline( imageInfo: ImageInfo, caption: String?, formattedCaption: String?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ): Result = simulateLongTask { sendImageLambda( file, @@ -187,7 +187,7 @@ class FakeTimeline( videoInfo: VideoInfo, body: String?, formattedBody: String?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ) -> Result = { _, _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } @@ -198,7 +198,7 @@ class FakeTimeline( videoInfo: VideoInfo, caption: String?, formattedCaption: String?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ): Result = simulateLongTask { sendVideoLambda( file, @@ -215,7 +215,7 @@ class FakeTimeline( audioInfo: AudioInfo, caption: String?, formattedCaption: String?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ) -> Result = { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } @@ -225,7 +225,7 @@ class FakeTimeline( audioInfo: AudioInfo, caption: String?, formattedCaption: String?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ): Result = simulateLongTask { sendAudioLambda( file, @@ -241,7 +241,7 @@ class FakeTimeline( fileInfo: FileInfo, caption: String?, formattedCaption: String?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ) -> Result = { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } @@ -251,7 +251,7 @@ class FakeTimeline( fileInfo: FileInfo, caption: String?, formattedCaption: String?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ): Result = simulateLongTask { sendFileLambda( file, @@ -266,7 +266,7 @@ class FakeTimeline( file: File, audioInfo: AudioInfo, waveform: List, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ) -> Result = { _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } @@ -275,7 +275,7 @@ class FakeTimeline( file: File, audioInfo: AudioInfo, waveform: List, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ): Result = simulateLongTask { sendVoiceMessageLambda( file, @@ -291,7 +291,7 @@ class FakeTimeline( description: String?, zoomLevel: Int?, assetType: AssetType?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ) -> Result = { _, _, _, _, _, _ -> lambdaError() } @@ -302,7 +302,7 @@ class FakeTimeline( description: String?, zoomLevel: Int?, assetType: AssetType?, - inReplyToEventId: EventId??, + inReplyToEventId: EventId?, ): Result = simulateLongTask { sendLocationLambda( body, From a12c37d6d9544b772fb530db69d2ef2cee859829 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 22 Dec 2025 15:25:54 +0100 Subject: [PATCH 253/347] misc : add enabled param to ListItemContent.Custom View --- .../shared/blockuser/BlockUserSection.kt | 2 +- .../components/list/ListItemContent.kt | 4 ++-- .../preferences/PreferenceCheckbox.kt | 1 - .../preferences/PreferenceDropdown.kt | 24 +++++++++++++------ .../components/preferences/PreferenceSlide.kt | 1 - .../preferences/PreferenceSwitch.kt | 1 - .../preferences/components/PreferenceIcon.kt | 3 +-- 7 files changed, 21 insertions(+), 15 deletions(-) diff --git a/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/blockuser/BlockUserSection.kt b/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/blockuser/BlockUserSection.kt index 7a73c60e4a..c3caffa7f3 100644 --- a/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/blockuser/BlockUserSection.kt +++ b/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/blockuser/BlockUserSection.kt @@ -70,7 +70,7 @@ private fun PreferenceBlockUser( isLoading: Boolean, eventSink: (UserProfileEvents) -> Unit, ) { - val loadingCurrentValue = @Composable { + val loadingCurrentValue = @Composable { _: Boolean -> CircularProgressIndicator( modifier = Modifier .progressSemantics() diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/ListItemContent.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/ListItemContent.kt index 022100abe1..e8add0369f 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/ListItemContent.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/ListItemContent.kt @@ -85,7 +85,7 @@ sealed interface ListItemContent { data class Text(val text: String) : ListItemContent /** Displays any custom content. */ - data class Custom(val content: @Composable () -> Unit) : ListItemContent + data class Custom(val content: @Composable (enabled: Boolean) -> Unit) : ListItemContent /** Displays a badge. */ data object Badge : ListItemContent @@ -131,7 +131,7 @@ sealed interface ListItemContent { is Counter -> { CounterAtom(count = count) } - is Custom -> content() + is Custom -> content(isItemEnabled) } } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceCheckbox.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceCheckbox.kt index 5277aca1c7..6b4a8e1e0c 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceCheckbox.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceCheckbox.kt @@ -43,7 +43,6 @@ fun PreferenceCheckbox( leadingContent = preferenceIcon( icon = icon, iconResourceId = iconResourceId, - enabled = enabled, showIconAreaIfNoIcon = showIconAreaIfNoIcon, ), headlineContent = { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt index 23fdec9942..5fcbcab475 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt @@ -40,7 +40,7 @@ import io.element.android.libraries.designsystem.theme.components.DropdownMenuIt import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.designsystem.toEnabledColor +import io.element.android.libraries.designsystem.toIconSecondaryEnabledColor import io.element.android.libraries.designsystem.toSecondaryEnabledColor import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @@ -64,7 +64,6 @@ fun PreferenceDropdown( leadingContent = preferenceIcon( icon = icon, iconResourceId = iconResourceId, - enabled = enabled, showIconAreaIfNoIcon = showIconAreaIfNoIcon, ), headlineContent = { @@ -72,7 +71,6 @@ fun PreferenceDropdown( style = ElementTheme.typography.fontBodyLgRegular, modifier = Modifier.fillMaxWidth(), text = title, - color = enabled.toEnabledColor(), ) }, supportingContent = supportingText?.let { @@ -80,22 +78,23 @@ fun PreferenceDropdown( Text( style = ElementTheme.typography.fontBodyMdRegular, text = it, - color = enabled.toSecondaryEnabledColor(), ) } }, trailingContent = ListItemContent.Custom( - content = { + content = { enabled -> DropdownTrailingContent( selectedOption = selectedOption, options = options, onSelectOption = onSelectOption, expanded = isDropdownExpanded, onExpandedChange = { isDropdownExpanded = it }, + enabled = enabled, modifier = Modifier.fillMaxSize(0.3f) ) } ), + enabled = enabled, onClick = { isDropdownExpanded = true }.takeIf { !isDropdownExpanded }, ) } @@ -118,6 +117,7 @@ private fun DropdownTrailingContent( expanded: Boolean, onExpandedChange: (Boolean) -> Unit, onSelectOption: (T) -> Unit, + enabled: Boolean, modifier: Modifier = Modifier, ) { Row( @@ -129,7 +129,7 @@ private fun DropdownTrailingContent( text = selectedOption?.getText().orEmpty(), maxLines = 1, style = ElementTheme.typography.fontBodyMdRegular, - color = ElementTheme.colors.textSecondary, + color = enabled.toSecondaryEnabledColor(), overflow = TextOverflow.Ellipsis, textAlign = TextAlign.End, modifier = Modifier.weight(1f), @@ -137,7 +137,7 @@ private fun DropdownTrailingContent( Icon( imageVector = CompoundIcons.ChevronDown(), contentDescription = null, - tint = ElementTheme.colors.iconSecondary, + tint = enabled.toIconSecondaryEnabledColor(), ) DropdownMenu( expanded = expanded, @@ -146,6 +146,7 @@ private fun DropdownTrailingContent( ) { options.forEach { option -> DropdownMenuItem( + enabled = enabled, text = { Text( text = option.getText(), @@ -206,5 +207,14 @@ internal fun PreferenceDropdownPreview() = ElementThemedPreview { options = options, onSelectOption = {}, ) + PreferenceDropdown( + title = "Dropdown", + supportingText = "Options for dropdown", + icon = CompoundIcons.Threads(), + selectedOption = options.first(), + options = options, + onSelectOption = {}, + enabled = false + ) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSlide.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSlide.kt index a5092609e9..671eb5bf3f 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSlide.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSlide.kt @@ -44,7 +44,6 @@ fun PreferenceSlide( leadingContent = preferenceIcon( icon = icon, iconResourceId = iconResourceId, - enabled = enabled, showIconAreaIfNoIcon = showIconAreaIfNoIcon, ), headlineContent = { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSwitch.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSwitch.kt index 404a26737f..4545dbdf3e 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSwitch.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSwitch.kt @@ -42,7 +42,6 @@ fun PreferenceSwitch( leadingContent = preferenceIcon( icon = icon, iconResourceId = iconResourceId, - enabled = enabled, showIconAreaIfNoIcon = showIconAreaIfNoIcon, ), headlineContent = { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt index b3e1227525..59e818c18a 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt @@ -34,11 +34,10 @@ fun preferenceIcon( @DrawableRes iconResourceId: Int? = null, showIconBadge: Boolean = false, tintColor: Color? = null, - enabled: Boolean = true, showIconAreaIfNoIcon: Boolean = false, ): ListItemContent.Custom? { return if (icon != null || iconResourceId != null || showIconAreaIfNoIcon) { - ListItemContent.Custom { + ListItemContent.Custom { enabled -> PreferenceIcon( icon = icon, iconResourceId = iconResourceId, From 401fc26b80666a276554bfc34cd5c6cfadb61764 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Mon, 22 Dec 2025 14:41:43 +0000 Subject: [PATCH 254/347] Update screenshots --- ...ns.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png | 4 ++-- ....impl.permissions_ChangeRoomPermissionsView_Night_1_en.png | 4 ++-- ...mponents.preferences_PreferenceDropdown_Preferences_en.png | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png index a6d9a85284..de8c905de2 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4eadce77750c8946f3d506a59925901fe3a44ac61ac08e4a23b6517f4596eece -size 48910 +oid sha256:12c69b646ec09afdbc6e90873ee831adbd62ea7c45679c54620f74a9bd74941c +size 48321 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png index 43f63ee7f9..b261774095 100644 --- a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:009e04296b2dbeb127e6d3b9306dce996fa35bf4443d34abbdf2b8cc14126053 -size 47615 +oid sha256:e72874066861ce76c76134dd84b9ab058ea3c7ca1c54176f8863c6bc1b8226fc +size 47273 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png index 1d7613430e..47d04e19bb 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00eb9c6756c353ac82144c391617a515d871940c32d0604d86203f8568e9e5e2 -size 32077 +oid sha256:ed643834f8fd2bc167dfd95113ab9098392f4d626ccdd58c9fae2cfd264f70c5 +size 41611 From 9afdbdc4abcea39e104e0ecbd6318e64152dbea2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 22 Dec 2025 17:46:45 +0100 Subject: [PATCH 255/347] Remove FeatureFlags.Space entirely --- .../features/home/impl/HomePresenter.kt | 7 ---- .../android/features/home/impl/HomeState.kt | 3 +- .../features/home/impl/HomeStateProvider.kt | 4 -- .../android/features/home/impl/HomeView.kt | 12 ++---- .../features/home/impl/HomePresenterTest.kt | 38 +------------------ .../libraries/featureflag/api/FeatureFlags.kt | 6 --- 6 files changed, 7 insertions(+), 63 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt index e53d20857e..3f223135c1 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomePresenter.kt @@ -28,8 +28,6 @@ import io.element.android.features.rageshake.api.RageshakeFeatureAvailability import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState -import io.element.android.libraries.featureflag.api.FeatureFlagService -import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.indicator.api.IndicatorService import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.sync.SyncService @@ -48,7 +46,6 @@ class HomePresenter( private val homeSpacesPresenter: Presenter, private val logoutPresenter: Presenter, private val rageshakeFeatureAvailability: RageshakeFeatureAvailability, - private val featureFlagService: FeatureFlagService, private val sessionStore: SessionStore, private val announcementService: AnnouncementService, ) : Presenter { @@ -69,9 +66,6 @@ class HomePresenter( val canReportBug by remember { rageshakeFeatureAvailability.isAvailable() }.collectAsState(false) val roomListState = roomListPresenter.present() val homeSpacesState = homeSpacesPresenter.present() - val isSpaceFeatureEnabled by remember { - featureFlagService.isFeatureEnabledFlow(FeatureFlags.Space) - }.collectAsState(initial = false) var currentHomeNavigationBarItemOrdinal by rememberSaveable { mutableIntStateOf(HomeNavigationBarItem.Chats.ordinal) } val currentHomeNavigationBarItem by remember { derivedStateOf { @@ -117,7 +111,6 @@ class HomePresenter( snackbarMessage = snackbarMessage, canReportBug = canReportBug, directLogoutState = directLogoutState, - isSpaceFeatureEnabled = isSpaceFeatureEnabled, eventSink = ::handleEvent, ) } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeState.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeState.kt index 90667a8734..474fb6d5ba 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeState.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeState.kt @@ -29,10 +29,9 @@ data class HomeState( val snackbarMessage: SnackbarMessage?, val canReportBug: Boolean, val directLogoutState: DirectLogoutState, - val isSpaceFeatureEnabled: Boolean, val eventSink: (HomeEvents) -> Unit, ) { val displayActions = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats val displayRoomListFilters = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats && roomListState.displayFilters - val showNavigationBar = isSpaceFeatureEnabled && homeSpacesState.spaceRooms.isNotEmpty() + val showNavigationBar = homeSpacesState.spaceRooms.isNotEmpty() } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeStateProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeStateProvider.kt index 43010b1720..e68ff7aa1f 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeStateProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeStateProvider.kt @@ -31,7 +31,6 @@ open class HomeStateProvider : PreviewParameterProvider { aHomeState(hasNetworkConnection = false), aHomeState(snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete)), aHomeState( - isSpaceFeatureEnabled = true, roomListState = aRoomListState( // Add more rooms to see the blur effect under the NavigationBar contentState = aRoomsContentState( @@ -42,7 +41,6 @@ open class HomeStateProvider : PreviewParameterProvider { homeSpacesState = aHomeSpacesState(), ), aHomeState( - isSpaceFeatureEnabled = true, currentHomeNavigationBarItem = HomeNavigationBarItem.Spaces, ), ) + RoomListStateProvider().values.map { @@ -60,7 +58,6 @@ internal fun aHomeState( roomListState: RoomListState = aRoomListState(), homeSpacesState: HomeSpacesState = aHomeSpacesState(), canReportBug: Boolean = true, - isSpaceFeatureEnabled: Boolean = false, directLogoutState: DirectLogoutState = aDirectLogoutState(), eventSink: (HomeEvents) -> Unit = {} ) = HomeState( @@ -73,6 +70,5 @@ internal fun aHomeState( currentHomeNavigationBarItem = currentHomeNavigationBarItem, roomListState = roomListState, homeSpacesState = homeSpacesState, - isSpaceFeatureEnabled = isSpaceFeatureEnabled, eventSink = eventSink, ) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt index 42e4f72073..1b05fc99ec 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt @@ -179,14 +179,10 @@ private fun HomeScaffold( displayFilters = state.displayRoomListFilters, filtersState = roomListState.filtersState, canReportBug = state.canReportBug, - modifier = if (state.isSpaceFeatureEnabled) { - Modifier.hazeEffect( - state = hazeState, - style = HazeMaterials.thick(), - ) - } else { - Modifier.background(ElementTheme.colors.bgCanvasDefault) - } + modifier = Modifier.hazeEffect( + state = hazeState, + style = HazeMaterials.thick(), + ) ) }, bottomBar = { diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt index 0ae3ea1ff3..266c33015d 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/HomePresenterTest.kt @@ -22,9 +22,6 @@ import io.element.android.features.rageshake.api.RageshakeFeatureAvailability import io.element.android.features.rageshake.test.logs.FakeAnnouncementService import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher -import io.element.android.libraries.featureflag.api.FeatureFlagService -import io.element.android.libraries.featureflag.api.FeatureFlags -import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.indicator.api.IndicatorService import io.element.android.libraries.indicator.test.FakeIndicatorService import io.element.android.libraries.matrix.api.MatrixClient @@ -35,7 +32,6 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_NAME import io.element.android.libraries.matrix.test.FakeMatrixClient -import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.sync.FakeSyncService import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.test.InMemorySessionStore @@ -54,8 +50,6 @@ class HomePresenterTest { @get:Rule val warmUpRule = WarmUpRule() - private val isSpaceEnabled = FeatureFlags.Space.defaultValue(aBuildMeta()) - @Test fun `present - should start with no user and then load user with success`() = runTest { val matrixClient = FakeMatrixClient( @@ -79,7 +73,6 @@ class HomePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - if (isSpaceEnabled) skipItems(1) val initialState = awaitItem() assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo( MatrixUser(A_USER_ID, null, null) @@ -91,8 +84,7 @@ class HomePresenterTest { MatrixUser(A_USER_ID, A_USER_NAME, AN_AVATAR_URL) ) assertThat(withUserState.showAvatarIndicator).isFalse() - assertThat(withUserState.isSpaceFeatureEnabled).isEqualTo(isSpaceEnabled) - assertThat(withUserState.showNavigationBar).isEqualTo(isSpaceEnabled) + assertThat(withUserState.showNavigationBar).isTrue() } } @@ -114,23 +106,6 @@ class HomePresenterTest { } } - @Test - fun `present - space feature enabled`() = runTest { - val presenter = createHomePresenter( - featureFlagService = FakeFeatureFlagService( - initialState = mapOf(FeatureFlags.Space.key to true), - ), - sessionStore = InMemorySessionStore( - updateUserProfileResult = { _, _, _ -> }, - ), - ) - presenter.test { - skipItems(1) - val initialState = awaitItem() - assertThat(initialState.isSpaceFeatureEnabled).isTrue() - } - } - @Test fun `present - show avatar indicator`() = runTest { val indicatorService = FakeIndicatorService() @@ -143,7 +118,6 @@ class HomePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - if (isSpaceEnabled) skipItems(1) val initialState = awaitItem() assertThat(initialState.showAvatarIndicator).isFalse() indicatorService.setShowRoomListTopBarIndicator(true) @@ -168,7 +142,6 @@ class HomePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - if (isSpaceEnabled) skipItems(1) val initialState = awaitItem() assertThat(initialState.currentUserAndNeighbors.first()).isEqualTo(MatrixUser(matrixClient.sessionId)) // No new state is coming @@ -189,7 +162,6 @@ class HomePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - if (isSpaceEnabled) skipItems(1) val initialState = awaitItem() assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats) initialState.eventSink(HomeEvents.SelectHomeNavigationBarItem(HomeNavigationBarItem.Spaces)) @@ -207,16 +179,12 @@ class HomePresenterTest { sessionStore = InMemorySessionStore( updateUserProfileResult = { _, _, _ -> }, ), - featureFlagService = FakeFeatureFlagService( - initialState = mapOf(FeatureFlags.Space.key to true), - ), homeSpacesPresenter = homeSpacesPresenter, announcementService = FakeAnnouncementService( showAnnouncementResult = {}, ) ) presenter.test { - skipItems(1) val initialState = awaitItem() assertThat(initialState.currentHomeNavigationBarItem).isEqualTo(HomeNavigationBarItem.Chats) assertThat(initialState.showNavigationBar).isTrue() @@ -241,7 +209,6 @@ internal fun createHomePresenter( snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(), rageshakeFeatureAvailability: RageshakeFeatureAvailability = RageshakeFeatureAvailability { flowOf(false) }, indicatorService: IndicatorService = FakeIndicatorService(), - featureFlagService: FeatureFlagService = FakeFeatureFlagService(), homeSpacesPresenter: Presenter = Presenter { aHomeSpacesState() }, sessionStore: SessionStore = InMemorySessionStore(), announcementService: AnnouncementService = FakeAnnouncementService(), @@ -250,11 +217,10 @@ internal fun createHomePresenter( syncService = syncService, snackbarDispatcher = snackbarDispatcher, indicatorService = indicatorService, - logoutPresenter = { aDirectLogoutState() }, roomListPresenter = { aRoomListState() }, homeSpacesPresenter = homeSpacesPresenter, + logoutPresenter = { aDirectLogoutState() }, rageshakeFeatureAvailability = rageshakeFeatureAvailability, - featureFlagService = featureFlagService, sessionStore = sessionStore, announcementService = announcementService, ) 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 f7227a9ac9..08bdaf942f 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 @@ -70,12 +70,6 @@ enum class FeatureFlags( defaultValue = { false }, isFinished = false, ), - Space( - key = "feature.space", - title = "Spaces", - defaultValue = { true }, - isFinished = true, - ), SpaceSettings( key = "feature.spaceSettings", title = "Space settings", From fd43d58351a1e8afe3f596afe98de001de5891c4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 22 Dec 2025 17:49:41 +0100 Subject: [PATCH 256/347] change: finished feature flag should fallback to default value --- .../featureflag/impl/DefaultFeatureFlagService.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt index f7361b69b1..74967a574d 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagService.kt @@ -25,10 +25,14 @@ class DefaultFeatureFlagService( private val featuresProvider: FeaturesProvider, ) : FeatureFlagService { override fun isFeatureEnabledFlow(feature: Feature): Flow { - return providers.filter { it.hasFeature(feature) } - .maxByOrNull(FeatureFlagProvider::priority) - ?.isFeatureEnabledFlow(feature) - ?: flowOf(feature.defaultValue(buildMeta)) + return if (feature.isFinished) { + flowOf(feature.defaultValue(buildMeta)) + } else { + providers.filter { it.hasFeature(feature) } + .maxByOrNull(FeatureFlagProvider::priority) + ?.isFeatureEnabledFlow(feature) + ?: flowOf(feature.defaultValue(buildMeta)) + } } override suspend fun setFeatureEnabled(feature: Feature, enabled: Boolean): Boolean { From 2dcfdf6e4fcee89e31eedc4a9e4a4dea0bb045de Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 22 Dec 2025 18:04:08 +0100 Subject: [PATCH 257/347] quality: rename enum after PR review --- .../impl/root/RolesAndPermissionsPresenter.kt | 6 +++--- .../impl/root/RolesAndPermissionsState.kt | 6 +++--- .../impl/root/RolesAndPermissionsStateProvider.kt | 6 +++--- .../impl/root/RolesAndPermissionsView.kt | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt index f80899fc0f..dd3a59b99e 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsPresenter.kt @@ -54,8 +54,8 @@ class RolesAndPermissionsPresenter( derivedStateOf { val currentRole = roomInfo.roleOf(room.sessionId) when (currentRole) { - is RoomMember.Role.Admin -> persistentListOf(DemoteActions.ToModerator, DemoteActions.ToMember) - is RoomMember.Role.Moderator -> persistentListOf(DemoteActions.ToMember) + is RoomMember.Role.Admin -> persistentListOf(SelfDemoteAction.ToModerator, SelfDemoteAction.ToMember) + is RoomMember.Role.Moderator -> persistentListOf(SelfDemoteAction.ToMember) else -> persistentListOf() } } @@ -88,7 +88,7 @@ class RolesAndPermissionsPresenter( roomSupportsOwnerRole = roomInfo.privilegedCreatorRole, adminCount = adminCount, moderatorCount = moderatorCount, - availableDemoteActions = availableDemoteActions, + availableSelfDemoteActions = availableDemoteActions, changeOwnRoleAction = changeOwnRoleAction.value, resetPermissionsAction = resetPermissionsAction.value, eventSink = ::handleEvent, diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt index 9064f559c6..626ad3b699 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsState.kt @@ -17,15 +17,15 @@ data class RolesAndPermissionsState( val roomSupportsOwnerRole: Boolean, val adminCount: Int?, val moderatorCount: Int?, - val availableDemoteActions: ImmutableList, + val availableSelfDemoteActions: ImmutableList, val changeOwnRoleAction: AsyncAction, val resetPermissionsAction: AsyncAction, val eventSink: (RolesAndPermissionsEvents) -> Unit, ) { - val canDemoteSelf = availableDemoteActions.isNotEmpty() + val canSelfDemote = availableSelfDemoteActions.isNotEmpty() } -enum class DemoteActions(val role: RoomMember.Role, val titleRes: Int) { +enum class SelfDemoteAction(val role: RoomMember.Role, val titleRes: Int) { ToModerator(RoomMember.Role.Moderator, R.string.screen_room_roles_and_permissions_change_role_demote_to_moderator), ToMember(RoomMember.Role.User, R.string.screen_room_roles_and_permissions_change_role_demote_to_member) } diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsStateProvider.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsStateProvider.kt index cf0163d0ba..45bd72db19 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsStateProvider.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsStateProvider.kt @@ -47,7 +47,7 @@ class RolesAndPermissionsStateProvider : PreviewParameterProvider = listOf(DemoteActions.ToModerator, DemoteActions.ToMember), + availableSelfDemoteActions: List = listOf(SelfDemoteAction.ToModerator, SelfDemoteAction.ToMember), changeOwnRoleAction: AsyncAction = AsyncAction.Uninitialized, resetPermissionsAction: AsyncAction = AsyncAction.Uninitialized, eventSink: (RolesAndPermissionsEvents) -> Unit = {}, ) = RolesAndPermissionsState( roomSupportsOwnerRole = roomSupportsOwners, adminCount = adminCount, - availableDemoteActions = availableDemoteActions.toImmutableList(), + availableSelfDemoteActions = availableSelfDemoteActions.toImmutableList(), moderatorCount = moderatorCount, changeOwnRoleAction = changeOwnRoleAction, resetPermissionsAction = resetPermissionsAction, diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt index 82b49f0d81..269fdee664 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/root/RolesAndPermissionsView.kt @@ -76,7 +76,7 @@ fun RolesAndPermissionsView( }, onClick = { rolesAndPermissionsNavigator.openModeratorList() }, ) - if (state.canDemoteSelf) { + if (state.canSelfDemote) { ListItem( headlineContent = { Text(stringResource(R.string.screen_room_roles_and_permissions_change_my_role)) }, onClick = { state.eventSink(RolesAndPermissionsEvents.ChangeOwnRole) }, @@ -117,7 +117,7 @@ fun RolesAndPermissionsView( when (state.changeOwnRoleAction) { is AsyncAction.Confirming -> { ChangeOwnRoleBottomSheet( - availableDemoteActions = state.availableDemoteActions, + availableDemoteActions = state.availableSelfDemoteActions, eventSink = state.eventSink, ) } @@ -137,7 +137,7 @@ fun RolesAndPermissionsView( @OptIn(ExperimentalMaterial3Api::class) @Composable private fun ChangeOwnRoleBottomSheet( - availableDemoteActions: ImmutableList, + availableDemoteActions: ImmutableList, eventSink: (RolesAndPermissionsEvents) -> Unit, ) { val coroutineScope = rememberCoroutineScope() From f7248b87f0dd7e5aa8f7c30b98115dad8e2402c2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 22 Dec 2025 18:06:41 +0100 Subject: [PATCH 258/347] fix: display banned member list if permissions.canKick or permissions.canBan --- .../features/roomdetails/impl/members/RoomMemberListState.kt | 2 +- .../roommembermoderation/api/RoomMemberModerationPermissions.kt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt index 7c928fb27a..5a113bc3b2 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt @@ -26,7 +26,7 @@ data class RoomMemberListState( val moderationState: RoomMemberModerationState, val eventSink: (RoomMemberListEvents) -> Unit, ) { - val showBannedSection: Boolean = moderationState.permissions.canBan && roomMembers.dataOrNull()?.banned?.isNotEmpty() == true + val showBannedSection: Boolean = moderationState.permissions.hasAny && roomMembers.dataOrNull()?.banned?.isNotEmpty() == true } enum class SelectedSection { diff --git a/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt index 223456de69..10ea6c4451 100644 --- a/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt +++ b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt @@ -13,6 +13,8 @@ data class RoomMemberModerationPermissions( val canKick: Boolean, val canBan: Boolean, ) { + val hasAny = canKick || canBan + companion object { val DEFAULT = RoomMemberModerationPermissions( canKick = false, From a2ca2e7c1f033feea5de7f5387626c8a6196fb8f Mon Sep 17 00:00:00 2001 From: bmarty <3940906+bmarty@users.noreply.github.com> Date: Mon, 22 Dec 2025 00:35:17 +0000 Subject: [PATCH 259/347] Sync Strings from Localazy --- .../src/main/res/values-et/translations.xml | 2 +- .../src/main/res/values-nb/translations.xml | 1 + .../src/main/res/values-be/translations.xml | 38 + .../src/main/res/values-bg/translations.xml | 4 + .../src/main/res/values-cs/translations.xml | 38 + .../src/main/res/values-cy/translations.xml | 38 + .../src/main/res/values-da/translations.xml | 38 + .../src/main/res/values-de/translations.xml | 38 + .../src/main/res/values-el/translations.xml | 38 + .../main/res/values-en-rUS/translations.xml | 4 + .../src/main/res/values-es/translations.xml | 38 + .../src/main/res/values-et/translations.xml | 57 + .../src/main/res/values-eu/translations.xml | 36 + .../src/main/res/values-fa/translations.xml | 36 + .../src/main/res/values-fi/translations.xml | 38 + .../src/main/res/values-fr/translations.xml | 36 + .../src/main/res/values-hr/translations.xml | 57 + .../src/main/res/values-hu/translations.xml | 38 + .../src/main/res/values-in/translations.xml | 38 + .../src/main/res/values-it/translations.xml | 38 + .../src/main/res/values-ka/translations.xml | 4 + .../src/main/res/values-ko/translations.xml | 38 + .../src/main/res/values-nb/translations.xml | 38 + .../src/main/res/values-nl/translations.xml | 38 + .../src/main/res/values-pl/translations.xml | 38 + .../main/res/values-pt-rBR/translations.xml | 54 + .../src/main/res/values-pt/translations.xml | 38 + .../src/main/res/values-ro/translations.xml | 54 + .../src/main/res/values-ru/translations.xml | 38 + .../src/main/res/values-sk/translations.xml | 38 + .../src/main/res/values-sv/translations.xml | 38 + .../src/main/res/values-tr/translations.xml | 38 + .../src/main/res/values-uk/translations.xml | 38 + .../src/main/res/values-ur/translations.xml | 38 + .../src/main/res/values-uz/translations.xml | 38 + .../main/res/values-zh-rTW/translations.xml | 38 + .../src/main/res/values-zh/translations.xml | 38 + .../src/main/res/values-et/translations.xml | 2 + .../src/main/res/values-fr/translations.xml | 10 +- .../src/main/res/values-hr/translations.xml | 2 + .../src/main/res/values-da/translations.xml | 4 + .../src/main/res/values-et/translations.xml | 4 + .../src/main/res/values-hr/translations.xml | 4 + .../src/main/res/values-nb/translations.xml | 18 +- .../src/main/res/values-ro/translations.xml | 4 + .../src/main/res/values-sk/translations.xml | 4 + .../src/main/res/values-uz/translations.xml | 3 +- .../src/main/res/values-be/translations.xml | 1 - .../src/main/res/values-bg/translations.xml | 1 - .../src/main/res/values-da/translations.xml | 1 - .../src/main/res/values-el/translations.xml | 1 - .../src/main/res/values-es/translations.xml | 1 - .../src/main/res/values-et/translations.xml | 11 +- .../src/main/res/values-eu/translations.xml | 1 - .../src/main/res/values-hr/translations.xml | 5 +- .../src/main/res/values-in/translations.xml | 1 - .../src/main/res/values-ko/translations.xml | 1 - .../src/main/res/values-nb/translations.xml | 46 +- .../src/main/res/values-nl/translations.xml | 1 - .../src/main/res/values-pl/translations.xml | 2 +- .../main/res/values-pt-rBR/translations.xml | 11 +- .../src/main/res/values-ro/translations.xml | 1 - .../src/main/res/values-sv/translations.xml | 1 - .../src/main/res/values-uk/translations.xml | 2 +- .../src/main/res/values-uz/translations.xml | 6 +- .../src/main/res/values-nb/translations.xml | 2 +- .../src/main/res/values-uz/translations.xml | 2 +- .../src/main/res/values-nb/translations.xml | 2 +- .../src/main/res/values-uz/translations.xml | 2 +- .../src/main/res/values-be/translations.xml | 1 - .../src/main/res/values-bg/translations.xml | 1 - .../src/main/res/values-da/translations.xml | 1 - .../src/main/res/values-el/translations.xml | 1 - .../src/main/res/values-es/translations.xml | 1 - .../src/main/res/values-et/translations.xml | 7 +- .../src/main/res/values-eu/translations.xml | 1 - .../src/main/res/values-hr/translations.xml | 5 +- .../src/main/res/values-in/translations.xml | 1 - .../src/main/res/values-ko/translations.xml | 1 - .../src/main/res/values-nb/translations.xml | 26 +- .../src/main/res/values-nl/translations.xml | 1 - .../src/main/res/values-pl/translations.xml | 2 +- .../main/res/values-pt-rBR/translations.xml | 11 +- .../src/main/res/values-ro/translations.xml | 1 - .../src/main/res/values-sv/translations.xml | 1 - .../src/main/res/values-uk/translations.xml | 2 +- .../src/main/res/values-uz/translations.xml | 1 - .../src/main/res/values-uz/translations.xml | 4 +- .../src/main/res/values-be/translations.xml | 1 + .../src/main/res/values-de/translations.xml | 2 +- .../src/main/res/values-el/translations.xml | 1 + .../src/main/res/values-es/translations.xml | 1 + .../src/main/res/values-eu/translations.xml | 1 + .../src/main/res/values-in/translations.xml | 1 + .../src/main/res/values-ka/translations.xml | 1 + .../src/main/res/values-ko/translations.xml | 1 + .../src/main/res/values-nb/translations.xml | 1 + .../src/main/res/values-nl/translations.xml | 1 + .../main/res/values-pt-rBR/translations.xml | 2 + .../src/main/res/values-sv/translations.xml | 1 + .../src/main/res/values-tr/translations.xml | 1 + .../src/main/res/values-uk/translations.xml | 1 + .../src/main/res/values-ur/translations.xml | 1 + .../src/main/res/values-uz/translations.xml | 1 + .../main/res/values-zh-rTW/translations.xml | 2 +- .../src/main/res/values-be/translations.xml | 2 + .../src/main/res/values-bg/translations.xml | 2 +- .../src/main/res/values-cs/translations.xml | 1 + .../src/main/res/values-cy/translations.xml | 1 + .../src/main/res/values-da/translations.xml | 1 + .../src/main/res/values-de/translations.xml | 1 + .../src/main/res/values-el/translations.xml | 2 + .../src/main/res/values-es/translations.xml | 2 + .../src/main/res/values-et/translations.xml | 3 +- .../src/main/res/values-eu/translations.xml | 2 + .../src/main/res/values-fa/translations.xml | 1 + .../src/main/res/values-fi/translations.xml | 1 + .../src/main/res/values-fr/translations.xml | 3 +- .../src/main/res/values-hr/translations.xml | 2 +- .../src/main/res/values-hu/translations.xml | 1 + .../src/main/res/values-in/translations.xml | 2 + .../src/main/res/values-it/translations.xml | 1 + .../src/main/res/values-ka/translations.xml | 1 + .../src/main/res/values-ko/translations.xml | 3 +- .../src/main/res/values-lt/translations.xml | 1 + .../src/main/res/values-nb/translations.xml | 2 + .../src/main/res/values-nl/translations.xml | 2 + .../src/main/res/values-pl/translations.xml | 1 + .../main/res/values-pt-rBR/translations.xml | 11 + .../src/main/res/values-pt/translations.xml | 1 + .../src/main/res/values-ru/translations.xml | 1 + .../src/main/res/values-sk/translations.xml | 1 + .../src/main/res/values-sv/translations.xml | 1 + .../src/main/res/values-tr/translations.xml | 2 + .../src/main/res/values-uk/translations.xml | 1 + .../src/main/res/values-ur/translations.xml | 2 + .../src/main/res/values-uz/translations.xml | 1 + .../main/res/values-zh-rTW/translations.xml | 3 +- .../src/main/res/values-zh/translations.xml | 1 + .../src/main/res/values/localazy.xml | 1 + ...epeople.impl_InvitePeopleView_Day_0_de.png | 4 +- ...epeople.impl_InvitePeopleView_Day_1_de.png | 4 +- ...epeople.impl_InvitePeopleView_Day_4_de.png | 4 +- ...epeople.impl_InvitePeopleView_Day_5_de.png | 4 +- ...epeople.impl_InvitePeopleView_Day_6_de.png | 4 +- ...epeople.impl_InvitePeopleView_Day_7_de.png | 4 +- ...epeople.impl_InvitePeopleView_Day_9_de.png | 4 +- ...ens.desktop_DesktopNoticeView_Day_0_de.png | 3 + ...ens.desktop_DesktopNoticeView_Day_1_de.png | 3 + ....impl.screens.error_ErrorView_Day_0_de.png | 3 + ....impl.screens.error_ErrorView_Day_1_de.png | 3 + ....impl.screens.error_ErrorView_Day_2_de.png | 3 + ....impl.screens.error_ErrorView_Day_3_de.png | 3 + ....impl.screens.error_ErrorView_Day_4_de.png | 3 + ....impl.screens.error_ErrorView_Day_5_de.png | 3 + ....impl.screens.error_ErrorView_Day_6_de.png | 3 + ....impl.screens.error_ErrorView_Day_7_de.png | 3 + ...creens.number_EnterNumberView_Day_0_de.png | 3 + ...creens.number_EnterNumberView_Day_1_de.png | 3 + ...creens.number_EnterNumberView_Day_2_de.png | 3 + ...creens.number_EnterNumberView_Day_3_de.png | 3 + ...creens.number_EnterNumberView_Day_4_de.png | 3 + ...creens.number_EnterNumberView_Day_5_de.png | 3 + ...screens.qrcode_ShowQrCodeView_Day_0_de.png | 3 + ...ns.root_LinkNewDeviceRootView_Day_0_de.png | 3 + ...ns.root_LinkNewDeviceRootView_Day_2_de.png | 3 + ...ns.root_LinkNewDeviceRootView_Day_3_de.png | 3 + ...ns.root_LinkNewDeviceRootView_Day_5_de.png | 3 + ...l.screens.scan_ScanQrCodeView_Day_0_de.png | 3 + ...l.screens.scan_ScanQrCodeView_Day_1_de.png | 3 + ...l.screens.scan_ScanQrCodeView_Day_2_de.png | 3 + ...l.screens.scan_ScanQrCodeView_Day_3_de.png | 3 + ...een.impl.unlock_PinUnlockView_Day_0_de.png | 4 +- ...een.impl.unlock_PinUnlockView_Day_1_de.png | 4 +- ...een.impl.unlock_PinUnlockView_Day_2_de.png | 4 +- ...een.impl.unlock_PinUnlockView_Day_3_de.png | 4 +- ...een.impl.unlock_PinUnlockView_Day_4_de.png | 4 +- ...een.impl.unlock_PinUnlockView_Day_5_de.png | 4 +- ...een.impl.unlock_PinUnlockView_Day_6_de.png | 4 +- ...een.impl.unlock_PinUnlockView_Day_7_de.png | 4 +- ...ns.qrcode.scan_QrCodeScanView_Day_0_de.png | 4 +- ...ns.qrcode.scan_QrCodeScanView_Day_1_de.png | 4 +- ...ns.qrcode.scan_QrCodeScanView_Day_2_de.png | 4 +- ...ns.qrcode.scan_QrCodeScanView_Day_3_de.png | 4 +- ...ns.qrcode.scan_QrCodeScanView_Day_4_de.png | 4 +- ...ns.qrcode.scan_QrCodeScanView_Day_5_de.png | 4 +- ...s.preview_AttachmentsPreviewView_0_de.png} | 0 ...s.preview_AttachmentsPreviewView_1_de.png} | 0 ...s.preview_AttachmentsPreviewView_2_de.png} | 0 ...s.preview_AttachmentsPreviewView_3_de.png} | 0 ...s.preview_AttachmentsPreviewView_4_de.png} | 0 ...s.preview_AttachmentsPreviewView_5_de.png} | 0 ...ts.preview_AttachmentsPreviewView_6_de.png | 3 + ...s.preview_AttachmentsPreviewView_7_de.png} | 0 ...ts.preview_AttachmentsPreviewView_8_de.png | 3 + ...tachments.preview_AttachmentsView_6_de.png | 3 - ...tachments.preview_AttachmentsView_8_de.png | 3 - ...ew_VideoQualitySelectorDialog_Day_0_de.png | 4 +- ...omreaction.picker_EmojiPicker_Day_0_de.png | 4 +- ...omreaction.picker_EmojiPicker_Day_1_de.png | 4 +- ...msheet_ReadReceiptBottomSheet_Day_1_de.png | 4 +- ...msheet_ReadReceiptBottomSheet_Day_2_de.png | 4 +- ...msheet_ReadReceiptBottomSheet_Day_3_de.png | 4 +- ...msheet_ReadReceiptBottomSheet_Day_4_de.png | 4 +- ...msheet_ReadReceiptBottomSheet_Day_5_de.png | 4 +- ...eline.components_CallMenuItem_Day_3_de.png | 4 +- ...ts_TimelineItemCallNotifyView_Day_0_de.png | 4 +- ...pl.topbars_MessagesViewTopBar_Day_0_de.png | 4 +- ...blockedusers_BlockedUsersView_Day_0_de.png | 4 +- ...blockedusers_BlockedUsersView_Day_1_de.png | 4 +- ...blockedusers_BlockedUsersView_Day_3_de.png | 4 +- ...blockedusers_BlockedUsersView_Day_4_de.png | 4 +- ...blockedusers_BlockedUsersView_Day_5_de.png | 4 +- ...blockedusers_BlockedUsersView_Day_6_de.png | 4 +- ...impl.root_MultiAccountSection_Day_0_de.png | 3 - ...impl.root_PreferencesRootViewDark_0_de.png | 4 +- ...impl.root_PreferencesRootViewDark_1_de.png | 4 +- ...mpl.root_PreferencesRootViewLight_0_de.png | 4 +- ...mpl.root_PreferencesRootViewLight_1_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_0_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_1_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_2_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_3_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_4_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_5_de.png | 3 + ...ns.impl.roles_ChangeRolesView_Day_0_de.png | 4 +- ...s.impl.roles_ChangeRolesView_Day_10_de.png | 4 +- ...s.impl.roles_ChangeRolesView_Day_11_de.png | 4 +- ...s.impl.roles_ChangeRolesView_Day_12_de.png | 4 +- ...s.impl.roles_ChangeRolesView_Day_13_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_1_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_2_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_3_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_4_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_6_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_7_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_8_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_9_de.png | 4 +- ...pl.members_RoomMemberListView_Day_2_de.png | 4 +- ...pl.members_RoomMemberListView_Day_3_de.png | 4 +- ...pl.members_RoomMemberListView_Day_4_de.png | 4 +- ...pl.members_RoomMemberListView_Day_5_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_0_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_16_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_17_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_18_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_19_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_4_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_0_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_16_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_17_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_18_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_19_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_4_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_9_de.png | 4 +- ...nents_SearchMultipleUsersResultItem_de.png | 4 +- ...mponents_SearchSingleUserResultItem_de.png | 4 +- ....impl.components_UserListView_Day_0_de.png | 4 +- ....impl.components_UserListView_Day_1_de.png | 4 +- ....impl.components_UserListView_Day_2_de.png | 4 +- ....impl.components_UserListView_Day_7_de.png | 4 +- ....impl.components_UserListView_Day_9_de.png | 4 +- ...tchat.impl.root_StartChatView_Day_0_de.png | 4 +- ...tchat.impl.root_StartChatView_Day_1_de.png | 4 +- ...tchat.impl.root_StartChatView_Day_2_de.png | 4 +- ...tchat.impl.root_StartChatView_Day_3_de.png | 4 +- ...tchat.impl.root_StartChatView_Day_4_de.png | 4 +- ...tchat.impl.root_StartChatView_Day_5_de.png | 4 +- ...select.impl_AccountSelectView_Day_1_de.png | 4 +- ...mePickerHorizontal_DateTime_pickers_de.png | 4 +- ...BarActiveWithNoResults_Search_views_de.png | 4 +- ...mponents_CheckableUnresolvedUserRow_de.png | 4 +- ...rix.ui.components_UnresolvedUserRow_de.png | 4 +- ...oomselect.impl_RoomSelectView_Day_0_de.png | 4 +- ...oomselect.impl_RoomSelectView_Day_1_de.png | 4 +- ...oomselect.impl_RoomSelectView_Day_2_de.png | 4 +- ...oomselect.impl_RoomSelectView_Day_3_de.png | 4 +- ...oomselect.impl_RoomSelectView_Day_4_de.png | 2 +- ...oomselect.impl_RoomSelectView_Day_5_de.png | 4 +- screenshots/html/data.js | 1930 +++++++++-------- 280 files changed, 2762 insertions(+), 1268 deletions(-) create mode 100644 features/linknewdevice/impl/src/main/res/values-be/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-bg/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-cs/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-cy/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-da/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-de/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-el/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-en-rUS/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-es/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-et/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-eu/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-fa/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-fi/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-fr/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-hr/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-hu/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-in/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-it/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-ka/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-ko/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-nb/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-nl/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-pl/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-pt-rBR/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-pt/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-ro/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-ru/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-sk/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-sv/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-tr/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-uk/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-ur/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-uz/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-zh-rTW/translations.xml create mode 100644 features/linknewdevice/impl/src/main/res/values-zh/translations.xml create mode 100644 screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_0_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_1_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_2_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_3_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_4_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_5_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_6_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_7_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_de.png rename screenshots/de/{features.messages.impl.attachments.preview_AttachmentsView_0_de.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_0_de.png} (100%) rename screenshots/de/{features.messages.impl.attachments.preview_AttachmentsView_1_de.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_1_de.png} (100%) rename screenshots/de/{features.messages.impl.attachments.preview_AttachmentsView_2_de.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_2_de.png} (100%) rename screenshots/de/{features.messages.impl.attachments.preview_AttachmentsView_3_de.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_3_de.png} (100%) rename screenshots/de/{features.messages.impl.attachments.preview_AttachmentsView_4_de.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_4_de.png} (100%) rename screenshots/de/{features.messages.impl.attachments.preview_AttachmentsView_5_de.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_5_de.png} (100%) create mode 100644 screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_de.png rename screenshots/de/{features.messages.impl.attachments.preview_AttachmentsView_7_de.png => features.messages.impl.attachments.preview_AttachmentsPreviewView_7_de.png} (100%) create mode 100644 screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_de.png delete mode 100644 screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_6_de.png delete mode 100644 screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_8_de.png delete mode 100644 screenshots/de/features.preferences.impl.root_MultiAccountSection_Day_0_de.png create mode 100644 screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png diff --git a/features/createroom/impl/src/main/res/values-et/translations.xml b/features/createroom/impl/src/main/res/values-et/translations.xml index 6a1d9dc58a..98449f4817 100644 --- a/features/createroom/impl/src/main/res/values-et/translations.xml +++ b/features/createroom/impl/src/main/res/values-et/translations.xml @@ -9,7 +9,7 @@ Sa võid seda jututoa seadistustest alati muuta."
"Avalik jututuba" "Kõik võivad selle jututoaga liituda" - "Kõik" + "Kõik kasutajad" "Ligipääs jututoale" "Kõik võivad paluda selle jututoaga liitumist, kuid peakasutaja või moderaator peavad selle kinnitama" "Küsi võimalust liitumiseks" diff --git a/features/createroom/impl/src/main/res/values-nb/translations.xml b/features/createroom/impl/src/main/res/values-nb/translations.xml index 9a15981112..e6021cf5ac 100644 --- a/features/createroom/impl/src/main/res/values-nb/translations.xml +++ b/features/createroom/impl/src/main/res/values-nb/translations.xml @@ -14,6 +14,7 @@ Du kan endre dette når som helst i rominnstillingene."
"Alle kan be om å få bli med i rommet, men en administrator eller moderator må godta forespørselen" "Be om å bli med" "For at dette rommet skal være synlig i den offentlige romkatalogen, trenger du en romadresse." + "Romadresse" "Romnavn" "Romsynlighet" "Opprett et rom" diff --git a/features/linknewdevice/impl/src/main/res/values-be/translations.xml b/features/linknewdevice/impl/src/main/res/values-be/translations.xml new file mode 100644 index 0000000000..16372fa6e4 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-be/translations.xml @@ -0,0 +1,38 @@ + + + "Сканіраваць QR-код" + "Адсканіруйце QR-код з дапамогай гэтай прылады" + "Гатовы да сканіравання" + "Ваш правайдар уліковага запісу не падтрымлівае %1$s." + "%1$s не падтрымліваецца" + "QR-код не падтрымліваецца" + "Уваход быў адменены на іншай прыладзе." + "Запыт на ўваход скасаваны" + "Тэрмін уваходу скончыўся. Калі ласка, паспрабуйце яшчэ раз." + "Уваход у сістэму не быў завершаны своечасова" + "Выберыце %1$s" + "Не атрымалася ўсталяваць бяспечнае злучэнне з новай прыладай. Існуючыя прылады па-ранейшаму ў бяспецы, і вам не трэба турбавацца пра іх." + "Што зараз?" + "Паспрабуйце зноў увайсці ў сістэму з дапамогай QR-кода, калі гэта была сеткавая праблема" + "Калі вы сутыкнуліся з той жа праблемай, паспрабуйце іншую сетку Wi-Fi або скарыстайцеся мабільнымі дадзенымі замест Wi-Fi." + "Калі гэта не дапамагло, увайдзіце ўручную" + "Злучэнне небяспечнае" + "Уваход быў адменены на іншай прыладзе." + "Запыт на ўваход скасаваны" + "Уваход на іншай прыладзе быў адхілены." + "Уваход адхілены" + "Тэрмін уваходу скончыўся. Калі ласка, паспрабуйце яшчэ раз." + "Уваход у сістэму не быў завершаны своечасова" + "Ваша іншая прылада не падтрымлівае ўваход у %s з дапамогай QR-кода. + +Паспрабуйце ўвайсці ў сістэму ўручную або адсканіруйце QR-код з дапамогай іншай прылады." + "QR-код не падтрымліваецца" + "Ваш правайдар уліковага запісу не падтрымлівае %1$s." + "%1$s не падтрымліваецца" + "Выкарыстоўвайце QR-код, паказаны на іншай прыладзе." + "Паўтарыць спробу" + "Няправільны QR-код" + "Каб працягнуць, вам неабходна дазволіць %1$s выкарыстоўваць камеру вашай прылады." + "Дазвольце доступ да камеры для сканіравання QR-кода" + "Адбылася нечаканая памылка. Калі ласка, паспрабуйце яшчэ раз." + diff --git a/features/linknewdevice/impl/src/main/res/values-bg/translations.xml b/features/linknewdevice/impl/src/main/res/values-bg/translations.xml new file mode 100644 index 0000000000..e8a8ea95d3 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-bg/translations.xml @@ -0,0 +1,4 @@ + + + "Повторен опит" + diff --git a/features/linknewdevice/impl/src/main/res/values-cs/translations.xml b/features/linknewdevice/impl/src/main/res/values-cs/translations.xml new file mode 100644 index 0000000000..de08f790e3 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-cs/translations.xml @@ -0,0 +1,38 @@ + + + "Naskenujte QR kód" + "Naskenujte QR kód pomocí tohoto zařízení" + "Připraveno ke skenování" + "Váš poskytovatel účtu nepodporuje %1$s." + "%1$s není podporováno" + "QR kód není podporován" + "Přihlášení bylo na druhém zařízení zrušeno." + "Žádost o přihlášení zrušena" + "Platnost přihlášení vypršela. Zkuste to prosím znovu." + "Přihlášení nebylo dokončeno včas" + "Vybrat %1$s" + "K novému zařízení se nepodařilo navázat bezpečné připojení. Vaše stávající zařízení jsou stále v bezpečí a nemusíte se o ně obávat." + "Co teď?" + "Zkuste se znovu přihlásit pomocí QR kódu v případě, že se jednalo o problém se sítí" + "Pokud narazíte na stejný problém, zkuste jinou síť wifi nebo použijte mobilní data místo wifi" + "Pokud to nefunguje, přihlaste se ručně" + "Připojení není zabezpečené" + "Přihlášení bylo na druhém zařízení zrušeno." + "Žádost o přihlášení zrušena" + "Přihlášení bylo na druhém zařízení odmítnuto." + "Přihlášení odmítnuto" + "Platnost přihlášení vypršela. Zkuste to prosím znovu." + "Přihlášení nebylo dokončeno včas" + "Vaše druhé zařízení nepodporuje přihlášení k %su pomocí QR kódu. + +Zkuste se přihlásit ručně nebo naskenujte QR kód pomocí jiného zařízení." + "QR kód není podporován" + "Váš poskytovatel účtu nepodporuje %1$s." + "%1$s není podporováno" + "Použijte QR kód zobrazený na druhém zařízení." + "Zkusit znovu" + "Špatný QR kód" + "Abyste mohli pokračovat, musíte aplikaci %1$s udělit povolení k použití kamery vašeho zařízení." + "Povolte přístup k fotoaparátu a naskenujte QR kód" + "Vyskytla se neočekávaná chyba. Prosím zkuste to znovu." + diff --git a/features/linknewdevice/impl/src/main/res/values-cy/translations.xml b/features/linknewdevice/impl/src/main/res/values-cy/translations.xml new file mode 100644 index 0000000000..b26aed52ef --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-cy/translations.xml @@ -0,0 +1,38 @@ + + + "Sganiwch y cod QR" + "Sganiwch y cod QR gyda\'r ddyfais hon" + "Yn barod i sganio" + "Nid yw darparwr eich cyfrif yn cefnogi %1$s." + "%1$s heb ei gefnogi" + "Nid yw\'r cod QR yn cael ei gefnogi" + "Cafodd y mewngofnodi ei ddiddymu ar y ddyfais arall." + "Cais mewngofnodi wedi\'i ddiddymu" + "Mewngofnodi wedi dod i ben. Ceisiwch eto." + "Heb gwblhau\'r mewngofnodi mewn pryd" + "Dewiswch %1$s" + "Nid oedd modd gwneud cysylltiad diogel â\'r ddyfais newydd. Mae eich dyfeisiau presennol yn dal yn ddiogel a does dim angen i chi boeni amdanyn nhw." + "Beth nawr?" + "Ceisiwch fewngofnodi eto gyda chod QR rhag ofn bod hyn yn broblem rhwydwaith" + "Os ydych chi\'n dod ar draws yr un broblem, rhowch gynnig ar rwydwaith wifi gwahanol neu defnyddiwch eich data symudol yn lle wifi" + "Os nad yw hynny\'n gweithio, mewngofnodwch â llaw" + "Nid yw\'r cysylltiad yn ddiogel" + "Cafodd y mewngofnodi ei ddiddymu ar y ddyfais arall." + "Cais mewngofnodi wedi\'i ddiddymu" + "Cafodd y mewngofnodi ar y ddyfais arall ei wrthod." + "Gwrthodwyd y mewngofnodi" + "Mewngofnodi wedi dod i ben. Ceisiwch eto." + "Heb gwblhau\'r mewngofnodi mewn pryd" + "Nid yw eich dyfais arall yn cefnogi mewngofnodi i %s gyda chod QR. + +Ceisiwch fewngofnodi â llaw, neu sganiwch y cod QR gyda dyfais arall." + "Nid yw\'r cod QR yn cael ei gefnogi" + "Nid yw darparwr eich cyfrif yn cefnogi %1$s." + "%1$s heb ei gefnogi" + "Defnyddiwch y cod QR sy\'n cael ei ddangos ar y ddyfais arall." + "Ceisiwch eto" + "Cod QR anghywir" + "Mae angen i chi roi caniatâd i %1$s ddefnyddio camera eich dyfais er mwyn parhau." + "Caniatáu mynediad camera i sganio\'r cod QR" + "Digwyddodd gwall annisgwyl. Ceisiwch eto." + diff --git a/features/linknewdevice/impl/src/main/res/values-da/translations.xml b/features/linknewdevice/impl/src/main/res/values-da/translations.xml new file mode 100644 index 0000000000..a31175c1d5 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-da/translations.xml @@ -0,0 +1,38 @@ + + + "Scan QR-koden" + "Scan QR-koden med denne enhed" + "Klar til at scanne" + "Din kontoudbyder understøtter ikke %1$s." + "%1$s understøttes ikke" + "QR-kode understøttes ikke" + "Login blev annulleret på den anden enhed." + "Anmodning om login annulleret" + "Login er udløbet. Prøv venligst igen." + "Login blev ikke afsluttet i tide" + "Vælg %1$s" + "Der kunne ikke oprettes en sikker forbindelse til den nye enhed. Dine eksisterende enheder er stadig sikre, og du behøver ikke bekymre dig om dem." + "Hvad nu?" + "Prøv at logge ind igen med en QR-kode, hvis dette skyldtes et netværksproblem" + "Hvis du støder på det samme problem, kan du prøve et andet wifi-netværk eller bruge dine mobildata i stedet for wifi" + "Hvis det ikke virker, skal du logge ind manuelt" + "Forbindelsen er ikke sikker" + "Login blev annulleret på den anden enhed." + "Anmodning om login annulleret" + "Login blev afvist på den anden enhed." + "Login afvist" + "Login er udløbet. Prøv venligst igen." + "Login blev ikke afsluttet i tide" + "Din anden enhed understøtter ikke at logge ind på %s med en QR-kode. + +Prøv at logge ind manuelt, eller scan QR-koden med en anden enhed." + "QR-kode understøttes ikke" + "Din kontoudbyder understøtter ikke %1$s." + "%1$s understøttes ikke" + "Brug den QR-kode, der bliver vist på den anden enhed." + "Prøv igen" + "Forkert QR-kode" + "Du skal give tilladelse til at %1$s kan benytte enhedens kamera, for at fortsætte." + "Tillad kameraadgang for at scanne QR-koden" + "Der opstod en uventet fejl. Prøv venligst igen." + diff --git a/features/linknewdevice/impl/src/main/res/values-de/translations.xml b/features/linknewdevice/impl/src/main/res/values-de/translations.xml new file mode 100644 index 0000000000..25343c93c2 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-de/translations.xml @@ -0,0 +1,38 @@ + + + "QR-Code scannen" + "Scanne den QR-Code mit diesem Gerät" + "Bereit zum Scannen" + "Dein Kontoanbieter unterstützt %1$s nicht." + "%1$s wird nicht unterstützt" + "QR-Code wird nicht unterstützt" + "Die Anmeldung wurde auf dem anderen Gerät abgebrochen." + "Anmeldeanfrage abgebrochen" + "Die Anmeldung ist abgelaufen. Bitte versuche es erneut." + "Die Anmeldung wurde nicht rechtzeitig abgeschlossen" + "Wähle %1$s" + "Es konnte keine sichere Verbindung zu dem neuen Gerät hergestellt werden." + "Und jetzt?" + "Versuche, dich erneut mit einem QR-Code anzumelden, falls dies ein Netzwerkproblem war." + "Wenn das Problem bestehen bleibt, versuche es mit einem anderen WLAN-Netzwerk oder verwende deine mobilen Daten statt WLAN." + "Wenn das nicht funktioniert, melde dich manuell an" + "Die Verbindung ist nicht sicher" + "Die Anmeldung wurde auf dem anderen Gerät abgebrochen." + "Anmeldeanfrage abgebrochen" + "Die Anmeldung auf dem anderen Gerät wurde abgelehnt." + "Anmelden abgelehnt" + "Die Anmeldung ist abgelaufen. Bitte versuche es erneut." + "Die Anmeldung wurde nicht rechtzeitig abgeschlossen" + "Dein anderes Gerät unterstützt die Anmeldung bei %s mit einem QR-Code nicht. + +Versuche, dich manuell anzumelden, oder scanne den QR-Code mit einem anderen Gerät." + "QR-Code wird nicht unterstützt" + "Dein Kontoanbieter unterstützt %1$s nicht." + "%1$s wird nicht unterstützt" + "Verwende den QR-Code, der auf dem anderen Gerät angezeigt wird." + "Erneut versuchen" + "Falscher QR-Code" + "Du musst %1$s die Berechtigung erteilen, die Kamera deines Geräts zu verwenden, um fortzufahren." + "Erlaube Zugriff auf die Kamera zum Scannen des QR-Codes" + "Ein unerwarteter Fehler ist aufgetreten. Bitte versuche es erneut." + diff --git a/features/linknewdevice/impl/src/main/res/values-el/translations.xml b/features/linknewdevice/impl/src/main/res/values-el/translations.xml new file mode 100644 index 0000000000..2133bb352c --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-el/translations.xml @@ -0,0 +1,38 @@ + + + "Σάρωση κωδικού QR" + "Σάρωσε τον κωδικό QR με αυτήν τη συσκευή" + "Έτοιμο για σάρωση" + "Ο πάροχος λογαριασμού σου δεν υποστηρίζει το %1$s." + "Το %1$s δεν υποστηρίζεται" + "Ο κωδικός QR δεν υποστηρίζεται" + "Η σύνδεση ακυρώθηκε στην άλλη συσκευή." + "Το αίτημα σύνδεσης ακυρώθηκε" + "Η είσοδος έληξε. Παρακαλώ προσπάθησε ξανά." + "Η σύνδεση δεν ολοκληρώθηκε εγκαίρως" + "Επιλογή %1$s" + "Δεν ήταν δυνατή η πραγματοποίηση ασφαλούς σύνδεσης στη νέα συσκευή. Οι υπάρχουσες συσκευές σας εξακολουθούν να είναι ασφαλείς και δεν χρειάζεται να ανησυχείς για αυτές." + "Τί είναι πάλι;" + "Δοκίμασε να συνδεθείς ξανά με έναν κωδικό QR σε περίπτωση που ήταν πρόβλημα του δικτύου" + "Εάν αντιμετωπίσεις το ίδιο πρόβλημα, δοκίμασε ένα διαφορετικό δίκτυο wifi ή χρησιμοποίησε τα δεδομένα του κινητού σου αντί για wifi" + "Εάν δεν λειτουργήσει, συνδέσου χειροκίνητα" + "Η σύνδεση δεν είναι ασφαλής" + "Η σύνδεση ακυρώθηκε στην άλλη συσκευή." + "Το αίτημα σύνδεσης ακυρώθηκε" + "Η σύνδεση απορρίφθηκε στην άλλη συσκευή." + "Η σύνδεση απορρίφθηκε" + "Η είσοδος έληξε. Παρακαλώ προσπάθησε ξανά." + "Η σύνδεση δεν ολοκληρώθηκε εγκαίρως" + "Η άλλη σου συσκευή δεν υποστηρίζει σύνδεση στο %s με κωδικό QR. + +Δοκίμασε να συνδεθείς χειροκίνητα ή σάρωσε τον κωδικό QR με άλλη συσκευή." + "Ο κωδικός QR δεν υποστηρίζεται" + "Ο πάροχος λογαριασμού σου δεν υποστηρίζει το %1$s." + "Το %1$s δεν υποστηρίζεται" + "Χρησιμοποίησε τον κωδικό QR που εμφανίζεται στην άλλη συσκευή." + "Προσπάθησε ξανά" + "Λάθος κωδικός QR" + "Πρέπει να δώσεις άδεια για %1$s για να χρησιμοποιήσεις την κάμερα της συσκευής σου και να συνεχίσεις." + "Επέτρεψε την πρόσβαση της κάμερας για σάρωση του κωδικού QR" + "Παρουσιάστηκε ένα απροσδόκητο σφάλμα. Παρακαλώ προσπάθησε ξανά." + diff --git a/features/linknewdevice/impl/src/main/res/values-en-rUS/translations.xml b/features/linknewdevice/impl/src/main/res/values-en-rUS/translations.xml new file mode 100644 index 0000000000..6395ce9e54 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-en-rUS/translations.xml @@ -0,0 +1,4 @@ + + + "If you encounter the same problem, try a different Wi-Fi network or use your mobile data instead of Wi-Fi" + diff --git a/features/linknewdevice/impl/src/main/res/values-es/translations.xml b/features/linknewdevice/impl/src/main/res/values-es/translations.xml new file mode 100644 index 0000000000..032813a2c4 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-es/translations.xml @@ -0,0 +1,38 @@ + + + "Escanea el código QR" + "Escanea el código QR con este dispositivo" + "Listo para escanear" + "Tu proveedor de cuentas no es compatible con %1$s." + "%1$s no admitido" + "Código QR no admitido" + "El inicio de sesión se canceló en el otro dispositivo." + "Solicitud de inicio de sesión cancelada" + "El inicio de sesión ha caducado. Inténtalo de nuevo." + "El inicio de sesión no se completó a tiempo" + "Selecciona %1$s" + "No se pudo establecer una conexión segura con el nuevo dispositivo. Tus dispositivos actuales siguen siendo seguros y no tienes que preocuparte por ellos." + "¿Y ahora qué?" + "Intenta iniciar sesión de nuevo con un código QR en caso de que se trate de un problema de red" + "Si te encuentras con el mismo problema, prueba con una red wifi diferente o usa tus datos móviles en lugar de wifi" + "Si eso no funciona, inicia sesión manualmente" + "La conexión no es segura" + "El inicio de sesión se canceló en el otro dispositivo." + "Solicitud de inicio de sesión cancelada" + "El inicio de sesión se rechazó en el otro dispositivo." + "Inicio de sesión rechazado" + "El inicio de sesión ha caducado. Inténtalo de nuevo." + "El inicio de sesión no se completó a tiempo" + "Tu otro dispositivo no admite el inicio de sesión en %s con un código QR. + +Intenta iniciar sesión manualmente o escanea el código QR con otro dispositivo." + "Código QR no admitido" + "Tu proveedor de cuentas no es compatible con %1$s." + "%1$s no admitido" + "Usa el código QR que se muestra en el otro dispositivo." + "Intentar de nuevo" + "Código QR incorrecto" + "Tienes que dar permiso a %1$s para que utilice la cámara de tu dispositivo y así poder continuar." + "Permite el acceso a la cámara para escanear el código QR" + "Se ha producido un error inesperado. Vuelve a intentarlo." + diff --git a/features/linknewdevice/impl/src/main/res/values-et/translations.xml b/features/linknewdevice/impl/src/main/res/values-et/translations.xml new file mode 100644 index 0000000000..6aa1398e0a --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-et/translations.xml @@ -0,0 +1,57 @@ + + + "Skaneeri QR-koodi" + "Ava %1$s kas oma süle- või lauaarvutis" + "Skaneeri QR-koodi selle seadmega" + "Skaneerimiseks valmis" + "QR-koodi laadimiseks ava %1$s süle- või lauaarvutis" + "Numbrid ei klapi" + "Sisesta kahekohaline kood" + "Sellega verifitseerime, et ühendus sinu teise seadmega on turvaline." + "Sisesta teises seadmes kuvatud number" + "Sinu teenusepakkuja ei toeta rakendust %1$s." + "%1$s pole toetatud" + "Sinu kasutajakonto teenusepakkuja ei toeta võimalust logida sisse QR-koodi abil." + "QR-kood pole toetatud" + "Sisselogimine katkestati teises seadmes." + "Sisselogimispäring on tühistatud" + "Sisselogimine aegus. Palun proovi uuesti." + "Sisselogimine jäi etteantud aja jooksul tegemata" + "Ava %1$s teises seadmes" + "Vali %1$s" + "„Logi sisse QR-koodiga“" + "Skaneeri siin näidatud QR-koodi teise seadmega" + "Ava %1$s teises seadmes" + "Lauaarvuti" + "Laadin QR-koodi…" + "Nutiseade" + "Mis tüüpi seadet soovid siduda?" + "Palun proovi uuesti ja veendu, et sisestasid kahekohalise koodi õigesti. Kui numbrid ikka ei klapi, võta ühendust oma kasutajakonto teenusepakkujaga." + "Numbrid ei klapi" + "Turvalise ühenduse loomine uue seadmega ei õnnestunud. Sinu olemasolevad seadmed on jätkuvalt turvatud ja sa ei pea nende pärast muretsema." + "Mida järgmiseks teeme?" + "Kui see juhtumisi oli võrguühenduse viga, siis proovi uuesti QR-koodiga sisse logida" + "Kui sama probleem kordub, siis kasuta mõnda muud WiFi- või mobiilset andmedsideühendust" + "Kui see ka ei aita, siis logi sisse käsitsi" + "Ühendus pole turvaline" + "Sisselogimine katkestati teises seadmes." + "Sisselogimispäring on tühistatud" + "Sisselogimisest on teises seadmes keeldutud." + "Sisselogimisest on keeldutud" + "Sa ei pea enam midagi muud tegema." + "Sinu muu seade on juba sisse logitud" + "Sisselogimine aegus. Palun proovi uuesti." + "Sisselogimine jäi etteantud aja jooksul tegemata" + "Sinu teine seade ei toeta %s sisselogimist QR-koodiga. + +Proovi käsitsi sisselogimist või skaneeri QR-koodi mõne muu seadmega." + "QR-kood pole toetatud" + "Sinu teenusepakkuja ei toeta rakendust %1$s." + "%1$s pole toetatud" + "Kasuta teises seadmes näidatavat QR-koodi" + "Proovi uuesti" + "Vale QR-kood" + "Jätkamiseks pead lubama, et %1$s saab kasutada sinu nutiseadme kaamerat" + "QR-koodi lugemiseks luba kaamerat kasutada" + "Tekkis ootamatu viga. Palun proovi uuesti." + diff --git a/features/linknewdevice/impl/src/main/res/values-eu/translations.xml b/features/linknewdevice/impl/src/main/res/values-eu/translations.xml new file mode 100644 index 0000000000..06cc0fd857 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-eu/translations.xml @@ -0,0 +1,36 @@ + + + "Eskaneatu QR kodea" + "Eskaneatu QR kodea gailu honekin" + "Eskaneatzeko prest" + "Zure kontu-hornitzailea ez da %1$s-ekin bateragarria." + "%1$s ez da bateragarria" + "QR kodea ez da bateragarria" + "Saioa hasteko eskaera bertan behera utzi da beste gailuan" + "Saioa hasteko eskaera bertan behera utzi da" + "Saio-hasiera iraungi da. Saiatu berriro." + "Saio-hasiera ez da garaiz gauzatu." + "Hautatu %1$s" + "Ezin izan da konexio segururik ezarri gailu berriarekin. Lehendik dauden gailuak seguru daude oraindik ere eta ez duzu haietaz kezkatu beharrik." + "Orain zer?" + "Saiatu berriro QR kodearekin saioa hasten sare-arazo bat izan bada" + "Horrek ez badu funtzionatzen, hasi saioa eskuz" + "Konexioa ez da segurua" + "Saioa hasteko eskaera bertan behera utzi da beste gailuan" + "Saioa hasteko eskaera bertan behera utzi da" + "Saioa hasteari uko egin zaio beste dispositiboan." + "Saio-hasiera ukatu da" + "Saio-hasiera iraungi da. Saiatu berriro." + "Saio-hasiera ez da garaiz gauzatu." + "Beste gailua ez da bateragarria QR kodeak erabiliz %s(e)n saioa hastearekin. + +Saiatu saioa eskuz hasten, edo eskaneatu QR kodea beste gailu batean." + "QR kodea ez da bateragarria" + "Zure kontu-hornitzailea ez da %1$s-ekin bateragarria." + "%1$s ez da bateragarria" + "Erabili beste gailuan agertzen den QR kodea." + "Saiatu berriro" + "QR kode okerra" + "Baimendu kameraren sarbidea QR kodea eskaneatzeko" + "Ustekabeko errore bat gertatu da. Saiatu berriro." + diff --git a/features/linknewdevice/impl/src/main/res/values-fa/translations.xml b/features/linknewdevice/impl/src/main/res/values-fa/translations.xml new file mode 100644 index 0000000000..804fa653ad --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-fa/translations.xml @@ -0,0 +1,36 @@ + + + "پویش کد پاس" + "پویش کد پاس با این افزاره" + "آمادهٔ پویش" + "فراهم کنندهٔ حسابتان از %1$s پشتیبانی نمی‌کند." + "%1$s پشتیبانی نمی‌شود" + "کد پاس پشتیبانی نمی‌شود" + "ورود روی افزارهٔ دیگر لغو شد." + "درخواست ورد لغو شد" + "ورود منقضی شد. لطفاً دوباره تلاش کنید." + "ورود در زمان معیّن کامل نشد" + "گزینش %1$s" + "نتوانست اتّصالی امن به افزارهٔ جدید بسازد. افزاره‌های موجودتان هنوز امنند و نیازی نیست نگرانشان باشید." + "اکنون چه؟" + "ورود دستی در صورت کار نکردنش" + "اتّصال ناامن" + "ورود روی افزارهٔ دیگر لغو شد." + "درخواست ورد لغو شد" + "ورود به دست افزارهٔ دیگر رد شد." + "ورود رد شد" + "ورود منقضی شد. لطفاً دوباره تلاش کنید." + "ورود در زمان معیّن کامل نشد" + "افزارهٔ دیگرتان از ورود به %s با کد پاس پشتیبانی نمی‌کند. + +آزمودن ورود دستی یا پویش کد پاس با افزاره‌ای دیگر." + "کد پاس پشتیبانی نمی‌شود" + "فراهم کنندهٔ حسابتان از %1$s پشتیبانی نمی‌کند." + "%1$s پشتیبانی نمی‌شود" + "استفاده از کد پاس نشان داده روی افزارهٔ دیگر." + "تلاش دوباره" + "کد پاس اشتباه" + "برای ادامه باید اجازهٔ استفادهٔ %1$s از دوربین افزاره‌تان را بدهید." + "اجازهٔ دسترسی دوربین برای پویش کد پاس" + "خطایی غیرمنتظره رخ داد. لطفاً دوباره تلاش کنید." + diff --git a/features/linknewdevice/impl/src/main/res/values-fi/translations.xml b/features/linknewdevice/impl/src/main/res/values-fi/translations.xml new file mode 100644 index 0000000000..3ed954a842 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-fi/translations.xml @@ -0,0 +1,38 @@ + + + "Skannaa QR-koodi" + "Skannaa QR-koodi tällä laitteella" + "Valmis skannaamaan" + "Palveluntarjoajasi ei tue %1$s -sovellusta" + "%1$s -sovellusta ei tueta" + "QR-koodia ei tueta" + "Kirjautuminen peruutettiin toisella laitteella." + "Kirjautumispyyntö peruutettu" + "Kirjautuminen vanhentui. Yritä uudelleen." + "Kirjautumista ei suoritettu ajoissa" + "Valitse %1$s" + "Turvallista yhteyttä uuteen laitteeseen ei voitu muodostaa. Olemassa olevat laitteesi ovat edelleen turvassa, eikä sinun tarvitse huolehtia niistä." + "Mitä nyt?" + "Yritä kirjautua sisään uudelleen QR-koodilla, jos kyseessä oli verkko-ongelma" + "Jos kohtaat saman ongelman, kokeile toista wifi-verkkoa tai käytä mobiilidataa wifi-yhteyden sijaan" + "Jos tämä ei auta, kirjaudu sisään manuaalisesti" + "Yhteys ei ole turvallinen" + "Kirjautuminen peruutettiin toisella laitteella." + "Kirjautumispyyntö peruutettu" + "Kirjautuminen hylättiin toisella laitteella." + "Kirjautuminen hylätty" + "Kirjautuminen vanhentui. Yritä uudelleen." + "Kirjautumista ei suoritettu ajoissa" + "Toinen laitteesi ei tue kirjautumista %s -sovellukseen QR-koodilla. + +Yritä kirjautua sisään manuaalisesti tai skannaa QR-koodi toisella laitteella." + "QR-koodia ei tueta" + "Palveluntarjoajasi ei tue %1$s -sovellusta" + "%1$s -sovellusta ei tueta" + "Käytä toisessa laitteessa näkyvää QR-koodia." + "Yritä uudelleen" + "Väärä QR-koodi" + "Jatkaaksesi sinun on annettava lupa %1$s -sovellukselle käyttää laitteesi kameraa." + "Salli lupa kameraan QR-koodin skannaamiseksi" + "Tapahtui odottamaton virhe. Yritä uudelleen." + diff --git a/features/linknewdevice/impl/src/main/res/values-fr/translations.xml b/features/linknewdevice/impl/src/main/res/values-fr/translations.xml new file mode 100644 index 0000000000..f1ffe128cc --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-fr/translations.xml @@ -0,0 +1,36 @@ + + + "Scannez le QR code" + "Scanner le QR code avec cet appareil" + "Prêt à scanner" + "Votre fournisseur de compte ne supporte pas %1$s." + "%1$s n’est pas supporté" + "QR code non supporté" + "La connexion a été annulée sur l’autre appareil." + "Demande de connexion annulée" + "Connexion expirée. Veuillez essayer à nouveau." + "La connexion a pris trop de temps." + "Choisissez %1$s" + "Aucune connexion sécurisée n’a pu être établie avec la nouvelle session. Vos sessions existantes sont toujours en sécurité et vous n’avez pas à vous en soucier." + "Et maintenant ?" + "Essayez de vous connecter à nouveau à l’aide du QR code au cas où il s’agirait d’un problème réseau" + "Si vous rencontrez le même problème, essayez un autre réseau wifi ou utilisez vos données mobiles au lieu du wifi" + "Si cela ne fonctionne pas, connectez-vous manuellement" + "La connexion n’est pas sécurisée" + "La connexion a été annulée sur l’autre appareil." + "Demande de connexion annulée" + "La connexion a été refusée sur l’autre appareil." + "Connexion refusée" + "Connexion expirée. Veuillez essayer à nouveau." + "La connexion a pris trop de temps." + "Votre autre appareil ne supporte pas la connexion à %s avec un QR code. Essayer de vous connecter manuellement, ou scanner le QR code avec un autre appareil." + "QR code non supporté" + "Votre fournisseur de compte ne supporte pas %1$s." + "%1$s n’est pas supporté" + "Scannez le QR code affiché sur l’autre appareil." + "Essayer à nouveau" + "QR code erroné" + "Vous devez autoriser %1$s à utiliser la camera de votre appareil pour continuer." + "Autoriser l’usage de la caméra pour scanner le QR code" + "Une erreur inattendue s’est produite. Veuillez réessayer." + diff --git a/features/linknewdevice/impl/src/main/res/values-hr/translations.xml b/features/linknewdevice/impl/src/main/res/values-hr/translations.xml new file mode 100644 index 0000000000..20c194ef93 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-hr/translations.xml @@ -0,0 +1,57 @@ + + + "Skeniraj QR kod" + "Otvorite %1$s na prijenosnom ili stolnom računalu" + "Skenirajte QR kod ovim uređajem" + "Spremno za skeniranje" + "Otvorite %1$s na stolnom računalu kako biste dobili QR kod" + "Brojevi se ne podudaraju" + "Unesite dvoznamenkasti kod" + "Time ćete potvrditi da je veza s vašim drugim uređajem sigurna." + "Unesite broj prikazan na vašem drugom uređaju" + "Vaš davatelj usluga računa ne podržava %1$s ." + "%1$s nije podržan" + "Vaš davatelj usluga računa ne podržava prijavu na novi uređaj pomoću QR koda." + "QR kod nije podržan" + "Prijava je otkazana na drugom uređaju." + "Zahtjev za prijavu je otkazan" + "Prijava je istekla. Pokušajte ponovno." + "Prijava nije dovršena na vrijeme" + "Otvorite %1$s na drugom uređaju" + "Odaberite %1$s" + "“Prijavi se pomoću QR koda”" + "Skenirajte ovdje prikazani QR kod drugim uređajem" + "Otvorite %1$s na drugom uređaju" + "Stolno računalo" + "Učitavanje QR koda…" + "Mobilni uređaj" + "Koju vrstu uređaja želite povezati?" + "Pokušajte ponovno i provjerite jeste li ispravno unijeli dvoznamenkasti kod. Ako se brojevi i dalje ne podudaraju, obratite se davatelju usluge računa." + "Brojevi se ne podudaraju" + "Nije moguće uspostaviti sigurnu vezu s novim uređajem. Vaši postojeći uređaji i dalje su sigurni i ne morate se brinuti zbog njih." + "Što sad?" + "Pokušajte se ponovno prijaviti pomoću QR koda u slučaju da se radilo o problemu s mrežom" + "Ako se problem ponovi, pokušajte s drugom Wi-Fi mrežom ili mobilnim podatcima umjesto Wi-Fi-ja." + "Ako to ne uspije, prijavite se ručno" + "Veza nije sigurna" + "Prijava je otkazana na drugom uređaju." + "Zahtjev za prijavu je otkazan" + "Prijava je odbijena na drugom uređaju." + "Prijava je odbijena" + "Ne morate ništa drugo napraviti." + "Vaš drugi uređaj već je prijavljen" + "Prijava je istekla. Pokušajte ponovno." + "Prijava nije dovršena na vrijeme" + "Vaš drugi uređaj ne podržava prijavu na %s pomoću QR koda. + +Pokušajte se prijaviti ručno ili skenirajte QR kod drugim uređajem." + "QR kod nije podržan" + "Vaš davatelj usluga računa ne podržava %1$s ." + "%1$s nije podržan" + "Upotrijebite QR kod prikazan na drugom uređaju." + "Pokušajte ponovno" + "Pogrešan QR kod" + "Za nastavak morate dati dopuštenje za %1$s da biste se mogli služiti kamerom svog uređaja." + "Dopustite pristup kameri kako biste mogli skenirati QR kod" + "Došlo je do neočekivane pogreške. Pokušajte ponovno." + diff --git a/features/linknewdevice/impl/src/main/res/values-hu/translations.xml b/features/linknewdevice/impl/src/main/res/values-hu/translations.xml new file mode 100644 index 0000000000..b06d7e2fd6 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-hu/translations.xml @@ -0,0 +1,38 @@ + + + "Olvassa be a QR-kódot" + "Olvassa be a QR-kódot ezzel az eszközzel" + "Készen áll a beolvasásra" + "A fiókszolgáltatója nem támogatja az %1$s-et." + "Az %1$s nem támogatott" + "A QR-kód nem támogatott" + "A bejelentkezést megszakították a másik eszközön." + "Bejelentkezési kérés törölve" + "A bejelentkezés lejárt. Próbálja újra." + "A bejelentkezés nem fejeződött be időben" + "Válassza ezt: %1$s" + "Nem sikerült biztonságos kapcsolatot létesíteni az új eszközzel. A meglévő eszközei továbbra is biztonságban vannak, és nem kell aggódnia miattuk." + "Most mi lesz?" + "Próbáljon meg újra bejelentkezni egy QR-kóddal, ha ez hálózati probléma volt." + "Ha ugyanezzel a problémával találkozik, próbálkozzon másik Wi-Fi-hálózattal, vagy a Wi-Fi helyett használja a mobil-adatkapcsolatát" + "Ha ez nem működik, jelentkezzen be kézileg" + "A kapcsolat nem biztonságos" + "A bejelentkezést megszakították a másik eszközön." + "Bejelentkezési kérés törölve" + "A bejelentkezést elutasították a másik eszközön." + "A bejelentkezés elutasítva" + "A bejelentkezés lejárt. Próbálja újra." + "A bejelentkezés nem fejeződött be időben" + "A másik eszköz nem támogatja QR-kóddal történő bejelentkezést az %sbe. + +Próbáljon meg kézileg bejelentkezni, vagy olvassa be a QR-kódot egy másik eszközzel." + "A QR-kód nem támogatott" + "A fiókszolgáltatója nem támogatja az %1$s-et." + "Az %1$s nem támogatott" + "Használja a másik eszközön látható QR-kódot." + "Próbálja újra" + "Hibás QR-kód" + "A folytatáshoz engedélyeznie kell, hogy az %1$s használhassa az eszköz kameráját." + "Engedélyezze a kamera elérését a QR-kód beolvasásához" + "Váratlan hiba történt. Próbálja meg újra." + diff --git a/features/linknewdevice/impl/src/main/res/values-in/translations.xml b/features/linknewdevice/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..20badba9ba --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,38 @@ + + + "Pindai kode QR" + "Pindai kode QR dengan perangkat ini" + "Siap untuk memindai" + "Penyedia akun Anda tidak mendukung %1$s." + "%1$s tidak didukung" + "Kode QR tidak didukung" + "Proses masuk dibatalkan di perangkat lain." + "Permintaan masuk dibatalkan" + "Masa masuk kedaluwarsa. Silakan coba lagi." + "Proses masuk tidak selesai tepat waktu" + "Pilih %1$s" + "Koneksi aman tidak dapat dibuat ke perangkat baru. Perangkat Anda yang ada masih aman dan Anda tidak perlu khawatir tentang mereka." + "Apa sekarang?" + "Coba masuk lagi dengan kode QR jika ini adalah masalah jaringan" + "Jika Anda mengalami masalah yang sama, coba jaringan Wi-Fi yang berbeda atau gunakan data seluler Anda daripada Wi-Fi" + "Jika tidak berhasil, masuk secara manual" + "Koneksi tidak aman" + "Proses masuk dibatalkan di perangkat lain." + "Permintaan masuk dibatalkan" + "Proses masuk ditolak di perangkat lain." + "Proses masuk ditolak" + "Masa masuk kedaluwarsa. Silakan coba lagi." + "Proses masuk tidak selesai tepat waktu" + "Perangkat Anda yang lain tidak mendukung masuk ke %s dengan kode QR. + +Coba masuk secara manual, atau pindai kode QR dengan perangkat lain." + "Kode QR tidak didukung" + "Penyedia akun Anda tidak mendukung %1$s." + "%1$s tidak didukung" + "Gunakan kode QR yang ditampilkan di perangkat lain." + "Coba lagi" + "Kode QR salah" + "Anda perlu memberikan izin ke %1$s untuk menggunakan kamera perangkat Anda untuk melanjutkan." + "Izinkan akses kamera untuk memindai kode QR" + "Terjadi kesalahan tak terduga. Silakan coba lagi." + diff --git a/features/linknewdevice/impl/src/main/res/values-it/translations.xml b/features/linknewdevice/impl/src/main/res/values-it/translations.xml new file mode 100644 index 0000000000..0cf548c19b --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-it/translations.xml @@ -0,0 +1,38 @@ + + + "Scansiona il codice QR" + "Scansiona il codice QR con questo dispositivo" + "Pronto per la scansione" + "Il tuo fornitore di account non supporta %1$s." + "%1$s non supportato" + "Codice QR non supportato" + "L\'accesso è stato annullato sull\'altro dispositivo." + "Richiesta di accesso annullata" + "L\'accesso è scaduto. Riprova." + "L\'accesso non è stato completato in tempo" + "Seleziona %1$s" + "Non è stato possibile stabilire una connessione sicura con il nuovo dispositivo. I tuoi dispositivi esistenti sono ancora al sicuro e non devi preoccuparti di loro." + "E adesso?" + "Prova ad accedere di nuovo con un codice QR nel caso si sia verificato un problema di rete." + "Se riscontri lo stesso problema, prova con un altra rete wifi o usa i dati mobili al posto del wifi." + "Se il problema persiste, accedi manualmente" + "La connessione non è sicura" + "L\'accesso è stato annullato sull\'altro dispositivo." + "Richiesta di accesso annullata" + "L\'accesso è stato rifiutato sull\'altro dispositivo." + "Accesso rifiutato" + "L\'accesso è scaduto. Riprova." + "L\'accesso non è stato completato in tempo" + "L\'altro dispositivo non supporta l\'accesso a %s con un codice QR. + +Prova ad accedere manualmente o scansiona il codice QR con un altro dispositivo." + "Codice QR non supportato" + "Il tuo fornitore di account non supporta %1$s." + "%1$s non supportato" + "Usa il codice QR mostrato sull\'altro dispositivo." + "Riprova" + "Codice QR sbagliato" + "Per continuare, è necessario fornire l\'autorizzazione a %1$s per utilizzare la fotocamera del dispositivo." + "Consenti l\'accesso alla fotocamera per la scansione del codice QR" + "Si è verificato un errore inatteso. Riprova." + diff --git a/features/linknewdevice/impl/src/main/res/values-ka/translations.xml b/features/linknewdevice/impl/src/main/res/values-ka/translations.xml new file mode 100644 index 0000000000..f378e585ce --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-ka/translations.xml @@ -0,0 +1,4 @@ + + + "ხელახლა ცდა" + diff --git a/features/linknewdevice/impl/src/main/res/values-ko/translations.xml b/features/linknewdevice/impl/src/main/res/values-ko/translations.xml new file mode 100644 index 0000000000..6af49fd3cf --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-ko/translations.xml @@ -0,0 +1,38 @@ + + + "QR 코드를 스캔하세요" + "이 기기로 QR 코드를 스캔하세요." + "스캔 준비 완료" + "귀하의 계정 제공자는 지원하지 않습니다 %1$s ." + "%1$s 지원되지 않습니다" + "QR 코드는 지원되지 않습니다" + "다른 기기에서 로그인이 취소되었습니다." + "로그인 요청이 취소되었습니다" + "로그인이 만료되었습니다. 다시 시도해 주세요." + "로그인 시간이 초과되었습니다." + "선택 %1$s" + "새 장치에 안전하게 연결할 수 없습니다. 기존 장치는 여전히 안전하므로 걱정할 필요가 없습니다." + "이제 어떻게 해야 할까?" + "네트워크 문제로 인해 로그인에 실패한 경우 QR 코드로 다시 로그인해 보세요." + "동일한 문제를 겪으신 경우 다른 Wi-Fi 네트워크를 사용해 보거나 Wi-Fi 대신 모바일 데이터를 사용해 보세요." + "만약 작동하지 않는 경우, 수동으로 로그인하세요." + "연결이 안전하지 않습니다" + "다른 기기에서 로그인이 취소되었습니다." + "로그인 요청이 취소되었습니다" + "다른 기기에서 로그인이 거부되었습니다." + "로그인 거부됨" + "로그인이 만료되었습니다. 다시 시도해 주세요." + "로그인 시간이 초과되었습니다." + "다른 기기에서는 QR 코드로 %s 에 로그인할 수 없습니다. + +수동으로 로그인하거나 다른 기기로 QR 코드를 스캔해 보세요." + "QR 코드는 지원되지 않습니다" + "귀하의 계정 제공자는 지원하지 않습니다 %1$s ." + "%1$s 지원되지 않습니다" + "다른 기기에 표시된 QR 코드를 사용하세요." + "다시 시도하기" + "잘못된 QR 코드" + "계속하려면 %1$s 가 기기의 카메라를 사용할 수 있도록 권한을 부여해야 합니다." + "카메라 액세스를 허용하여 QR 코드를 스캔하세요" + "예기치 않은 오류가 발생했습니다. 다시 시도해 주세요." + diff --git a/features/linknewdevice/impl/src/main/res/values-nb/translations.xml b/features/linknewdevice/impl/src/main/res/values-nb/translations.xml new file mode 100644 index 0000000000..af3559d3e8 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-nb/translations.xml @@ -0,0 +1,38 @@ + + + "Skann QR-koden" + "Skann QR-koden med denne enheten" + "Klar til å skanne" + "Kontotilbyderen din støtter ikke %1$s." + "%1$s støttes ikke" + "QR-kode støttes ikke" + "Påloggingen ble kansellert på den andre enheten." + "Påloggingsforespørsel kansellert" + "Påloggingen er utløpt. Vennligst prøv igjen." + "Påloggingen ble ikke fullført i tide" + "Velg %1$s" + "En sikker tilkobling kunne ikke opprettes til den nye enheten. Dine eksisterende enheter er fortsatt trygge, og du trenger ikke å bekymre deg for dem." + "Hva nå?" + "Prøv å logge på igjen med en QR-kode i tilfelle dette var et nettverksproblem" + "Hvis du støter på det samme problemet, kan du prøve et annet wifi-nettverk eller bruke mobildata i stedet for wifi" + "Hvis det ikke fungerer, kan du logge på manuelt" + "Forbindelsen er ikke sikker" + "Påloggingen ble kansellert på den andre enheten." + "Påloggingsforespørsel kansellert" + "Påloggingen ble avvist på den andre enheten." + "Pålogging avslått" + "Påloggingen er utløpt. Vennligst prøv igjen." + "Påloggingen ble ikke fullført i tide" + "Den andre enheten din støtter ikke pålogging på %s med en QR-kode. + +Prøv å logge på manuelt, eller skann QR-koden med en annen enhet." + "QR-kode støttes ikke" + "Kontotilbyderen din støtter ikke %1$s." + "%1$s støttes ikke" + "Bruk QR-koden som vises på den andre enheten." + "Prøv igjen" + "Feil QR-kode" + "Du må gi tillatelse til at %1$s kan bruke enhetens kamera for å fortsette." + "Tillat kameratilgang for å skanne QR-koden" + "Det oppstod en uventet feil. Prøv igjen." + diff --git a/features/linknewdevice/impl/src/main/res/values-nl/translations.xml b/features/linknewdevice/impl/src/main/res/values-nl/translations.xml new file mode 100644 index 0000000000..407a470e48 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-nl/translations.xml @@ -0,0 +1,38 @@ + + + "Scan de QR-code" + "Scan de QR-code met dit apparaat" + "Klaar om te scannen" + "Je accountprovider ondersteunt geen %1$s." + "%1$s wordt niet ondersteund" + "QR-code wordt niet ondersteund" + "De aanmelding is geannuleerd op het andere apparaat." + "Login verzoek geannuleerd" + "Aanmelden is verlopen. Probeer het opnieuw." + "De aanmelding was niet op tijd voltooid" + "Selecteer %1$s" + "Er kon geen beveiligde verbinding worden gemaakt met het nieuwe apparaat. Je bestaande apparaten zijn nog steeds veilig en je hoeft je daarover geen zorgen te maken." + "Wat nu?" + "Probeer opnieuw in te loggen met een QR-code voor het geval dit een netwerkprobleem was" + "Als je hetzelfde probleem ondervindt, probeer dan een ander wifi-netwerk of gebruik je mobiele data in plaats van wifi." + "Als dat niet werkt, log dan handmatig in" + "Verbinding niet veilig" + "De aanmelding is geannuleerd op het andere apparaat." + "Login verzoek geannuleerd" + "De aanmelding is geweigerd op het andere apparaat." + "Aanmelden geweigerd" + "Aanmelden is verlopen. Probeer het opnieuw." + "De aanmelding was niet op tijd voltooid" + "Jouw andere apparaat ondersteunt geen inloggen op %s met een QR code. + +Probeer handmatig in te loggen, of scan de QR code met een ander apparaat." + "QR-code wordt niet ondersteund" + "Je accountprovider ondersteunt geen %1$s." + "%1$s wordt niet ondersteund" + "Gebruik de QR-code die op het andere apparaat wordt weergegeven." + "Probeer het opnieuw" + "Verkeerde QR-code" + "Je moet %1$s toestemming geven om de camera van je apparaat te gebruiken om verder te gaan." + "Cameratoegang toestaan om de QR-code te scannen" + "Er is een onverwachte fout opgetreden. Probeer het opnieuw." + diff --git a/features/linknewdevice/impl/src/main/res/values-pl/translations.xml b/features/linknewdevice/impl/src/main/res/values-pl/translations.xml new file mode 100644 index 0000000000..4db42a2a49 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-pl/translations.xml @@ -0,0 +1,38 @@ + + + "Skanuj kod QR" + "Zeskanuj kod QR za pomocą tego urządzenia" + "Gotowy do skanowania" + "Twój dostawca konta nie obsługuje %1$s." + "%1$s nie jest wspierany" + "Kod QR nie jest wspierany" + "Logowanie zostało anulowane na drugim urządzeniu." + "Prośba o logowanie została anulowana" + "Logowanie wygasło. Spróbuj ponownie." + "Logowanie nie zostało ukończone na czas" + "Wybierz %1$s" + "Nie udało się nawiązać bezpiecznego połączenia z nowym urządzeniem. Twoje istniejące urządzenia są nadal bezpieczne i nie musisz się o nie martwić." + "Co teraz?" + "Spróbuj zalogować się ponownie za pomocą kodu QR, jeśli byłby to problem z siecią" + "Jeśli napotkasz ten sam problem, użyj innej sieci Wi-FI lub danych mobilnych" + "Jeśli to nie zadziała, zaloguj się ręcznie" + "Połączenie nie jest bezpieczne" + "Logowanie zostało anulowane na drugim urządzeniu." + "Prośba o logowanie została anulowana" + "Logowanie zostało odrzucone na drugim urządzeniu." + "Logowanie odrzucone" + "Logowanie wygasło. Spróbuj ponownie." + "Logowanie nie zostało ukończone na czas" + "Twoje drugie urządzenie nie wspiera logowania się do %s za pomocą kodu QR. + +Spróbuj zalogować się ręcznie lub zeskanuj kod QR na innym urządzeniu." + "Kod QR nie jest wspierany" + "Twój dostawca konta nie obsługuje %1$s." + "%1$s nie jest wspierany" + "Użyj kodu QR widocznego na drugim urządzeniu." + "Spróbuj ponownie" + "Błędny kod QR" + "Musisz przyznać uprawnienia %1$s do korzystania z kamery, aby kontynuować." + "Zezwól na dostęp do kamery, aby zeskanować kod QR" + "Wystąpił nieoczekiwany błąd. Spróbuj ponownie." + diff --git a/features/linknewdevice/impl/src/main/res/values-pt-rBR/translations.xml b/features/linknewdevice/impl/src/main/res/values-pt-rBR/translations.xml new file mode 100644 index 0000000000..8fb178f3e5 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-pt-rBR/translations.xml @@ -0,0 +1,54 @@ + + + "Leia o código QR" + "Abra o %1$s em um computador" + "Leia o código QR com este dispositivo" + "Pronto para ler" + "Abra o %1$s em um computador para receber o código QR" + "Os números não conferem" + "Digite o código de 2 dígitos" + "Isso verificará que a conexão com o seu outro dispositivo é segura." + "Digite o número exibido no outro dispositivo" + "Seu provedor de conta não tem suporte ao %1$s." + "%1$s não suportado" + "O seu provedor de conta não tem suporte a autenticação de dispositivos novos com um código QR." + "Código QR não suportado" + "A entrada foi cancelada no outro dispositivo." + "Solicitação de entrada foi cancelada" + "O processo de entrada expirou. Tente novamente." + "A entrada não foi concluída a tempo" + "Abra o %1$s no outro dispositivo" + "Selecione %1$s" + "\"Entrar com código QR\"" + "Leia o código QR exibido aqui com o outro dispositivo" + "Abra o %1$s no outro dispositivo" + "Computador" + "Carregando código QR…" + "Dispositivo móvel" + "Que tipo de dispositivo você deseja vincular?" + "Os números não conferem" + "Não foi possível estabelecer uma conexão segura com o novo dispositivo. Seus dispositivos existentes ainda estão seguros e você não precisa se preocupar com eles." + "E agora?" + "Tente entrar novamente com um código QR caso seja um problema de rede" + "Se o problema persistir, tente uma rede Wi-Fi diferente ou use seus dados móveis em vez de Wi-Fi" + "Se isso não funcionar, entre manualmente" + "Conexão insegura" + "A entrada foi cancelada no outro dispositivo." + "Solicitação de entrada foi cancelada" + "A entrada foi recusada no outro dispositivo." + "Entrada recusada" + "O processo de entrada expirou. Tente novamente." + "A entrada não foi concluída a tempo" + "Seu outro dispositivo não tem suporte a entrar no %s com um código QR. + +Tente entrar manualmente ou ler o código QR com outro dispositivo." + "Código QR não suportado" + "Seu provedor de conta não tem suporte ao %1$s." + "%1$s não suportado" + "Use o código QR exibido no outro dispositivo." + "Tente novamente" + "Código QR errado" + "Você deve permitir que o %1$s use a câmera do seu dispositivo para continuar." + "Permita o acesso à câmera para ler o código QR" + "Ocorreu um erro inesperado. Tente novamente." + diff --git a/features/linknewdevice/impl/src/main/res/values-pt/translations.xml b/features/linknewdevice/impl/src/main/res/values-pt/translations.xml new file mode 100644 index 0000000000..da6da08f38 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-pt/translations.xml @@ -0,0 +1,38 @@ + + + "Ler o código QR" + "Lê o código QR com este dispositivo" + "Pronto para ler" + "O teu operador de conta não suporta %1$s." + "%1$s não suportado" + "Código QR não suportado" + "O início de sessão foi cancelado no outro dispositivo." + "Pedido de início de sessão cancelado" + "O início de sessão expirou. Por favor, tenta novamente." + "O início de sessão não foi concluído a tempo" + "Seleciona %1$s" + "Não foi possível estabelecer uma ligação segura com o novo dispositivo. Os teus outros dispositivos continuam seguros, não precisas de te preocupar com eles." + "E agora?" + "Tenta iniciar sessão novamente com um código QR, caso se trate de um problema de rede" + "Se tiveres o mesmo problema, experimenta uma rede Wi-Fi diferente ou utiliza os teus dados móveis." + "Se isso não funcionar, inicia sessão manualmente" + "Ligação insegura" + "O início de sessão foi cancelado no outro dispositivo." + "Pedido de início de sessão cancelado" + "O início de sessão foi rejeitado no outro dispositivo." + "Início de sessão rejeitado" + "O início de sessão expirou. Por favor, tenta novamente." + "O início de sessão não foi concluído a tempo" + "O teu outro dispositivo não suporta o início de sessão na %s com um código QR. + +Tenta iniciar a sessão manualmente ou digitaliza o código QR com outro dispositivo." + "Código QR não suportado" + "O teu operador de conta não suporta %1$s." + "%1$s não suportado" + "Lê o código QR apresentado no outro dispositivo." + "Tentar novamente" + "Código QR inválido" + "Para continuar, tens que dar permissão à %1$s para aceder à câmara do teu dispositivo." + "Permitir o acesso à câmara para ler o código QR" + "Ocorreu um erro inesperado. Tenta novamente." + diff --git a/features/linknewdevice/impl/src/main/res/values-ro/translations.xml b/features/linknewdevice/impl/src/main/res/values-ro/translations.xml new file mode 100644 index 0000000000..f1a4f3db59 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-ro/translations.xml @@ -0,0 +1,54 @@ + + + "Scanați codul QR" + "Deschide %1$s pe un laptop sau un computer desktop" + "Scanați codul QR cu acest dispozitiv" + "Gata de scanare" + "Deschide %1$s pe un computer desktop pentru a obține codul QR" + "Numerele nu se potrivesc" + "Introduceți codul de 2 cifre" + "Aceasta va verifica dacă conexiunea cu celălalt dispozitiv este sigură." + "Introduceți numărul afișat pe celălalt dispozitiv" + "Furnizorul dumneavoastră de cont nu acceptă %1$s." + "%1$s nu este acceptat" + "Furnizorul contului dumneavoastră nu acceptă conectarea la un dispozitiv nou cu un cod QR." + "Formatul codului QR nu este acceptat." + "Autentificarea a fost anulată de pe celălalt dispozitiv." + "Cererea de autentificare a fost anulată" + "Autentificarea a expirat. Vă rugăm să încercați din nou." + "Autentificarea nu a fost finalizată la timp" + "Deschideți %1$s pe celălalt dispozitiv" + "Selectați %1$s" + "“Conectați-vă cu un cod QR”" + "Scanați codul QR afișat aici cu celălalt dispozitiv." + "Deschideți %1$s pe celălalt dispozitiv" + "Calculator desktop" + "Se încarcă codul QR…" + "Dispozitiv mobil" + "Ce tip de dispozitiv doriți să conectați?" + "Numerele nu se potrivesc" + "Nu a putut fi făcută o conexiune sigură la noul dispozitiv. Dispozitivele existente sunt încă în siguranță și nu trebuie să vă faceți griji cu privire la ele." + "Și acum?" + "Încercați să vă conectați din nou cu un cod QR în cazul în care a fost o problemă de rețea." + "Dacă întâmpinați aceeași problemă, încercați o altă rețea Wi-Fi sau utilizați datele mobile în loc de Wi-Fi." + "Dacă nu funcționează, conectați-vă manual" + "Conexiunea nu este sigură" + "Autentificarea a fost anulată de pe celălalt dispozitiv." + "Cererea de autentificare a fost anulată" + "Autentificarea a fost refuzată pe celălalt dispozitiv." + "Autentificarea a fost refuzată" + "Autentificarea a expirat. Vă rugăm să încercați din nou." + "Autentificarea nu a fost finalizată la timp" + "Celălalt dispozitiv nu acceptă autentificarea la %s cu un cod QR. + +Încercați să vă autentificați manual sau să scanați codul QR cu un alt dispozitiv." + "Formatul codului QR nu este acceptat." + "Furnizorul dumneavoastră de cont nu acceptă %1$s." + "%1$s nu este acceptat" + "Utilizați codul QR afișat pe celălalt dispozitiv." + "Încercați din nou" + "Cod QR greșit" + "Trebuie să acordați permisiunea ca %1$s să folosească camera dispozitivului pentru a continua." + "Permiteți accesul la cameră pentru a scana codul QR" + "A apărut o eroare neașteptată. Vă rugăm să încercați din nou." + diff --git a/features/linknewdevice/impl/src/main/res/values-ru/translations.xml b/features/linknewdevice/impl/src/main/res/values-ru/translations.xml new file mode 100644 index 0000000000..16ed8eeb37 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-ru/translations.xml @@ -0,0 +1,38 @@ + + + "Сканировать QR-код" + "Отсканируйте QR-код с помощью этого устройства" + "Готово к сканированию" + "Поставщик учетной записи не поддерживает %1$s." + "%1$s не поддерживается" + "QR-код не поддерживается" + "Вход на другом устройстве был отменен." + "Запрос на вход отменен" + "Срок действия входа истек. Пожалуйста, попробуйте еще раз." + "Вход в систему не был выполнен вовремя" + "Выберите %1$s" + "Не удалось установить безопасное соединение с новым устройством. Существующие устройства по-прежнему в безопасности, и вам не нужно беспокоиться о них." + "Что теперь?" + "Попробуйте снова войти в систему с помощью QR-кода, если это была проблема с соединением" + "Если вы столкнулись с той же проблемой, попробуйте сменить точку доступа Wi-Fi или используйте мобильные данные" + "Если это не помогло, войдите вручную" + "Соединение не защищено" + "Вход на другом устройстве был отменен." + "Запрос на вход отменен" + "Вход в систему был отклонен на другом устройстве." + "Вход отклонен" + "Срок действия входа истек. Пожалуйста, попробуйте еще раз." + "Вход в систему не был выполнен вовремя" + "Другое устройство не поддерживает вход в %s с помощью QR-кода. + +Попробуйте войти вручную или отсканируйте QR-код на другом устройстве." + "QR-код не поддерживается" + "Поставщик учетной записи не поддерживает %1$s." + "%1$s не поддерживается" + "Используйте QR-код, показанный на другом устройстве." + "Повторить попытку" + "Неверный QR-код" + "Чтобы продолжить, вам необходимо разрешить %1$s использовать камеру вашего устройства." + "Разрешите доступ к камере для сканирования QR-кода" + "Произошла непредвиденная ошибка. Пожалуйста, попробуйте еще раз." + diff --git a/features/linknewdevice/impl/src/main/res/values-sk/translations.xml b/features/linknewdevice/impl/src/main/res/values-sk/translations.xml new file mode 100644 index 0000000000..9617df3acc --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-sk/translations.xml @@ -0,0 +1,38 @@ + + + "Naskenovať QR kód" + "Naskenujte QR kód pomocou tohto zariadenia" + "Pripravené na skenovanie" + "Poskytovateľ vášho účtu nepodporuje %1$s." + "%1$s nie je podporovaný" + "QR kód nie je podporovaný" + "Prihlásenie bolo zrušené na druhom zariadení." + "Žiadosť o prihlásenie bola zrušená" + "Platnosť prihlásenia vypršala. Skúste to prosím znova." + "Prihlásenie nebolo včas dokončené" + "Vyberte %1$s" + "K novému zariadeniu sa nepodarilo vytvoriť bezpečné pripojenie. Vaše existujúce zariadenia sú stále v bezpečí a nemusíte sa o ne obávať." + "Čo teraz?" + "Skúste sa znova prihlásiť pomocou QR kódu v prípade, že ide o problém so sieťou" + "Ak narazíte na rovnaký problém, vyskúšajte inú sieť Wi-Fi alebo namiesto siete Wi-Fi použite mobilné dáta" + "Ak to nefunguje, prihláste sa manuálne" + "Pripojenie nie je bezpečené" + "Prihlásenie bolo zrušené na druhom zariadení." + "Žiadosť o prihlásenie bola zrušená" + "Prihlásenie bolo zamietnuté na druhom zariadení." + "Prihlásenie bolo odmietnuté" + "Platnosť prihlásenia vypršala. Skúste to prosím znova." + "Prihlásenie nebolo včas dokončené" + "Vaše druhé zariadenie nepodporuje prihlásenie do aplikácie %s pomocou QR kódu. + +Skúste sa prihlásiť manuálne alebo naskenujte QR kód pomocou iného zariadenia." + "QR kód nie je podporovaný" + "Poskytovateľ vášho účtu nepodporuje %1$s." + "%1$s nie je podporovaný" + "Použite QR kód zobrazený na druhom zariadení." + "Skúste to znova" + "Nesprávny QR kód" + "Ak chcete pokračovať, musíte udeliť povolenie aplikácii %1$s používať fotoaparát vášho zariadenia." + "Povoľte prístup k fotoaparátu na naskenovanie QR kódu" + "Vyskytla sa neočakávaná chyba. Prosím, skúste to znova." + diff --git a/features/linknewdevice/impl/src/main/res/values-sv/translations.xml b/features/linknewdevice/impl/src/main/res/values-sv/translations.xml new file mode 100644 index 0000000000..8a1bef434a --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-sv/translations.xml @@ -0,0 +1,38 @@ + + + "Skanna QR-koden" + "Skanna QR-koden med den här enheten" + "Redo att skanna" + "Din kontoleverantör stöder inte %1$s." + "%1$s stöds inte" + "QR-kod stöds inte" + "Inloggningen avbröts på den andra enheten." + "Inloggningsförfrågan avbröts" + "Inloggningen har löpt ut. Vänligen försök igen." + "Inloggningen slutfördes inte i tid" + "Välj %1$s" + "En säker anslutning kunde inte göras till den nya enheten. Dina befintliga enheter är fortfarande säkra och du behöver inte oroa dig för dem." + "Nu då?" + "Pröva att logga in igen med en QR-kod ifall detta skulle vara ett nätverksproblem" + "Om du stöter på samma problem, prova ett annat wifi-nätverk eller använd din mobildata istället för wifi" + "Om det inte fungerar, logga in manuellt" + "Anslutningen är inte säker" + "Inloggningen avbröts på den andra enheten." + "Inloggningsförfrågan avbröts" + "Inloggningen avvisades på den andra enheten." + "Inloggning avvisad" + "Inloggningen har löpt ut. Vänligen försök igen." + "Inloggningen slutfördes inte i tid" + "Din andra enhet stöder inte inloggning i %s med en QR-kod. + +Prova att logga in manuellt eller skanna QR-koden med en annan enhet." + "QR-kod stöds inte" + "Din kontoleverantör stöder inte %1$s." + "%1$s stöds inte" + "Använd QR-koden som visas på den andra enheten." + "Försök igen" + "Fel QR-kod" + "Du måste ge tillstånd för %1$s att använda enhetens kamera för att kunna fortsätta." + "Tillåt kameraåtkomst för att skanna QR-koden" + "Ett oväntat fel inträffade. Vänligen försök igen." + diff --git a/features/linknewdevice/impl/src/main/res/values-tr/translations.xml b/features/linknewdevice/impl/src/main/res/values-tr/translations.xml new file mode 100644 index 0000000000..2d3bebcad8 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-tr/translations.xml @@ -0,0 +1,38 @@ + + + "QR kodunu tara" + "QR kodunu bu cihazla tarayın" + "Taramaya hazır" + "Hesap sağlayıcınız %1$s desteklemiyor." + "%1$s desteklenmiyor" + "QR kodu desteklenmiyor" + "Oturum açma işlemi diğer cihazda iptal edildi." + "Oturum açma isteği iptal edildi" + "Oturum açma süresi doldu. Lütfen tekrar deneyin." + "Oturum açma işlemi zamanında tamamlanmadı" + "Seç %1$s" + "Yeni cihaza güvenli bir bağlantı kurulamadı. Mevcut cihazlarınız hala güvende ve onlar için endişelenmenize gerek yok." + "Şimdi ne olacak?" + "Bunun bir ağ sorunu olması ihtimaline karşı bir QR koduyla tekrar oturum açmayı deneyin" + "Aynı sorunla karşılaşırsanız, farklı bir wifi ağı deneyin veya wifi yerine mobil verinizi kullanın" + "Bu işe yaramazsa, manuel olarak oturum açın" + "Bağlantı güvenli değil" + "Oturum açma işlemi diğer cihazda iptal edildi." + "Oturum açma isteği iptal edildi" + "Diğer cihazda oturum açma işlemi reddedildi." + "Oturum açma reddedildi" + "Oturum açma süresi doldu. Lütfen tekrar deneyin." + "Oturum açma işlemi zamanında tamamlanmadı" + "Diğer cihazınız %s QR koduyla oturum açmayı desteklemiyor. + +Manuel olarak oturum açmayı deneyin veya QR kodunu başka bir cihazla tarayın." + "QR kodu desteklenmiyor" + "Hesap sağlayıcınız %1$s desteklemiyor." + "%1$s desteklenmiyor" + "Diğer cihazda gösterilen QR kodunu kullan." + "Tekrar deneyin" + "Yanlış QR kodu" + "Devam etmek için %1$s cihazınızın kamerasını kullanmasına izin vermeniz gerekir." + "QR kodunu taramak için kamera erişimine izin verin" + "Beklenmeyen bir hata oluştu. Lütfen tekrar deneyin." + diff --git a/features/linknewdevice/impl/src/main/res/values-uk/translations.xml b/features/linknewdevice/impl/src/main/res/values-uk/translations.xml new file mode 100644 index 0000000000..e7104a914d --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-uk/translations.xml @@ -0,0 +1,38 @@ + + + "Зіскануйте QR-код" + "Зіскануйте QR-код цим пристроєм" + "Готовий до сканування" + "Постачальник вашого облікового запису не підтримує %1$s." + "%1$s не підтримується" + "QR-код не підтримується" + "Вхід було скасовано на іншому пристрої." + "Запит на вхід скасовано" + "Термін входу сплив. Будь ласка, спробуйте ще раз." + "Вхід не було завершено вчасно" + "Виберіть %1$s" + "Не вдалося встановити безпечне з\'єднання з новим пристроєм. Ваші наявні пристрої досі в безпеці, і вам не потрібно про них турбуватися." + "Що тепер?" + "Спробуйте увійти ще раз за допомогою QR-коду, якщо це була проблема з мережею" + "Якщо ви зіткнулися з тією ж проблемою, спробуйте іншу мережу Wi-Fi або використовуйте мобільний інтернет замість Wi-Fi" + "Якщо це не спрацює, увійдіть вручну" + "З\'єднання не безпечне" + "Вхід було скасовано на іншому пристрої." + "Запит на вхід скасовано" + "Вхід був відхилений на іншому пристрої." + "Вхід відхилено" + "Термін входу сплив. Будь ласка, спробуйте ще раз." + "Вхід не було завершено вчасно" + "Ваш інший пристрій не підтримує вхід у %s за допомогою QR-коду. + +Спробуйте ввійти вручну або відскануйте QR-код за допомогою іншого пристрою." + "QR-код не підтримується" + "Постачальник вашого облікового запису не підтримує %1$s." + "%1$s не підтримується" + "Використовуйте QR-код, показаний на іншому пристрої." + "Спробуйте ще раз" + "Неправильний QR-код" + "Вам потрібно дати дозвіл %1$s на використання камери вашого пристрою, щоб продовжити." + "Надайте доступ до камери, щоб сканувати QR-код" + "Сталася несподівана помилка. Будь ласка, спробуйте ще раз." + diff --git a/features/linknewdevice/impl/src/main/res/values-ur/translations.xml b/features/linknewdevice/impl/src/main/res/values-ur/translations.xml new file mode 100644 index 0000000000..54d2c2e401 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-ur/translations.xml @@ -0,0 +1,38 @@ + + + "کیو آر رمز مسح ضوئی کریں" + "اس آلے کے ساتھ کیو آر رمز مسح ضوئی کریں" + "مسح ضوئی کیلئے تیار" + "آپ کا کھاتہ فراہم کنندہ %1$s کا تعاون نہیں کرتا۔" + "%1$s تعاون یافتہ نہیں" + "کر رمز غیر تعاون یافتہ" + "دوسرے آلے پر دخول منسوخ کر دیا گیا تھا۔" + "دخول کی درخواست منسوخ" + "دخول کی میعاد ختم۔ برائے مہربانی دوبارہ کوشش کریں۔" + "دخول وقت پر مکمل نہیں ہوا تھا" + "%1$s منتخب کریں" + "نئے آلے سے محفوظ اتصال نہیں بنایا جا سکا۔ آپ کے موجودہ آلات اب بھی محفوظ ہیں اور آپ کو ان کے بارے میں فکر کرنے کی ضرورت نہیں ہے۔" + "اب کیا؟" + "اگر یہ شبکہ کا مسئلہ تھا تو کیو آر رمز کے ساتھ دوبارہ داخل ہونے کی کوشش کریں۔" + "اگر آپ کو بھی یہی مسئلہ درپیش ہو، تو کوئی دوسرا وائی فائی شبکہ آزمائیں یا وائی فائی کے بجائے اپنے محمول بیانات استعمال کریں۔" + "اگر یہ کام نہ کرے، تو دستی طور پر داخل ہوں" + "اتصال محفوظ نہیں" + "دوسرے آلے پر دخول منسوخ کر دیا گیا تھا۔" + "دخول کی درخواست منسوخ" + "دوسرے آلہ پر دخول کو مسترد کر دیا گیا تھا۔" + "دخول مسترد کیا گیا" + "دخول کی میعاد ختم۔ برائے مہربانی دوبارہ کوشش کریں۔" + "دخول وقت پر مکمل نہیں ہوا تھا" + "آپ کا دوسرا آلہ کیو آر رمز کے ساتھ %s میں دخول کا تعاون نہیں کرتا۔ + +دستی طور پر داخل ہونے کی کوشش کریں ، یا کسی دوسرے آلے سے کیو آر رمز مسح ضوئی کریں۔" + "کر رمز غیر تعاون یافتہ" + "آپ کا کھاتہ فراہم کنندہ %1$s کا تعاون نہیں کرتا۔" + "%1$s تعاون یافتہ نہیں" + "دوسرے آلے پر دکھایا گیا کیو آر رمز استعمال کریں۔" + "دوبارہ کوشش کریں" + "غلط کیو آر رمز" + "جاری رکھنے کے لیے آپ %1$s کو اپنے آلے کا تصویرگر استعمال کرنے کی اجازت دینے کی ضرورت ہے۔" + "کیو آر رمز کو مسح ضوئی کرنے کے لئے تصویرگر تک رسائی کی اجازت دیں" + "ایک غیر متوقع نقص واقع ہوا۔ برائے مہربانی دوبارہ کوشش کریں۔" + diff --git a/features/linknewdevice/impl/src/main/res/values-uz/translations.xml b/features/linknewdevice/impl/src/main/res/values-uz/translations.xml new file mode 100644 index 0000000000..d2f3b7a865 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-uz/translations.xml @@ -0,0 +1,38 @@ + + + "QR kodni skanerlash" + "Bu qurilma bilan QR kodni skanerlang" + "Skanerlashga tayyor" + "Hisob provayderingiz %1$s bilan ishlamaydi." + "%1$s qoʻllab-quvvatlanmaydi" + "QR kod qoʻllab-quvvatlanmaydi" + "Boshqa qurilmadan hisobga kirish bekor qilindi." + "Tizimga kirish soʻrovi bekor qilindi" + "Kirish muddati tugagan. Iltimos, qayta urinib koʻring." + "Kirish oʻz vaqtida tugallanmagan" + "%1$sʼni tanlang" + "Yangi qurilmaga xavfsiz ulanish amalga oshirilmadi. Mavjud qurilmalaringiz hali ham xavfsiz va ular haqida qaygʻurishingiz shart emas." + "Endi nima?" + "Agar bu tarmoq muammosi boʻlsa, QR kod bilan qayta kiring" + "Xuddi shu muammoga duch kelsangiz, boshqa wifi tarmogʻini sinang yoki wifi oʻrniga mobil internetdan foydalaning" + "Agar bunisi ishlamasa, oddiy usulda kiring" + "Ulanish xavfsiz emas" + "Boshqa qurilmadan hisobga kirish bekor qilindi." + "Tizimga kirish soʻrovi bekor qilindi" + "Boshqa qurilmadan hisobga kirish bekor qilindi." + "Tizimga kirish rad etildi" + "Kirish muddati tugagan. Iltimos, qayta urinib koʻring." + "Kirish oʻz vaqtida tugallanmagan" + "Boshqa qurilmangiz %s hisobiga QR kod orqali kirishni qoʻllab-quvvatlamaydi. + +Oddiy usulda kiring yoki boshqa qurilma bilan QR kodni skanerlang." + "QR kod qoʻllab-quvvatlanmaydi" + "Hisob provayderingiz %1$s bilan ishlamaydi." + "%1$s qoʻllab-quvvatlanmaydi" + "Narigi qurilmada koʻrsatilgan QR koddan foydalaning." + "Qayta urinib ko\'ring" + "QR kod notoʻgʻri" + "Davom etish uchun %1$s qurilmangiz kamerasidan foydalanishiga ruxsat berishingiz kerak." + "QR kodni skanerlash uchun kameraga ruxsat bering" + "Kutilmagan xatolik yuz berdi. Qayta urining." + diff --git a/features/linknewdevice/impl/src/main/res/values-zh-rTW/translations.xml b/features/linknewdevice/impl/src/main/res/values-zh-rTW/translations.xml new file mode 100644 index 0000000000..9b3cd5ead5 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-zh-rTW/translations.xml @@ -0,0 +1,38 @@ + + + "掃描 QR code" + "使用此裝置掃描 QR code" + "準備掃描" + "您的帳號提供者不支援 %1$s。" + "不支援 %1$s" + "不支援 QR code" + "已在其他裝置上取消登入。" + "已取消登入請求" + "登入已過期。請再試一次。" + "未及時完成登入" + "選取 %1$s" + "無法與新裝置建立安全連線。您現有的裝置仍然安全,您不必擔心它們。" + "現在怎麼辦?" + "嘗試再次使用 QR code 登入以確認不是網路問題" + "如果遇到相同的問題,請嘗試使用其他 wifi 網路或您的行動數據" + "若無法運作,請手動登入" + "連線不安全" + "已在其他裝置上取消登入。" + "已取消登入請求" + "其他裝置拒絕登入。" + "已拒絕登入" + "登入已過期。請再試一次。" + "未及時完成登入" + "您的其他裝置不支援使用 QR cpde 登入 %s。 + +嘗試手動登入,或是使用其他裝置掃描 QR code。" + "不支援 QR code" + "您的帳號提供者不支援 %1$s。" + "不支援 %1$s" + "使用其他裝置上顯示的 QR code。" + "再試一次" + "錯誤的 QR code" + "您必須授予 %1$s 權限以使用裝置相機才能繼續。" + "允許相機權限以掃描 QR code" + "發生意外錯誤。請再試一次。" + diff --git a/features/linknewdevice/impl/src/main/res/values-zh/translations.xml b/features/linknewdevice/impl/src/main/res/values-zh/translations.xml new file mode 100644 index 0000000000..99359cc695 --- /dev/null +++ b/features/linknewdevice/impl/src/main/res/values-zh/translations.xml @@ -0,0 +1,38 @@ + + + "扫描二维码" + "使用此设备扫描二维码" + "准备进行扫描" + "账户提供方不支持 %1$s." + "不支持 %1$s." + "不支持二维码" + "登录被另一台设备取消" + "登录请求已取消" + "登录已过期. 请重试." + "登录未及时完成" + "选择 %1$s" + "无法与新设备建立安全连接。您现有的设备仍然安全,无需担心。" + "现在怎么办?" + "如果这是网络问题,请尝试使用二维码再次登录" + "如果遇到同样的问题,请尝试使用不同的 WiFi 网络或使用移动数据代替 WiFi" + "如果不起作用,请手动登录" + "连接不安全" + "登录被另一台设备取消" + "登录请求已取消" + "其它设备未接受请求" + "登录被拒绝" + "登录已过期. 请重试." + "登录未及时完成" + "另一个设备不支持使用二维码登录 %s. + +尝试手动或使用另一个设备扫描二维码." + "不支持二维码" + "账户提供方不支持 %1$s." + "不支持 %1$s." + "使用其他设备上显示的二维码。" + "再试一次" + "二维码错误" + "您需要授予 %1$s 使用设备摄像头的权限才能继续。" + "允许摄像头权限以扫描 QR 码" + "发生了意外错误。请再试一次。" + diff --git a/features/login/impl/src/main/res/values-et/translations.xml b/features/login/impl/src/main/res/values-et/translations.xml index 3e3e6add37..0a1a99383d 100644 --- a/features/login/impl/src/main/res/values-et/translations.xml +++ b/features/login/impl/src/main/res/values-et/translations.xml @@ -60,6 +60,8 @@ "Sisselogimispäring on tühistatud" "Sisselogimisest on teises seadmes keeldutud." "Sisselogimisest on keeldutud" + "Sa ei pea enam midagi muud tegema." + "Sinu muu seade on juba sisse logitud" "Sisselogimine aegus. Palun proovi uuesti." "Sisselogimine jäi etteantud aja jooksul tegemata" "Sinu teine seade ei toeta %s sisselogimist QR-koodiga. diff --git a/features/login/impl/src/main/res/values-fr/translations.xml b/features/login/impl/src/main/res/values-fr/translations.xml index 946fec802e..3410e56ece 100644 --- a/features/login/impl/src/main/res/values-fr/translations.xml +++ b/features/login/impl/src/main/res/values-fr/translations.xml @@ -48,7 +48,7 @@ "Établissement d’une connexion sécurisée" "Aucune connexion sécurisée n’a pu être établie avec la nouvelle session. Vos sessions existantes sont toujours en sécurité et vous n’avez pas à vous en soucier." "Et maintenant ?" - "Essayez de vous connecter à nouveau à l’aide du code QR au cas où il s’agirait d’un problème réseau" + "Essayez de vous connecter à nouveau à l’aide du QR code au cas où il s’agirait d’un problème réseau" "Si vous rencontrez le même problème, essayez un autre réseau wifi ou utilisez vos données mobiles au lieu du wifi" "Si cela ne fonctionne pas, connectez-vous manuellement" "La connexion n’est pas sécurisée" @@ -62,8 +62,8 @@ "Connexion refusée" "Connexion expirée. Veuillez essayer à nouveau." "La connexion a pris trop de temps." - "Votre autre appareil ne supporte pas la connexion à %s avec un code QR. Essayer de vous connecter manuellement, ou scanner le code QR avec un autre appareil." - "Code QR non supporté" + "Votre autre appareil ne supporte pas la connexion à %s avec un QR code. Essayer de vous connecter manuellement, ou scanner le QR code avec un autre appareil." + "QR code non supporté" "Votre fournisseur de compte ne supporte pas %1$s." "%1$s n’est pas supporté" "Prêt à scanner" @@ -71,7 +71,7 @@ "Cliquez sur votre image de profil" "Choisissez %1$s" "“Associer une nouvelle session”" - "Scanner le code QR avec cet appareil" + "Scanner le QR code avec cet appareil" "Disponible uniquement si votre fournisseur de compte le supporte." "Ouvrez %1$s sur un autre appareil pour obtenir le QR code" "Scannez le QR code affiché sur l’autre appareil." @@ -79,7 +79,7 @@ "QR code erroné" "Accéder aux paramètres de l’appareil photo" "Vous devez autoriser %1$s à utiliser la camera de votre appareil pour continuer." - "Autoriser l’usage de la caméra pour scanner le code QR" + "Autoriser l’usage de la caméra pour scanner le QR code" "Scannez le QR code" "Recommencer" "Une erreur inattendue s’est produite. Veuillez réessayer." diff --git a/features/login/impl/src/main/res/values-hr/translations.xml b/features/login/impl/src/main/res/values-hr/translations.xml index 2c0251df66..efb1cbb016 100644 --- a/features/login/impl/src/main/res/values-hr/translations.xml +++ b/features/login/impl/src/main/res/values-hr/translations.xml @@ -60,6 +60,8 @@ "Zahtjev za prijavu je otkazan" "Prijava je odbijena na drugom uređaju." "Prijava je odbijena" + "Ne morate ništa drugo napraviti." + "Vaš drugi uređaj već je prijavljen" "Prijava je istekla. Pokušajte ponovno." "Prijava nije dovršena na vrijeme" "Vaš drugi uređaj ne podržava prijavu na %s pomoću QR koda. diff --git a/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml index 382372329b..31aee3436e 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml @@ -2,9 +2,12 @@ "Administrator" "Spær brugere" + "Skift indstillinger" "Fjern beskeder" "Medlem" "Invitér andre" + "Administrér gruppe" + "Administrer rum" "Administrer medlemmer" "Beskeder og indhold" "Moderator" @@ -14,6 +17,7 @@ "Skift rummets navn" "Skift emne for rummet" "Send beskeder" + "Tilladelser" "Redigér admins" "Du kan ikke fortryde denne handling. Du forfremmer brugeren til at have samme magtniveau som dig." "Tilføj Admin?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml index 4a2754c1e0..1c1f490580 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml @@ -38,6 +38,10 @@ "Sul on salvestamata muudatusi" "Kas salvestame muudatused?" "Suhtluskeeluga kasutajaid pole" + + "%1$d suhtluskeeluga kasutaja" + "%1$d suhtluskeeluga kasutajat" + "Palun kontrolli otsingusõna korrektsust ja proovi siis uuesti" "Otsingul „%1$s“ pole tulemusi" diff --git a/features/rolesandpermissions/impl/src/main/res/values-hr/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-hr/translations.xml index db31f8f985..7f24535124 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-hr/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-hr/translations.xml @@ -2,9 +2,12 @@ "Administrator" "Zabrana pristupa osobama" + "Promijeni postavke" "Uklanjanje poruka" "Član" "Pozivanje osoba" + "Upravljaj prostorom" + "Upravljaj sobama" "Upravljanje članovima" "Poruke i sadržaj" "Moderator" @@ -14,6 +17,7 @@ "Promjena imena" "Promjena teme" "Slanje poruka" + "Dopuštenja" "Uredi administratore" "Nećete moći poništiti ovu radnju. Postavit ćete da korisnik ima isti položaj kao i vi." "Dodati administratora?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-nb/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-nb/translations.xml index 65664c187a..41f475012f 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-nb/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-nb/translations.xml @@ -1,14 +1,16 @@ - "Kun for administratorer" + "Admin" "Forby folk" "Fjern meldinger" - "Inviter folk og godta forespørsler om å bli med" + "Medlem" + "Inviter folk" + "Administrer medlemmer" "Meldinger og innhold" - "Administratorer og moderatorer" - "Fjern folk og avslå forespørsler om å bli med" + "Moderator" + "Fjern folk" "Endre romavatar" - "Rediger rom" + "Rediger detaljer" "Endre romnavn" "Endre temaet til rommet" "Send meldinger" @@ -31,7 +33,7 @@ "Medlemmer" "Du har endringer som ikke er lagret." "Lagre endringer?" - "Det er ingen utestengte brukere i dette rommet." + "Det er ingen utestengte brukere." "%1$d person" "%1$d personer" @@ -43,8 +45,8 @@ "Fjern utestengelsen fra rommet" "Utestengt" "Medlemmer" - "Kun for administratorer" - "Administratorer og moderatorer" + "Admin" + "Moderator" "Eier" "Medlemmer av rommet" "Oppheve utestengelsen av %1$s" diff --git a/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml index 4d3be082dd..ac9ec710a2 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml @@ -2,9 +2,12 @@ "Administrator" "Interziceți persoane" + "Modificați setările" "Ștergeți mesajele" "Membru" "Invitați persoane" + "Gestionați spațiul" + "Gestionați camerele" "Gestionați membrii" "Mesaje și conținut" "Moderator" @@ -14,6 +17,7 @@ "Schimbă numele camerei" "Schimbați subiectul camerei" "Trimiteți mesaje" + "Permisiuni" "Editați administratorii" "Promovați utilizatorul să aibă același nivel de putere ca dumneavoastră. Nu veți putea anula această acțiune." "Adăugați administrator?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml index ad4832dfd0..d159fb03f9 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml @@ -2,9 +2,12 @@ "Správca" "Zakázať ľudí" + "Zmeniť nastavenia" "Odstrániť správy" "Člen" "Pozvať ľudí" + "Spravovať priestor" + "Spravovať miestnosti" "Spravovať členov" "Správy a obsah" "Moderátor" @@ -14,6 +17,7 @@ "Zmeniť názov miestnosti" "Zmeniť tému miestnosti" "Odoslať správy" + "Povolenia" "Upraviť správcov" "Túto akciu nebudete môcť vrátiť späť. Zvyšujete úroveň používateľa na rovnakú úroveň výkonu ako máte vy." "Pridať správcu?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml index f56210a29a..03f94969b5 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml @@ -4,11 +4,12 @@ "Odamlarni taqiqlash" "Xabarlarni olib tashlash" "Odamlarni taklif qiling va qo‘shilish so‘rovlarini qabul qiling" + "A’zolarni boshqarish" "Xabarlar va kontent" "Adminlar va moderatorlar" "Odamlarni olib tashlash va qoʻshilish soʻrovlarini rad etish" "Xona avatarini oʻzgartirish" - "Xonani tahrirlash" + "Tafsilotlarni tahrirlash" "Xona nomini oʻzgartirish" "Xona mavzusini almashtirish" "Xabarlar yuborish" diff --git a/features/roomdetails/impl/src/main/res/values-be/translations.xml b/features/roomdetails/impl/src/main/res/values-be/translations.xml index fe337177df..a986cd9789 100644 --- a/features/roomdetails/impl/src/main/res/values-be/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-be/translations.xml @@ -102,5 +102,4 @@ "Ролі і дазволы" "Папрасіце далучыцца" "Хто заўгодна" - "Хто заўгодна" diff --git a/features/roomdetails/impl/src/main/res/values-bg/translations.xml b/features/roomdetails/impl/src/main/res/values-bg/translations.xml index 4ea6d24af6..340f14a8f1 100644 --- a/features/roomdetails/impl/src/main/res/values-bg/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-bg/translations.xml @@ -93,7 +93,6 @@ "Членове на пространството" "Пространствата в момента не се поддържат" "Видима в директорията на обществените стаи" - "Всеки" "Кой може да чете историята" "Само за членове откакто са поканени" "Само за членове от избирането на тази опция" diff --git a/features/roomdetails/impl/src/main/res/values-da/translations.xml b/features/roomdetails/impl/src/main/res/values-da/translations.xml index 18e1246e98..9da1c66904 100644 --- a/features/roomdetails/impl/src/main/res/values-da/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-da/translations.xml @@ -151,7 +151,6 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Tillad, at dette rum kan findes ved at søge i %1$s fortegnelse over offentlige rum" "Gør det muligt at blive fundet ved søgninger i det offentlige register." "Synlig i det offentlige register" - "Enhver" "Hvem kan læse historikken?" "Kun medlemmer, efter de blev inviteret" "Kun medlemmer siden valg af denne mulighed" diff --git a/features/roomdetails/impl/src/main/res/values-el/translations.xml b/features/roomdetails/impl/src/main/res/values-el/translations.xml index a2deb1c706..9f481e8d46 100644 --- a/features/roomdetails/impl/src/main/res/values-el/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-el/translations.xml @@ -126,7 +126,6 @@ "Θα χρειαστείτε μια διεύθυνση αίθουσας για να την κάνετε ορατή στον κατάλογο." "Επιστρέψτε την εύρεση αυτής της αίθουσας με αναζήτηση στον κατάλογο %1$s δημοσίων αιθουσών" "Ορατή στον κατάλογο δημόσιων αιθουσών" - "Οποιοσδήποτε" "Ποιος μπορεί να διαβάσει το ιστορικό" "Μόνο μέλη από τη στιγμή που προσκλήθηκαν" "Μόνο για μέλη μετά από αυτήν την επιλογή" diff --git a/features/roomdetails/impl/src/main/res/values-es/translations.xml b/features/roomdetails/impl/src/main/res/values-es/translations.xml index c179a4d16e..43a42bb274 100644 --- a/features/roomdetails/impl/src/main/res/values-es/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-es/translations.xml @@ -126,7 +126,6 @@ No recomendamos habilitar el cifrado para las salas que cualquiera pueda encontr "Necesitarás una dirección de sala para que sea visible en el directorio." "Permite encontrar esta sala buscando en el directorio de salas públicas de %1$s" "Visible en el directorio de salas públicas" - "Cualquiera" "Quién puede leer el historial" "Solo participantes desde que fueron invitados" "Solo participantes desde que se selecciona esta opción" diff --git a/features/roomdetails/impl/src/main/res/values-et/translations.xml b/features/roomdetails/impl/src/main/res/values-et/translations.xml index f4199cb10b..1c45e12cef 100644 --- a/features/roomdetails/impl/src/main/res/values-et/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-et/translations.xml @@ -71,6 +71,10 @@ "Teema" "Uuendame jututuba…" "Suhtluskeeluga kasutajaid pole" + + "%1$d suhtluskeeluga kasutaja" + "%1$d suhtluskeeluga kasutajat" + "Palun kontrolli otsingusõna korrektsust ja proovi siis uuesti" "Otsingul „%1$s“ pole tulemusi" @@ -138,7 +142,7 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Krüptimine" "Võta läbiv krüptimine kasutusele" "Kõik võivad jututoaga liituda" - "Kõik" + "Kõik kasutajad" "Vali kogukonnad, mille liikmed saavad selle jututoaga liituda ilma kutseta. %1$s" "Halda kogukondi" "Liituda saab vaid kutse olemasolul" @@ -153,10 +157,11 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Võimalda leida seda jututuba avalikust kataloogist otsides „%1$s“" "Luba leitavus avaliku kataloogi otsingust." "Nähtav avalikus kataloogis" - "Kõik" + "Kõik (ajalugu on avalik)" + "Muudatused ei mõjuta varasemaid sõnumeid, ainult uusi. %1$s" "Kes võivad lugeda jututoa ajalugu" "Liikmed peale kutse saamist" - "Liikmed peale selle valiku sisselülitamist" + "Liikmed (terviklik ajalugu)" "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada. Lisaks võid sa jututoa avaldada oma koduserveri avalikus jututubade kataloogis." "Jututoa avaldamine" diff --git a/features/roomdetails/impl/src/main/res/values-eu/translations.xml b/features/roomdetails/impl/src/main/res/values-eu/translations.xml index 5d0f61fb40..95d6b17daf 100644 --- a/features/roomdetails/impl/src/main/res/values-eu/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-eu/translations.xml @@ -112,7 +112,6 @@ "Gaur-gaurkoz ez da guneekin bateragarria" "Gelaren helbidea" "Gela publikoen direktorioan ikusgai" - "Edonork" "Nork irakur dezake historia" "Kideek bakarrik, gonbidatu zituztenetik" "Kideek bakarrik, aukera hau hautatu zenetik" diff --git a/features/roomdetails/impl/src/main/res/values-hr/translations.xml b/features/roomdetails/impl/src/main/res/values-hr/translations.xml index b6ed2e142f..0edf4dadbb 100644 --- a/features/roomdetails/impl/src/main/res/values-hr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-hr/translations.xml @@ -160,10 +160,11 @@ Ne preporučujemo omogućavanje šifriranja za sobe koje svatko može pronaći i "Omogući pronalazak ove sobe pretraživanjem %1$s javnog direktorija soba" "Omogući pronalazak pretraživanjem javnog direktorija." "Vidljivo u javnom direktoriju" - "Svatko" + "Svatko (povijest je javna)" + "Promjene neće utjecati na prethodne poruke, samo na nove. %1$s" "Tko zna čitati povijest" "Samo za članove nakon što su pozvani" - "Samo za članove nakon što se odabere ova mogućnost" + "Članovi (cjelokupna povijest)" "Adrese soba služe za pronalaženje i pristup sobama. Time se također osigurava jednostavno dijeljenje sobe s drugim korisnicima. Možete odabrati objavljivanje svoje sobe u javnom direktoriju soba na matičnom poslužitelju." "Objavljivanje sobe" diff --git a/features/roomdetails/impl/src/main/res/values-in/translations.xml b/features/roomdetails/impl/src/main/res/values-in/translations.xml index 097cd371f6..34703d6c01 100644 --- a/features/roomdetails/impl/src/main/res/values-in/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-in/translations.xml @@ -125,7 +125,6 @@ Kami tidak menyarankan untuk mengaktifkan enkripsi untuk ruangan yang dapat dite "Anda akan memerlukan alamat ruangan untuk membuatnya terlihat dalam direktori." "Izinkan ruangan ini ditemukan dengan mencari direktori ruangan %1$s publik" "Terlihat di direktori ruangan publik" - "Siapa pun" "Siapa yang bisa membaca riwayat" "Hanya anggota sejak mereka diundang" "Hanya anggota sejak memilih opsi ini" diff --git a/features/roomdetails/impl/src/main/res/values-ko/translations.xml b/features/roomdetails/impl/src/main/res/values-ko/translations.xml index 22f3fe99e6..196656408c 100644 --- a/features/roomdetails/impl/src/main/res/values-ko/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ko/translations.xml @@ -132,7 +132,6 @@ "디렉토리에 표시하려면 방 주소가 필요합니다." "%1$s 공개 방 디렉토리에서 이 방을 검색할 수 있도록 허용합니다" "공개 룸 디렉토리에 표시됨" - "누구나" "누가 기록을 읽을 수 있는가" "초대받은 회원만 이용 가능합니다" "이 옵션을 선택한 회원만 이용 가능합니다." diff --git a/features/roomdetails/impl/src/main/res/values-nb/translations.xml b/features/roomdetails/impl/src/main/res/values-nb/translations.xml index 7d23507a8b..45499ee3c9 100644 --- a/features/roomdetails/impl/src/main/res/values-nb/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-nb/translations.xml @@ -1,19 +1,21 @@ - "Du trenger en adresse til rommet for å gjøre det synlig i katalogen." - "Romadresse" + "Du trenger en adresse for å gjøre den synlig i den offentlige katalogen." + "Rediger adresse" "Det oppstod en feil under oppdatering av varslingsinnstillingen." "Hjemmeserveren din støtter ikke dette alternativet i krypterte rom, og det kan hende at du ikke blir varslet i enkelte rom." "Avstemninger" - "Kun for administratorer" + "Admin" "Forby folk" "Fjern meldinger" - "Inviter folk og godta forespørsler om å bli med" + "Medlem" + "Inviter folk" + "Administrer medlemmer" "Meldinger og innhold" - "Administratorer og moderatorer" - "Fjern folk og avslå forespørsler om å bli med" + "Moderator" + "Fjern folk" "Endre romavatar" - "Rediger rom" + "Rediger detaljer" "Endre romnavn" "Endre temaet til rommet" "Send meldinger" @@ -40,7 +42,7 @@ "Kryptert" "Ikke kryptert" "Offentlig rom" - "Rediger rom" + "Rediger detaljer" "Det oppstod en ukjent feil, og informasjonen kunne ikke endres." "Kan ikke oppdatere rommet" "Meldingene er krypterte. Det er bare du og mottakerne som har de unike nøklene til å låse dem opp." @@ -68,7 +70,7 @@ "Informasjon om rommet" "Emne" "Oppdaterer rommet …" - "Det er ingen utestengte brukere i dette rommet." + "Det er ingen utestengte brukere." "%1$d person" "%1$d personer" @@ -80,8 +82,8 @@ "Fjern utestengelsen fra rommet" "Utestengt" "Medlemmer" - "Kun for administratorer" - "Administratorer og moderatorer" + "Admin" + "Moderator" "Eier" "Medlemmer av rommet" "Oppheve utestengelsen av %1$s" @@ -114,8 +116,8 @@ "Roller" "Romdetaljer" "Roller og tillatelser" - "Legg til romadresse" - "Alle kan be om å bli med i rommet, men en administrator eller moderator må godta forespørselen." + "Legg til adresse" + "Alle må be om tilgang." "Be om å bli med" "Ja, aktiver kryptering" "Når kryptering for et rom er aktivert, kan den ikke deaktiveres. Meldingshistorikken vil bare være synlig for rommedlemmer siden de ble invitert eller siden de ble med i rommet. @@ -125,22 +127,24 @@ Vi anbefaler ikke å aktivere kryptering for rom som hvem som helst kan finne og "Når kryptering er aktivert, kan det ikke deaktiveres." "Kryptering" "Aktiver ende-til-ende-kryptering" - "Alle kan finne og bli med" + "Alle kan bli med." "Alle" - "Folk kan bare bli med hvis de er invitert" + "Bare inviterte personer kan bli med." "Kun for inviterte" - "Tilgang til rom" + "Tilgang" "Medlemmer av område" "Områder støttes ikke for øyeblikket" - "Du trenger en adresse til rommet for å gjøre det synlig i katalogen." + "Du trenger en adresse for å gjøre den synlig i den offentlige katalogen." + "Adresse" "Tillat at dette rommet blir funnet ved å søke %1$s offentlig romkatalog" - "Synlig i offentlig romkatalog" - "Alle" + "Synlig i offentlig katalog" + "Alle (historikken er offentlig)" "Hvem kan lese historikk" - "Medlemmer bare siden de ble invitert" - "Kun medlemmer siden du valgte dette alternativet" + "Medlemmer siden de ble invitert" + "Medlemmer (full historikk)" "Romadresser er måter å finne og få tilgang til rom på. Dette sikrer også at du enkelt kan dele rommet ditt med andre. Du kan velge å publisere rommet ditt i hjemeserverens offentlige romkatalog." "Publisering av rom" + "Synlighet" "Sikkerhet og personvern" diff --git a/features/roomdetails/impl/src/main/res/values-nl/translations.xml b/features/roomdetails/impl/src/main/res/values-nl/translations.xml index 73e7b7f8c6..f780437cd5 100644 --- a/features/roomdetails/impl/src/main/res/values-nl/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-nl/translations.xml @@ -101,5 +101,4 @@ "Rollen en rechten" "Vraag om toe te treden" "Iedereen" - "Iedereen" diff --git a/features/roomdetails/impl/src/main/res/values-pl/translations.xml b/features/roomdetails/impl/src/main/res/values-pl/translations.xml index a24774c736..620bd0d674 100644 --- a/features/roomdetails/impl/src/main/res/values-pl/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pl/translations.xml @@ -137,7 +137,7 @@ Odradzamy włączanie szyfrowania dla pokoi, które każdy może znaleźć i do "Adres pokoju" "Zezwól na znalezienie tego pokoju wyszukując %1$s w katalogu pokoi publicznych" "Widoczny w katalogu pokoi publicznych" - "Wszyscy" + "Ktokolwiek" "Kto może czytać historię" "Od momentu kiedy członkowie zostali zaproszeni" "Członkowie od momentu włączenia tej opcji" diff --git a/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml b/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml index da19da98ed..0b65ee0f63 100644 --- a/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml @@ -129,8 +129,10 @@ "Detalhes da sala" "Cargos e permissões" "Adicionar endereço" + "Qualquer um nos espaços autorizados podem entrar, mas todos os outros devem pedir acesso." "Qualquer um pode pedir acesso, mas um administrador terá que aceitar o pedido." "Pedir para entrar" + "Qualquer um em %1$s pode entrar, mas todos os outros devem pedir acesso." "Sim, ativar a criptografia" "Uma vez ativada, a criptografia de uma sala não pode ser desativada. O histórico de mensagens só será visível para os membros da sala desde que foram convidados ou desde que entraram na sala. Ninguém além dos membros da sala poderá ler as mensagens. Isso pode impedir que os bots e as pontes funcionem corretamente. @@ -141,9 +143,13 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Ativar a criptografia de ponta a ponta" "Qualquer um pode entrar" "Qualquer pessoa" + "Escolha os espaços dos quais os membros podem entrar nesta sala sem um convite. %1$s" + "Gerenciar espaços" "Apenas pessoas convidadas podem entrar." "Privado" "Acesso" + "Qualquer um em espaços autorizados podem entrar." + "Qualquer um em %1$s pode entrar." "Membros do espaço" "No momento, não há suporte aos espaços" "Você precisará de um endereço para torná-la visível no diretório." @@ -151,10 +157,9 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Permitir que esta sala seja encontrada pesquisando diretório de salas públicas de %1$s" "Permite que seja encontrada ao buscar no diretório público." "Visível no diretório público" - "Qualquer pessoa" "Quem pode ler o histórico" - "Somente membros, desde que foram convidados" - "Somente para membros após selecionar esta opção" + "Membros desde o convite" + "Membros (histórico completo)" "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhar facilmente sua sala com outras pessoas. Você pode optar por publicar sua sala no diretório público de salas do seu servidor-casa." "Publicação da sala" diff --git a/features/roomdetails/impl/src/main/res/values-ro/translations.xml b/features/roomdetails/impl/src/main/res/values-ro/translations.xml index effa5c3204..854d3643ce 100644 --- a/features/roomdetails/impl/src/main/res/values-ro/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ro/translations.xml @@ -160,7 +160,6 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Permiteți găsirea acestei camere prin căutarea în directorul de camere publice al %1$s" "Permiteți găsirea prin căutarea în directorul public." "Vizibilă în directorul de camere publice" - "Oricine" "Cine poate citi mesajele anterioare" "Doar pentru membri, de la momentul în care au fost invitați" "Doar pentru membri, după selectarea acestei opțiuni" diff --git a/features/roomdetails/impl/src/main/res/values-sv/translations.xml b/features/roomdetails/impl/src/main/res/values-sv/translations.xml index 2dc590c2f4..1cc0d81715 100644 --- a/features/roomdetails/impl/src/main/res/values-sv/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-sv/translations.xml @@ -133,7 +133,6 @@ Vi rekommenderar inte att aktivera kryptering för rum som vem som helst kan hit "Du behöver en rumsadress för att göra den synlig i katalogen." "Tillåt att detta rum hittas genom att söka i den offentliga rumskatalogen på %1$s" "Synlig i katalogen för offentliga rum" - "Vem som helst" "Vem kan läsa historik" "Endast medlemmar sedan de bjöds in" "Endast medlemmar sedan det här alternativet har valts" diff --git a/features/roomdetails/impl/src/main/res/values-uk/translations.xml b/features/roomdetails/impl/src/main/res/values-uk/translations.xml index 57a604bfe8..fddcca05d0 100644 --- a/features/roomdetails/impl/src/main/res/values-uk/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-uk/translations.xml @@ -135,7 +135,7 @@ "Адреса кімнати" "Дозвольте, щоб цю кімнату можна було знайти за допомогою пошуку в каталозі загальнодоступних кімнат %1$s " "Видима в каталозі загальнодоступних кімнат" - "Кожний" + "Будь-хто" "Хто може читати історію" "Лише учасники з моменту запрошення" "Лише учасники після вибору цього параметра" diff --git a/features/roomdetails/impl/src/main/res/values-uz/translations.xml b/features/roomdetails/impl/src/main/res/values-uz/translations.xml index 401d015735..466bf18b8b 100644 --- a/features/roomdetails/impl/src/main/res/values-uz/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-uz/translations.xml @@ -9,11 +9,12 @@ "Odamlarni taqiqlash" "Xabarlarni olib tashlash" "Odamlarni taklif qiling va qo‘shilish so‘rovlarini qabul qiling" + "A’zolarni boshqarish" "Xabarlar va kontent" "Adminlar va moderatorlar" "Odamlarni olib tashlash va qoʻshilish soʻrovlarini rad etish" "Xona avatarini oʻzgartirish" - "Xonani tahrirlash" + "Tafsilotlarni tahrirlash" "Xona nomini oʻzgartirish" "Xona mavzusini almashtirish" "Xabarlar yuborish" @@ -40,7 +41,7 @@ "Shifrlangan" "Shifrlanmagan" "Jamoat xonasi" - "Xonani tahrirlash" + "Tafsilotlarni tahrirlash" "Nomaʼlum xatolik yuz berdi va maʼlumotni oʻzgartirib boʻlmadi." "Xonani yangilab bo‘lmadi" "Xabarlar qulflar bilan himoyalangan. Faqat siz va qabul qiluvchilar ularni qulfdan chiqarish uchun noyob kalitlarga ega." @@ -132,7 +133,6 @@ Shu sababli, har kim topishi va qo‘shilishi mumkin bo‘lgan xonalar uchun shi "Katalogda ko‘rinadigan qilish uchun xona manzili kerak bo‘ladi." "Bu xonani %1$s umumiy xonalar ro‘yxatidan qidirib topish imkoniyatini berish" "Umumiy xona ro‘yxatida ko‘rinadi" - "Har kim" "Tarixni kim o‘qiy oladi" "Taklif qilinganidan buyon faqat a’zolar" "A’zolar faqat bu parametr tanlanganidan keyin" diff --git a/features/roomdetailsedit/impl/src/main/res/values-nb/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-nb/translations.xml index d5095ae854..e660c40e7b 100644 --- a/features/roomdetailsedit/impl/src/main/res/values-nb/translations.xml +++ b/features/roomdetailsedit/impl/src/main/res/values-nb/translations.xml @@ -1,6 +1,6 @@ - "Rediger rom" + "Rediger detaljer" "Det oppstod en ukjent feil, og informasjonen kunne ikke endres." "Kan ikke oppdatere rommet" "Oppdaterer rommet …" diff --git a/features/roomdetailsedit/impl/src/main/res/values-uz/translations.xml b/features/roomdetailsedit/impl/src/main/res/values-uz/translations.xml index e3ab69c86d..cd11813116 100644 --- a/features/roomdetailsedit/impl/src/main/res/values-uz/translations.xml +++ b/features/roomdetailsedit/impl/src/main/res/values-uz/translations.xml @@ -1,6 +1,6 @@ - "Xonani tahrirlash" + "Tafsilotlarni tahrirlash" "Nomaʼlum xatolik yuz berdi va maʼlumotni oʻzgartirib boʻlmadi." "Xonani yangilab bo‘lmadi" "Xona yangilanmoqda…" diff --git a/features/roommembermoderation/impl/src/main/res/values-nb/translations.xml b/features/roommembermoderation/impl/src/main/res/values-nb/translations.xml index 4507fce49c..392b271a1a 100644 --- a/features/roommembermoderation/impl/src/main/res/values-nb/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-nb/translations.xml @@ -9,7 +9,7 @@ "De vil kunne bli med i dette rommet igjen hvis de blir invitert." "Er du sikker på at du vil fjerne dette medlemmet?" "Vis profil" - "Fjern fra rommet" + "Fjern bruker" "Fjerne medlem og utestenge fra å bli med i fremtiden?" "Fjerner %1$s…" "Fjern utestengelsen fra rommet" diff --git a/features/roommembermoderation/impl/src/main/res/values-uz/translations.xml b/features/roommembermoderation/impl/src/main/res/values-uz/translations.xml index 90dfae8ce3..9b8c57ede3 100644 --- a/features/roommembermoderation/impl/src/main/res/values-uz/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-uz/translations.xml @@ -9,7 +9,7 @@ "Agar taklif qilinsa, ular bu xonaga qayta qo‘shilishlari mumkin." "Haqiqatan ham bu a’zoni olib tashlaysizmi?" "Profilni koʻrish" - "Xonadan olib tashlash" + "Foydalanuvchini olib tashlash" "Aʻzo oʻchirilsinmi va kelgusida qoʻshilish taqiqlansinmi?" "Oʻchirish %1$s …" "Xonadan taqiqni olib tashlash" diff --git a/features/securityandprivacy/impl/src/main/res/values-be/translations.xml b/features/securityandprivacy/impl/src/main/res/values-be/translations.xml index a1e1745100..4587ac191c 100644 --- a/features/securityandprivacy/impl/src/main/res/values-be/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-be/translations.xml @@ -2,5 +2,4 @@ "Папрасіце далучыцца" "Хто заўгодна" - "Хто заўгодна" diff --git a/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml b/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml index 9917a7146f..348c9d491f 100644 --- a/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml @@ -14,7 +14,6 @@ "Членове на пространството" "Пространствата в момента не се поддържат" "Видима в директорията на обществените стаи" - "Всеки" "Кой може да чете историята" "Само за членове откакто са поканени" "Само за членове от избирането на тази опция" diff --git a/features/securityandprivacy/impl/src/main/res/values-da/translations.xml b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml index f7ab1b6ce0..12ab70d44e 100644 --- a/features/securityandprivacy/impl/src/main/res/values-da/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml @@ -25,7 +25,6 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Tillad, at dette rum kan findes ved at søge i %1$s fortegnelse over offentlige rum" "Gør det muligt at blive fundet ved søgninger i det offentlige register." "Synlig i det offentlige register" - "Enhver" "Hvem kan læse historikken?" "Kun medlemmer, efter de blev inviteret" "Kun medlemmer siden valg af denne mulighed" diff --git a/features/securityandprivacy/impl/src/main/res/values-el/translations.xml b/features/securityandprivacy/impl/src/main/res/values-el/translations.xml index 1946bae8b2..c9a65b058d 100644 --- a/features/securityandprivacy/impl/src/main/res/values-el/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-el/translations.xml @@ -23,7 +23,6 @@ "Θα χρειαστείτε μια διεύθυνση αίθουσας για να την κάνετε ορατή στον κατάλογο." "Επιστρέψτε την εύρεση αυτής της αίθουσας με αναζήτηση στον κατάλογο %1$s δημοσίων αιθουσών" "Ορατή στον κατάλογο δημόσιων αιθουσών" - "Οποιοσδήποτε" "Ποιος μπορεί να διαβάσει το ιστορικό" "Μόνο μέλη από τη στιγμή που προσκλήθηκαν" "Μόνο για μέλη μετά από αυτήν την επιλογή" diff --git a/features/securityandprivacy/impl/src/main/res/values-es/translations.xml b/features/securityandprivacy/impl/src/main/res/values-es/translations.xml index 2799d9d196..c63bee50ef 100644 --- a/features/securityandprivacy/impl/src/main/res/values-es/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-es/translations.xml @@ -23,7 +23,6 @@ No recomendamos habilitar el cifrado para las salas que cualquiera pueda encontr "Necesitarás una dirección de sala para que sea visible en el directorio." "Permite encontrar esta sala buscando en el directorio de salas públicas de %1$s" "Visible en el directorio de salas públicas" - "Cualquiera" "Quién puede leer el historial" "Solo participantes desde que fueron invitados" "Solo participantes desde que se selecciona esta opción" diff --git a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml index f6986ce49b..8d74c35733 100644 --- a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml @@ -16,7 +16,7 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Krüptimine" "Võta läbiv krüptimine kasutusele" "Kõik võivad jututoaga liituda" - "Kõik" + "Kõik kasutajad" "Vali kogukonnad, mille liikmed saavad selle jututoaga liituda ilma kutseta. %1$s" "Halda kogukondi" "Liituda saab vaid kutse olemasolul" @@ -31,10 +31,11 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Võimalda leida seda jututuba avalikust kataloogist otsides „%1$s“" "Luba leitavus avaliku kataloogi otsingust." "Nähtav avalikus kataloogis" - "Kõik" + "Kõik (ajalugu on avalik)" + "Muudatused ei mõjuta varasemaid sõnumeid, ainult uusi. %1$s" "Kes võivad lugeda jututoa ajalugu" "Liikmed peale kutse saamist" - "Liikmed peale selle valiku sisselülitamist" + "Liikmed (terviklik ajalugu)" "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada. Lisaks võid sa jututoa avaldada oma koduserveri avalikus jututubade kataloogis." "Jututoa avaldamine" diff --git a/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml b/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml index c66b6769ce..7024f1c40b 100644 --- a/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml @@ -13,7 +13,6 @@ "Gaur-gaurkoz ez da guneekin bateragarria" "Gelaren helbidea" "Gela publikoen direktorioan ikusgai" - "Edonork" "Nork irakur dezake historia" "Kideek bakarrik, gonbidatu zituztenetik" "Kideek bakarrik, aukera hau hautatu zenetik" diff --git a/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml index 02fada87db..401fe806f8 100644 --- a/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml @@ -31,10 +31,11 @@ Ne preporučujemo omogućavanje šifriranja za sobe koje svatko može pronaći i "Omogući pronalazak ove sobe pretraživanjem %1$s javnog direktorija soba" "Omogući pronalazak pretraživanjem javnog direktorija." "Vidljivo u javnom direktoriju" - "Svatko" + "Svatko (povijest je javna)" + "Promjene neće utjecati na prethodne poruke, samo na nove. %1$s" "Tko zna čitati povijest" "Samo za članove nakon što su pozvani" - "Samo za članove nakon što se odabere ova mogućnost" + "Članovi (cjelokupna povijest)" "Adrese soba služe za pronalaženje i pristup sobama. Time se također osigurava jednostavno dijeljenje sobe s drugim korisnicima. Možete odabrati objavljivanje svoje sobe u javnom direktoriju soba na matičnom poslužitelju." "Objavljivanje sobe" diff --git a/features/securityandprivacy/impl/src/main/res/values-in/translations.xml b/features/securityandprivacy/impl/src/main/res/values-in/translations.xml index 17f14057cb..ea7668dac5 100644 --- a/features/securityandprivacy/impl/src/main/res/values-in/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-in/translations.xml @@ -23,7 +23,6 @@ Kami tidak menyarankan untuk mengaktifkan enkripsi untuk ruangan yang dapat dite "Anda akan memerlukan alamat ruangan untuk membuatnya terlihat dalam direktori." "Izinkan ruangan ini ditemukan dengan mencari direktori ruangan %1$s publik" "Terlihat di direktori ruangan publik" - "Siapa pun" "Siapa yang bisa membaca riwayat" "Hanya anggota sejak mereka diundang" "Hanya anggota sejak memilih opsi ini" diff --git a/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml index 8afa1987eb..e18ba05140 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml @@ -23,7 +23,6 @@ "디렉토리에 표시하려면 방 주소가 필요합니다." "%1$s 공개 방 디렉토리에서 이 방을 검색할 수 있도록 허용합니다" "공개 룸 디렉토리에 표시됨" - "누구나" "누가 기록을 읽을 수 있는가" "초대받은 회원만 이용 가능합니다" "이 옵션을 선택한 회원만 이용 가능합니다." diff --git a/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml b/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml index 2d0f8db8a5..3a9d90345d 100644 --- a/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml @@ -1,9 +1,9 @@ - "Du trenger en adresse til rommet for å gjøre det synlig i katalogen." - "Romadresse" - "Legg til romadresse" - "Alle kan be om å bli med i rommet, men en administrator eller moderator må godta forespørselen." + "Du trenger en adresse for å gjøre den synlig i den offentlige katalogen." + "Rediger adresse" + "Legg til adresse" + "Alle må be om tilgang." "Be om å bli med" "Ja, aktiver kryptering" "Når kryptering for et rom er aktivert, kan den ikke deaktiveres. Meldingshistorikken vil bare være synlig for rommedlemmer siden de ble invitert eller siden de ble med i rommet. @@ -13,22 +13,24 @@ Vi anbefaler ikke å aktivere kryptering for rom som hvem som helst kan finne og "Når kryptering er aktivert, kan det ikke deaktiveres." "Kryptering" "Aktiver ende-til-ende-kryptering" - "Alle kan finne og bli med" + "Alle kan bli med." "Alle" - "Folk kan bare bli med hvis de er invitert" + "Bare inviterte personer kan bli med." "Kun for inviterte" - "Tilgang til rom" + "Tilgang" "Medlemmer av område" "Områder støttes ikke for øyeblikket" - "Du trenger en adresse til rommet for å gjøre det synlig i katalogen." + "Du trenger en adresse for å gjøre den synlig i den offentlige katalogen." + "Adresse" "Tillat at dette rommet blir funnet ved å søke %1$s offentlig romkatalog" - "Synlig i offentlig romkatalog" - "Alle" + "Synlig i offentlig katalog" + "Alle (historikken er offentlig)" "Hvem kan lese historikk" - "Medlemmer bare siden de ble invitert" - "Kun medlemmer siden du valgte dette alternativet" + "Medlemmer siden de ble invitert" + "Medlemmer (full historikk)" "Romadresser er måter å finne og få tilgang til rom på. Dette sikrer også at du enkelt kan dele rommet ditt med andre. Du kan velge å publisere rommet ditt i hjemeserverens offentlige romkatalog." "Publisering av rom" + "Synlighet" "Sikkerhet og personvern" diff --git a/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml b/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml index 5fdc9466b5..6925a40289 100644 --- a/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml @@ -2,5 +2,4 @@ "Vraag om toe te treden" "Iedereen" - "Iedereen" diff --git a/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml index 11b8189cc4..f49f944872 100644 --- a/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml @@ -24,7 +24,7 @@ Odradzamy włączanie szyfrowania dla pokoi, które każdy może znaleźć i do "Adres pokoju" "Zezwól na znalezienie tego pokoju wyszukując %1$s w katalogu pokoi publicznych" "Widoczny w katalogu pokoi publicznych" - "Wszyscy" + "Ktokolwiek" "Kto może czytać historię" "Od momentu kiedy członkowie zostali zaproszeni" "Członkowie od momentu włączenia tej opcji" diff --git a/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml index 584e94dc20..658067be2d 100644 --- a/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml @@ -3,8 +3,10 @@ "Você precisará de um endereço para torná-la visível no diretório." "Editar endereço" "Adicionar endereço" + "Qualquer um nos espaços autorizados podem entrar, mas todos os outros devem pedir acesso." "Qualquer um pode pedir acesso, mas um administrador terá que aceitar o pedido." "Pedir para entrar" + "Qualquer um em %1$s pode entrar, mas todos os outros devem pedir acesso." "Sim, ativar a criptografia" "Uma vez ativada, a criptografia de uma sala não pode ser desativada. O histórico de mensagens só será visível para os membros da sala desde que foram convidados ou desde que entraram na sala. Ninguém além dos membros da sala poderá ler as mensagens. Isso pode impedir que os bots e as pontes funcionem corretamente. @@ -15,9 +17,13 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Ativar a criptografia de ponta a ponta" "Qualquer um pode entrar" "Qualquer pessoa" + "Escolha os espaços dos quais os membros podem entrar nesta sala sem um convite. %1$s" + "Gerenciar espaços" "Apenas pessoas convidadas podem entrar." "Privado" "Acesso" + "Qualquer um em espaços autorizados podem entrar." + "Qualquer um em %1$s pode entrar." "Membros do espaço" "No momento, não há suporte aos espaços" "Você precisará de um endereço para torná-la visível no diretório." @@ -25,10 +31,9 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Permitir que esta sala seja encontrada pesquisando diretório de salas públicas de %1$s" "Permite que seja encontrada ao buscar no diretório público." "Visível no diretório público" - "Qualquer pessoa" "Quem pode ler o histórico" - "Somente membros, desde que foram convidados" - "Somente para membros após selecionar esta opção" + "Membros desde o convite" + "Membros (histórico completo)" "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhar facilmente sua sala com outras pessoas. Você pode optar por publicar sua sala no diretório público de salas do seu servidor-casa." "Publicação da sala" diff --git a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml index 8c3dabd163..701cb72370 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml @@ -31,7 +31,6 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Permiteți găsirea acestei camere prin căutarea în directorul de camere publice al %1$s" "Permiteți găsirea prin căutarea în directorul public." "Vizibilă în directorul de camere publice" - "Oricine" "Cine poate citi mesajele anterioare" "Doar pentru membri, de la momentul în care au fost invitați" "Doar pentru membri, după selectarea acestei opțiuni" diff --git a/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml b/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml index 4fbfe47ba7..c77201aa5b 100644 --- a/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml @@ -23,7 +23,6 @@ Vi rekommenderar inte att aktivera kryptering för rum som vem som helst kan hit "Du behöver en rumsadress för att göra den synlig i katalogen." "Tillåt att detta rum hittas genom att söka i den offentliga rumskatalogen på %1$s" "Synlig i katalogen för offentliga rum" - "Vem som helst" "Vem kan läsa historik" "Endast medlemmar sedan de bjöds in" "Endast medlemmar sedan det här alternativet har valts" diff --git a/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml b/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml index 55c7d4fda7..511ebbd980 100644 --- a/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml @@ -24,7 +24,7 @@ "Адреса кімнати" "Дозвольте, щоб цю кімнату можна було знайти за допомогою пошуку в каталозі загальнодоступних кімнат %1$s " "Видима в каталозі загальнодоступних кімнат" - "Кожний" + "Будь-хто" "Хто може читати історію" "Лише учасники з моменту запрошення" "Лише учасники після вибору цього параметра" diff --git a/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml b/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml index 06f0337bf1..671308c8a1 100644 --- a/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml @@ -22,7 +22,6 @@ Shu sababli, har kim topishi va qo‘shilishi mumkin bo‘lgan xonalar uchun shi "Katalogda ko‘rinadigan qilish uchun xona manzili kerak bo‘ladi." "Bu xonani %1$s umumiy xonalar ro‘yxatidan qidirib topish imkoniyatini berish" "Umumiy xona ro‘yxatida ko‘rinadi" - "Har kim" "Tarixni kim o‘qiy oladi" "Taklif qilinganidan buyon faqat a’zolar" "A’zolar faqat bu parametr tanlanganidan keyin" diff --git a/features/verifysession/impl/src/main/res/values-uz/translations.xml b/features/verifysession/impl/src/main/res/values-uz/translations.xml index 04169a71d0..26ba7393df 100644 --- a/features/verifysession/impl/src/main/res/values-uz/translations.xml +++ b/features/verifysession/impl/src/main/res/values-uz/translations.xml @@ -16,7 +16,7 @@ "Quyidagi emojilar narigi foydalanuvchining qurilmasida ko‘rsatilgan emojilarga mos kelishini tasdiqlang." "Quyidagi raqamlarning boshqa sessiyangizda koʻrsatilgan raqamlarga mos kelishini tasdiqlang." "Sonlarni taqqoslash" - "Yangi seansingiz tasdiqlandi. U sizning shifrlangan xabarlaringizga kirish huquqiga ega va boshqa foydalanuvchilar uni ishonchli deb bilishadi." + "Endi xabarlarni boshqa qurilmangizda xavfsiz o‘qish yoki yuborishingiz mumkin." "Endi xabarlarni yuborish yoki qabul qilishda bu foydalanuvchining shaxsiga ishonishingiz mumkin." "Qurilma tasdiqlandi" "Tiklash kalitini kiriting" @@ -33,7 +33,7 @@ "Tasdiqlanmadi" "Bu tekshiruvni boshlagan bo‘lsangizgina davom eting." "Xabarlaringiz tarixini xavfsiz saqlash uchun narigi qurilmani tasdiqlang." - "Yangi seansingiz tasdiqlandi. U sizning shifrlangan xabarlaringizga kirish huquqiga ega va boshqa foydalanuvchilar uni ishonchli deb bilishadi." + "Endi xabarlarni boshqa qurilmangizda xavfsiz o‘qish yoki yuborishingiz mumkin." "Qurilma tasdiqlandi" "Tasdiqlash talab qilindi" "Ular mos kelmaydi" diff --git a/libraries/push/impl/src/main/res/values-be/translations.xml b/libraries/push/impl/src/main/res/values-be/translations.xml index 7a30be6f01..aec22f9910 100644 --- a/libraries/push/impl/src/main/res/values-be/translations.xml +++ b/libraries/push/impl/src/main/res/values-be/translations.xml @@ -59,6 +59,7 @@ "Фонавая сінхранізацыя" "Сэрвісы Google" "Службы Google Play не знойдзены. Апавяшчэнні могуць не працаваць належным чынам." + "Заблакіраваныя карыстальнікі" "Атрымаць назву бягучага пастаўшчыка." "Пастаўшчыкі push-апавяшчэнняў не выбраны." "Бягучы пастаўшчык push-апавяшчэнняў: %1$s." diff --git a/libraries/push/impl/src/main/res/values-de/translations.xml b/libraries/push/impl/src/main/res/values-de/translations.xml index 1a9e2f21c4..6997c9f160 100644 --- a/libraries/push/impl/src/main/res/values-de/translations.xml +++ b/libraries/push/impl/src/main/res/values-de/translations.xml @@ -62,7 +62,7 @@ "Du hast %1$d Nutzer gesperrt. Du wirst für diesen Nutzer keine Benachrichtigungen erhalten." "Du hast %1$d Nutzer gesperrt. Du wirst für diese Nutzer keine Benachrichtigungen erhalten." - "Gesperrte Nutzer" + "Blockierte Nutzer" "Ermittele den Namen des aktuellen Anbieters." "Kein Dienst für Push-Benachrichtigungen ausgewählt." "Aktueller Push-Dienst: %1$s und aktueller UnifiedPush-Distributor: %2$s. Aber der Distributor %3$s kann nicht gefunden werden. Vielleicht wurde die App deinstalliert?" diff --git a/libraries/push/impl/src/main/res/values-el/translations.xml b/libraries/push/impl/src/main/res/values-el/translations.xml index da21ccfce7..1229218f09 100644 --- a/libraries/push/impl/src/main/res/values-el/translations.xml +++ b/libraries/push/impl/src/main/res/values-el/translations.xml @@ -54,6 +54,7 @@ "Συγχρονισμός στο παρασκήνιο" "Υπηρεσίες Google" "Δεν βρέθηκαν έγκυρες υπηρεσίες Google Play. Οι ειδοποιήσεις ενδέχεται να μην λειτουργούν σωστά." + "Αποκλεισμένοι χρήστες" "Λάβε το όνομα του τρέχοντος παρόχου." "Δεν έχουν επιλεγεί πάροχοι push." "Τρέχων πάροχος push: %1$s." diff --git a/libraries/push/impl/src/main/res/values-es/translations.xml b/libraries/push/impl/src/main/res/values-es/translations.xml index 4200cb9baf..cee68d6072 100644 --- a/libraries/push/impl/src/main/res/values-es/translations.xml +++ b/libraries/push/impl/src/main/res/values-es/translations.xml @@ -53,6 +53,7 @@ "Sincronización en segundo plano" "Servicios de Google" "No se han encontrado Servicios de Google Play válidos. Es posible que las notificaciones no funcionen correctamente." + "Usuarios bloqueados" "Obtener el nombre del proveedor actual." "No se ha seleccionado ningún proveedor de push." "Proveedor de push actual: %1$s." diff --git a/libraries/push/impl/src/main/res/values-eu/translations.xml b/libraries/push/impl/src/main/res/values-eu/translations.xml index c72badbb52..826b9a762f 100644 --- a/libraries/push/impl/src/main/res/values-eu/translations.xml +++ b/libraries/push/impl/src/main/res/values-eu/translations.xml @@ -53,6 +53,7 @@ "Atzeko planoko sinkronizazioa" "Google Services" "Ez da baliozko Google Play Servicerik aurkitu. Litekeena da jakinarazpenak behar bezala ez ibiltzea." + "Blokeatutako erabiltzaileak" "Lortu uneko hornitzailearen izena." "Ez da push hornitzailerik hautatu." "Uneko push hornitzailea: %1$s." diff --git a/libraries/push/impl/src/main/res/values-in/translations.xml b/libraries/push/impl/src/main/res/values-in/translations.xml index 760d507e08..4baa46d5a9 100644 --- a/libraries/push/impl/src/main/res/values-in/translations.xml +++ b/libraries/push/impl/src/main/res/values-in/translations.xml @@ -48,6 +48,7 @@ "Sinkronisasi latar belakang" "Layanan Google" "Tidak ditemukan Layanan Google Play yang valid. Pemberitahuan mungkin tidak berfungsi dengan baik." + "Pengguna yang diblokir" "Dapatkan nama penyedia saat ini." "Tidak ada penyedia notifikasi dorongan yang dipilih." "Penyedia notifikasi dorongan saat ini: %1$s." diff --git a/libraries/push/impl/src/main/res/values-ka/translations.xml b/libraries/push/impl/src/main/res/values-ka/translations.xml index 3a0d626016..9cf2ddcab2 100644 --- a/libraries/push/impl/src/main/res/values-ka/translations.xml +++ b/libraries/push/impl/src/main/res/values-ka/translations.xml @@ -47,6 +47,7 @@ "ფონის სინქრონიზაცია" "Google სერვისები" "მოქმედი Google Play სერვისები ვერ მოიძებნა. შეტყობინებები შეიძლება ვერ იმუშაოს სწორად." + "დაბლოკილი მომხმარებლები" "მიმდინარე პროვაიდერის სახელის გაგება" "push პროვაიდერები არაა არჩეული." "მიმდინარე push პროვაიდერი: %1$s." diff --git a/libraries/push/impl/src/main/res/values-ko/translations.xml b/libraries/push/impl/src/main/res/values-ko/translations.xml index 9c2aa8c710..c65b6c3388 100644 --- a/libraries/push/impl/src/main/res/values-ko/translations.xml +++ b/libraries/push/impl/src/main/res/values-ko/translations.xml @@ -48,6 +48,7 @@ "백그라운드 동기화" "Google 서비스" "유효한 Google Play 서비스를 찾지 못했습니다. 알림이 정상적으로 동작하지 않을 수 있습니다." + "차단한 사용자" "현재 제공자의 이름을 가져옵니다." "푸시 제공자가 선택되지 않았습니다." "현재 푸시 제공자: %1$s." diff --git a/libraries/push/impl/src/main/res/values-nb/translations.xml b/libraries/push/impl/src/main/res/values-nb/translations.xml index c7114551d3..933b5b886b 100644 --- a/libraries/push/impl/src/main/res/values-nb/translations.xml +++ b/libraries/push/impl/src/main/res/values-nb/translations.xml @@ -38,6 +38,7 @@ "Meg" "%1$s nevnt eller besvart" "Du ser på varselet! Klikk på meg!" + "Tråd i %1$s" "%1$s: %2$s" "%1$s: %2$s %3$s" diff --git a/libraries/push/impl/src/main/res/values-nl/translations.xml b/libraries/push/impl/src/main/res/values-nl/translations.xml index 833c6e7107..79244669e6 100644 --- a/libraries/push/impl/src/main/res/values-nl/translations.xml +++ b/libraries/push/impl/src/main/res/values-nl/translations.xml @@ -53,6 +53,7 @@ "Achtergrondsynchronisatie" "Google-services" "Geen geldige Google Play-services gevonden. Meldingen werken mogelijk niet goed." + "Geblokkeerde gebruikers" "Naam van de huidige provider aan het ophalen." "Er zijn geen push-providers geselecteerd." "Huidige push-provider: %1$s." diff --git a/libraries/push/impl/src/main/res/values-pt-rBR/translations.xml b/libraries/push/impl/src/main/res/values-pt-rBR/translations.xml index 178823e629..0e01d67105 100644 --- a/libraries/push/impl/src/main/res/values-pt-rBR/translations.xml +++ b/libraries/push/impl/src/main/res/values-pt-rBR/translations.xml @@ -38,6 +38,8 @@ "%1$s te convidou para entrar na sala" "Eu" "%1$s mencionado ou respondido" + "Te convidou para entrar no espaço" + "%1$s te convidou para entrar no espaço" "Você está visualizando a notificação! Clique em mim!" "Tópico em %1$s" "%1$s: %2$s" diff --git a/libraries/push/impl/src/main/res/values-sv/translations.xml b/libraries/push/impl/src/main/res/values-sv/translations.xml index aff078b2c0..9f978c253f 100644 --- a/libraries/push/impl/src/main/res/values-sv/translations.xml +++ b/libraries/push/impl/src/main/res/values-sv/translations.xml @@ -54,6 +54,7 @@ "Bakgrundssynkronisering" "Google-tjänster" "Inga giltiga Google Play-tjänster hittades. Aviseringar kanske inte fungerar korrekt." + "Blockerade användare" "Hämta namnet på den nuvarande leverantören." "Inga push-leverantörer valda." "Nuvarande push-leverantör: %1$s." diff --git a/libraries/push/impl/src/main/res/values-tr/translations.xml b/libraries/push/impl/src/main/res/values-tr/translations.xml index a3c415a210..558c206749 100644 --- a/libraries/push/impl/src/main/res/values-tr/translations.xml +++ b/libraries/push/impl/src/main/res/values-tr/translations.xml @@ -54,6 +54,7 @@ "Arkaplan senkronizasyonu" "Google Hizmetleri" "Geçerli bir Google Play Hizmeti bulunamadı. Bildirimler düzgün çalışmayabilir." + "Engellenen kullanıcılar" "Geçerli sağlayıcının adını al." "Hiçbir gönderme sağlayıcısı seçilmedi." "Geçerli gönderme sağlayıcısı: %1$s." diff --git a/libraries/push/impl/src/main/res/values-uk/translations.xml b/libraries/push/impl/src/main/res/values-uk/translations.xml index 1aa535b1e2..43ca0faaca 100644 --- a/libraries/push/impl/src/main/res/values-uk/translations.xml +++ b/libraries/push/impl/src/main/res/values-uk/translations.xml @@ -60,6 +60,7 @@ "Фонова синхронізація" "Сервіси Google" "Не знайдено дійсних сервісів Google Play. Сповіщення можуть не працювати належним чином." + "Заблоковані користувачі" "Отримує назву поточного постачальника." "Постачальників push-сповіщень не вибрано." "Поточний постачальник: %1$s." diff --git a/libraries/push/impl/src/main/res/values-ur/translations.xml b/libraries/push/impl/src/main/res/values-ur/translations.xml index 40a54ab313..8f358b1616 100644 --- a/libraries/push/impl/src/main/res/values-ur/translations.xml +++ b/libraries/push/impl/src/main/res/values-ur/translations.xml @@ -54,6 +54,7 @@ "پس منظر مطابقت پذیری" "گوگل سروسز" "کوئی درست گوگل پلے سروسز نہیں ملی۔ ہو سکتا ہے اطلاعات ٹھیک سے کام نہ کریں۔" + "مسدود صارفین" "موجودہ فراہم کنندہ کا نام حاصل کریں۔" "کوئی دھکا فراہم کنندہ منتخب نہیں کیا گیا" "موجودہ دھکا فراہم کنندہ: %1$s۔" diff --git a/libraries/push/impl/src/main/res/values-uz/translations.xml b/libraries/push/impl/src/main/res/values-uz/translations.xml index 7ba9e6319c..e967b47d34 100644 --- a/libraries/push/impl/src/main/res/values-uz/translations.xml +++ b/libraries/push/impl/src/main/res/values-uz/translations.xml @@ -54,6 +54,7 @@ "Orqa Fon sinxronizatsiyasi" "Google xizmatlari" "Yaroqli Google Play xizmatlari topilmadi. Bildirishnomalar to\'g\'ri ishlamasligi mumkin." + "Bloklangan foydalanuvchilar" "Joriy provayder nomini oling." "Hech qanday push-provayder tanlanmagan." "Joriy push provider: %1$s." diff --git a/libraries/push/impl/src/main/res/values-zh-rTW/translations.xml b/libraries/push/impl/src/main/res/values-zh-rTW/translations.xml index f0c1f1046f..2d289e9a9e 100644 --- a/libraries/push/impl/src/main/res/values-zh-rTW/translations.xml +++ b/libraries/push/impl/src/main/res/values-zh-rTW/translations.xml @@ -56,7 +56,7 @@ "您已封鎖 %1$d 個使用者。您將不會收到來自這些使用者的通知。" - "已封鎖使用者" + "封鎖的使用者" "取得目前提供者的名稱。" "未選取推播提供者。" "目前的推播提供者 %1$s 與目前的散佈者 %2$s。但找不到散佈者 %3$s。可能已解除安裝應用程式?" diff --git a/libraries/ui-strings/src/main/res/values-be/translations.xml b/libraries/ui-strings/src/main/res/values-be/translations.xml index 39da09fb9d..d2a1f4dea7 100644 --- a/libraries/ui-strings/src/main/res/values-be/translations.xml +++ b/libraries/ui-strings/src/main/res/values-be/translations.xml @@ -117,6 +117,7 @@ "Прапусціць" "Пачаць" "Пачаць чат" + "Пачаць спачатку" "Пачаць праверку" "Націсніце, каб загрузіць карту" "Зрабіць фота" @@ -132,6 +133,7 @@ "Палітыка дапушчальнага выкарыстання" "Пашыраныя налады" "Аналітыка" + "Вы выйшлі з пакоя" "Знешні выгляд" "Аўдыя" "Заблакіраваныя карыстальнікі" diff --git a/libraries/ui-strings/src/main/res/values-bg/translations.xml b/libraries/ui-strings/src/main/res/values-bg/translations.xml index 5265110a65..483c47fbea 100644 --- a/libraries/ui-strings/src/main/res/values-bg/translations.xml +++ b/libraries/ui-strings/src/main/res/values-bg/translations.xml @@ -134,7 +134,7 @@ "Разширени настройки" "изображение" "Статистика" - "Напуснахте стаята" + "Вие напуснахте стаята" "Облик" "Аудио" "Блокирани потребители" diff --git a/libraries/ui-strings/src/main/res/values-cs/translations.xml b/libraries/ui-strings/src/main/res/values-cs/translations.xml index 176175a04b..196ec6f175 100644 --- a/libraries/ui-strings/src/main/res/values-cs/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cs/translations.xml @@ -158,6 +158,7 @@ "Přeskočit" "Začít" "Zahájit chat" + "Začít znovu" "Zahájit ověření" "Klepnutím načtete mapu" "Vyfotit" diff --git a/libraries/ui-strings/src/main/res/values-cy/translations.xml b/libraries/ui-strings/src/main/res/values-cy/translations.xml index bfc00ddffb..1aa932f8ed 100644 --- a/libraries/ui-strings/src/main/res/values-cy/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cy/translations.xml @@ -161,6 +161,7 @@ "Hepgor" "Cychwyn" "Dechrau sgwrs" + "Cychwyn eto" "Dechrau dilysu" "Tapio i lwytho map" "Cymryd llun" 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 6de4dc7ebd..73b70cf4f1 100644 --- a/libraries/ui-strings/src/main/res/values-da/translations.xml +++ b/libraries/ui-strings/src/main/res/values-da/translations.xml @@ -156,6 +156,7 @@ "Spring over" "Start" "Start samtale" + "Begynd forfra" "Begynd verifikation" "Tryk for at indlæse kort" "Tag billede" diff --git a/libraries/ui-strings/src/main/res/values-de/translations.xml b/libraries/ui-strings/src/main/res/values-de/translations.xml index 7467a59bd9..65803db3aa 100644 --- a/libraries/ui-strings/src/main/res/values-de/translations.xml +++ b/libraries/ui-strings/src/main/res/values-de/translations.xml @@ -155,6 +155,7 @@ "Überspringen" "Start" "Chat starten" + "Neu beginnen" "Verifizierung starten" "Tippe, um die Karte zu laden" "Foto aufnehmen" diff --git a/libraries/ui-strings/src/main/res/values-el/translations.xml b/libraries/ui-strings/src/main/res/values-el/translations.xml index f6bca76182..98d20a1599 100644 --- a/libraries/ui-strings/src/main/res/values-el/translations.xml +++ b/libraries/ui-strings/src/main/res/values-el/translations.xml @@ -130,6 +130,7 @@ "Παράλειψη" "Εκκίνηση" "Έναρξη συνομιλίας" + "Ξανά από την αρχή" "Έναρξη επαλήθευσης" "Πάτα για φόρτωση χάρτη" "Τράβηξε φωτογραφία" @@ -148,6 +149,7 @@ "Ρυθμίσεις για προχωρημένους" "μια εικόνα" "Στατιστικά στοιχεία" + "Αποχωρήσατε από την αίθουσα" "Εμφάνιση" "Ήχος" "Αποκλεισμένοι χρήστες" diff --git a/libraries/ui-strings/src/main/res/values-es/translations.xml b/libraries/ui-strings/src/main/res/values-es/translations.xml index 4fcc3fd9df..740f96edd4 100644 --- a/libraries/ui-strings/src/main/res/values-es/translations.xml +++ b/libraries/ui-strings/src/main/res/values-es/translations.xml @@ -128,6 +128,7 @@ "Saltar" "Comenzar" "Iniciar chat" + "Empezar de nuevo" "Iniciar la verificación" "Pulsa para cargar el mapa" "Hacer foto" @@ -145,6 +146,7 @@ "Añadiendo leyenda" "Ajustes avanzados" "Estadísticas" + "Saliste de la sala" "Apariencia" "Sonido" "Usuarios bloqueados" diff --git a/libraries/ui-strings/src/main/res/values-et/translations.xml b/libraries/ui-strings/src/main/res/values-et/translations.xml index 76a703f9e1..67d323e77b 100644 --- a/libraries/ui-strings/src/main/res/values-et/translations.xml +++ b/libraries/ui-strings/src/main/res/values-et/translations.xml @@ -161,6 +161,7 @@ "Kaardi laadimiseks klõpsa" "Tee pilt" "Valikuteks klõpsa" + "Tõlgi" "Proovi uuesti" "Eemalda esiletõstmine" "Vaata" @@ -178,7 +179,7 @@ "Täiendavad seadistused" "pilt" "Analüütika" - "Sa oled jututoast lahkunud" + "Sina lahkusid jututoast" "Sa olid sessioonist väljaloginud" "Välimus" "Heli" diff --git a/libraries/ui-strings/src/main/res/values-eu/translations.xml b/libraries/ui-strings/src/main/res/values-eu/translations.xml index 10f914d0fd..9a92bf6289 100644 --- a/libraries/ui-strings/src/main/res/values-eu/translations.xml +++ b/libraries/ui-strings/src/main/res/values-eu/translations.xml @@ -137,6 +137,7 @@ "Saltatu" "Hasi" "Hasi txata" + "Hasi berriro" "Hasi egiaztapena" "Sakatu mapa kargatzeko" "Egin argazkia" @@ -155,6 +156,7 @@ "Ezarpen aurreratuak" "irudia" "Estatistikak" + "Gelatik atera zara" "Itxura" "Audioa" "Blokeatutako erabiltzaileak" diff --git a/libraries/ui-strings/src/main/res/values-fa/translations.xml b/libraries/ui-strings/src/main/res/values-fa/translations.xml index 0522010510..16872a2e91 100644 --- a/libraries/ui-strings/src/main/res/values-fa/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fa/translations.xml @@ -150,6 +150,7 @@ "پرش" "آغاز" "آغاز گپ" + "آغاز از نو" "آغاز تأیید" "زدن برای بار کردن نقشه" "عکس گرفتن" 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 97e0c7b037..f6a7678358 100644 --- a/libraries/ui-strings/src/main/res/values-fi/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fi/translations.xml @@ -156,6 +156,7 @@ "Ohita" "Aloita" "Aloita keskustelu" + "Aloita alusta" "Aloita vahvistus" "Lataa kartta napauttamalla" "Ota kuva" 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 5cf19b8dfe..9392933cf8 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -156,6 +156,7 @@ "Passer" "Démarrer" "Démarrer une discussion" + "Recommencer" "Commencer la vérification" "Cliquez pour charger la carte" "Prendre une photo" @@ -177,7 +178,7 @@ "Paramètres avancés" "une image" "Statistiques d’utilisation" - "Vous avez quitter le salon" + "Vous avez quitté le salon" "Vous avez été déconnecté de la session" "Apparence" "Audio" diff --git a/libraries/ui-strings/src/main/res/values-hr/translations.xml b/libraries/ui-strings/src/main/res/values-hr/translations.xml index 1d41bf0593..139e68230f 100644 --- a/libraries/ui-strings/src/main/res/values-hr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hr/translations.xml @@ -158,7 +158,7 @@ "Preskoči" "Započni" "Započni razgovor" - "Počni ispočetka" + "Kreni ispočetka" "Započni provjeru" "Dodirnite za učitavanje karte" "Uslikaj" diff --git a/libraries/ui-strings/src/main/res/values-hu/translations.xml b/libraries/ui-strings/src/main/res/values-hu/translations.xml index 0dd7b35b51..0174bd79b1 100644 --- a/libraries/ui-strings/src/main/res/values-hu/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hu/translations.xml @@ -156,6 +156,7 @@ "Kihagyás" "Indítás" "Csevegés indítása" + "Újrakezdés" "Ellenőrzés elindítása" "Koppintson a térkép betöltéséhez" "Fénykép készítése" diff --git a/libraries/ui-strings/src/main/res/values-in/translations.xml b/libraries/ui-strings/src/main/res/values-in/translations.xml index 9735344818..cc2bad1f2b 100644 --- a/libraries/ui-strings/src/main/res/values-in/translations.xml +++ b/libraries/ui-strings/src/main/res/values-in/translations.xml @@ -139,6 +139,7 @@ "Lewati" "Mulai" "Mulai obrolan" + "Mulai dari awal" "Mulai verifikasi" "Ketuk untuk memuat peta" "Ambil foto" @@ -158,6 +159,7 @@ "Pengaturan tingkat lanjut" "sebuah gambar" "Analitik" + "Anda keluar dari ruangan" "Penampilan" "Audio" "Pengguna yang diblokir" diff --git a/libraries/ui-strings/src/main/res/values-it/translations.xml b/libraries/ui-strings/src/main/res/values-it/translations.xml index ec359908ce..abde675f0f 100644 --- a/libraries/ui-strings/src/main/res/values-it/translations.xml +++ b/libraries/ui-strings/src/main/res/values-it/translations.xml @@ -156,6 +156,7 @@ "Salta" "Inizia" "Avvia conversazione" + "Ricomincia" "Avvia la verifica" "Tocca per caricare la mappa" "Scatta foto" diff --git a/libraries/ui-strings/src/main/res/values-ka/translations.xml b/libraries/ui-strings/src/main/res/values-ka/translations.xml index 393b404f31..0a7b612e55 100644 --- a/libraries/ui-strings/src/main/res/values-ka/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ka/translations.xml @@ -113,6 +113,7 @@ "მისაღები გამოყენების პოლიტიკა" "გაფართოებული პარამეტრები" "ანალიტიკა" + "თქვენ დატოვეთ ოთახი" "გარეგნობა" "აუდიო" "დაბლოკილი მომხმარებლები" diff --git a/libraries/ui-strings/src/main/res/values-ko/translations.xml b/libraries/ui-strings/src/main/res/values-ko/translations.xml index f00637dbe5..2ea2017c76 100644 --- a/libraries/ui-strings/src/main/res/values-ko/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ko/translations.xml @@ -148,6 +148,7 @@ "건너뛰기" "시작" "채팅 시작" + "다시 시작하다" "인증 시작" "탭해서 지도 불러오기" "사진 찍기" @@ -167,7 +168,7 @@ "고급 설정" "이미지" "통계" - "방에서 나갔습니다" + "방을 떠남" "세션에서 로그아웃되었습니다." "외관" "소리" diff --git a/libraries/ui-strings/src/main/res/values-lt/translations.xml b/libraries/ui-strings/src/main/res/values-lt/translations.xml index 535e57f7fe..90aed6b6f8 100644 --- a/libraries/ui-strings/src/main/res/values-lt/translations.xml +++ b/libraries/ui-strings/src/main/res/values-lt/translations.xml @@ -64,6 +64,7 @@ "Taip" "Apie" "Analitika" + "Jūs išėjote iš kambario" "Garsas" "Burbulai" "Pokalbio atsarginė kopija" diff --git a/libraries/ui-strings/src/main/res/values-nb/translations.xml b/libraries/ui-strings/src/main/res/values-nb/translations.xml index 2c62758e39..09d3eab84c 100644 --- a/libraries/ui-strings/src/main/res/values-nb/translations.xml +++ b/libraries/ui-strings/src/main/res/values-nb/translations.xml @@ -95,6 +95,7 @@ "Glemt passordet?" "Videresend" "Gå tilbake" + "Gå til roller og tillatelser" "Gå til innstillinger" "Ignorer" "Inviter" @@ -155,6 +156,7 @@ "Hopp over" "Start" "Start chat" + "Begynn på nytt" "Start verifisering" "Trykk for å laste inn kart" "Ta bilde" diff --git a/libraries/ui-strings/src/main/res/values-nl/translations.xml b/libraries/ui-strings/src/main/res/values-nl/translations.xml index cbd2d4d63b..790363ba54 100644 --- a/libraries/ui-strings/src/main/res/values-nl/translations.xml +++ b/libraries/ui-strings/src/main/res/values-nl/translations.xml @@ -140,6 +140,7 @@ "Overslaan" "Starten" "Chat starten" + "Opnieuw beginnen" "Verificatie starten" "Tik om kaart te laden" "Foto maken" @@ -158,6 +159,7 @@ "Bijschrift toevoegen" "Geavanceerde instellingen" "Gebruiksgegevens" + "Je hebt de kamer verlaten" "Weergave" "Geluid" "Geblokkeerde gebruikers" diff --git a/libraries/ui-strings/src/main/res/values-pl/translations.xml b/libraries/ui-strings/src/main/res/values-pl/translations.xml index 7b12125a3a..aafac63332 100644 --- a/libraries/ui-strings/src/main/res/values-pl/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pl/translations.xml @@ -157,6 +157,7 @@ "Pomiń" "Rozpocznij" "Rozpocznij chat" + "Zacznij od nowa" "Rozpocznij weryfikację" "Stuknij, aby załadować mapę" "Zrób zdjęcie" diff --git a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml index c61dadbd7a..3863a24fd8 100644 --- a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml @@ -156,6 +156,7 @@ "Pular" "Iniciar" "Iniciar conversa" + "Começar de novo" "Iniciar verificação" "Toque para carregar o mapa" "Tirar foto" @@ -234,6 +235,7 @@ Motivo:​ %1$s." "Claro" "Linha copiada para a área de transferência" "Link copiado para área de transferência" + "Vincular novo dispositivo" "Carregando…" "Carregando mais…" @@ -246,10 +248,12 @@ Motivo:​ %1$s."
"Mensagem" "Ações de mensagem" + "Falha no envio da mensagem" "Layout da mensagem" "Mensagem removida" "Moderno" "Mudo" + "Nome" "%1$s (%2$s)" "Não há resultados" "Não há um nome para a sala" @@ -324,6 +328,7 @@ Motivo:​ %1$s." "Algo deu errado" "Encontramos um problema. Tente novamente." "Espaço" + "Sobre o que é esse espaço?" "%1$d espaço" "%1$d espaços" @@ -368,6 +373,7 @@ Motivo:​ %1$s." "Aguardando…" "Aguardando por esta mensagem" "Você" + "Esta sala foi configurada para que membros novos possam ler o histórico. %1$s" "A identidade de %1$s foi redefinida. %2$s" "A identidade de %1$s %2$s foi redefinida. %3$s" "(%1$s)" @@ -428,6 +434,11 @@ Você tem certeza de que deseja continuar?" "Opções" "Remover %1$s" "Configurações" + "Os espaços dos quais os membros podem entrar na sala sem um convite." + "Gerenciar espaços" + "(Espaço desconhecido)" + "Outros espaços dos quais você não é um membro" + "Seus espaços" "Falha ao selecionar a mídia, tente novamente." "Pressione em uma mensagem e escolha \"%1$s\" para incluir aqui." "Fixe mensagens importantes para que elas possam ser facilmente descobertas" diff --git a/libraries/ui-strings/src/main/res/values-pt/translations.xml b/libraries/ui-strings/src/main/res/values-pt/translations.xml index 5fbf7338f4..019f2e6ac4 100644 --- a/libraries/ui-strings/src/main/res/values-pt/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pt/translations.xml @@ -153,6 +153,7 @@ "Saltar" "Iniciar" "Iniciar conversa" + "Começar de novo" "Iniciar verificação" "Toca para carregar o mapa" "Tirar foto" 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 d0fca61375..1ccde058c3 100644 --- a/libraries/ui-strings/src/main/res/values-ru/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ru/translations.xml @@ -158,6 +158,7 @@ "Пропустить" "Начать" "Начать чат" + "Начать заново" "Начать подтверждение" "Нажмите, чтобы загрузить карту" "Сделать фото" diff --git a/libraries/ui-strings/src/main/res/values-sk/translations.xml b/libraries/ui-strings/src/main/res/values-sk/translations.xml index d225eecc4f..0928010918 100644 --- a/libraries/ui-strings/src/main/res/values-sk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sk/translations.xml @@ -158,6 +158,7 @@ "Preskočiť" "Spustiť" "Začať konverzáciu" + "Začať odznova" "Spustiť overovanie" "Ťuknutím načítate mapu" "Urobiť fotku" diff --git a/libraries/ui-strings/src/main/res/values-sv/translations.xml b/libraries/ui-strings/src/main/res/values-sv/translations.xml index 9d928a406f..7d84b11d87 100644 --- a/libraries/ui-strings/src/main/res/values-sv/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sv/translations.xml @@ -148,6 +148,7 @@ "Hoppa över" "Starta" "Starta chat" + "Börja om" "Starta verifiering" "Tryck för att ladda kartan" "Ta ett foto" diff --git a/libraries/ui-strings/src/main/res/values-tr/translations.xml b/libraries/ui-strings/src/main/res/values-tr/translations.xml index cabfc68e01..b7b0bc841d 100644 --- a/libraries/ui-strings/src/main/res/values-tr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-tr/translations.xml @@ -122,6 +122,7 @@ "Atla" "Başlat" "Sohbeti başlat" + "Yeniden Başla" "Doğrulamayı başlat" "Haritayı yüklemek için dokunun" "Fotoğraf çek" @@ -139,6 +140,7 @@ "Açıklama ekleme" "Gelişmiş Ayarlar" "Analizler" + "Odadan ayrıldın." "Görünüm" "Ses" "Engellenen kullanıcılar" diff --git a/libraries/ui-strings/src/main/res/values-uk/translations.xml b/libraries/ui-strings/src/main/res/values-uk/translations.xml index 03b3b6b3f2..0b1083ea1a 100644 --- a/libraries/ui-strings/src/main/res/values-uk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-uk/translations.xml @@ -152,6 +152,7 @@ "Пропустити" "Розпочати" "Розпочати бесіду" + "Почати спочатку" "Почати верифікацію" "Натисніть, щоб завантажити мапу" "Зробити фото" diff --git a/libraries/ui-strings/src/main/res/values-ur/translations.xml b/libraries/ui-strings/src/main/res/values-ur/translations.xml index ef53dc7843..18d8b49ed5 100644 --- a/libraries/ui-strings/src/main/res/values-ur/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ur/translations.xml @@ -114,6 +114,7 @@ "چھوڑیں" "شروع کریں" "گفتگو شروع کریں" + "از سر نو شروع کریں" "توثیق شروع کریں" "نقشہ لادنے کیلئے تھپتھپائیں" "تصویر لیں" @@ -129,6 +130,7 @@ "قابل قبول استعمال کی سیاست" "اعلیٰ ترتیبات" "تجزیات" + "آپ کمرے سے رخصت ہوگئے" "ظہور" "صوت" "مسدود صارفین" diff --git a/libraries/ui-strings/src/main/res/values-uz/translations.xml b/libraries/ui-strings/src/main/res/values-uz/translations.xml index fb36f3658b..5d5b7ea4d4 100644 --- a/libraries/ui-strings/src/main/res/values-uz/translations.xml +++ b/libraries/ui-strings/src/main/res/values-uz/translations.xml @@ -150,6 +150,7 @@ "Oʻtkazib yuborish" "Boshlash" "Suhbatni boshlash" + "Qaytadan boshlang" "Tasdiqlashni boshlang" "Xaritani yuklash uchun bosing" "Rasmga olmoq" diff --git a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml index e4dfb2805c..046d7f36ba 100644 --- a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml @@ -154,6 +154,7 @@ "略過" "開始" "開始聊天" + "重新開始" "開始驗證" "點擊以載入地圖" "拍照" @@ -175,7 +176,7 @@ "進階設定" "影像" "分析" - "您離開了聊天室" + "您離開聊天室" "您已登出工作階段" "外觀" "音訊" diff --git a/libraries/ui-strings/src/main/res/values-zh/translations.xml b/libraries/ui-strings/src/main/res/values-zh/translations.xml index 402029cb2c..774a3d3f89 100644 --- a/libraries/ui-strings/src/main/res/values-zh/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh/translations.xml @@ -154,6 +154,7 @@ "跳过" "开始" "开始聊天" + "重新开始" "开始验证" "点击以加载地图" "拍摄照片" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 690a53b343..df47b71577 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -161,6 +161,7 @@ "Tap to load map" "Take photo" "Tap for options" + "Translate" "Try again" "Unpin" "View" diff --git a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_0_de.png b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_0_de.png index 2a28b1e8f4..0402613534 100644 --- a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_0_de.png +++ b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4bae9cb2503981a199cf82e53a538e2cd5d5071a4d49ea0dd9ddc6efc8eaff69 -size 9393 +oid sha256:2a5b7c5d7fa9a6f9156f25aa565944028149a7d2ab9f418a0b02a17d948a6768 +size 9415 diff --git a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_1_de.png b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_1_de.png index f2d7135b76..999bb266e8 100644 --- a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_1_de.png +++ b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12e179c18e4fe4dd12f72be6e4dd3ea3f428220206ff179f11873156201bb8b0 -size 21703 +oid sha256:53643845f3b082175ed3a33e0d8fd6edc4006cbe74a0c9db7a7100c2351acc4d +size 21744 diff --git a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_4_de.png b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_4_de.png index 7c2afb45b5..5472de64d6 100644 --- a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_4_de.png +++ b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf1cafe9f59259e325cc772768436da6615bc8796c758882c2eab1f2ded58ac3 -size 9905 +oid sha256:51b14d3633dd614fcad706c714e93447dc3ac6039ef0cec6213f77a3c24cf2b3 +size 9984 diff --git a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_5_de.png b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_5_de.png index 0155d2b086..ba1c5b663c 100644 --- a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_5_de.png +++ b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f40663092e27a21969d6a7d43ecf384cb978c4ba473a2d3dc59d4c9a4896b63 -size 39241 +oid sha256:7402d0fb1b714f733d3929955fcbf0b096187cf70e3503acc21ffa089142610f +size 38851 diff --git a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_6_de.png b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_6_de.png index ebc6bab03b..d46d8971aa 100644 --- a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_6_de.png +++ b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c64c5ad385c27b8db8ddf0612b6b45e6b77699292154c1291c862e110775f4cd -size 38286 +oid sha256:2457c74365a98c64974eeaf607879461d2cd9a1757096f330d913fb034816b31 +size 38734 diff --git a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_7_de.png b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_7_de.png index 2324cdc8cd..988c8dd318 100644 --- a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_7_de.png +++ b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d7ab5834d27935ba64544d7d768ba7aba1144bb127c6cf902d05c103394d2057 -size 30295 +oid sha256:045a5183f88a998968af1f1f8a02e864697add38b1259b6e40fda702dce82b48 +size 30661 diff --git a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_9_de.png b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_9_de.png index f2d7135b76..999bb266e8 100644 --- a/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_9_de.png +++ b/screenshots/de/features.invitepeople.impl_InvitePeopleView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12e179c18e4fe4dd12f72be6e4dd3ea3f428220206ff179f11873156201bb8b0 -size 21703 +oid sha256:53643845f3b082175ed3a33e0d8fd6edc4006cbe74a0c9db7a7100c2351acc4d +size 21744 diff --git a/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_de.png new file mode 100644 index 0000000000..1e1846298a --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c039b7577f65380d5c54ae7d9a82d62f8a43f4888c86c799fb5b982ba6817d8 +size 45019 diff --git a/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_de.png b/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_de.png new file mode 100644 index 0000000000..8dca9fed7d --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48e2d8fffea5b23d7894fc546dac33bb87d7df5267aa58d3f79a14f7f93ee85a +size 44823 diff --git a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_0_de.png new file mode 100644 index 0000000000..65573d908f --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fc70436b6ccb1afd77bed07598c020796341aa100b1eab6dc5b00868297dca6 +size 24990 diff --git a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_1_de.png b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_1_de.png new file mode 100644 index 0000000000..c7cf5a7efa --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50c28eb8481b1101f75bf8341481ead0e77daf116207d27ddc5c95316daf8e41 +size 22035 diff --git a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_2_de.png b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_2_de.png new file mode 100644 index 0000000000..4468511356 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20558650fc6a3859569d52baaab1c8af2a68e2944fd772f0d62ced5c1aa44208 +size 29397 diff --git a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_3_de.png b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_3_de.png new file mode 100644 index 0000000000..3603b23b24 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba73d59bab19bc1263174c632f6ca3bfed98d11b1bb949e9340b02bb5c666580 +size 38741 diff --git a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_4_de.png b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_4_de.png new file mode 100644 index 0000000000..a11f674a7a --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_4_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14e81841b45d0400c65a3a052e8c0c15d48ce88f7f4b50d4e453f92bdb82bbb4 +size 33097 diff --git a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_5_de.png b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_5_de.png new file mode 100644 index 0000000000..33122e6dea --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_5_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b39882c9c6d9920d0f76f3b80599b7b41cc6eab4480c6a10f09cf0992acbf203 +size 68940 diff --git a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_6_de.png b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_6_de.png new file mode 100644 index 0000000000..8d47b730a2 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9bc94377c776271128fd411397d698539fdf74870b074988b8de1c86a4ecec0 +size 21798 diff --git a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_7_de.png b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_7_de.png new file mode 100644 index 0000000000..5f79162d1b --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_7_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c184323fa1b1d87f46be6f49bf983f7d4048b5547906531b452924ee89110d30 +size 23962 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_de.png new file mode 100644 index 0000000000..bad5f73502 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:754f8340cc0f39b0c2e63065bf6d03b3716d74176973b0380f348a866c0b233f +size 30062 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_de.png new file mode 100644 index 0000000000..7021172235 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8884d4a3a61239a030dac21660f0cb6d9ed54d3db08c7b2a48e6b18894a0bbf +size 30043 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_de.png new file mode 100644 index 0000000000..97e470d460 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:101ae89accacc3707b71a091eaacb7676ffc24a92d4cfd48edcf077a414130fa +size 30642 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_de.png new file mode 100644 index 0000000000..3c9eff4eb0 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40b967dec26c18a3122b3a80f8e29bb0e7b3d16452f4f8061c729134ac5f9f53 +size 30819 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_de.png new file mode 100644 index 0000000000..152fb7112b --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50a6ffd3a59bcf661d5e666736d1189c3c5eaa4bee573644f0a9255d0ffe3a3d +size 34079 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_de.png new file mode 100644 index 0000000000..da8006965a --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1f9958366956cc133eed94df188a51dacfdb3de4195d91cfdc16cf6cbdf412e +size 33794 diff --git a/screenshots/de/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_de.png new file mode 100644 index 0000000000..9cd8daefdb --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57f7c6b4d39222cf3e8e92777a0aa319f2654687dd298ce1f60cecdb3e2ce0c1 +size 32149 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_de.png new file mode 100644 index 0000000000..2def92650e --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fca6a90b7a667ed9d4d5c0cf2616664468b3ff6dd59d6460651c3e3aa3fae08 +size 17847 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_de.png new file mode 100644 index 0000000000..8582608925 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb7142589d7c830c72fa5b7bc853027b83a2b864e43c849107d35c0a849c4f02 +size 27470 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_de.png new file mode 100644 index 0000000000..442f156ff0 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34243ec18f06c11de6103bf7787d80b366f12890f01ffe31674ae77ee113dbf1 +size 24679 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_de.png new file mode 100644 index 0000000000..67228c7c86 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:437eda5bc2439120a5bca6b88e307d5f0ba1cdce4683e3bb946e7f174419c6e5 +size 34336 diff --git a/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_de.png new file mode 100644 index 0000000000..153df13caa --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:adda1a1a7c20d0eb54528f5f8c60e13c2e8428afc92d849f882f25d727136687 +size 15861 diff --git a/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_de.png b/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_de.png new file mode 100644 index 0000000000..d50a67ef38 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a12dbc4f2fb3d12b1848e2ac4e079522613df2493d0a416f2f47827eb0daa322 +size 16502 diff --git a/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_de.png b/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_de.png new file mode 100644 index 0000000000..b786292896 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e19add1c5894aa7dbad4bc1fff8f3789584946ca1069c3b39b17ed826f4a06c +size 16673 diff --git a/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_de.png b/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_de.png new file mode 100644 index 0000000000..305f24b9d7 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6a773294a47272bcc0333e7a325e0609ef53d576eca1d40422b0855cc48dae7 +size 31739 diff --git a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_0_de.png b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_0_de.png index cc177bb9f6..e09362dd03 100644 --- a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_0_de.png +++ b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d46d8b8f49f4a15e342099444367b5ea84d0663ce24d1b125f128e1a5e42c7ba -size 38378 +oid sha256:fa4cf17898cfd78c295bcacb9df84a30e2bde4a3d819cce2a737c887976d1a7e +size 38448 diff --git a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_1_de.png b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_1_de.png index f2d4e3c45e..ed1ba7c97d 100644 --- a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_1_de.png +++ b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:442886da954416ff3d3d5a9833af2c906490f6e58792e5ac64435fc754545942 -size 38777 +oid sha256:8066d263a899ca57f633bd2d6792c249f6a5674ca523fd1afec337b074f854b3 +size 38849 diff --git a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_2_de.png b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_2_de.png index cf7f7a70b8..0045d8f0c3 100644 --- a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_2_de.png +++ b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0056002441e3a5632172c328ec764f08b7482b4c294aa46bc58517e97f333329 -size 39063 +oid sha256:b002741ad82c48b8b8e48303cf7473d1da596437809119093e004588a50e4bf7 +size 39136 diff --git a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_3_de.png b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_3_de.png index 78b50bdac7..f63895de69 100644 --- a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_3_de.png +++ b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77b60d10bdf6f4805fd8414f2ac06550014cf7dae09741475dd9dd680969e32f -size 44276 +oid sha256:60b61665c7356642f4775acb9968d01d43817dd67801afca9ad5b60d6b570b0f +size 44321 diff --git a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_4_de.png b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_4_de.png index a933e30339..b2a0b0915b 100644 --- a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_4_de.png +++ b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc498359b64e564bbe93584bf06a5dee85e69bf087739b06cf8f6b45f9ef8a38 -size 35777 +oid sha256:27b58735f417e5883f45ff9a40fdffc8250f1db728ac0de7410d0f8d7021e5e0 +size 35846 diff --git a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_5_de.png b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_5_de.png index e4109aa848..81789e7884 100644 --- a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_5_de.png +++ b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d1c96ff639d6f90a5ac3d0602fa274be5b337f93ede86d67f4884a776c79690 -size 41196 +oid sha256:ebe316bccee2ef6045a8a3e77d48c633ad6855dcbec3f7fd3f69071abddde135 +size 41246 diff --git a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_6_de.png b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_6_de.png index 557ee76ac4..5405dde38b 100644 --- a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_6_de.png +++ b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ff076d7a9b3ec5e47eaac119c674a06ed9701fae17b93bd33fd12fd0a730d5f0 -size 32089 +oid sha256:807ced3cff6d0a0f70738bd4723be16df848f61fb7a8c594c3c5261a4b9267a2 +size 32133 diff --git a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_7_de.png b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_7_de.png index 9a70572566..3368a795a0 100644 --- a/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_7_de.png +++ b/screenshots/de/features.lockscreen.impl.unlock_PinUnlockView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a85c15d3d4fd79b4ea8070675e416bac6fccee1976dbfee7f266afd8eb1ab4ce -size 32285 +oid sha256:014e8208a369fcc39f331a752f4c1f7039ef966d8af12cefb46fded6d7c07d28 +size 32326 diff --git a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_de.png b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_de.png index ff4a5d5785..d50a67ef38 100644 --- a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_de.png +++ b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:530e1e9747be0284eb2600abcca2ad6103d10aa1513712d610b797d0595190a3 -size 14532 +oid sha256:a12dbc4f2fb3d12b1848e2ac4e079522613df2493d0a416f2f47827eb0daa322 +size 16502 diff --git a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_de.png b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_de.png index 736fcfe796..c98fa292ed 100644 --- a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_de.png +++ b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ba23fbb4402878a5a249a997504d69fcc268a15b5ef00512dd15e12857280a2 -size 19411 +oid sha256:1e6e8cd76fdbb3835b0622593e099ed61d526de35c6d20b6547cea83d6aa8e19 +size 20741 diff --git a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_de.png b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_de.png index 303f7d4282..305f24b9d7 100644 --- a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_de.png +++ b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26d79ad02e39da6cb3f5a5f962b302832dee465096a1269941f9eb6c74277971 -size 30499 +oid sha256:a6a773294a47272bcc0333e7a325e0609ef53d576eca1d40422b0855cc48dae7 +size 31739 diff --git a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_de.png b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_de.png index 6fcadfdd61..877598f1e1 100644 --- a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_de.png +++ b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3562640bc228a3977c216d7981692029b0a94c2b109628121571cb9804a68024 -size 39016 +oid sha256:500c0857431f0604b828e50751b6250e8349559a39b73f201ff5e7eb4fe0239c +size 40262 diff --git a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_de.png b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_de.png index 77f1733a60..46cb868856 100644 --- a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_de.png +++ b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eafdb26bca443afa4921432073c560c48116c2d3e9d45f8afcc1e35d8819905d -size 34110 +oid sha256:60ee229ac4cc0712b8afba1d678cebc88bc1f0abfe133bf4e4311f05b0fa6c28 +size 35288 diff --git a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_de.png b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_de.png index 11303295df..cef37f8936 100644 --- a/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_de.png +++ b/screenshots/de/features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:988384f6d8fc5b65e5e8d5c047ddb55a953867d34fa7d9d6543ff7f07c096b34 -size 32203 +oid sha256:848b24931a1da8f4e2b3dfdbb6b8e3f09d71dee356507eb5f46e08e74ffe94a5 +size 33464 diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_0_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_0_de.png similarity index 100% rename from screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_0_de.png rename to screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_0_de.png diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_1_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_1_de.png similarity index 100% rename from screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_1_de.png rename to screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_1_de.png diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_2_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_2_de.png similarity index 100% rename from screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_2_de.png rename to screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_2_de.png diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_3_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_3_de.png similarity index 100% rename from screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_3_de.png rename to screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_3_de.png diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_4_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_4_de.png similarity index 100% rename from screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_4_de.png rename to screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_4_de.png diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_5_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_5_de.png similarity index 100% rename from screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_5_de.png rename to screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_5_de.png diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_de.png new file mode 100644 index 0000000000..5a467d20db --- /dev/null +++ b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4824c960aeced8a1745c0beac52b406e83d24079eeac21bca78aa7ef0698a4f0 +size 72357 diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_7_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_7_de.png similarity index 100% rename from screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_7_de.png rename to screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_7_de.png diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_de.png new file mode 100644 index 0000000000..9c80295727 --- /dev/null +++ b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsPreviewView_8_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0afbea1b4ee5db426d45293cc3260cef6ebf7cbcf7aa387452b6433120e5c5e0 +size 89922 diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_6_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_6_de.png deleted file mode 100644 index 9b9c0d482b..0000000000 --- a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_6_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:40ec83fef8cf41389125f11d8a42c46b76b45225016e77ee2f9a49dcbcd4a006 -size 71980 diff --git a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_8_de.png b/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_8_de.png deleted file mode 100644 index 4061478525..0000000000 --- a/screenshots/de/features.messages.impl.attachments.preview_AttachmentsView_8_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c5e0b2b6866184d18ed0928af4450cadfa860e60b60713dac4399c9b0dedc16c -size 89678 diff --git a/screenshots/de/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_de.png b/screenshots/de/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_de.png index f614e6eac7..8f9bad96f6 100644 --- a/screenshots/de/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_de.png +++ b/screenshots/de/features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c71d15c6788611ecc0be5f75d64696d7bf68673f9c75c91d692358fedf219ba6 -size 71872 +oid sha256:0346829dcefb0fa299a8ef834ca56e76fa258e49fa36aea425e0a2f074fde401 +size 71943 diff --git a/screenshots/de/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_de.png b/screenshots/de/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_de.png index f4b2bf2d83..35761fbc07 100644 --- a/screenshots/de/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_de.png +++ b/screenshots/de/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:72e593c0daada7d0dbb3bd964c6296e6432e97a5480429da9562782e76b27e57 -size 22225 +oid sha256:ad8fc597fb7c6674d5c9402f659ef163296d2131e80f7d0f89c6ac8a2e7201f9 +size 22266 diff --git a/screenshots/de/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_de.png b/screenshots/de/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_de.png index 49addf5d03..c1409acb77 100644 --- a/screenshots/de/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_de.png +++ b/screenshots/de/features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d1a41cc35a495f97b8a4660fa9e905e05e8f1ee41980e67237899cd49506c0b -size 6535 +oid sha256:6d907836e749f5d74713e58b7427cac9c3972919ccccb2c66f41a688e9367c67 +size 6653 diff --git a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_de.png b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_de.png index 2e4b967586..dbe86d6685 100644 --- a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_de.png +++ b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a07d10aba2d12a4e664b4ff122f10434b5af4bb90fdaf57fc05a52c67bd47ff -size 12207 +oid sha256:82f339bf796b1dd88bb2eb7bc20ea999402b83764c267fe70d91e69aacfd8365 +size 12199 diff --git a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_de.png b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_de.png index d1d9065005..8f400cf087 100644 --- a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_de.png +++ b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:212650482a277d51efb218af0485aa0e5d7c72a33bd5e8c482dd704299c975c6 -size 17684 +oid sha256:2267052cc5675747b74f096b308431c77356d1c8937d827fd1d0f29dafc39096 +size 17718 diff --git a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_de.png b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_de.png index 3a19f3bf86..1a0298e410 100644 --- a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_de.png +++ b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:240798176e52148a905fb4beecd34e9ae962c5da9ba03324d3f3cf48ef9544ad -size 22605 +oid sha256:a366fe4261a7a35cdcd357814d56361b3fe30d96b94984866e78b0fac0dec742 +size 22667 diff --git a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_de.png b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_de.png index 828befb6d1..4029a678d4 100644 --- a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_de.png +++ b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f875b3189dd12e945dd7128e1c826e4b17463d098d790f52a4932cf27b878b5b -size 27015 +oid sha256:34d0a6f5093359b0f233d11152b1cb17905b11bfb71be11ce9ed3f41cd50e76e +size 27084 diff --git a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_de.png b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_de.png index edbda381af..95153ad95a 100644 --- a/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_de.png +++ b/screenshots/de/features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1cd78cd18060a2799221b3e6f3eb517bf6d597927fe4900d8c49349ca3a545d1 -size 32333 +oid sha256:836b4253c1846802ee4000455f91ba9a55195ab04f875cbece2bb57054456783 +size 32496 diff --git a/screenshots/de/features.messages.impl.timeline.components_CallMenuItem_Day_3_de.png b/screenshots/de/features.messages.impl.timeline.components_CallMenuItem_Day_3_de.png index 8a2b554cfe..7aebedf5a4 100644 --- a/screenshots/de/features.messages.impl.timeline.components_CallMenuItem_Day_3_de.png +++ b/screenshots/de/features.messages.impl.timeline.components_CallMenuItem_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:af71462d647769e7b003ebe9878b6ae75c09d47bdce0c9c5aaf90c960398fb54 -size 6275 +oid sha256:f34a79713b48c14bc96c3b1371c74cdf3703339af04bfa3cc90b022101b30abf +size 6114 diff --git a/screenshots/de/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_de.png b/screenshots/de/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_de.png index 3528c076eb..7522320c11 100644 --- a/screenshots/de/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_de.png +++ b/screenshots/de/features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4bf1663b19905d0da350f70de60a1561a3ccf7870b63ad151822908b69e0ab11 -size 42177 +oid sha256:37907f4f9f4f18857605e4e524793c0282100f07cf6e44fe8c8e4467c71bfca1 +size 42078 diff --git a/screenshots/de/features.messages.impl.topbars_MessagesViewTopBar_Day_0_de.png b/screenshots/de/features.messages.impl.topbars_MessagesViewTopBar_Day_0_de.png index f012ca51b8..89b6968710 100644 --- a/screenshots/de/features.messages.impl.topbars_MessagesViewTopBar_Day_0_de.png +++ b/screenshots/de/features.messages.impl.topbars_MessagesViewTopBar_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a582f6175541953aa8ca75a42990c50fd24befd4db63e10aad16d6dfa360ffff -size 41968 +oid sha256:9eee9b32dc1ebb91657140f277f4ef9f41167383b28d12a3b0d8137d8637fcf7 +size 41896 diff --git a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_0_de.png b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_0_de.png index a2afac1d7e..871afe71ef 100644 --- a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_0_de.png +++ b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:faf2b9b719419f5644c315c9b2e0c69bf5789107239b89b557d26c4b2815087d -size 59229 +oid sha256:e5a733462618eb242f77a46c18e66a3d98d7de1ff300441350a56bf59edcb63b +size 53727 diff --git a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_1_de.png b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_1_de.png index 94e921838f..5fe49e4950 100644 --- a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_1_de.png +++ b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0cd97628c4eab2c22a1b7f5268839313fb0e162df3a4b65e18861b816d7915d4 -size 58932 +oid sha256:4e1bb7419a82d26252fea05af5206635e64a1b64d4063ac51e5ff5c51fd3d655 +size 58261 diff --git a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_3_de.png b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_3_de.png index 38457ca8d2..e838aea107 100644 --- a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_3_de.png +++ b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5eec8a8effd80ef9b443ae64d90ebf37de0b06496d20c69d08d17c0dbc67181b -size 58732 +oid sha256:fb7f869a12d97b8890e582f378f6d6811d1cff943121d3513e964b89bd29bf9c +size 58676 diff --git a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_4_de.png b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_4_de.png index dbf0e397ab..3ca273fede 100644 --- a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_4_de.png +++ b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d6988ce2970cc634277fe3d6f6fc3769c8259bdfb465e55bbf0477bcd1bd83a -size 62803 +oid sha256:555e0b1dc3ad335956a9c9595ab074a8678b81a593d8d5789b64369be625b40e +size 57370 diff --git a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_5_de.png b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_5_de.png index 6987693d94..f3a824bcf6 100644 --- a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_5_de.png +++ b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:507ac618ea0b3a0ce08b22f9ed53736d2c264d9ff732583756276f184c4f3680 -size 61958 +oid sha256:a0d7f67c26cb32ed1d64ddf4abb629e9b72a6a38d74079c549a27b8c1ee9fca2 +size 56497 diff --git a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_6_de.png b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_6_de.png index a2afac1d7e..871afe71ef 100644 --- a/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_6_de.png +++ b/screenshots/de/features.preferences.impl.blockedusers_BlockedUsersView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:faf2b9b719419f5644c315c9b2e0c69bf5789107239b89b557d26c4b2815087d -size 59229 +oid sha256:e5a733462618eb242f77a46c18e66a3d98d7de1ff300441350a56bf59edcb63b +size 53727 diff --git a/screenshots/de/features.preferences.impl.root_MultiAccountSection_Day_0_de.png b/screenshots/de/features.preferences.impl.root_MultiAccountSection_Day_0_de.png deleted file mode 100644 index 71d906108f..0000000000 --- a/screenshots/de/features.preferences.impl.root_MultiAccountSection_Day_0_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:934c47b945f3eecd77a6ab6c050c3ca4f0594a78e05d292970e398f03883e82e -size 59248 diff --git a/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_0_de.png b/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_0_de.png index e08cac7ffe..9c1a6d041e 100644 --- a/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_0_de.png +++ b/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e5805062266fb2efac61ce1814526f39bb79421227e59968fd1bc56ed2ad6d4 -size 42026 +oid sha256:bd194f574a10021900922b975c3168b16f52e6710e1630e53784f25466ad0be9 +size 41559 diff --git a/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_1_de.png b/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_1_de.png index fdc2a6ff05..99ddb60522 100644 --- a/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_1_de.png +++ b/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7dbe9c6ad43bf8565729ab434faa610223d77b1d8d9de4757acccf781c47b5f7 -size 41853 +oid sha256:166e8fb118c62ddef9f92be1ae2ff427d60d8a3bc9a348b047c6d3a165afd730 +size 41377 diff --git a/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_0_de.png b/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_0_de.png index 7b3621de72..54daf8b831 100644 --- a/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_0_de.png +++ b/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2314627a1260dd216ce430b72c9bf4651865e73d8f115518b99b5f8dfd153b0f -size 43272 +oid sha256:7484ed26275f9b1198ff8ae6b9e1ccf149be88d43cce04bf4be7443abfac1f52 +size 42781 diff --git a/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_1_de.png b/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_1_de.png index 0f3320eeb4..546348fc80 100644 --- a/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_1_de.png +++ b/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4222dd22f478350a2f82ca8103cecc367453535e957490ab775d05f32742554 -size 43316 +oid sha256:f3ca986d2446bb2920809b20c0be5ccb0adf21383782613720d44784c3c5bab5 +size 42822 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_de.png index 4f14062a27..a4bc8d4e44 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5100a5f28d7b50041614ceffa1af0cc39f4499042db9015f1121b525ead0714 -size 65983 +oid sha256:39a79b789373312096c863a37afc548827a4d662571aa6c8efd62ff9c60b2a00 +size 65296 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png index 3220967582..875ef8326c 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9bea2e31996df7b7bd5c8c52b68b84c5b97ef5aa57a371665a4f2b204667219 -size 65870 +oid sha256:d95bf342ddba5663a36a1f435351e7a3017cad73f7cd58504913681feced1ce2 +size 65157 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png index dc09753419..a04a0cd23a 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8ef02193c4dc5171c0d0fcd79444a3a5b48157d5c6b26cb11d9d97a67321499 -size 55804 +oid sha256:e5ab43cd09460063624d2e583b71af3bb3a286890cbf07744d101042aa7c45f5 +size 56783 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png index bb3df793b8..7da0708b92 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8bc40679b33ab4c63b9a102388ca87c4c9d48461651cff9e2289604904a2ee0 -size 53277 +oid sha256:41d2484c7ddee013f9cf001dc2eb0ff8a99ac22b7e70816752c97893d1db4c95 +size 54265 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png index f8720be316..6d24520c56 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9fe026d2e48b1759d1c270615d87d23df2d7528d6fcfd2f91f39f0142abea5e6 -size 61953 +oid sha256:3afe4b55dd9e11397b9f4b5a99cfc6f5a1a4cebcbdc8cdfb0f81f43eb6912f15 +size 63039 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png new file mode 100644 index 0000000000..c0656d9b7e --- /dev/null +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ad55fc63c50a403a3218e9168df15c92f91430e60bd4adde45247080cf50543 +size 62971 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_de.png index 39882e6a27..ce06429382 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:483f7a76717c263bfd76df2487c548c16d159e5a150149671b540d84b4a5a326 -size 16124 +oid sha256:70b9a96c4dff57091a091d74896aa85ae1d5ed3a45e58dd46e0e4e5cc758150f +size 16149 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png index 5ce611d271..0446bc13ad 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5531d2f264a7b6c0f543a4ffb9987d4c7d60caec8f2d0d260a8b1fd1aae8c2a8 -size 52265 +oid sha256:5bf22144267e8ebed2c074cfe017aebcd5c59f5ad55cf81775802654aa0f5450 +size 52254 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_de.png index fd537c7a4e..3fc5b0b10c 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:855d5b61a769766d83a20afc32cef6477bb09cb84b29669a8807481373b3f958 -size 55451 +oid sha256:ea2b8ef893a86cff4960d16540a417d9c03b0c7c14952c0f798d95dabb2bcbd4 +size 55482 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_de.png index 2e3a538aaa..9d47bfbbfb 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4b70e827c255d99cc8f976b8ea1dd247c060eccaac1db132d0fa5d2a7bba8dd1 -size 55489 +oid sha256:5061a9d86c7b222f7be0d61d2ff4ca4da7504f50d172189c9c9a8a70baa1a126 +size 55517 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_de.png index 747cad00c9..09a60754b4 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:640f53a7cac7a3b6693d462bb86a50db212d749a8603e8edaeed6c874ae573ba -size 66148 +oid sha256:5a6779a089b642b924e927cdf0813dd25707dbaeaaab6bc0d4c255df3bc6f7c2 +size 66133 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png index 96a5fe50e1..6be2aa5649 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d71db8b8e66e0fcd0f82ad7356d3a9794bb4dc980dbfbf1545c00206776ddb90 -size 70427 +oid sha256:d768711fbfe3c3086657733175ad23601160ba9485365d1ed24b56e81c54061f +size 70451 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png index 1c3d282116..e4b304c7a2 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:175f2fcd689cd82461350b65db068202972182bda557895c403bbd93d6a73481 -size 64096 +oid sha256:5ac6592c003e271d3578152b1c579b457fd64673789173ec37d1a73cd55422cb +size 64133 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png index 482a1270c5..e5930b5c27 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b70911a26479225e26f4fa68e5629043a4e3d3fa7e2ef3c11682ac1fcf52c374 -size 63932 +oid sha256:cf48c5af53b599814c1a43db660283f091e4a1948839e211eb117b931df79a77 +size 63967 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png index c7a8938912..094c990d90 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:55b998f4f10f8aeb8b72a746b6f9645570b48b5b130f10e4e6d4bc239571b82f -size 57804 +oid sha256:e3664e7b03b65c06d0e79fa2b6d690cb1e1bcb33df279ce2e01b15b447f1a41d +size 57833 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png index c4aeacefe1..1c27d4d4f9 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58229d50524a34a5eba484ea7012876c6b90256fa0a293faadd8ebddc935db42 -size 61091 +oid sha256:06b099b4780f03abf3a9e3a6417c7981a83276bc5c689f9508db3c8e54a4631b +size 61079 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png index 5938604641..bc7cefa438 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5741c7ed5079e1dfeb125ea2a5f3ab429b01966b70fef16ade5d83785f785a7e -size 65477 +oid sha256:fdeb03d0a6a5edac44e9c9f6d27843ac86194d5791188c23d874ecbd5343f782 +size 65469 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png index 53ddd8d7d1..fa0f3ecc71 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:261e28da918e11842e7d80449de98b861979aa6ee2d32f6f4d4662084a7bfb49 -size 54978 +oid sha256:63856a50b0fa099695709dc720e600ae9b36b62cb3bfac28a940607c72efd5c5 +size 54966 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png index 482a1270c5..e5930b5c27 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b70911a26479225e26f4fa68e5629043a4e3d3fa7e2ef3c11682ac1fcf52c374 -size 63932 +oid sha256:cf48c5af53b599814c1a43db660283f091e4a1948839e211eb117b931df79a77 +size 63967 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png index e916b74f83..bbd4881433 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:817a9c7ab2ef22da1cedd89ba652696ca95fe623baa480f42b86a5e990e58e71 -size 58010 +oid sha256:fb9f15f43fe78b8cb9683297c3adec0b8354f3afe9b7deb523e0c94964c2ca7c +size 56601 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png index 9cad7e89e3..3bfa26d702 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a721a146e8c91aee975941f1c58484de7bf7d28073ec3b31027df72d0a398788 -size 31317 +oid sha256:be327333c430fe7de69ee8540ee2f499e2e02575e95c05fc54b5264fa79b8771 +size 31384 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png index d551980d61..4bded04dba 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40be9c1c2afaa5171b96a66adebf9c665324ff1cc323060b0998edad9f788e9c -size 59249 +oid sha256:9070e72ccf6ba4553cd093f686f55329221b88df7b188716f20b2029ad639517 +size 57820 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png index 4e8c43e825..0ef6abe726 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8174b00bbcae8f48833c10a474ddb26c2f003c23bb36b43c91b3a3c13485b23e -size 19444 +oid sha256:a9223b4e39ba96f63148d6b33ffb70cd3893926032bcf1b05e76193873f47716 +size 19654 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png index 631fd4634e..bcdf552747 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:76bbbeb0e07b75805decc4a25d815ec1b73f83947b861c71ef697463ff00d9be -size 50558 +oid sha256:31e3ddc060f3c87cd761dd58ff73ef00b0af8e2fba6bf06e27f0396e52a04df3 +size 54661 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png index ef5cc7a3d4..919ee0cbcd 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:148d51c2ea8929c978065e5db9a531f4611559d230b73ac3fde013992c3d28fb -size 43911 +oid sha256:a6df150ce5cdb2e3233444c122b6bbd0b71fcfb8819eccd15f7ddbafd7e2d4d6 +size 47665 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png index 71265a00fe..bab63e3455 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:afe4234500a2f3696e7e794bed9fb62477c3a6f1439d597a7df5cfd1a61fb73f -size 42978 +oid sha256:f53320f4b69908a32f3723a1d098eac5c993574e877dd1ce5faac9028ad4fb4e +size 46743 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png index 56d7e39c4f..a62aca41d7 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4d1963026fb35db84c4413a5c6e225657c95eabeee95b880afd8e7a59de9c28d -size 45475 +oid sha256:12d639b33a6424d0807bff2545b874b16abb2c0147662d04f21df28d915fe2e4 +size 49225 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png index eef53d5522..0cfbaa9762 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49607772cae3cc9f9e6e8436369a9e84392e1fb0892c2f9f4dbe2834f67cbdc8 -size 50557 +oid sha256:55626ae74436af585b326f621d6d5d75729d180c4d653882f81e1484dac753fe +size 52976 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png index 97921c3734..04a8ae33bd 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b52d24166c4f30cef7e158016c7d799dab0836750f5193b2997dea90698260da -size 47067 +oid sha256:dd49f1b0f3dae2a57e4a63b54a2cb98dffab50ed3b2cb9d46f951eb1ea2f99c8 +size 51549 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png index c005294209..eb68edb577 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0c524cf2a0ebd4afd7cf3517b6a10a8d7aef0f3b5dfd9f83438ac7983e1ca18 -size 52459 +oid sha256:851affa2b63b0c70a282c182bf1ce615283c6d0ed732ee3b3102d3dcb862349c +size 57340 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png index 3f12de9672..386a05f453 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:739a7daec14bf01495a99e7e9584e3fdf4a26b1a7135cb0a109d32d275ab4344 -size 45484 +oid sha256:711800e228ac74d8971a383ecd85f560d050000f886d6107aa7ea0c9d6099d95 +size 49348 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png index d83fa83f95..ac8d242b19 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d80cbcafde684e8c85e36c1106f4cf3d945856c6df6c4455f6d8f1d2b1ffe459 -size 45172 +oid sha256:4624bd99900eb3d30256aa81dbe6c48f017480ebc4c97d3fbf47529ffd62e899 +size 49078 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png index 5f861eda69..f70a5bf36d 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ed8de485d7c5d33e08ed500600848b29c49d03c8f51de3484781c05963eb34f -size 47813 +oid sha256:612ffe06d38570e32215b9f117f979382832a9aed3fddcde38b0a461bf1b653d +size 51684 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png index 481cc91dee..867cb18108 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:658a968e9ca2d1f55766a45c6c101e136eafefe1c511d22f8368ae42cc5319eb -size 52820 +oid sha256:11ebd0e210579c60b07136685c82f3d73648a3742344d4d15a5ed3df9b48ced9 +size 55476 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png index 9632558d7b..6ec398b86b 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e905e5db59825bd332e89d69fc741c4146d0e6f8bdeab428dbc0e6eb27f3341 -size 49369 +oid sha256:00b2576dacba4388bb8259a7c6fbacbe713c805695efc4ea6e98c50f0cd28196 +size 53621 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png index 7fdf34a72d..6b2e354a36 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:90f702d73cbcbb3e5edcef7cf685d7fa03b0b72caca50f3e8de11311d901e765 -size 30323 +oid sha256:2fb101aadb226cf66041f2abda6edc1fb9877765ad9d88607135503bdc2037dd +size 37509 diff --git a/screenshots/de/features.startchat.impl.components_SearchMultipleUsersResultItem_de.png b/screenshots/de/features.startchat.impl.components_SearchMultipleUsersResultItem_de.png index b982015aa8..28418751a5 100644 --- a/screenshots/de/features.startchat.impl.components_SearchMultipleUsersResultItem_de.png +++ b/screenshots/de/features.startchat.impl.components_SearchMultipleUsersResultItem_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9095e96b3bec5fe4a0ae7c7e8d92da5c3b6cf1124d861841bb0beebf1a05c341 -size 101077 +oid sha256:ecea6fc10d3d405e26f5ed488bc858b78e7dab1d6cafb76cc7a2feed3d3eddc6 +size 96954 diff --git a/screenshots/de/features.startchat.impl.components_SearchSingleUserResultItem_de.png b/screenshots/de/features.startchat.impl.components_SearchSingleUserResultItem_de.png index 17b20844ec..0bae881bb1 100644 --- a/screenshots/de/features.startchat.impl.components_SearchSingleUserResultItem_de.png +++ b/screenshots/de/features.startchat.impl.components_SearchSingleUserResultItem_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2ce695e52de4d6bfdb0aaed99f8ece00e6029216f5e410a86d714f84e367ed37 -size 51258 +oid sha256:feab59ca75900214799f9a81f50a96a5622224bacf6c236857d7c7ae267108e8 +size 52398 diff --git a/screenshots/de/features.startchat.impl.components_UserListView_Day_0_de.png b/screenshots/de/features.startchat.impl.components_UserListView_Day_0_de.png index 1f2648a705..20761a5b3e 100644 --- a/screenshots/de/features.startchat.impl.components_UserListView_Day_0_de.png +++ b/screenshots/de/features.startchat.impl.components_UserListView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f097b3df60f86719f7afeff0c47139d1ebf918b181bae9f8e1735368ef9bd503 -size 9248 +oid sha256:03ef449ecfe5699f1135a83e128d6efb93efc53a84036ff364c6ea489ef9a781 +size 9269 diff --git a/screenshots/de/features.startchat.impl.components_UserListView_Day_1_de.png b/screenshots/de/features.startchat.impl.components_UserListView_Day_1_de.png index bf860dc9ed..1ff42f7afe 100644 --- a/screenshots/de/features.startchat.impl.components_UserListView_Day_1_de.png +++ b/screenshots/de/features.startchat.impl.components_UserListView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cdf90ae9ef087c52d69297d9c98e81f49a63ff92029a1925dbe3f666106536b -size 21801 +oid sha256:058ac0f03151792e2a55090a4f170e5332e94339c56fbf029b05b6050c155549 +size 21841 diff --git a/screenshots/de/features.startchat.impl.components_UserListView_Day_2_de.png b/screenshots/de/features.startchat.impl.components_UserListView_Day_2_de.png index 79a25499ad..05a41f4fd0 100644 --- a/screenshots/de/features.startchat.impl.components_UserListView_Day_2_de.png +++ b/screenshots/de/features.startchat.impl.components_UserListView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f3641f966fcf71259afeedc2c4b32d3e2c581af23c9c4220c9b80152501e77f -size 7949 +oid sha256:f29343d52eb4641591c6e1fba1d889e5ff5d39839708cf79697fc1745ed90c67 +size 8077 diff --git a/screenshots/de/features.startchat.impl.components_UserListView_Day_7_de.png b/screenshots/de/features.startchat.impl.components_UserListView_Day_7_de.png index 3ba65e7151..80bfc28b09 100644 --- a/screenshots/de/features.startchat.impl.components_UserListView_Day_7_de.png +++ b/screenshots/de/features.startchat.impl.components_UserListView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:251848f9afc246fb2ec6f36da893878360e24634efdcb3920aac174768f9ad6e -size 12298 +oid sha256:dc767435f491d1700a220497c0cc6d73da3d823e9f042bb6e9c65eaa7fcc018c +size 12375 diff --git a/screenshots/de/features.startchat.impl.components_UserListView_Day_9_de.png b/screenshots/de/features.startchat.impl.components_UserListView_Day_9_de.png index 209c122051..1f2c501d1a 100644 --- a/screenshots/de/features.startchat.impl.components_UserListView_Day_9_de.png +++ b/screenshots/de/features.startchat.impl.components_UserListView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ffb21cbd09d472fe88da527a064a57862e40ffbc3208247398ab3db45ddcc14 -size 37168 +oid sha256:59d6fcb404f29561e3e56ec4a76c07b8d88d813c790ce4badb54699415835a1d +size 38127 diff --git a/screenshots/de/features.startchat.impl.root_StartChatView_Day_0_de.png b/screenshots/de/features.startchat.impl.root_StartChatView_Day_0_de.png index ac7f3fc01b..bdc1faebb7 100644 --- a/screenshots/de/features.startchat.impl.root_StartChatView_Day_0_de.png +++ b/screenshots/de/features.startchat.impl.root_StartChatView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:23f792a9a1f33ec9bf3548485579983c98675e2ffb0400489cafa6aeabbd68bf -size 28076 +oid sha256:771be782de8b73b0bdb9ac6208102f2f773cee37e98fa614334c6ad9eb7f1299 +size 28118 diff --git a/screenshots/de/features.startchat.impl.root_StartChatView_Day_1_de.png b/screenshots/de/features.startchat.impl.root_StartChatView_Day_1_de.png index 0582665018..eddbdd659b 100644 --- a/screenshots/de/features.startchat.impl.root_StartChatView_Day_1_de.png +++ b/screenshots/de/features.startchat.impl.root_StartChatView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:074f07583d066deac988cb26df841a4d6a8ec1713af4eb42c89bee693fe6baa6 -size 21018 +oid sha256:a535b503bd51307d37e81071e90e993b9197beddb771e6164525f5d4ea30421a +size 21112 diff --git a/screenshots/de/features.startchat.impl.root_StartChatView_Day_2_de.png b/screenshots/de/features.startchat.impl.root_StartChatView_Day_2_de.png index f9be1b4c79..a970242e06 100644 --- a/screenshots/de/features.startchat.impl.root_StartChatView_Day_2_de.png +++ b/screenshots/de/features.startchat.impl.root_StartChatView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eeba1031812aa4029a3d0fe55b637b2b1187c9b809240280e3ac93348f03b7eb -size 31837 +oid sha256:e7698997e24292a0faf338ccdd386c95c475f7d0bc835e94a82703fcf257bab4 +size 31951 diff --git a/screenshots/de/features.startchat.impl.root_StartChatView_Day_3_de.png b/screenshots/de/features.startchat.impl.root_StartChatView_Day_3_de.png index e0af3ed6dc..3e70e4d220 100644 --- a/screenshots/de/features.startchat.impl.root_StartChatView_Day_3_de.png +++ b/screenshots/de/features.startchat.impl.root_StartChatView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e2fe8f9ac0af9e866f4e79af1c99680495f4a7ef96ebc440b48eb22419562565 -size 55164 +oid sha256:16da63819524ef1e4535776caaa9e073731fe79f85ba798b57d8552999cc8789 +size 52219 diff --git a/screenshots/de/features.startchat.impl.root_StartChatView_Day_4_de.png b/screenshots/de/features.startchat.impl.root_StartChatView_Day_4_de.png index 8c02706075..a0e0627c21 100644 --- a/screenshots/de/features.startchat.impl.root_StartChatView_Day_4_de.png +++ b/screenshots/de/features.startchat.impl.root_StartChatView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3cd6e4e494cd61e5cccc61786e33565e66108e3d9315dade7e091ee8233047e7 -size 45620 +oid sha256:f3a846c1d350efed3709f806d07983cf26fe9b6de78e4f3bce3df55002c2eb89 +size 45654 diff --git a/screenshots/de/features.startchat.impl.root_StartChatView_Day_5_de.png b/screenshots/de/features.startchat.impl.root_StartChatView_Day_5_de.png index e7b3e18d43..24e0ba7b39 100644 --- a/screenshots/de/features.startchat.impl.root_StartChatView_Day_5_de.png +++ b/screenshots/de/features.startchat.impl.root_StartChatView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f7000b367f113aaf18a08089e01cfc3d46228032a0a9fdab19a9e5c89fa28c24 -size 32084 +oid sha256:d81b395d52397f11e919d4f1de9cf64b4adb12a5c060c91ddbc91cce4bc71e2c +size 32104 diff --git a/screenshots/de/libraries.accountselect.impl_AccountSelectView_Day_1_de.png b/screenshots/de/libraries.accountselect.impl_AccountSelectView_Day_1_de.png index efd1b648c2..79b4891388 100644 --- a/screenshots/de/libraries.accountselect.impl_AccountSelectView_Day_1_de.png +++ b/screenshots/de/libraries.accountselect.impl_AccountSelectView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d9fa23fe8db80a547f5955eee300a43d64d277f17fae32dd002fca1141100318 -size 49053 +oid sha256:1a107feebf22d62e559f7ea31951c6924f8991244efa2a032961a2808c432bf6 +size 43697 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 d72b78ab4c..056bccc5b5 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:853edd40133d53f4109934cadfd7efd2cb6c6aeab6ad345b29a9008e902a9904 -size 36437 +oid sha256:ad5c8bbac1c770be5924fa44d79fb728b54593a6091b5a3fc78a69936668eab7 +size 34121 diff --git a/screenshots/de/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_de.png b/screenshots/de/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_de.png index 5be94f8d2d..026aa22f79 100644 --- a/screenshots/de/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_de.png +++ b/screenshots/de/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5117f9e69029fc92ac52e9db641a4faf1b285dfd21bd607b5001a83a10387848 -size 10359 +oid sha256:f846e8780ecc4d76c5623f67b1fb2637daa0dd3844464aa59ed122f553d6508f +size 17214 diff --git a/screenshots/de/libraries.matrix.ui.components_CheckableUnresolvedUserRow_de.png b/screenshots/de/libraries.matrix.ui.components_CheckableUnresolvedUserRow_de.png index 9795c4e10c..262a2e6c45 100644 --- a/screenshots/de/libraries.matrix.ui.components_CheckableUnresolvedUserRow_de.png +++ b/screenshots/de/libraries.matrix.ui.components_CheckableUnresolvedUserRow_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4fd702f03c1886684a2ded6deb907f4f64c2d8c749eb8a86c4f6f697625a616 -size 127507 +oid sha256:d4450043c6ecfee5bdbd017027e5b20372b35f01ac3821d5a73cfbf807799424 +size 116244 diff --git a/screenshots/de/libraries.matrix.ui.components_UnresolvedUserRow_de.png b/screenshots/de/libraries.matrix.ui.components_UnresolvedUserRow_de.png index 195fc6212a..f6d4ee1516 100644 --- a/screenshots/de/libraries.matrix.ui.components_UnresolvedUserRow_de.png +++ b/screenshots/de/libraries.matrix.ui.components_UnresolvedUserRow_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e49d17ed624b012da26430405c715f6be034e2c73c1202ab979002443764f1c7 -size 73774 +oid sha256:a2bde77f49fd90f85c376daaf41346838c2d3e91a8cf52d734c61c2f419aa369 +size 74298 diff --git a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_0_de.png b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_0_de.png index a685eda44f..6bfc8717fd 100644 --- a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_0_de.png +++ b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d93ffd5275a31b3f10d3118fd969b444dca509b99a2d38ec505b3f40d5dca41 -size 14069 +oid sha256:a0326603669450bb553227feb450a83c2c4f8a83a0b45fc00a0439b5ae6cee40 +size 14087 diff --git a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_1_de.png b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_1_de.png index b5f861d09b..b62ad00757 100644 --- a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_1_de.png +++ b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3bd016c197832e8c4bafc03f6e01298ac9a4f28a7ffd56c072d08dcd1abc7a06 -size 12049 +oid sha256:4e1d912da6419dc1baec30171634ac9764862390d714191b71c2b94d896fa10a +size 12058 diff --git a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_2_de.png b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_2_de.png index 837a336f66..5ce059f931 100644 --- a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_2_de.png +++ b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb3260ccf57e31534397b97c896200fa222c3ce1c41dbeb34ecee18deac26ae3 -size 32571 +oid sha256:53f60adb0f0abafad2a18536e13a64b6a9115f78c51de81fcf87521e14de79e9 +size 32590 diff --git a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_3_de.png b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_3_de.png index 98ed051caf..4354ba502c 100644 --- a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_3_de.png +++ b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a8ae61dde38c637924bd95c73408856d4cdfb61728128983354ea566b5a02b6f -size 30936 +oid sha256:5171547f2ff09da353a6a2fb52a734930c165cdcf22b1dca58b89e47d2c3626d +size 30933 diff --git a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_4_de.png b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_4_de.png index e6ffefefbb..5704892c4a 100644 --- a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_4_de.png +++ b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:417ae6a02eb2ac758bd42f287c9ac9b35565afda2fa62783f03aeaca56990da5 +oid sha256:ad039c7af5726a980a586bd483c4aa938dde1cc2f116882ad7b6ca343495805d size 35196 diff --git a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_5_de.png b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_5_de.png index 40ac87be2e..30c7d47ede 100644 --- a/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_5_de.png +++ b/screenshots/de/libraries.roomselect.impl_RoomSelectView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2a40da17d87b7b39c4064cd148327723efda66bea208bd683efeb477616642c4 -size 30235 +oid sha256:180014cd36d6721b426d212581f9cceb3ba55f6e3e11fd5357d9311f786526c0 +size 30257 diff --git a/screenshots/html/data.js b/screenshots/html/data.js index 2705fbc626..8b1a2cf28c 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,80 +1,80 @@ // 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",20434,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20442,], ["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",20434,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20434,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20434,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20434,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20434,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20434,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20434,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20434,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20434,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20434,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20434,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20442,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20442,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20442,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20442,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20442,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20442,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20442,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20442,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20442,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20442,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20442,], ["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",20434,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20434,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20442,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20442,], ["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",20434,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20434,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20442,], ["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",20434,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20434,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20434,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20434,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20434,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20434,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20434,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20434,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20434,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20434,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20434,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20434,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20434,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20434,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20434,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20442,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20442,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20442,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20442,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20442,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20442,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20442,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20442,], ["libraries.designsystem.theme.components_AllIcons_Icons_en","",0,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20434,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20434,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20434,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20434,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20434,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20442,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20442,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20442,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20442,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20442,], ["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",20434,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20442,], ["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",20434,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20442,], ["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",20434,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20442,], ["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",20434,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20442,], ["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",20434,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20442,], ["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,], @@ -84,19 +84,19 @@ export const screenshots = [ ["libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_7_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_7_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_8_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_8_en",0,], -["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20434,], -["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20434,], -["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20434,], -["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20434,], -["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20434,], -["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20434,], -["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20434,], -["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20434,], -["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20434,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_0_en","",20444,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en","",20444,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en","",20444,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en","",20444,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en","",20444,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en","",20444,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en","",20444,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en","",20444,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en","",20444,], ["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",20434,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20442,], ["libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en","",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_0_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_1_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_1_en",0,], @@ -123,22 +123,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",20434,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20442,], ["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",20434,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20434,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20434,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20434,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20434,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20434,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20434,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20442,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20442,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20442,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20442,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20442,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20442,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20442,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20434,], -["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20434,], -["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20434,], -["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20434,], -["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20434,], +["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20442,], +["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20442,], +["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20442,], +["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20442,], +["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20442,], ["features.rageshake.impl.bugreport_BugReportViewNight_0_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_1_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_2_en","",0,], @@ -148,133 +148,136 @@ export const screenshots = [ ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20434,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20434,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20442,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20442,], ["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], ["features.call.impl.ui_CallScreenView_Day_0_en","features.call.impl.ui_CallScreenView_Night_0_en",0,], -["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20434,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20434,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20434,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20434,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20434,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20434,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20442,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20442,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20442,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20442,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20442,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20442,], ["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",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20434,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20434,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20434,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20434,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20434,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20434,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20434,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20442,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20442,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20442,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20442,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20442,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20442,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20442,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en",20444,], ["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",20434,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20434,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20434,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20434,], -["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20434,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20442,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20442,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20442,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20442,], +["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20442,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20434,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20442,], ["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",20434,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20434,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20434,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20434,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20434,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20434,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20434,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20434,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20442,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20442,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20442,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20442,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20442,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20442,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20442,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20442,], ["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",20434,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20434,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20434,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20434,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20434,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20434,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20434,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20434,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20434,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20434,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20442,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20442,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20442,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20442,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20442,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20442,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20442,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20442,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20442,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20442,], ["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","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20434,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20434,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20434,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20434,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20434,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20434,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20442,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20442,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20442,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20442,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20442,], ["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",20434,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20434,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20434,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20434,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20434,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20434,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20434,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20434,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20434,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20434,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20434,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20434,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20434,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20434,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20434,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20434,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20434,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20434,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20434,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20434,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20442,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20442,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20442,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20442,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20442,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20442,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20442,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20442,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20442,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20442,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20442,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20442,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20442,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20442,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20442,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20442,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20442,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20442,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20442,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20442,], ["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","",20434,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20434,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20434,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20434,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20434,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20434,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20434,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20442,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20442,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20442,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20442,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20442,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20442,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20442,], ["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",20434,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20434,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20434,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20442,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20442,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20442,], ["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",20434,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20442,], ["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",20434,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20434,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20434,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20434,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20434,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20434,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20434,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20434,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20442,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20442,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20442,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20442,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en",20444,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en",20444,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20442,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20442,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20442,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20442,], ["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,], @@ -289,19 +292,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",20434,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20434,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20434,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20434,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20434,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20434,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20434,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20434,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20434,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20434,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20434,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20434,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20434,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20442,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20442,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20442,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20442,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20442,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20442,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20442,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20442,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20442,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20442,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20442,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20442,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20442,], ["libraries.matrix.ui.components_EditableAvatarView_Day_0_en","libraries.matrix.ui.components_EditableAvatarView_Night_0_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_1_en","libraries.matrix.ui.components_EditableAvatarView_Night_1_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_2_en","libraries.matrix.ui.components_EditableAvatarView_Night_2_en",0,], @@ -312,14 +315,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",20434,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20434,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20442,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20442,], ["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,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20434,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20434,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20434,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en",20444,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en",20444,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en",20444,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en",20444,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en",20444,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en",20444,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20442,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20442,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20442,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_0_en","features.linknewdevice.impl.screens.error_ErrorView_Night_0_en",20444,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_1_en","features.linknewdevice.impl.screens.error_ErrorView_Night_1_en",20444,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_2_en","features.linknewdevice.impl.screens.error_ErrorView_Night_2_en",20444,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_3_en","features.linknewdevice.impl.screens.error_ErrorView_Night_3_en",20444,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_4_en","features.linknewdevice.impl.screens.error_ErrorView_Night_4_en",20444,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_5_en","features.linknewdevice.impl.screens.error_ErrorView_Night_5_en",20444,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_6_en","features.linknewdevice.impl.screens.error_ErrorView_Night_6_en",20444,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_7_en","features.linknewdevice.impl.screens.error_ErrorView_Night_7_en",20444,], ["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,], @@ -338,44 +355,44 @@ 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",20434,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20434,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20434,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20442,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20442,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20442,], ["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",20434,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20434,], +["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20442,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20442,], ["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.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en","features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en",20437,], -["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20434,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20434,], -["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20434,], -["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20434,], -["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20434,], +["features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en","features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en",20442,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20442,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20442,], +["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20442,], +["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20442,], +["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20442,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20434,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20434,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20442,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20442,], ["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",20434,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20434,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20434,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20434,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20434,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20434,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20434,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20434,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20434,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20434,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20434,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20434,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20442,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20442,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20442,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20442,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20442,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20442,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20442,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20442,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20442,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20442,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20442,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20442,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.ruler_HorizontalRuler_Day_0_en","libraries.designsystem.ruler_HorizontalRuler_Night_0_en",0,], ["libraries.designsystem.theme.components_IconButton_Buttons_en","",0,], @@ -388,8 +405,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",20434,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20434,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20442,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20442,], ["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,], @@ -397,109 +414,115 @@ 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",20434,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20442,], ["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",20434,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20442,], ["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",20434,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20442,], ["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20434,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20434,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20442,], ["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",20434,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20434,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20434,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20442,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20442,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20442,], ["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",20434,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20434,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20434,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20434,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20442,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20442,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20442,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20442,], ["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",20434,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20434,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20434,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20434,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20434,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20434,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20434,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20434,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20442,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20442,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20442,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20442,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20442,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20442,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20442,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20442,], ["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",20434,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20434,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20434,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20434,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20434,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20434,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20434,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20434,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20434,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20434,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20434,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20442,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20442,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20442,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20442,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20442,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20442,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20442,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20442,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20442,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], -["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20434,], -["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20434,], +["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20442,], +["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20442,], ["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",20434,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20434,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20434,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20434,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20434,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20434,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20434,], -["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20434,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20442,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20442,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20442,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20442,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20442,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20442,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20442,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20442,], ["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",20444,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en",0,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en",20444,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en",20444,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en",0,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en",20444,], ["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",20434,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20442,], ["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,], @@ -554,38 +577,38 @@ 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",20434,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20434,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20434,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20434,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20442,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20442,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20442,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20442,], ["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",20434,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20434,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20434,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20434,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20434,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20434,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20434,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20434,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20434,], -["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20434,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20434,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20434,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20434,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20434,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20434,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20434,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20434,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20434,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20434,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20434,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20434,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20434,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20434,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20434,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20434,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20442,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20442,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20442,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20442,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20442,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20442,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20442,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20442,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20442,], +["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20442,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20442,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20442,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20442,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20442,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20442,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20442,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20442,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20442,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20442,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20442,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20442,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20442,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20442,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20442,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20442,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20434,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20442,], ["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,], @@ -598,22 +621,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",20434,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20434,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20442,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20442,], ["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",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20434,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20434,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20442,], ["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,], @@ -621,14 +644,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","",20434,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20434,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20442,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20442,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20434,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20442,], ["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","",20434,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20442,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -642,7 +665,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",20434,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20442,], ["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,], @@ -651,7 +674,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",20434,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20442,], ["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,], @@ -659,141 +682,142 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessagesReactionButton_Day_1_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_1_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_2_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_2_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_3_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_3_en",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20434,], -["features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en","features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en",20437,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20434,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20434,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20434,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20434,], -["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20437,], -["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20437,], -["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20437,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20434,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20434,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20434,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20434,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20434,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20434,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20434,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20434,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20434,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20442,], +["features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en","features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en",20442,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20442,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20442,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20442,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20442,], +["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20442,], +["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20442,], +["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20442,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20442,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20442,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20442,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20442,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20442,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20442,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20442,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20442,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20442,], ["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",20434,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20442,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], -["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20434,], +["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",0,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_MultipleSelectionDialog_Night_0_en",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelectedTrailingContent_Multiple_selection_List_item_-_selection_in_trailing_content_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelected_Multiple_selection_List_item_-_selection_in_supporting_text_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItem_Multiple_selection_List_item_-_no_selection_List_items_en","",0,], ["libraries.designsystem.theme.components_NavigationBar_App_Bars_en","",0,], -["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20434,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20434,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20434,], +["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20442,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20442,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20442,], +["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",20434,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20434,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20434,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20434,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20434,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20434,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20434,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20434,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20442,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20442,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20442,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20442,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20442,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20442,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20442,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20442,], ["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",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20434,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20442,], ["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",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20434,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20434,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20442,], ["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",20434,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20442,], ["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",0,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20434,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20434,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20434,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20434,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20442,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20442,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20442,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20442,], ["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",20434,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20434,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20434,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20442,], ["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",20434,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20434,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20434,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20434,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20434,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20434,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20434,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20434,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20434,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20434,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20434,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20434,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20434,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20434,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20442,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20442,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20442,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20442,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20442,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20434,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20434,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20434,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20434,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20434,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20442,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20442,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20442,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20442,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20442,], ["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",20434,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20434,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20434,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20434,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20434,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20434,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20434,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20434,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20434,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20434,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20434,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20442,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20442,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20442,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20442,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20442,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20442,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20442,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20442,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20442,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20442,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20442,], ["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,], @@ -807,206 +831,207 @@ export const screenshots = [ ["libraries.designsystem.components.preferences_PreferenceRow_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSlide_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en","",0,], -["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20434,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20434,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20434,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20434,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20442,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20442,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20442,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20442,], ["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","",20434,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20434,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20442,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20442,], ["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",20434,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20434,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20434,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20434,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20434,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20434,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20434,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20434,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20434,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20434,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20434,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20434,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20434,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20434,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20434,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20434,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20434,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20434,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20434,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20434,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20434,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20434,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20434,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20434,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20434,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20434,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20434,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20442,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20442,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20442,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20442,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20442,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20442,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20442,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20442,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20442,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20442,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20442,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20442,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20442,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20442,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20442,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20442,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20442,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20442,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20442,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20442,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20442,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20442,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20442,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20442,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20442,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20442,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20442,], +["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",20434,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20434,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20442,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20442,], ["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",20434,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20434,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20434,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20434,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20434,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20434,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20434,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20442,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20442,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20442,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20442,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20442,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20442,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20442,], ["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",20434,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20434,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20434,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20434,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20434,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20434,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20434,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20434,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20434,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20434,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20434,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20434,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20434,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20434,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20434,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20434,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20434,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20442,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20442,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20442,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20442,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20442,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20442,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20442,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20442,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20442,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20442,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20442,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20442,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20442,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20442,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20442,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20442,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20442,], ["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",20434,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20434,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20434,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20434,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20434,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20434,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20434,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20434,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20434,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20434,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20434,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20434,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20434,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20442,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20442,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20442,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20442,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20442,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20442,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20442,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20442,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20442,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20442,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20442,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20442,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20442,], ["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",20434,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20434,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20434,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20434,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20434,], -["features.roomdetails.impl_RoomDetails_0_en","",20434,], -["features.roomdetails.impl_RoomDetails_10_en","",20434,], -["features.roomdetails.impl_RoomDetails_11_en","",20434,], -["features.roomdetails.impl_RoomDetails_12_en","",20434,], -["features.roomdetails.impl_RoomDetails_13_en","",20434,], -["features.roomdetails.impl_RoomDetails_14_en","",20434,], -["features.roomdetails.impl_RoomDetails_15_en","",20434,], -["features.roomdetails.impl_RoomDetails_16_en","",20434,], -["features.roomdetails.impl_RoomDetails_17_en","",20434,], -["features.roomdetails.impl_RoomDetails_18_en","",20434,], -["features.roomdetails.impl_RoomDetails_19_en","",20434,], -["features.roomdetails.impl_RoomDetails_1_en","",20434,], -["features.roomdetails.impl_RoomDetails_2_en","",20434,], -["features.roomdetails.impl_RoomDetails_3_en","",20434,], -["features.roomdetails.impl_RoomDetails_4_en","",20434,], -["features.roomdetails.impl_RoomDetails_5_en","",20434,], -["features.roomdetails.impl_RoomDetails_6_en","",20434,], -["features.roomdetails.impl_RoomDetails_7_en","",20434,], -["features.roomdetails.impl_RoomDetails_8_en","",20434,], -["features.roomdetails.impl_RoomDetails_9_en","",20434,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20434,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20434,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20434,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20434,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20434,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20434,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20434,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20434,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20434,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20442,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20442,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20442,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20442,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20442,], +["features.roomdetails.impl_RoomDetails_0_en","",20442,], +["features.roomdetails.impl_RoomDetails_10_en","",20442,], +["features.roomdetails.impl_RoomDetails_11_en","",20442,], +["features.roomdetails.impl_RoomDetails_12_en","",20442,], +["features.roomdetails.impl_RoomDetails_13_en","",20442,], +["features.roomdetails.impl_RoomDetails_14_en","",20442,], +["features.roomdetails.impl_RoomDetails_15_en","",20442,], +["features.roomdetails.impl_RoomDetails_16_en","",20442,], +["features.roomdetails.impl_RoomDetails_17_en","",20442,], +["features.roomdetails.impl_RoomDetails_18_en","",20442,], +["features.roomdetails.impl_RoomDetails_19_en","",20442,], +["features.roomdetails.impl_RoomDetails_1_en","",20442,], +["features.roomdetails.impl_RoomDetails_2_en","",20442,], +["features.roomdetails.impl_RoomDetails_3_en","",20442,], +["features.roomdetails.impl_RoomDetails_4_en","",20442,], +["features.roomdetails.impl_RoomDetails_5_en","",20442,], +["features.roomdetails.impl_RoomDetails_6_en","",20442,], +["features.roomdetails.impl_RoomDetails_7_en","",20442,], +["features.roomdetails.impl_RoomDetails_8_en","",20442,], +["features.roomdetails.impl_RoomDetails_9_en","",20442,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20442,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20442,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20442,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20442,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20442,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20442,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20442,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20442,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20442,], ["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",20434,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20434,], -["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20434,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20434,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20434,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20434,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20434,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20434,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20434,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20442,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20442,], +["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20442,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20442,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20442,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20442,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20442,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20442,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20442,], ["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",20434,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20434,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20434,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20434,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20434,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20434,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20434,], -["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20434,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20434,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20434,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20434,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20434,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20434,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20434,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20434,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20434,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20434,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20442,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20442,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20442,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20442,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20442,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20442,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20442,], +["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20442,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20442,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20442,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20442,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20442,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20442,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20442,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20442,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20442,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20442,], ["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",20434,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20434,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20434,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20434,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20434,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20434,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20434,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20434,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20434,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20434,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20434,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20434,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20434,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20434,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20442,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20442,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20442,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20442,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20442,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20442,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20442,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20442,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20442,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20442,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20442,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20442,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20442,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20442,], ["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,], @@ -1029,14 +1054,14 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_26_en","features.home.impl.components_RoomSummaryRow_Night_26_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_27_en","features.home.impl.components_RoomSummaryRow_Night_27_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_28_en","features.home.impl.components_RoomSummaryRow_Night_28_en",0,], -["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20434,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20434,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20434,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20434,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20434,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20434,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20434,], -["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20434,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20442,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20442,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20442,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20442,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20442,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20442,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20442,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20442,], ["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",0,], ["features.home.impl.components_RoomSummaryRow_Day_3_en","features.home.impl.components_RoomSummaryRow_Night_3_en",0,], @@ -1046,105 +1071,109 @@ 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",20434,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20434,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20434,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20442,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20442,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20442,], ["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",20434,], -["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20434,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20434,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20434,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20442,], +["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20442,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en",20444,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en",20444,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en",20444,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en",20444,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20442,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20442,], ["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","",20434,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20442,], ["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","",20434,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20434,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20434,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20434,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20434,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20434,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20434,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20434,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20434,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20434,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20434,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20434,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20434,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20434,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20442,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20442,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20442,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20442,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20442,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20442,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20442,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20442,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20442,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20442,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20442,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20442,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20442,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20442,], ["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,], @@ -1158,11 +1187,11 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_1_en","libraries.matrix.ui.components_SelectedUser_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedUsersRowList_Day_0_en","libraries.matrix.ui.components_SelectedUsersRowList_Night_0_en",0,], ["libraries.textcomposer.components_SendButton_Day_0_en","libraries.textcomposer.components_SendButton_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20434,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20434,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20434,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20434,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20434,], +["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20442,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20442,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20442,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20442,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20442,], ["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,], @@ -1172,27 +1201,28 @@ 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",20434,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20434,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20434,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20434,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20434,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20434,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20434,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20434,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20442,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20442,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20442,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20442,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20442,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20442,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20442,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20442,], ["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",20434,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20434,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20434,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20434,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20434,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20434,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20434,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20434,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20434,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20434,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20442,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20442,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20442,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20442,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20442,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20442,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20442,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20442,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20442,], +["features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en","features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en",20444,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20442,], ["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,], @@ -1202,102 +1232,102 @@ 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",20434,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20442,], ["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",20434,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20442,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20434,], -["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20434,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20434,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20442,], +["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20442,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20442,], ["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",20434,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20434,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20434,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20434,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20434,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20434,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20434,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20434,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20434,], -["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20434,], -["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20434,], -["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20434,], -["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20434,], -["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20434,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20434,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20434,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20434,], -["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20434,], -["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20434,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20442,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20442,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20442,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20442,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20442,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20442,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20442,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20442,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20442,], +["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20442,], +["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20442,], +["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20442,], +["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20442,], +["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20442,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20442,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20442,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20442,], +["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20442,], +["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20442,], ["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",20434,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20434,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20434,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20434,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20434,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20434,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20434,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20442,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20442,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20442,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20442,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20442,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20442,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20442,], ["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",20434,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20442,], ["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",20434,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20442,], ["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",20434,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20434,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20434,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20434,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20434,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20434,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20434,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20434,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20434,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20434,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20434,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20434,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20434,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20434,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20434,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20442,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20442,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20442,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20442,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20442,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20442,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20442,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20442,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20442,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20442,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20442,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20442,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20442,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20442,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20442,], ["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",20434,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20434,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20442,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20442,], ["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,], @@ -1309,16 +1339,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",20434,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20434,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20434,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20434,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20434,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20442,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20442,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20442,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20442,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20442,], ["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",20434,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20434,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20442,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20442,], ["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,], @@ -1328,18 +1358,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",20434,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20442,], ["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",20434,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20442,], ["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,], @@ -1347,18 +1377,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",20434,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20442,], ["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",20434,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20434,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20442,], ["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",20434,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20442,], ["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,], @@ -1367,41 +1397,41 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20442,], ["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",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20442,], ["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",20434,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20442,], ["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","",20434,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20442,], ["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",20434,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20434,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20442,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20442,], ["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",20434,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20442,], ["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",20434,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20434,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20434,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20442,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20442,], ["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",20434,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20434,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20442,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20442,], ["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",20434,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20442,], ["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,], @@ -1410,8 +1440,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",20434,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20442,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20442,], ["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,], @@ -1426,8 +1456,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",20434,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20434,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20442,], ["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,], @@ -1450,85 +1480,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",20434,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20434,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20442,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20442,], ["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",20434,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20434,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20434,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20434,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20434,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20434,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20434,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20434,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20442,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20442,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20442,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20442,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20442,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20442,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20442,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20442,], ["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",20434,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20442,], ["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",20434,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20442,], ["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",20434,], +["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20442,], ["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",20434,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20434,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20434,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20434,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20434,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20434,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20434,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20434,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20442,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20442,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20442,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20442,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20442,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20442,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20442,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20442,], ["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",20434,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20434,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20434,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20434,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20434,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20434,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20442,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20442,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20442,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20442,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20442,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20442,], ["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","",20434,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20442,], ["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], ["libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en","libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en",0,], -["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20434,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20434,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20434,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20434,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20442,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20442,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20442,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20442,], ["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",20434,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20442,], ["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",20434,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20442,], ["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",20434,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20434,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20434,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20434,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20434,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20434,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20434,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20434,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20434,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20434,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20434,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20434,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20442,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20442,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20442,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20442,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20442,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20442,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20442,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20442,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20442,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20442,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20442,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20442,], ["features.verifysession.impl.ui_VerificationUserProfileContent_Day_0_en","features.verifysession.impl.ui_VerificationUserProfileContent_Night_0_en",0,], ["libraries.designsystem.ruler_VerticalRuler_Day_0_en","libraries.designsystem.ruler_VerticalRuler_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_1_en",0,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20434,], -["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20434,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20442,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20442,], ["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",20434,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20442,], ["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,], @@ -1543,9 +1573,9 @@ export const screenshots = [ ["libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en","libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en","libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en",0,], ["libraries.textcomposer.components_VoiceMessageDeleteButton_Day_0_en","libraries.textcomposer.components_VoiceMessageDeleteButton_Night_0_en",0,], +["libraries.textcomposer.components_VoiceMessagePreview_Day_0_en","libraries.textcomposer.components_VoiceMessagePreview_Night_0_en",0,], ["libraries.textcomposer.components_VoiceMessageRecorderButton_Day_0_en","libraries.textcomposer.components_VoiceMessageRecorderButton_Night_0_en",0,], ["libraries.textcomposer.components_VoiceMessageRecording_Day_0_en","libraries.textcomposer.components_VoiceMessageRecording_Night_0_en",0,], -["libraries.textcomposer.components_VoiceMessage_Day_0_en","libraries.textcomposer.components_VoiceMessage_Night_0_en",0,], ["libraries.designsystem.components.media_WaveformPlaybackView_Day_0_en","libraries.designsystem.components.media_WaveformPlaybackView_Night_0_en",0,], ["libraries.designsystem.ruler_WithRulers_Day_0_en","libraries.designsystem.ruler_WithRulers_Night_0_en",0,], ]; From 60fa76a9b98e3f6b895ca60a17591ab6ee082b37 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 23 Dec 2025 11:44:16 +0100 Subject: [PATCH 260/347] Revert "fix: display banned member list if permissions.canKick or permissions.canBan" This reverts commit f7248b87f0dd7e5aa8f7c30b98115dad8e2402c2. --- .../features/roomdetails/impl/members/RoomMemberListState.kt | 2 +- .../roommembermoderation/api/RoomMemberModerationPermissions.kt | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt index 5a113bc3b2..7c928fb27a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt @@ -26,7 +26,7 @@ data class RoomMemberListState( val moderationState: RoomMemberModerationState, val eventSink: (RoomMemberListEvents) -> Unit, ) { - val showBannedSection: Boolean = moderationState.permissions.hasAny && roomMembers.dataOrNull()?.banned?.isNotEmpty() == true + val showBannedSection: Boolean = moderationState.permissions.canBan && roomMembers.dataOrNull()?.banned?.isNotEmpty() == true } enum class SelectedSection { diff --git a/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt index 10ea6c4451..223456de69 100644 --- a/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt +++ b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt @@ -13,8 +13,6 @@ data class RoomMemberModerationPermissions( val canKick: Boolean, val canBan: Boolean, ) { - val hasAny = canKick || canBan - companion object { val DEFAULT = RoomMemberModerationPermissions( canKick = false, From f732aa18a87fec2a1478c37ef9af5b5c9d381aa0 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 23 Dec 2025 14:36:19 +0100 Subject: [PATCH 261/347] fix: unban action requires both ban and kick permissions --- .../impl/RoomMemberModerationPresenter.kt | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt index cfb9412394..3a5c364b31 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt @@ -161,16 +161,28 @@ class RoomMemberModerationPresenter( val canModerateThisUser = currentUserPowerLevel > targetMemberPowerLevel // Assume the member is joined when it's unknown val membership = member?.membership ?: RoomMembershipState.JOIN - if (permissions.canKick) { - // Unban requires kick permission instead of a dedicated unban permission - if (membership == RoomMembershipState.BAN) { - add(ModerationActionState(action = ModerationAction.UnbanUser, isEnabled = canModerateThisUser)) - } else if (membership != RoomMembershipState.LEAVE) { - add(ModerationActionState(action = ModerationAction.KickUser, isEnabled = canModerateThisUser)) + when (membership) { + RoomMembershipState.BAN -> { + // Unban requires both kick and ban permission instead of a dedicated unban permission + if (permissions.canBan && permissions.canKick) { + add(ModerationActionState(action = ModerationAction.UnbanUser, isEnabled = canModerateThisUser)) + } + } + RoomMembershipState.INVITE, + RoomMembershipState.JOIN, + RoomMembershipState.KNOCK -> { + if (permissions.canKick) { + add(ModerationActionState(action = ModerationAction.KickUser, isEnabled = canModerateThisUser)) + } + if (permissions.canBan) { + add(ModerationActionState(action = ModerationAction.BanUser, isEnabled = canModerateThisUser)) + } + } + RoomMembershipState.LEAVE -> { + if (permissions.canBan) { + add(ModerationActionState(action = ModerationAction.BanUser, isEnabled = canModerateThisUser)) + } } - } - if (permissions.canBan && membership != RoomMembershipState.BAN) { - add(ModerationActionState(action = ModerationAction.BanUser, isEnabled = canModerateThisUser)) } }.toImmutableList() } From 9fcbd36f42c4752de89eb83cb0ae93ff3ea698a5 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 3 Dec 2025 17:43:13 +0100 Subject: [PATCH 262/347] feature(security&privacy): create ManageAuthorizedSpace classes --- .../ManageAuthorizedSpacesEvent.kt | 16 ++++ .../ManageAuthorizedSpacesNode.kt | 42 ++++++++++ .../ManageAuthorizedSpacesPresenter.kt | 48 +++++++++++ .../ManageAuthorizedSpacesState.kt | 13 +++ .../ManageAuthorizedSpacesStateProvider.kt | 19 +++++ .../ManageAuthorizedSpacesView.kt | 80 +++++++++++++++++++ 6 files changed, 218 insertions(+) create mode 100644 features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt create mode 100644 features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt create mode 100644 features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt create mode 100644 features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt create mode 100644 features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt create mode 100644 features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt new file mode 100644 index 0000000000..0515878ade --- /dev/null +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces + +import io.element.android.libraries.matrix.api.core.RoomId + +sealed interface ManageAuthorizedSpacesEvent { + data object Done : ManageAuthorizedSpacesEvent + data class ToggleSpace(val roomId: RoomId) : ManageAuthorizedSpacesEvent +} diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt new file mode 100644 index 0000000000..3b52c2ac3f --- /dev/null +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import com.bumble.appyx.core.plugin.plugins +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedInject +import io.element.android.annotations.ContributesNode +import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator +import io.element.android.libraries.di.RoomScope + +@ContributesNode(RoomScope::class) +@AssistedInject +class ManageAuthorizedSpacesNode( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + presenterFactory: EditRoomAddressPresenter.Factory, +) : Node(buildContext, plugins = plugins) { + private val navigator = plugins().first() + private val presenter = presenterFactory.create(navigator) + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + ManageAuthorizedSpacesView( + state = state, + onBackClick = ::navigateUp, + modifier = modifier + ) + } +} diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt new file mode 100644 index 0000000000..758ea030d2 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedFactory +import dev.zacsweers.metro.AssistedInject +import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.room.JoinedRoom + +@AssistedInject +class EditRoomAddressPresenter( + @Assisted private val navigator: SecurityAndPrivacyNavigator, + private val client: MatrixClient, + private val room: JoinedRoom, +) : Presenter { + @AssistedFactory + interface Factory { + fun create(navigator: SecurityAndPrivacyNavigator): EditRoomAddressPresenter + } + + @Composable + override fun present(): ManageAuthorizedSpacesState { + val roomInfo by room.roomInfoFlow.collectAsState() + + fun handleEvent(event: ManageAuthorizedSpacesEvent) { + when (event) { + ManageAuthorizedSpacesEvent.Done -> TODO() + is ManageAuthorizedSpacesEvent.ToggleSpace -> TODO() + } + } + + return ManageAuthorizedSpacesState( + eventSink = ::handleEvent, + ) + } +} diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt new file mode 100644 index 0000000000..f0936e81b7 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces + +data class ManageAuthorizedSpacesState( + val eventSink: (ManageAuthorizedSpacesEvent) -> Unit +) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt new file mode 100644 index 0000000000..91ff1f9b22 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.matrix.ui.room.address.RoomAddressValidity + +open class ManageAuthorizedSpacesStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf() +} + diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt new file mode 100644 index 0000000000..632fb7ffcc --- /dev/null +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewParameter +import 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.Scaffold +import io.element.android.libraries.designsystem.theme.components.TextButton +import io.element.android.libraries.designsystem.theme.components.TopAppBar +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +fun ManageAuthorizedSpacesView( + state: ManageAuthorizedSpacesState, + onBackClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Scaffold( + modifier = modifier, + topBar = { + ManageAuthorizedSpacesTopBar( + onBackClick = onBackClick, + onDoneClick = { + state.eventSink(ManageAuthorizedSpacesEvent.Done) + }, + ) + } + ) { padding -> + LazyColumn( + modifier = Modifier.padding(padding) + ) { + + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun ManageAuthorizedSpacesTopBar( + onBackClick: () -> Unit, + onDoneClick: () -> Unit, + modifier: Modifier = Modifier, +) { + TopAppBar( + modifier = modifier, + titleStr = stringResource(CommonStrings.screen_manage_authorized_spaces_title), + navigationIcon = { BackButton(onClick = onBackClick) }, + actions = { + TextButton( + text = stringResource(CommonStrings.action_done), + onClick = onDoneClick, + ) + } + ) +} + +@PreviewsDayNight +@Composable +internal fun ManageAuthorizedSpacesViewPreview( + @PreviewParameter(ManageAuthorizedSpacesStateProvider::class) state: ManageAuthorizedSpacesState +) = ElementPreview { + ManageAuthorizedSpacesView( + state = state, + onBackClick = {}, + ) +} From d868bf64bf074319cf154a297f4275b443a87515 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 17 Dec 2025 13:58:54 +0100 Subject: [PATCH 263/347] localazy : sync strings # Conflicts: # features/roomdetails/impl/src/main/res/values/localazy.xml # features/securityandprivacy/impl/src/main/res/values/localazy.xml # libraries/ui-strings/src/main/res/values/localazy.xml --- .../src/main/res/values/localazy.xml | 31 ++++++++++++++++--- tools/localazy/config.json | 3 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index df47b71577..9afde6fefc 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -435,11 +435,32 @@ Are you sure you want to continue?" "Options" "Remove %1$s" "Settings" - "Spaces where members can join the room without an invitation." - "Manage spaces" - "(Unknown space)" - "Other spaces you’re not a member of" - "Your spaces" + "Scan the QR code" + "Open %1$s on a laptop or desktop computer" + "Scan the QR code with this device" + "Ready to scan" + "Open %1$s on a desktop computer to get the QR code" + "The numbers don’t match" + "Enter 2-digit code" + "This will verify that the connection to your other device is secure." + "Enter the number shown on your other device" + "Your account provider does not support %1$s." + "%1$s not supported" + "Your account provider doesn’t support signing into a new device with a QR code." + "QR code not supported" + "The sign in was cancelled on the other device." + "Sign in request cancelled" + "Sign in expired. Please try again." + "The sign in was not completed in time" + "Open %1$s on the other device" + "Select %1$s" + "“Sign in with QR code”" + "Scan the QR code shown here with the other device" + "Open %1$s on the other device" + "Desktop computer" + "Loading QR code…" + "Mobile device" + "What type of device do you want to link?" "Failed selecting media, please try again." "Press on a message and choose “%1$s” to include here." "Pin important messages so that they can be easily discovered" diff --git a/tools/localazy/config.json b/tools/localazy/config.json index a8572fb660..3894befcb0 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -403,7 +403,8 @@ "name" : ":features:securityandprivacy:impl", "includeRegex" : [ "screen\\.edit_room_address\\..*", - "screen\\.security_and_privacy\\..*" + "screen\\.security_and_privacy\\..*", + "screen\\.manage_authorized_spaces\\..*" ] } ] From 7b8950a51bc968f96ad7c0cfbd9700a1a994a114 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 18 Dec 2025 10:07:57 +0100 Subject: [PATCH 264/347] feature(security&privacy): start ManageAuthorizedSpacesView --- .../ManageAuthorizedSpacesPresenter.kt | 6 +- .../ManageAuthorizedSpacesState.kt | 8 ++ .../ManageAuthorizedSpacesStateProvider.kt | 48 +++++++- .../ManageAuthorizedSpacesView.kt | 115 +++++++++++++++++- 4 files changed, 171 insertions(+), 6 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt index 758ea030d2..527393c9d3 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt @@ -18,6 +18,7 @@ import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNav import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.room.JoinedRoom +import kotlinx.collections.immutable.persistentListOf @AssistedInject class EditRoomAddressPresenter( @@ -33,7 +34,6 @@ class EditRoomAddressPresenter( @Composable override fun present(): ManageAuthorizedSpacesState { val roomInfo by room.roomInfoFlow.collectAsState() - fun handleEvent(event: ManageAuthorizedSpacesEvent) { when (event) { ManageAuthorizedSpacesEvent.Done -> TODO() @@ -42,6 +42,10 @@ class EditRoomAddressPresenter( } return ManageAuthorizedSpacesState( + joinedSpaces = persistentListOf(), + unknownSpaceIds = persistentListOf(), + currentSelection = persistentListOf(), + initialSelection = persistentListOf(), eventSink = ::handleEvent, ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt index f0936e81b7..688ef6e6e9 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt @@ -8,6 +8,14 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import kotlinx.collections.immutable.ImmutableList + data class ManageAuthorizedSpacesState( + val joinedSpaces: ImmutableList, + val unknownSpaceIds: ImmutableList, + val currentSelection: ImmutableList, + val initialSelection: ImmutableList, val eventSink: (ManageAuthorizedSpacesEvent) -> Unit ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt index 91ff1f9b22..d91e16f3e6 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt @@ -9,11 +9,53 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.architecture.AsyncAction -import io.element.android.libraries.matrix.ui.room.address.RoomAddressValidity +import io.element.android.libraries.matrix.api.core.RoomAlias +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import io.element.android.libraries.previewutils.room.aSpaceRoom +import kotlinx.collections.immutable.toImmutableList open class ManageAuthorizedSpacesStateProvider : PreviewParameterProvider { override val values: Sequence - get() = sequenceOf() + get() = sequenceOf( + aManageAuthorizedSpacesState(), + aManageAuthorizedSpacesState( + unknownSpaceIds = listOf(aRoomId(99)) + ), + aManageAuthorizedSpacesState( + currentSelection = listOf(aRoomId(1), aRoomId(3)), + initialSelection = listOf(aRoomId(1)), + ), + ) } +private fun aRoomId(index: Int) = RoomId("!roomId$index:matrix.org") + +private fun aSpaceRoomList(count: Int): List { + return (1..count).map { index -> + aSpaceRoom( + roomId = aRoomId(index), + displayName = "Space $index", + canonicalAlias = if (index % 2 == 0) { + RoomAlias("#space$index:matrix.org") + } else { + null + } + ) + } +} + +private fun aManageAuthorizedSpacesState( + joinedSpaces: List = aSpaceRoomList(5), + unknownSpaceIds: List = emptyList(), + currentSelection: List = emptyList(), + initialSelection: List = emptyList(), + eventSink: (ManageAuthorizedSpacesEvent) -> Unit = {}, +) = ManageAuthorizedSpacesState( + joinedSpaces = joinedSpaces.toImmutableList(), + unknownSpaceIds = unknownSpaceIds.toImmutableList(), + currentSelection = currentSelection.toImmutableList(), + initialSelection = initialSelection.toImmutableList(), + eventSink = eventSink, +) + diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt index 632fb7ffcc..ed49e048aa 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt @@ -10,17 +10,34 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspac import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.items import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.securityandprivacy.impl.R +import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule +import io.element.android.libraries.designsystem.components.BigIcon +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.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.ListItem +import io.element.android.libraries.designsystem.theme.components.ListSectionHeader 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.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar +import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings @Composable @@ -43,11 +60,105 @@ fun ManageAuthorizedSpacesView( LazyColumn( modifier = Modifier.padding(padding) ) { - + headerItem() + item { + ListSectionHeader( + title = stringResource(R.string.screen_manage_authorized_spaces_your_spaces_section_title), + hasDivider = false, + ) + } + items(items = state.joinedSpaces) { space -> + CheckableSpaceListItem( + headlineText = space.displayName, + supportingText = space.canonicalAlias?.value, + avatarData = space.getAvatarData(AvatarSize.SpaceMember), + checked = state.currentSelection.contains(space.roomId), + onCheckedChange = { _ -> + state.eventSink( + ManageAuthorizedSpacesEvent.ToggleSpace(space.roomId) + ) + } + ) + } + if(state.unknownSpaceIds.isNotEmpty()){ + item { + ListSectionHeader( + title = stringResource(R.string.screen_manage_authorized_spaces_unknown_spaces_section_title), + hasDivider = false, + ) + } + items(items = state.unknownSpaceIds) { + CheckableSpaceListItem( + headlineText = stringResource(R.string.screen_manage_authorized_spaces_unknown_space), + supportingText = it.value, + avatarData = null, + checked = state.currentSelection.contains(it), + onCheckedChange = { _ -> + state.eventSink( + ManageAuthorizedSpacesEvent.ToggleSpace(it) + ) + } + ) + } + } } } } +private fun LazyListScope.headerItem() { + item(key = "header", contentType = "header") { + IconTitleSubtitleMolecule( + modifier = Modifier.padding( + vertical = 16.dp, + horizontal = 24.dp + ), + title = stringResource(R.string.screen_manage_authorized_spaces_header), + subTitle = null, + iconStyle = BigIcon.Style.Default( + vectorIcon = CompoundIcons.SpaceSolid(), + ) + ) + } +} + +@Composable +private fun CheckableSpaceListItem( + headlineText: String, + supportingText: String?, + avatarData: AvatarData?, + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, +) { + ListItem( + headlineContent = { + Text(text = headlineText) + }, + supportingContent = supportingText?.let { + @Composable { + Text(text = supportingText) + } + }, + leadingContent = avatarData?.let{ + ListItemContent.Custom { + Avatar( + avatarData = avatarData, + avatarType = AvatarType.Space(), + ) + } + }, + trailingContent = ListItemContent.Checkbox( + checked = checked, + enabled = enabled, + ), + enabled = enabled, + onClick = { onCheckedChange(!checked) }, + modifier = modifier, + ) +} + + @OptIn(ExperimentalMaterial3Api::class) @Composable private fun ManageAuthorizedSpacesTopBar( @@ -57,7 +168,7 @@ private fun ManageAuthorizedSpacesTopBar( ) { TopAppBar( modifier = modifier, - titleStr = stringResource(CommonStrings.screen_manage_authorized_spaces_title), + titleStr = stringResource(R.string.screen_manage_authorized_spaces_title), navigationIcon = { BackButton(onClick = onBackClick) }, actions = { TextButton( From 421f12f396a17da5f1ccb13d5c6f750526c514ad Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 23 Dec 2025 15:41:16 +0100 Subject: [PATCH 265/347] localazy: sync strings --- .../src/main/res/values-et/translations.xml | 5 ++++ .../src/main/res/values-fr/translations.xml | 5 ++++ .../src/main/res/values-hr/translations.xml | 5 ++++ .../main/res/values-pt-rBR/translations.xml | 5 ++++ .../src/main/res/values-ro/translations.xml | 5 ++++ .../src/main/res/values-sk/translations.xml | 5 ++++ .../impl/src/main/res/values/localazy.xml | 5 ++++ .../src/main/res/values-et/translations.xml | 5 ---- .../src/main/res/values-fr/translations.xml | 5 ---- .../src/main/res/values-hr/translations.xml | 5 ---- .../main/res/values-pt-rBR/translations.xml | 5 ---- .../src/main/res/values-ro/translations.xml | 5 ---- .../src/main/res/values-sk/translations.xml | 5 ---- .../src/main/res/values/localazy.xml | 26 ------------------- 14 files changed, 35 insertions(+), 56 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml index 8d74c35733..06d095cf4f 100644 --- a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml @@ -2,6 +2,11 @@ "Selleks, et jututuba oleks nähtav jututubade avalikus kataloogis, vajab ta aadressi." "Muuda aadressi" + "Kogukonnad, milles on võimalik jututoaga liituda ilma kutseta." + "Halda kogukondi" + "(Tundmatu kogukond)" + "Muud kogukonnad, mille liige sa ei ole" + "Sinu kogukonnad" "Lisa aadress" "Liituda saavad kõik volitatud kogukondade liikmed, kuid kõik teised peavad küsima võimalust ligipääsuks." "Kõik võivad paluda jututoaga liitumist." diff --git a/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml index 5426d71706..afa85522f1 100644 --- a/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml @@ -2,6 +2,11 @@ "Vous aurez besoin d’une adresse pour le rendre visible dans l’annuaire public." "Modifier l’adresse" + "Espaces où les membres peuvent rejoindre le salon sans invitation." + "Gérer les espaces" + "(Espace inconnu)" + "Autres espaces dont vous n’êtes pas membre" + "Vos espaces" "Ajouter une adresse" "Tout le monde doit demander un accès." "Demander à rejoindre" diff --git a/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml index 401fe806f8..b8905bef30 100644 --- a/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml @@ -2,6 +2,11 @@ "Trebat će vam adresa kako bi bila vidljiva u javnom direktoriju." "Uredi adresu" + "Prostori u kojima se članovi mogu pridružiti sobi bez pozivnice." + "Upravljaj prostorima" + "(nepoznati prostor)" + "Drugi prostori čiji niste član" + "Vaši prostori" "Dodaj adresu" "Svatko tko se nalazi u ovlaštenim prostorima može se pridružiti, ali svi ostali moraju zatražiti pristup." "Svi moraju zatražiti pristup." diff --git a/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml index 658067be2d..dfe1aee558 100644 --- a/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml @@ -2,6 +2,11 @@ "Você precisará de um endereço para torná-la visível no diretório." "Editar endereço" + "Os espaços dos quais os membros podem entrar na sala sem um convite." + "Gerenciar espaços" + "(Espaço desconhecido)" + "Outros espaços dos quais você não é um membro" + "Seus espaços" "Adicionar endereço" "Qualquer um nos espaços autorizados podem entrar, mas todos os outros devem pedir acesso." "Qualquer um pode pedir acesso, mas um administrador terá que aceitar o pedido." diff --git a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml index 701cb72370..f3c62f2497 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml @@ -2,6 +2,11 @@ "Veți avea nevoie de o adresă pentru a o face vizibilă în directorul public." "Editați adresa" + "Spațile din care membrii se pot alătura camerei fără invitație." + "Gestionați spațiile" + "(Spațiu necunoscut)" + "Alte spații din care nu faceți parte" + "Spațiile dumneavoastră" "Adăugați o adresă" "Oricine se află în spațiile autorizate se poate alătura, dar toți ceilalți trebuie să solicite accesul." "Toată lumea trebuie să solicite acces." diff --git a/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml b/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml index ee346dd5d0..3853fc5f8a 100644 --- a/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml @@ -2,6 +2,11 @@ "Budete potrebovať adresu, aby sa zobrazovala vo verejnom adresári." "Upraviť adresu" + "Priestory, kde sa členovia môžu pripojiť k miestnosti bez pozvania." + "Spravovať priestory" + "(Neznámy priestor)" + "Iné priestory, ktorých nie ste členom" + "Vaše priestory" "Pridať adresu" "Všetci musia požiadať o prístup." "Požiadať o pripojenie" diff --git a/features/securityandprivacy/impl/src/main/res/values/localazy.xml b/features/securityandprivacy/impl/src/main/res/values/localazy.xml index acf4b04e71..902a89d7bd 100644 --- a/features/securityandprivacy/impl/src/main/res/values/localazy.xml +++ b/features/securityandprivacy/impl/src/main/res/values/localazy.xml @@ -2,6 +2,11 @@ "You’ll need an address in order to make it visible in the public directory." "Edit address" + "Spaces where members can join the room without an invitation." + "Manage spaces" + "(Unknown space)" + "Other spaces you’re not a member of" + "Your spaces" "Add address" "Anyone in authorised spaces can join, but everyone else must request access." "Everyone must request access." diff --git a/libraries/ui-strings/src/main/res/values-et/translations.xml b/libraries/ui-strings/src/main/res/values-et/translations.xml index 67d323e77b..b2f08ecb65 100644 --- a/libraries/ui-strings/src/main/res/values-et/translations.xml +++ b/libraries/ui-strings/src/main/res/values-et/translations.xml @@ -435,11 +435,6 @@ Kas sa oled kindel, et soovid jätkata?" "Valikud" "Kustuta: %1$s" "Seadistused" - "Kogukonnad, milles on võimalik jututoaga liituda ilma kutseta." - "Halda kogukondi" - "(Tundmatu kogukond)" - "Muud kogukonnad, mille liige sa ei ole" - "Sinu kogukonnad" "Meediafaili valimine ei õnnestunud. Palun proovi uuesti." "Siia lisamiseks vajuta sõnumil ja vali „%1$s“." "Et olulisi sõnumeid oleks lihtsam leida, tõsta nad esile" 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 9392933cf8..4acbb6be48 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -431,11 +431,6 @@ Raison : %1$s." "Options" "Supprimer %1$s" "Paramètres" - "Espaces où les membres peuvent rejoindre le salon sans invitation." - "Gérer les espaces" - "(Espace inconnu)" - "Autres espaces dont vous n’êtes pas membre" - "Vos espaces" "Échec de la sélection du média, veuillez réessayer." "Cliquez (clic long) sur un message et choisissez « %1$s » pour qu‘il apparaisse ici." "Épinglez les messages importants pour leur donner plus de visibilité" diff --git a/libraries/ui-strings/src/main/res/values-hr/translations.xml b/libraries/ui-strings/src/main/res/values-hr/translations.xml index 139e68230f..4cbeecf7a8 100644 --- a/libraries/ui-strings/src/main/res/values-hr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hr/translations.xml @@ -442,11 +442,6 @@ Jeste li sigurni da želite nastaviti?" "Mogućnosti" "Ukloni %1$s" "Postavke" - "Prostori u kojima se članovi mogu pridružiti sobi bez pozivnice." - "Upravljaj prostorima" - "(nepoznati prostor)" - "Drugi prostori čiji niste član" - "Vaši prostori" "Odabir medija nije uspio, pokušajte ponovno." "Pritisnite poruku i odaberite “%1$s” kako biste uključili ovdje." "Prikvačite važne poruke kako bi ih se lakše moglo pronaći" diff --git a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml index 3863a24fd8..f588e6bdca 100644 --- a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml @@ -434,11 +434,6 @@ Você tem certeza de que deseja continuar?" "Opções" "Remover %1$s" "Configurações" - "Os espaços dos quais os membros podem entrar na sala sem um convite." - "Gerenciar espaços" - "(Espaço desconhecido)" - "Outros espaços dos quais você não é um membro" - "Seus espaços" "Falha ao selecionar a mídia, tente novamente." "Pressione em uma mensagem e escolha \"%1$s\" para incluir aqui." "Fixe mensagens importantes para que elas possam ser facilmente descobertas" diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index 9e56d09b16..69f2aba019 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -442,11 +442,6 @@ Sunteți sigur că doriți să continuați?" "Opțiuni" "Ștergeți %1$s" "Setări" - "Spațile din care membrii se pot alătura camerei fără invitație." - "Gestionați spațiile" - "(Spațiu necunoscut)" - "Alte spații din care nu faceți parte" - "Spațiile dumneavoastră" "Selectarea fișierelor media a eșuat, încercați din nou." "Apăsați pe un mesaj și alegeți \"%1$s\" pentru a-l include aici." "Fixați mesajele importante, astfel încât să poată fi descoperite cu ușurință" diff --git a/libraries/ui-strings/src/main/res/values-sk/translations.xml b/libraries/ui-strings/src/main/res/values-sk/translations.xml index 0928010918..3c8f4f16ef 100644 --- a/libraries/ui-strings/src/main/res/values-sk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sk/translations.xml @@ -439,11 +439,6 @@ Naozaj chcete pokračovať?" "Možnosti" "Odstrániť %1$s" "Nastavenia" - "Priestory, kde sa členovia môžu pripojiť k miestnosti bez pozvania." - "Spravovať priestory" - "(Neznámy priestor)" - "Iné priestory, ktorých nie ste členom" - "Vaše priestory" "Nepodarilo sa vybrať médium, skúste to prosím znova." "Stlačte správu a vyberte možnosť „%1$s“, ktorú chcete zahrnúť sem." "Pripnite dôležité správy, aby sa dali ľahko nájsť" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 9afde6fefc..3a108277ba 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -435,32 +435,6 @@ Are you sure you want to continue?" "Options" "Remove %1$s" "Settings" - "Scan the QR code" - "Open %1$s on a laptop or desktop computer" - "Scan the QR code with this device" - "Ready to scan" - "Open %1$s on a desktop computer to get the QR code" - "The numbers don’t match" - "Enter 2-digit code" - "This will verify that the connection to your other device is secure." - "Enter the number shown on your other device" - "Your account provider does not support %1$s." - "%1$s not supported" - "Your account provider doesn’t support signing into a new device with a QR code." - "QR code not supported" - "The sign in was cancelled on the other device." - "Sign in request cancelled" - "Sign in expired. Please try again." - "The sign in was not completed in time" - "Open %1$s on the other device" - "Select %1$s" - "“Sign in with QR code”" - "Scan the QR code shown here with the other device" - "Open %1$s on the other device" - "Desktop computer" - "Loading QR code…" - "Mobile device" - "What type of device do you want to link?" "Failed selecting media, please try again." "Press on a message and choose “%1$s” to include here." "Pin important messages so that they can be easily discovered" From b59e36aabd4f71e563814a85479c86237263265b Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 23 Dec 2025 20:49:41 +0100 Subject: [PATCH 266/347] space service : expose methods from sdk --- .../matrix/api/spaces/SpaceService.kt | 4 ++++ .../matrix/impl/spaces/RustSpaceService.kt | 23 +++++++++++++++---- .../matrix/test/spaces/FakeSpaceService.kt | 10 ++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceService.kt index 6f5ba674ec..8f005b0225 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/spaces/SpaceService.kt @@ -15,6 +15,10 @@ interface SpaceService { val spaceRoomsFlow: SharedFlow> suspend fun joinedSpaces(): Result> + suspend fun joinedParents(spaceId: RoomId): Result> + + suspend fun getSpaceRoom(spaceId: RoomId): SpaceRoom? + fun spaceRoomList(id: RoomId): SpaceRoomList fun getLeaveSpaceHandle(spaceId: RoomId): LeaveSpaceHandle diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt index ba816c11c7..fad698c731 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt @@ -51,13 +51,28 @@ class RustSpaceService( override suspend fun joinedSpaces(): Result> = withContext(sessionDispatcher) { runCatchingExceptions { - innerSpaceService.topLevelJoinedSpaces() - .map { - it.let(spaceRoomMapper::map) - } + innerSpaceService + .topLevelJoinedSpaces() + .map(spaceRoomMapper::map) } } + override suspend fun joinedParents(spaceId: RoomId): Result> = withContext(sessionDispatcher) { + runCatchingExceptions { + innerSpaceService + .joinedParentsOfChild(spaceId.value) + .map(spaceRoomMapper::map) + } + } + + override suspend fun getSpaceRoom(spaceId: RoomId): SpaceRoom? = withContext(sessionDispatcher) { + runCatchingExceptions { + innerSpaceService.getSpaceRoom(spaceId.value)?.let { spaceRoom -> + spaceRoomMapper.map(spaceRoom) + } + }.getOrNull() + } + override fun spaceRoomList(id: RoomId): SpaceRoomList { val childCoroutineScope = sessionCoroutineScope.childScope(sessionDispatcher, "SpaceRoomListScope-$this") return RustSpaceRoomList( diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeSpaceService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeSpaceService.kt index eaa36ee750..d796c0b538 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeSpaceService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/spaces/FakeSpaceService.kt @@ -23,6 +23,8 @@ class FakeSpaceService( private val joinedSpacesResult: () -> Result> = { lambdaError() }, private val spaceRoomListResult: (RoomId) -> SpaceRoomList = { lambdaError() }, private val leaveSpaceHandleResult: (RoomId) -> LeaveSpaceHandle = { lambdaError() }, + private val joinedParentsResult: (RoomId) -> Result> = { lambdaError() }, + private val getSpaceRoomResult: (RoomId) -> SpaceRoom? = { lambdaError() }, ) : SpaceService { private val _spaceRoomsFlow = MutableSharedFlow>() override val spaceRoomsFlow: SharedFlow> @@ -36,6 +38,14 @@ class FakeSpaceService( return joinedSpacesResult() } + override suspend fun joinedParents(spaceId: RoomId): Result> { + return joinedParentsResult(spaceId) + } + + override suspend fun getSpaceRoom(spaceId: RoomId): SpaceRoom? { + return getSpaceRoomResult(spaceId) + } + override fun spaceRoomList(id: RoomId): SpaceRoomList { return spaceRoomListResult(id) } From f35d7086cbead5a41b10c5c02eb8258ab0da847e Mon Sep 17 00:00:00 2001 From: bmarty <3940906+bmarty@users.noreply.github.com> Date: Mon, 29 Dec 2025 00:19:01 +0000 Subject: [PATCH 267/347] Sync Strings from Localazy --- .../src/main/res/values-hr/translations.xml | 8 +- .../src/main/res/values-hr/translations.xml | 1 + screenshots/html/data.js | 1949 +++++++++-------- 3 files changed, 980 insertions(+), 978 deletions(-) diff --git a/features/login/impl/src/main/res/values-hr/translations.xml b/features/login/impl/src/main/res/values-hr/translations.xml index efb1cbb016..ced196f87e 100644 --- a/features/login/impl/src/main/res/values-hr/translations.xml +++ b/features/login/impl/src/main/res/values-hr/translations.xml @@ -1,10 +1,10 @@ - "Promijeni davatelja računa" + "Promijeni davatelja usluga računa" "Adresa matičnog poslužitelja" "Unesite pojam za pretraživanje ili adresu domene." "Potražite tvrtku, zajednicu ili privatni poslužitelj." - "Pronađite davatelja računa" + "Pronađite davatelja usluga računa" "Ovdje će se čuvati vaši razgovori – baš kao što biste koristili davatelja usluga e-pošte za čuvanje svojih e-poruka." "Prijavit ćete se na %s" "Ovdje će se čuvati vaši razgovori – baš kao što biste koristili davatelja usluga e-pošte za čuvanje svojih e-poruka." @@ -12,7 +12,7 @@ "Matrix.org velik je, besplatni poslužitelj na javnoj Matrixovoj mreži koji pruža sigurnu, decentraliziranu komunikaciju, a kojim upravlja zaklada Matrix.org." "Ostalo" "Koristite drugog davatelja računa, kao što je vlastiti privatni poslužitelj ili poslovni račun." - "Promijeni davatelja računa" + "Promijeni davatelja usluga računa" "Google Play" "Potrebna je aplikacija Element Pro na %1$s. Molimo vas da je preuzmete iz trgovine." "Potreban je Element Pro" @@ -90,7 +90,7 @@ Pokušajte se prijaviti ručno ili skenirajte QR kod drugim uređajem." "Čekanje na vaš drugi uređaj" "Davatelj usluge računa može zatražiti sljedeći kod za potvrdu prijave." "Vaš verifikacijski kod" - "Promijeni davatelja računa" + "Promijeni davatelja usluga računa" "Privatni poslužitelj za zaposlenike aplikacije Element." "Matrix je otvorena mreža za sigurnu, decentraliziranu komunikaciju." "Ovdje će se čuvati vaši razgovori – baš kao što biste koristili davatelja usluga e-pošte za čuvanje svojih e-poruka." diff --git a/libraries/ui-strings/src/main/res/values-hr/translations.xml b/libraries/ui-strings/src/main/res/values-hr/translations.xml index 139e68230f..91caf1b6f9 100644 --- a/libraries/ui-strings/src/main/res/values-hr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hr/translations.xml @@ -163,6 +163,7 @@ "Dodirnite za učitavanje karte" "Uslikaj" "Dodirnite za mogućnosti" + "Prevedi" "Pokušajte ponovno" "Otkvači" "Prikaz" diff --git a/screenshots/html/data.js b/screenshots/html/data.js index 8b1a2cf28c..42d529aec6 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,80 +1,80 @@ // 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",20442,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20445,], ["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",20442,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20442,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20442,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20442,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20442,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20442,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20442,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20442,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20442,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20442,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20442,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20445,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20445,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20445,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20445,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20445,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20445,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20445,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20445,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20445,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20445,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20445,], ["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",20442,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20442,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20445,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20445,], ["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",20442,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20442,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20445,], ["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",20442,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20442,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20442,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20442,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20442,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20442,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20442,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20442,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20442,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20442,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20442,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20442,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20442,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20442,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20442,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20445,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20445,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20445,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20445,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20445,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20445,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20445,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20445,], ["libraries.designsystem.theme.components_AllIcons_Icons_en","",0,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20442,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20442,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20442,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20442,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20442,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20445,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20445,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20445,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20445,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20445,], ["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",20442,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20445,], ["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",20442,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20445,], ["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",20442,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20445,], ["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",20442,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20445,], ["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",20442,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20445,], ["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,], @@ -84,19 +84,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","",20444,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en","",20444,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en","",20444,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en","",20444,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en","",20444,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en","",20444,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en","",20444,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en","",20444,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en","",20444,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_0_en","",20445,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en","",20445,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en","",20445,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en","",20445,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en","",20445,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en","",20445,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en","",20445,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en","",20445,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en","",20445,], ["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",20442,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20445,], ["libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en","",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_0_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_1_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_1_en",0,], @@ -123,22 +123,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",20442,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20445,], ["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",20442,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20442,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20442,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20442,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20442,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20442,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20442,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20445,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20445,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20445,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20445,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20445,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20445,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20445,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20442,], -["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20442,], -["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20442,], -["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20442,], -["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20442,], +["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20445,], +["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20445,], +["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20445,], +["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20445,], +["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20445,], ["features.rageshake.impl.bugreport_BugReportViewNight_0_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_1_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_2_en","",0,], @@ -148,136 +148,137 @@ export const screenshots = [ ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20442,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20442,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20445,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20445,], ["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], ["features.call.impl.ui_CallScreenView_Day_0_en","features.call.impl.ui_CallScreenView_Night_0_en",0,], -["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20442,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20442,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20442,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20442,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20442,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20442,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20445,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20445,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20445,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20445,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20445,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20445,], ["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",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20442,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20442,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20442,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20442,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20442,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20442,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20442,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en",20444,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20445,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20445,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20445,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20445,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20445,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20445,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20445,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en",20445,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en",0,], ["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",20442,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20442,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20442,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20442,], -["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20442,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20445,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20445,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20445,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20445,], +["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20445,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20442,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20445,], ["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",20442,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20442,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20442,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20442,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20442,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20442,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20442,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20442,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20445,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20445,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20445,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20445,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20445,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20445,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20445,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20445,], ["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",20442,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20442,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20442,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20442,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20442,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20442,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20442,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20442,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20442,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20442,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20445,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20445,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20445,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20445,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20445,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20445,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20445,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20445,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20445,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20445,], ["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","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20442,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20442,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20442,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20442,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20442,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20442,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20445,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20445,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20445,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20445,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20445,], ["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",20442,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20442,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20442,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20442,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20442,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20442,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20442,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20442,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20442,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20442,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20442,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20442,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20442,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20442,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20442,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20442,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20442,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20442,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20442,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20442,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20445,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20445,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20445,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20445,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20445,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20445,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20445,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20445,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20445,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20445,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20445,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20445,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20445,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20445,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20445,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20445,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20445,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20445,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20445,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20445,], ["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","",20442,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20442,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20442,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20442,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20442,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20442,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20442,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20445,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20445,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20445,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20445,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20445,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20445,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20445,], ["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",20442,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20442,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20442,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20445,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20445,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20445,], ["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",20442,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20445,], ["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",20442,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20442,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20442,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20442,], -["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en",20444,], -["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en",20444,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20442,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20442,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20442,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20442,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20445,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20445,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20445,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20445,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en",20445,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en",20445,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20445,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20445,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20445,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20445,], ["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,], @@ -292,19 +293,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",20442,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20442,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20442,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20442,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20442,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20442,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20442,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20442,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20442,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20442,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20442,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20442,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20442,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20445,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20445,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20445,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20445,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20445,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20445,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20445,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20445,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20445,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20445,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20445,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20445,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20445,], ["libraries.matrix.ui.components_EditableAvatarView_Day_0_en","libraries.matrix.ui.components_EditableAvatarView_Night_0_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_1_en","libraries.matrix.ui.components_EditableAvatarView_Night_1_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_2_en","libraries.matrix.ui.components_EditableAvatarView_Night_2_en",0,], @@ -315,28 +316,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",20442,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20442,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20445,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20445,], ["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",20444,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en",20444,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en",20444,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en",20444,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en",20444,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en",20444,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20442,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20442,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20442,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_0_en","features.linknewdevice.impl.screens.error_ErrorView_Night_0_en",20444,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_1_en","features.linknewdevice.impl.screens.error_ErrorView_Night_1_en",20444,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_2_en","features.linknewdevice.impl.screens.error_ErrorView_Night_2_en",20444,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_3_en","features.linknewdevice.impl.screens.error_ErrorView_Night_3_en",20444,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_4_en","features.linknewdevice.impl.screens.error_ErrorView_Night_4_en",20444,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_5_en","features.linknewdevice.impl.screens.error_ErrorView_Night_5_en",20444,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_6_en","features.linknewdevice.impl.screens.error_ErrorView_Night_6_en",20444,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_7_en","features.linknewdevice.impl.screens.error_ErrorView_Night_7_en",20444,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en",20445,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en",20445,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en",20445,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en",20445,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en",20445,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en",20445,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20445,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20445,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20445,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_0_en","features.linknewdevice.impl.screens.error_ErrorView_Night_0_en",20445,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_1_en","features.linknewdevice.impl.screens.error_ErrorView_Night_1_en",20445,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_2_en","features.linknewdevice.impl.screens.error_ErrorView_Night_2_en",20445,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_3_en","features.linknewdevice.impl.screens.error_ErrorView_Night_3_en",20445,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_4_en","features.linknewdevice.impl.screens.error_ErrorView_Night_4_en",20445,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_5_en","features.linknewdevice.impl.screens.error_ErrorView_Night_5_en",20445,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_6_en","features.linknewdevice.impl.screens.error_ErrorView_Night_6_en",20445,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_7_en","features.linknewdevice.impl.screens.error_ErrorView_Night_7_en",20445,], ["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,], @@ -355,44 +356,44 @@ 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",20442,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20442,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20442,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20445,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20445,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20445,], ["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",20442,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20442,], +["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20445,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20445,], ["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.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en","features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en",20442,], -["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20442,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20442,], -["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20442,], -["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20442,], -["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20442,], +["features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en","features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en",20445,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20445,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20445,], +["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20445,], +["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20445,], +["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20445,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20442,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20442,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20445,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20445,], ["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",20442,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20442,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20442,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20442,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20442,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20442,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20442,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20442,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20442,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20442,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20442,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20442,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20445,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20445,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20445,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20445,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20445,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20445,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20445,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20445,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20445,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20445,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20445,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20445,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.ruler_HorizontalRuler_Day_0_en","libraries.designsystem.ruler_HorizontalRuler_Night_0_en",0,], ["libraries.designsystem.theme.components_IconButton_Buttons_en","",0,], @@ -405,8 +406,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",20442,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20442,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20445,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20445,], ["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,], @@ -414,115 +415,115 @@ 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",20442,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20445,], ["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",20442,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20445,], ["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",20442,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20445,], ["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20442,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20442,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20445,], ["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",20442,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20442,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20442,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20445,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20445,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20445,], ["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",20442,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20442,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20442,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20442,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20445,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20445,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20445,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20445,], ["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",20442,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20442,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20442,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20442,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20442,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20442,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20442,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20442,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20445,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20445,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20445,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20445,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20445,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20445,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20445,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20445,], ["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",20442,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20442,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20442,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20442,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20442,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20442,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20442,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20442,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20442,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20442,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20442,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20445,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20445,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20445,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20445,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20445,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20445,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20445,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20445,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20445,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], -["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20442,], -["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20442,], +["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20445,], +["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20445,], ["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",20442,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20442,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20442,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20442,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20442,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20442,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20442,], -["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20442,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20445,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20445,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20445,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20445,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20445,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20445,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20445,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20445,], ["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",20444,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_0_en",20445,], ["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en",0,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en",20444,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en",20444,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en",20445,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en",20445,], ["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en",0,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en",20444,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en",20445,], ["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",20442,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20445,], ["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,], @@ -577,38 +578,38 @@ 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",20442,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20442,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20442,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20442,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20445,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20445,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20445,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20445,], ["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",20442,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20442,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20442,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20442,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20442,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20442,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20442,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20442,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20442,], -["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20442,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20442,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20442,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20442,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20442,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20442,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20442,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20442,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20442,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20442,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20442,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20442,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20442,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20442,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20442,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20442,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20445,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20445,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20445,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20445,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20445,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20445,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20445,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20445,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20445,], +["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20445,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20445,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20445,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20445,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20445,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20445,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20445,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20445,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20445,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20445,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20445,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20445,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20445,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20445,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20445,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20445,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20442,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20445,], ["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,], @@ -621,22 +622,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",20442,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20442,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20445,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20445,], ["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",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20442,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20442,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20445,], ["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,], @@ -644,14 +645,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","",20442,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20442,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20445,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20445,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20442,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20445,], ["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","",20442,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20445,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -665,7 +666,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",20442,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20445,], ["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,], @@ -674,7 +675,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",20442,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20445,], ["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,], @@ -682,26 +683,26 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessagesReactionButton_Day_1_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_1_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_2_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_2_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_3_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_3_en",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20442,], -["features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en","features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en",20442,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20442,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20442,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20442,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20442,], -["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20442,], -["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20442,], -["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20442,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20442,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20442,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20442,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20442,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20442,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20442,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20442,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20442,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20442,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20445,], +["features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en","features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en",20445,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20445,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20445,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20445,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20445,], +["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20445,], +["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20445,], +["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20445,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20445,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20445,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20445,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20445,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20445,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20445,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20445,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20445,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20445,], ["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",20442,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20445,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], @@ -712,112 +713,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",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20442,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20442,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20442,], +["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20445,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20445,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20445,], ["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",20442,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20442,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20442,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20442,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20442,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20442,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20442,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20442,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20445,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20445,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20445,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20445,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20445,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20445,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20445,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20445,], ["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",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20442,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20445,], ["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",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20442,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20442,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20445,], ["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",20442,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20445,], ["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",0,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20442,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20442,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20442,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20442,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20445,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20445,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20445,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20445,], ["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",20442,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20442,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20442,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20445,], ["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",20442,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20442,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20442,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20442,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20442,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20442,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20442,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20442,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20442,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20442,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20442,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20442,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20442,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20442,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20445,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20445,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20445,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20445,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20445,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20442,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20442,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20442,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20442,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20442,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20445,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20445,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20445,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20445,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20445,], ["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",20442,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20442,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20442,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20442,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20442,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20442,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20442,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20442,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20442,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20442,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20442,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20445,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20445,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20445,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20445,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20445,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20445,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20445,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20445,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20445,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20445,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20445,], ["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,], @@ -831,207 +832,207 @@ export const screenshots = [ ["libraries.designsystem.components.preferences_PreferenceRow_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSlide_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en","",0,], -["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20442,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20442,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20442,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20442,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20445,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20445,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20445,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20445,], ["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","",20442,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20442,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20445,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20445,], ["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",20442,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20442,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20442,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20442,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20442,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20442,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20442,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20442,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20442,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20442,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20442,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20442,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20442,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20442,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20442,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20442,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20442,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20442,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20442,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20442,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20442,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20442,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20442,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20442,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20442,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20442,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20442,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20445,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20445,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20445,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20445,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20445,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20445,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20445,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20445,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20445,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20445,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20445,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20445,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20445,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20445,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20445,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20445,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20445,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20445,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20445,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20445,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20445,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20445,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20445,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20445,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20445,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20445,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20445,], ["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",20442,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20442,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20445,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20445,], ["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",20442,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20442,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20442,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20442,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20442,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20442,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20442,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20445,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20445,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20445,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20445,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20445,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20445,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20445,], ["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",20442,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20442,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20442,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20442,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20442,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20442,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20442,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20442,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20442,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20442,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20442,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20442,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20442,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20442,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20442,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20442,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20442,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20445,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20445,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20445,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20445,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20445,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20445,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20445,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20445,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20445,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20445,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20445,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20445,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20445,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20445,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20445,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20445,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20445,], ["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",20442,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20442,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20442,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20442,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20442,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20442,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20442,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20442,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20442,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20442,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20442,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20442,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20442,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20445,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20445,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20445,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20445,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20445,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20445,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20445,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20445,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20445,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20445,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20445,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20445,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20445,], ["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",20442,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20442,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20442,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20442,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20442,], -["features.roomdetails.impl_RoomDetails_0_en","",20442,], -["features.roomdetails.impl_RoomDetails_10_en","",20442,], -["features.roomdetails.impl_RoomDetails_11_en","",20442,], -["features.roomdetails.impl_RoomDetails_12_en","",20442,], -["features.roomdetails.impl_RoomDetails_13_en","",20442,], -["features.roomdetails.impl_RoomDetails_14_en","",20442,], -["features.roomdetails.impl_RoomDetails_15_en","",20442,], -["features.roomdetails.impl_RoomDetails_16_en","",20442,], -["features.roomdetails.impl_RoomDetails_17_en","",20442,], -["features.roomdetails.impl_RoomDetails_18_en","",20442,], -["features.roomdetails.impl_RoomDetails_19_en","",20442,], -["features.roomdetails.impl_RoomDetails_1_en","",20442,], -["features.roomdetails.impl_RoomDetails_2_en","",20442,], -["features.roomdetails.impl_RoomDetails_3_en","",20442,], -["features.roomdetails.impl_RoomDetails_4_en","",20442,], -["features.roomdetails.impl_RoomDetails_5_en","",20442,], -["features.roomdetails.impl_RoomDetails_6_en","",20442,], -["features.roomdetails.impl_RoomDetails_7_en","",20442,], -["features.roomdetails.impl_RoomDetails_8_en","",20442,], -["features.roomdetails.impl_RoomDetails_9_en","",20442,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20442,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20442,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20442,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20442,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20442,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20442,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20442,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20442,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20442,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20445,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20445,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20445,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20445,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20445,], +["features.roomdetails.impl_RoomDetails_0_en","",20445,], +["features.roomdetails.impl_RoomDetails_10_en","",20445,], +["features.roomdetails.impl_RoomDetails_11_en","",20445,], +["features.roomdetails.impl_RoomDetails_12_en","",20445,], +["features.roomdetails.impl_RoomDetails_13_en","",20445,], +["features.roomdetails.impl_RoomDetails_14_en","",20445,], +["features.roomdetails.impl_RoomDetails_15_en","",20445,], +["features.roomdetails.impl_RoomDetails_16_en","",20445,], +["features.roomdetails.impl_RoomDetails_17_en","",20445,], +["features.roomdetails.impl_RoomDetails_18_en","",20445,], +["features.roomdetails.impl_RoomDetails_19_en","",20445,], +["features.roomdetails.impl_RoomDetails_1_en","",20445,], +["features.roomdetails.impl_RoomDetails_2_en","",20445,], +["features.roomdetails.impl_RoomDetails_3_en","",20445,], +["features.roomdetails.impl_RoomDetails_4_en","",20445,], +["features.roomdetails.impl_RoomDetails_5_en","",20445,], +["features.roomdetails.impl_RoomDetails_6_en","",20445,], +["features.roomdetails.impl_RoomDetails_7_en","",20445,], +["features.roomdetails.impl_RoomDetails_8_en","",20445,], +["features.roomdetails.impl_RoomDetails_9_en","",20445,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20445,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20445,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20445,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20445,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20445,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20445,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20445,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20445,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20445,], ["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",20442,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20442,], -["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20442,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20442,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20442,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20442,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20442,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20442,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20442,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20445,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20445,], +["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20445,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20445,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20445,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20445,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20445,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20445,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20445,], ["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",20442,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20442,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20442,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20442,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20442,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20442,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20442,], -["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20442,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20442,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20442,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20442,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20442,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20442,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20442,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20442,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20442,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20442,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20445,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20445,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20445,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20445,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20445,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20445,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20445,], +["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20445,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20445,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20445,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20445,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20445,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20445,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20445,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20445,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20445,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20445,], ["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",20442,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20442,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20442,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20442,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20442,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20442,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20442,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20442,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20442,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20442,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20442,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20442,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20442,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20442,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20445,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20445,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20445,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20445,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20445,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20445,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20445,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20445,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20445,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20445,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20445,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20445,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20445,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20445,], ["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,], @@ -1054,14 +1055,14 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_26_en","features.home.impl.components_RoomSummaryRow_Night_26_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_27_en","features.home.impl.components_RoomSummaryRow_Night_27_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_28_en","features.home.impl.components_RoomSummaryRow_Night_28_en",0,], -["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20442,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20442,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20442,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20442,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20442,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20442,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20442,], -["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20442,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20445,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20445,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20445,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20445,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20445,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20445,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20445,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20445,], ["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",0,], ["features.home.impl.components_RoomSummaryRow_Day_3_en","features.home.impl.components_RoomSummaryRow_Night_3_en",0,], @@ -1071,109 +1072,109 @@ 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",20442,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20442,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20442,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20445,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20445,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20445,], ["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",20442,], -["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20442,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en",20444,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en",20444,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en",20444,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en",20444,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20442,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20442,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20445,], +["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20445,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en",20445,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en",20445,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en",20445,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en",20445,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20445,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20445,], ["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","",20442,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20445,], ["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","",20442,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20442,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20442,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20442,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20442,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20442,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20442,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20442,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20442,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20442,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20442,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20442,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20442,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20442,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20445,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20445,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20445,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20445,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20445,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20445,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20445,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20445,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20445,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20445,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20445,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20445,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20445,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20445,], ["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,], @@ -1187,11 +1188,11 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_1_en","libraries.matrix.ui.components_SelectedUser_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedUsersRowList_Day_0_en","libraries.matrix.ui.components_SelectedUsersRowList_Night_0_en",0,], ["libraries.textcomposer.components_SendButton_Day_0_en","libraries.textcomposer.components_SendButton_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20442,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20442,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20442,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20442,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20442,], +["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20445,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20445,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20445,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20445,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20445,], ["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,], @@ -1201,28 +1202,28 @@ 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",20442,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20442,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20442,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20442,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20442,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20442,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20442,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20442,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20445,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20445,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20445,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20445,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20445,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20445,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20445,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20445,], ["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",20442,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20442,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20442,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20442,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20442,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20442,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20442,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20442,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20442,], -["features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en","features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en",20444,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20442,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20445,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20445,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20445,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20445,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20445,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20445,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20445,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20445,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20445,], +["features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en","features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en",20445,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20445,], ["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,], @@ -1232,102 +1233,102 @@ 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",20442,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20445,], ["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",20442,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20445,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20442,], -["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20442,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20442,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20445,], +["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20445,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20445,], ["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",20442,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20442,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20442,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20442,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20442,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20442,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20442,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20442,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20442,], -["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20442,], -["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20442,], -["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20442,], -["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20442,], -["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20442,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20442,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20442,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20442,], -["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20442,], -["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20442,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20445,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20445,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20445,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20445,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20445,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20445,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20445,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20445,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20445,], +["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20445,], +["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20445,], +["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20445,], +["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20445,], +["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20445,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20445,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20445,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20445,], +["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20445,], +["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20445,], ["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",20442,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20442,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20442,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20442,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20442,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20442,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20442,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20445,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20445,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20445,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20445,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20445,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20445,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20445,], ["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",20442,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20445,], ["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",20442,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20445,], ["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",20442,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20442,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20442,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20442,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20442,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20442,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20442,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20442,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20442,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20442,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20442,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20442,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20442,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20442,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20442,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20445,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20445,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20445,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20445,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20445,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20445,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20445,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20445,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20445,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20445,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20445,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20445,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20445,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20445,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20445,], ["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",20442,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20442,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20445,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20445,], ["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,], @@ -1339,16 +1340,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",20442,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20442,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20442,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20442,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20442,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20445,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20445,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20445,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20445,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20445,], ["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",20442,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20442,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20445,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20445,], ["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,], @@ -1358,18 +1359,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",20442,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20445,], ["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",20442,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20445,], ["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,], @@ -1377,18 +1378,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",20442,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20445,], ["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",20442,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20442,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20445,], ["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",20442,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20445,], ["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,], @@ -1397,41 +1398,41 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20445,], ["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",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20445,], ["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",20442,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20445,], ["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","",20442,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20445,], ["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",20442,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20442,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20445,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20445,], ["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",20442,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20445,], ["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",20442,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20442,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20442,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20445,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20445,], ["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",20442,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20442,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20445,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20445,], ["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",20442,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20445,], ["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,], @@ -1440,8 +1441,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",20442,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20445,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20445,], ["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,], @@ -1456,8 +1457,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",20442,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20442,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20445,], ["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,], @@ -1480,85 +1481,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",20442,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20442,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20445,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20445,], ["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",20442,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20442,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20442,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20442,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20442,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20442,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20442,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20442,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20445,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20445,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20445,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20445,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20445,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20445,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20445,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20445,], ["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",20442,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20445,], ["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",20442,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20445,], ["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",20442,], +["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20445,], ["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",20442,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20442,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20442,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20442,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20442,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20442,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20442,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20442,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20445,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20445,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20445,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20445,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20445,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20445,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20445,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20445,], ["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",20442,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20442,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20442,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20442,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20442,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20442,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20445,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20445,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20445,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20445,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20445,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20445,], ["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","",20442,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20445,], ["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], ["libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en","libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en",0,], -["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20442,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20442,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20442,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20442,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20445,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20445,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20445,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20445,], ["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",20442,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20445,], ["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",20442,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20445,], ["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",20442,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20442,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20442,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20442,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20442,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20442,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20442,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20442,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20442,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20442,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20442,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20442,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20445,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20445,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20445,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20445,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20445,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20445,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20445,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20445,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20445,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20445,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20445,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20445,], ["features.verifysession.impl.ui_VerificationUserProfileContent_Day_0_en","features.verifysession.impl.ui_VerificationUserProfileContent_Night_0_en",0,], ["libraries.designsystem.ruler_VerticalRuler_Day_0_en","libraries.designsystem.ruler_VerticalRuler_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_1_en",0,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20442,], -["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20442,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20445,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20445,], ["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",20442,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20445,], ["features.viewfolder.impl.file_ViewFileView_Day_4_en","features.viewfolder.impl.file_ViewFileView_Night_4_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_5_en","features.viewfolder.impl.file_ViewFileView_Night_5_en",0,], ["features.viewfolder.impl.folder_ViewFolderView_Day_0_en","features.viewfolder.impl.folder_ViewFolderView_Night_0_en",0,], From 971bcbf0bfcf92b2a443f1e3732901f68dad1275 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 29 Dec 2025 09:37:56 +0100 Subject: [PATCH 268/347] Ensure factorize follow the same code convention --- .../fixtures/factories/EventTimelineItem.kt | 4 +-- .../factories/EventTimelineItemDebugInfo.kt | 2 +- .../fixtures/factories/NotificationItem.kt | 13 ++++---- .../fixtures/factories/RoomDescription.kt | 22 ++++++------- .../impl/fixtures/factories/RoomHero.kt | 12 +++---- .../impl/fixtures/factories/RoomInfo.kt | 2 +- .../impl/fixtures/factories/RoomMember.kt | 2 +- .../factories/RoomNotificationSettings.kt | 2 +- ...owerLevels.kt => RoomPowerLevelsValues.kt} | 0 .../fixtures/factories/RoomPreviewInfo.kt | 32 +++++++++---------- .../matrix/impl/fixtures/factories/Session.kt | 20 ++++++------ .../impl/fixtures/factories/SpaceRoom.kt | 2 +- ....kt => TimelineEventContentMessageLike.kt} | 16 ++++------ ...ntent.kt => TimelineItemContentMsgLike.kt} | 4 ++- .../fixtures/factories/UnableToDecryptInfo.kt | 20 ++++++------ .../impl/fixtures/factories/UserProfile.kt | 2 +- .../RustNotificationServiceTest.kt | 8 ++--- 17 files changed, 77 insertions(+), 86 deletions(-) rename libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/{RoomPowerLevels.kt => RoomPowerLevelsValues.kt} (100%) rename libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/{TimelineEventType.kt => TimelineEventContentMessageLike.kt} (81%) rename libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/{EventTimelineItemContent.kt => TimelineItemContentMsgLike.kt} (90%) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt index 1e5692d59c..c106b6b39e 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt @@ -21,14 +21,14 @@ import org.matrix.rustcomponents.sdk.ShieldState import org.matrix.rustcomponents.sdk.TimelineItemContent import uniffi.matrix_sdk_ui.EventItemOrigin -fun aRustEventTimelineItem( +internal fun aRustEventTimelineItem( isRemote: Boolean = true, eventOrTransactionId: EventOrTransactionId = EventOrTransactionId.EventId(AN_EVENT_ID.value), sender: String = A_USER_ID.value, senderProfile: ProfileDetails = ProfileDetails.Unavailable, isOwn: Boolean = true, isEditable: Boolean = true, - content: TimelineItemContent = aRustTimelineItemMessageContent(), + content: TimelineItemContent = aRustTimelineItemContentMsgLike(), timestamp: ULong = 0uL, debugInfo: EventTimelineItemDebugInfo = anEventTimelineItemDebugInfo(), localSendState: EventSendState? = null, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItemDebugInfo.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItemDebugInfo.kt index 6995c4915f..badd4c3aba 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItemDebugInfo.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItemDebugInfo.kt @@ -10,7 +10,7 @@ package io.element.android.libraries.matrix.impl.fixtures.factories import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfo -fun anEventTimelineItemDebugInfo( +internal fun anEventTimelineItemDebugInfo( model: String = "model", originalJson: String? = null, latestEditJson: String? = null, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/NotificationItem.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/NotificationItem.kt index e5b77b249c..672439ad6c 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/NotificationItem.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/NotificationItem.kt @@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiTimelineEv import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_USER_NAME import org.matrix.rustcomponents.sdk.Action +import org.matrix.rustcomponents.sdk.BatchNotificationResult import org.matrix.rustcomponents.sdk.JoinRule import org.matrix.rustcomponents.sdk.NotificationEvent import org.matrix.rustcomponents.sdk.NotificationItem @@ -21,7 +22,7 @@ import org.matrix.rustcomponents.sdk.NotificationSenderInfo import org.matrix.rustcomponents.sdk.NotificationStatus import org.matrix.rustcomponents.sdk.TimelineEvent -fun aRustNotificationItem( +internal fun aRustNotificationItem( event: NotificationEvent = aRustNotificationEventTimeline(), senderInfo: NotificationSenderInfo = aRustNotificationSenderInfo(), roomInfo: NotificationRoomInfo = aRustNotificationRoomInfo(), @@ -39,13 +40,13 @@ fun aRustNotificationItem( actions = actions, ) -fun aRustBatchNotificationResult( +internal fun aRustBatchNotificationResultOk( notificationStatus: NotificationStatus = NotificationStatus.Event(aRustNotificationItem()), -) = org.matrix.rustcomponents.sdk.BatchNotificationResult.Ok( +) = BatchNotificationResult.Ok( status = notificationStatus, ) -fun aRustNotificationSenderInfo( +internal fun aRustNotificationSenderInfo( displayName: String? = A_USER_NAME, avatarUrl: String? = null, isNameAmbiguous: Boolean = false, @@ -55,7 +56,7 @@ fun aRustNotificationSenderInfo( isNameAmbiguous = isNameAmbiguous, ) -fun aRustNotificationRoomInfo( +internal fun aRustNotificationRoomInfo( displayName: String = A_ROOM_NAME, avatarUrl: String? = null, canonicalAlias: String? = null, @@ -77,7 +78,7 @@ fun aRustNotificationRoomInfo( isSpace = isSpace, ) -fun aRustNotificationEventTimeline( +internal fun aRustNotificationEventTimeline( event: TimelineEvent = FakeFfiTimelineEvent(), ) = NotificationEvent.Timeline( event = event, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomDescription.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomDescription.kt index 9490937126..14960e9f70 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomDescription.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomDescription.kt @@ -22,15 +22,13 @@ internal fun aRustRoomDescription( joinRule: PublicRoomJoinRule = PublicRoomJoinRule.PUBLIC, isWorldReadable: Boolean = true, joinedMembers: ULong = 2u, -): RoomDescription { - return RoomDescription( - roomId = roomId, - name = name, - topic = topic, - alias = alias, - avatarUrl = avatarUrl, - joinRule = joinRule, - isWorldReadable = isWorldReadable, - joinedMembers = joinedMembers, - ) -} +) = RoomDescription( + roomId = roomId, + name = name, + topic = topic, + alias = alias, + avatarUrl = avatarUrl, + joinRule = joinRule, + isWorldReadable = isWorldReadable, + joinedMembers = joinedMembers, +) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomHero.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomHero.kt index 6725d8058f..6abb08c667 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomHero.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomHero.kt @@ -14,10 +14,8 @@ import org.matrix.rustcomponents.sdk.RoomHero internal fun aRustRoomHero( userId: UserId = A_USER_ID, -): RoomHero { - return RoomHero( - userId = userId.value, - displayName = "displayName", - avatarUrl = "avatarUrl", - ) -} +) = RoomHero( + userId = userId.value, + displayName = "displayName", + avatarUrl = "avatarUrl", +) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomInfo.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomInfo.kt index b8454b2318..298db5e722 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomInfo.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomInfo.kt @@ -22,7 +22,7 @@ import org.matrix.rustcomponents.sdk.RoomPowerLevels import org.matrix.rustcomponents.sdk.SuccessorRoom import uniffi.matrix_sdk_base.EncryptionState -fun aRustRoomInfo( +internal fun aRustRoomInfo( id: String = A_ROOM_ID.value, displayName: String? = A_ROOM_NAME, rawName: String? = A_ROOM_NAME, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt index 9004340939..77fa814cca 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt @@ -14,7 +14,7 @@ import org.matrix.rustcomponents.sdk.PowerLevel import org.matrix.rustcomponents.sdk.RoomMember import uniffi.matrix_sdk.RoomMemberRole -fun aRustRoomMember( +internal fun aRustRoomMember( userId: UserId, displayName: String? = null, avatarUrl: String? = null, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomNotificationSettings.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomNotificationSettings.kt index 30b9ed4a08..a66fb3f332 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomNotificationSettings.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomNotificationSettings.kt @@ -11,7 +11,7 @@ package io.element.android.libraries.matrix.impl.fixtures.factories import org.matrix.rustcomponents.sdk.RoomNotificationMode import org.matrix.rustcomponents.sdk.RoomNotificationSettings -fun aRustRoomNotificationSettings( +internal fun aRustRoomNotificationSettings( mode: RoomNotificationMode = RoomNotificationMode.ALL_MESSAGES, isDefault: Boolean = true, ) = RoomNotificationSettings( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPowerLevels.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPowerLevelsValues.kt similarity index 100% rename from libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPowerLevels.kt rename to libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPowerLevelsValues.kt diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPreviewInfo.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPreviewInfo.kt index 0ff92f2bdc..aacb809a70 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPreviewInfo.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPreviewInfo.kt @@ -19,20 +19,18 @@ internal fun aRustRoomPreviewInfo( canonicalAlias: String? = A_ROOM_ALIAS.value, membership: Membership? = Membership.JOINED, joinRule: JoinRule = JoinRule.Public, -): RoomPreviewInfo { - return RoomPreviewInfo( - roomId = A_ROOM_ID.value, - canonicalAlias = canonicalAlias, - name = "name", - topic = "topic", - avatarUrl = "avatarUrl", - numJoinedMembers = 1u, - numActiveMembers = 1u, - isDirect = false, - roomType = RoomType.Room, - isHistoryWorldReadable = true, - membership = membership, - joinRule = joinRule, - heroes = null, - ) -} +) = RoomPreviewInfo( + roomId = A_ROOM_ID.value, + canonicalAlias = canonicalAlias, + name = "name", + topic = "topic", + avatarUrl = "avatarUrl", + numJoinedMembers = 1u, + numActiveMembers = 1u, + isDirect = false, + roomType = RoomType.Room, + isHistoryWorldReadable = true, + membership = membership, + joinRule = joinRule, + heroes = null, +) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/Session.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/Session.kt index 133e7ff49f..4671c457b0 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/Session.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/Session.kt @@ -18,14 +18,12 @@ internal fun aRustSession( proxy: SlidingSyncVersion = SlidingSyncVersion.NONE, accessToken: String = "accessToken", refreshToken: String = "refreshToken", -): Session { - return Session( - accessToken = accessToken, - refreshToken = refreshToken, - userId = A_USER_ID.value, - deviceId = A_DEVICE_ID.value, - homeserverUrl = A_HOMESERVER_URL, - oidcData = null, - slidingSyncVersion = proxy, - ) -} +) = Session( + accessToken = accessToken, + refreshToken = refreshToken, + userId = A_USER_ID.value, + deviceId = A_DEVICE_ID.value, + homeserverUrl = A_HOMESERVER_URL, + oidcData = null, + slidingSyncVersion = proxy, +) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/SpaceRoom.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/SpaceRoom.kt index 7b821270af..50115055c2 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/SpaceRoom.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/SpaceRoom.kt @@ -16,7 +16,7 @@ import org.matrix.rustcomponents.sdk.RoomHero import org.matrix.rustcomponents.sdk.RoomType import org.matrix.rustcomponents.sdk.SpaceRoom -fun aRustSpaceRoom( +internal fun aRustSpaceRoom( roomId: RoomId = A_ROOM_ID, isDirect: Boolean = false, canonicalAlias: String? = null, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventType.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventContentMessageLike.kt similarity index 81% rename from libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventType.kt rename to libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventContentMessageLike.kt index 8d87afb4e7..877f2056e9 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventType.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineEventContentMessageLike.kt @@ -15,15 +15,13 @@ import org.matrix.rustcomponents.sdk.MessageType import org.matrix.rustcomponents.sdk.TextMessageContent import org.matrix.rustcomponents.sdk.TimelineEventContent -fun aRustTimelineEventContentMessageLike( +internal fun aRustTimelineEventContentMessageLike( content: MessageLikeEventContent = aRustMessageLikeEventContentRoomMessage(), -): TimelineEventContent.MessageLike { - return TimelineEventContent.MessageLike( - content = content, - ) -} +) = TimelineEventContent.MessageLike( + content = content, +) -fun aRustMessageLikeEventContentRoomMessage( +internal fun aRustMessageLikeEventContentRoomMessage( messageType: MessageType = aRustMessageTypeText(), inReplyToEventId: String? = null, ) = MessageLikeEventContent.RoomMessage( @@ -31,13 +29,13 @@ fun aRustMessageLikeEventContentRoomMessage( inReplyToEventId = inReplyToEventId, ) -fun aRustMessageTypeText( +internal fun aRustMessageTypeText( content: TextMessageContent = aRustTextMessageContent(), ) = MessageType.Text( content = content, ) -fun aRustTextMessageContent( +internal fun aRustTextMessageContent( body: String = A_MESSAGE, formatted: FormattedBody? = null, ) = TextMessageContent( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItemContent.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineItemContentMsgLike.kt similarity index 90% rename from libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItemContent.kt rename to libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineItemContentMsgLike.kt index cf29697f6a..0db7590a5c 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItemContent.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/TimelineItemContentMsgLike.kt @@ -15,7 +15,9 @@ import org.matrix.rustcomponents.sdk.MsgLikeKind import org.matrix.rustcomponents.sdk.TextMessageContent import org.matrix.rustcomponents.sdk.TimelineItemContent -fun aRustTimelineItemMessageContent(body: String = "Hello") = TimelineItemContent.MsgLike( +internal fun aRustTimelineItemContentMsgLike( + body: String = "Hello", +) = TimelineItemContent.MsgLike( content = MsgLikeContent( kind = MsgLikeKind.Message( content = MessageContent( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/UnableToDecryptInfo.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/UnableToDecryptInfo.kt index 7a7acec479..4faa914e8c 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/UnableToDecryptInfo.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/UnableToDecryptInfo.kt @@ -19,14 +19,12 @@ internal fun aRustUnableToDecryptInfo( userTrustsOwnIdentity: Boolean = false, senderHomeserver: String = "", ownHomeserver: String = "", -): UnableToDecryptInfo { - return UnableToDecryptInfo( - eventId = eventId, - timeToDecryptMs = timeToDecryptMs, - cause = cause, - eventLocalAgeMillis = eventLocalAgeMillis, - userTrustsOwnIdentity = userTrustsOwnIdentity, - senderHomeserver = senderHomeserver, - ownHomeserver = ownHomeserver, - ) -} +) = UnableToDecryptInfo( + eventId = eventId, + timeToDecryptMs = timeToDecryptMs, + cause = cause, + eventLocalAgeMillis = eventLocalAgeMillis, + userTrustsOwnIdentity = userTrustsOwnIdentity, + senderHomeserver = senderHomeserver, + ownHomeserver = ownHomeserver, +) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/UserProfile.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/UserProfile.kt index c91327a692..8713e08f1c 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/UserProfile.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/UserProfile.kt @@ -11,7 +11,7 @@ package io.element.android.libraries.matrix.impl.fixtures.factories import io.element.android.libraries.matrix.test.A_USER_ID import org.matrix.rustcomponents.sdk.UserProfile -fun aRustUserProfile( +internal fun aRustUserProfile( userId: String = A_USER_ID.value, displayName: String = "displayName", avatarUrl: String = "avatarUrl", diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt index a50fa4c45b..eecc37a529 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationServiceTest.kt @@ -12,7 +12,7 @@ import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.exception.NotificationResolverException import io.element.android.libraries.matrix.api.notification.NotificationContent import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType -import io.element.android.libraries.matrix.impl.fixtures.factories.aRustBatchNotificationResult +import io.element.android.libraries.matrix.impl.fixtures.factories.aRustBatchNotificationResultOk import io.element.android.libraries.matrix.impl.fixtures.factories.aRustNotificationEventTimeline import io.element.android.libraries.matrix.impl.fixtures.factories.aRustNotificationItem import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiNotificationClient @@ -38,7 +38,7 @@ class RustNotificationServiceTest { @Test fun test() = runTest { val notificationClient = FakeFfiNotificationClient( - notificationItemResult = mapOf(AN_EVENT_ID.value to aRustBatchNotificationResult()), + notificationItemResult = mapOf(AN_EVENT_ID.value to aRustBatchNotificationResultOk()), ) val sut = createRustNotificationService( notificationClient = notificationClient, @@ -66,10 +66,10 @@ class RustNotificationServiceTest { } val notificationClient = FakeFfiNotificationClient( notificationItemResult = mapOf( - AN_EVENT_ID.value to aRustBatchNotificationResult( + AN_EVENT_ID.value to aRustBatchNotificationResultOk( notificationStatus = NotificationStatus.Event(aRustNotificationItem(aRustNotificationEventTimeline(faultyEvent))) ), - AN_EVENT_ID_2.value to aRustBatchNotificationResult() + AN_EVENT_ID_2.value to aRustBatchNotificationResultOk() ), ) val sut = createRustNotificationService( From 0162a08ccb46de44d52f38d0b131810058fa7238 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 29 Dec 2025 09:47:29 +0100 Subject: [PATCH 269/347] Rename parameter --- .../element/android/features/space/impl/root/SpaceViewTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt index defac3406a..406b5d17e8 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/root/SpaceViewTest.kt @@ -140,7 +140,7 @@ private fun AndroidComposeTestRule.setSpace onRoomClick: (SpaceRoom) -> Unit = EnsureNeverCalledWithParam(), onShareSpace: () -> Unit = EnsureNeverCalled(), onLeaveSpaceClick: () -> Unit = EnsureNeverCalled(), - onDetailsClick: () -> Unit = EnsureNeverCalled(), + onSettingsClick: () -> Unit = EnsureNeverCalled(), onViewMembersClick: () -> Unit = EnsureNeverCalled(), acceptDeclineInviteView: @Composable () -> Unit = {}, ) { @@ -151,7 +151,7 @@ private fun AndroidComposeTestRule.setSpace onRoomClick = onRoomClick, onShareSpace = onShareSpace, onLeaveSpaceClick = onLeaveSpaceClick, - onSettingsClick = onDetailsClick, + onSettingsClick = onSettingsClick, onViewMembersClick = onViewMembersClick, acceptDeclineInviteView = acceptDeclineInviteView, ) From c4f1d3d3d046c3aced3b8f58ad776a11e681be14 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 09:57:09 +0100 Subject: [PATCH 270/347] fix(deps): update dependency com.posthog:posthog-android to v3.28.0 (#5941) 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 5daa441233..424f7a5620 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -218,7 +218,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.27.2" +posthog = "com.posthog:posthog-android:3.28.0" sentry = "io.sentry:sentry-android:8.29.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.29.2" From 6715104f8f31920f2bddb74056709fda74bd2982 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 29 Dec 2025 12:00:58 +0100 Subject: [PATCH 271/347] Fix class cast exception java.lang.ClassCastException: io.element.android.libraries.androidutils.json.DefaultJsonProvider cannot be cast to kotlinx.serialization.json.Json --- .../android/libraries/androidutils/json/JsonProvider.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt index fb92adddb9..b13d7824be 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt @@ -10,14 +10,15 @@ package io.element.android.libraries.androidutils.json import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding -import dev.zacsweers.metro.Provider import dev.zacsweers.metro.SingleIn import kotlinx.serialization.json.Json /** * Provides a Json instance configured to ignore unknown keys. */ -typealias JsonProvider = Provider +interface JsonProvider { + operator fun invoke(): Json +} @ContributesBinding(AppScope::class) @SingleIn(AppScope::class) From 155d3fb96f920f55ea9450f24c82eaf49c2be117 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 29 Dec 2025 12:47:21 +0100 Subject: [PATCH 272/347] Fix test compilation --- .../element/android/libraries/androidutils/json/JsonProvider.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt index b13d7824be..1e25599962 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/json/JsonProvider.kt @@ -16,7 +16,7 @@ import kotlinx.serialization.json.Json /** * Provides a Json instance configured to ignore unknown keys. */ -interface JsonProvider { +fun interface JsonProvider { operator fun invoke(): Json } From ab92a3485836e9bf93a33124abb6c7a801f6becf Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 30 Dec 2025 09:39:13 +0000 Subject: [PATCH 273/347] Update screenshots --- .../snapshots/images/features.home.impl_HomeViewA11y_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_0_en.png | 4 ++-- .../images/features.home.impl_HomeView_Day_10_en.png | 4 ++-- .../images/features.home.impl_HomeView_Day_11_en.png | 4 ++-- .../images/features.home.impl_HomeView_Day_13_en.png | 4 ++-- .../images/features.home.impl_HomeView_Day_14_en.png | 4 ++-- .../images/features.home.impl_HomeView_Day_15_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_1_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_2_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_5_en.png | 4 ++-- .../snapshots/images/features.home.impl_HomeView_Day_9_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_0_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_10_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_11_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_13_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_14_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_15_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_1_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_2_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_5_en.png | 4 ++-- .../images/features.home.impl_HomeView_Night_9_en.png | 4 ++-- 21 files changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png index 78e57157df..98ce0d3bc1 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeViewA11y_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29076d1c09d92943b1ba143d0ed3798fe92f7d37f87f45c0ae5f7326afe66f74 -size 136708 +oid sha256:cc3fcb72de86766e3b97ffe0802551d7597b688f2a52ef73938d91c9cfdf0633 +size 141868 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_0_en.png index 3e870ea8d7..edc3a6f1f1 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1 -size 61515 +oid sha256:02f12178991ed984da4b2d0a9883250750b6e37e7c9ce8494ca12bb987f29ad4 +size 65455 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_10_en.png index be60b0ceec..eb4002392c 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd257b64d9e91bedebcf4552e8b93d357304954ad844b7f7d52bc76fc1543747 -size 29901 +oid sha256:4eb7b8997069e2a4b37cd27c33e2862cba1871e1b58e85feb0b1bc4da6a3fce8 +size 33631 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_11_en.png index 95987c0cb2..886d567126 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e3e455fbe6e3a10ec1578e01dc3f10c3b2b0688f99a1855319143c8fc7044a8 -size 25355 +oid sha256:ff84f90db0deea1d8edc52a2067855cf277cc747f5c357dc0758ce72bbc6d0c8 +size 28014 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_13_en.png index 343550c109..583ae6e976 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:821cb6a2068561375d0988d4ba5404e52411a6d9b73cefbe1a6bd7bc6d467673 -size 88367 +oid sha256:e8cd2089f07a93e3dc62e41d80a3253d800b4463947276ccd461428280aff6b8 +size 84644 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_14_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_14_en.png index 191d910e04..faee0bc22d 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9f5fef39d80aacb9666deeea43e4df48f7c70231bd8ec41edf2f3eed5f0aa42 -size 81149 +oid sha256:71f336f93dd3fe736187a38aba6c1f14420bb0da9d574603f6df2042bce8f8d1 +size 83116 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_15_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_15_en.png index 2eb8a41683..7d6ed57883 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c9e019924f41de0c16f1f403944b8fe390afa65d1ad604db3dd0baadbc30db5b -size 50953 +oid sha256:d7840847edf48b171393418d6fc26d846d772fa8be919f55dfee086d85cab814 +size 51404 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_1_en.png index 3e870ea8d7..edc3a6f1f1 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1 -size 61515 +oid sha256:02f12178991ed984da4b2d0a9883250750b6e37e7c9ce8494ca12bb987f29ad4 +size 65455 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_2_en.png index 3e870ea8d7..edc3a6f1f1 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1 -size 61515 +oid sha256:02f12178991ed984da4b2d0a9883250750b6e37e7c9ce8494ca12bb987f29ad4 +size 65455 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_5_en.png index 3e870ea8d7..edc3a6f1f1 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:580c70e645e954e9e3d29a68aa46b1eae3a82651eb5e419eb92cba48bf7baaf1 -size 61515 +oid sha256:02f12178991ed984da4b2d0a9883250750b6e37e7c9ce8494ca12bb987f29ad4 +size 65455 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_9_en.png index 277cd740bb..0f387ca179 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a5a68b4d8951b7c516561d538c5d328a84948c66af7eb7c80ac77cd005620cf2 -size 80977 +oid sha256:9fb19cc1e169e81f301a12ff3e30b8118682248ec3c13ea29b54f87398a54c3e +size 82977 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_0_en.png index a46c9d21bf..e011cf5f07 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e -size 58325 +oid sha256:62f84bd6941a00ee6b006318b8ac9e659694c2749a3bfa1d8ca72ca2ce413c90 +size 62152 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_10_en.png index 19f76b695e..1052c94a6e 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:496855b1b3186adcad8b35895ee51776dce00a8d3229b8dccac4d6e4482bdaff -size 26577 +oid sha256:ab4a977d119ae80ddb92198b9c26b4b42d842eba0fd0543896f55914018d34f2 +size 30548 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_11_en.png index 7c3b6e1552..40455a3752 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b98678dc90bce52ab2293e5102794b4fc3b51fc667a6c061d771ea90212a0f2 -size 22034 +oid sha256:66824bcff1cf8fdd0fd88c3e0272bd11eaf6fdd16d24120c9346c99378226eee +size 24633 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_13_en.png index 8094781a7f..69ec4c780c 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:541740cdd54ef7b9a868c1409330a6ca7417bce9f022b22c3d395ac9b215d470 -size 83939 +oid sha256:7d1745b2665a9329808f69e2750b50d59eac2d92216a25bae03a52907b6c7681 +size 80341 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_14_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_14_en.png index 40695d7c0c..ffba98b54e 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a44897f23fc0e6a90779fe96638c560973caf7dbb9a7c92ec4d2f5b56de3ddcc -size 77280 +oid sha256:9017e66bb482de6a517065efe2e9d66ce4eb561fb848ca29d3245a2abc02d4c0 +size 79209 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_15_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_15_en.png index 8a3822d03c..c58e0fe485 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f0e5430bcd399d5a39c3d92e7551243f0e15bc315f9ec6ded43829d4672308c -size 47186 +oid sha256:6fd8d9d809b65df1690bf132351eec86736224d50fdd1bc9f9d2e731a4669ad6 +size 47687 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_1_en.png index a46c9d21bf..e011cf5f07 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e -size 58325 +oid sha256:62f84bd6941a00ee6b006318b8ac9e659694c2749a3bfa1d8ca72ca2ce413c90 +size 62152 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_2_en.png index a46c9d21bf..e011cf5f07 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e -size 58325 +oid sha256:62f84bd6941a00ee6b006318b8ac9e659694c2749a3bfa1d8ca72ca2ce413c90 +size 62152 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_5_en.png index a46c9d21bf..e011cf5f07 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37660e7c0626ae3e5a8404fdc7e57e41d43750abb4004572ffd9c25a501c668e -size 58325 +oid sha256:62f84bd6941a00ee6b006318b8ac9e659694c2749a3bfa1d8ca72ca2ce413c90 +size 62152 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_9_en.png index fc269825f1..a3e0ad8645 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49ea33ae74532c350b4176355203561cfc5eb79c93c4993d6ffb0cf933f8ad2f -size 77167 +oid sha256:6c7790afd67222ce61ea0b72f1af3c1877b7e88580a644524c33f18d6fe76137 +size 79096 From 556fdadd7f06a736b3fbd47420e4d12dd4ed654a Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 30 Dec 2025 15:56:32 +0100 Subject: [PATCH 274/347] feature(security&privacy): start branching logic of ManageAuthorizedSpaces --- .../impl/SecurityAndPrivacyFlowNode.kt | 7 ++ .../impl/SecurityAndPrivacyNavigator.kt | 10 ++ .../ManageAuthorizedSpacesView.kt | 8 +- .../impl/root/SecurityAndPrivacyEvent.kt | 3 + .../impl/root/SecurityAndPrivacyPresenter.kt | 92 +++++++++++++++++-- .../impl/root/SecurityAndPrivacyState.kt | 32 +++++-- .../root/SecurityAndPrivacyStateProvider.kt | 8 +- .../impl/root/SecurityAndPrivacyView.kt | 24 ++++- 8 files changed, 161 insertions(+), 23 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index 3d62e7b5d7..844c4f1a70 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -24,6 +24,7 @@ import io.element.android.annotations.ContributesNode import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions import io.element.android.features.securityandprivacy.impl.editroomaddress.EditRoomAddressNode +import io.element.android.features.securityandprivacy.impl.manageauthorizedspaces.ManageAuthorizedSpacesNode import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyNode import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode @@ -58,6 +59,9 @@ class SecurityAndPrivacyFlowNode( @Parcelize data object EditRoomAddress : NavTarget + + @Parcelize + data object ManageAuthorizedSpaces : NavTarget } private val callback: SecurityAndPrivacyEntryPoint.Callback = callback() @@ -89,6 +93,9 @@ class SecurityAndPrivacyFlowNode( NavTarget.EditRoomAddress -> { createNode(buildContext, plugins = listOf(navigator)) } + NavTarget.ManageAuthorizedSpaces -> { + createNode(buildContext, plugins = listOf(navigator)) + } } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt index 092da87943..274bf0b823 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt @@ -18,6 +18,8 @@ interface SecurityAndPrivacyNavigator : Plugin { fun onDone() fun openEditRoomAddress() fun closeEditRoomAddress() + fun openManageAuthorizedSpaces() + fun closeManageAuthorizedSpaces() } class BackstackSecurityAndPrivacyNavigator( @@ -35,4 +37,12 @@ class BackstackSecurityAndPrivacyNavigator( override fun closeEditRoomAddress() { backStack.pop() } + + override fun openManageAuthorizedSpaces() { + backStack.push(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces) + } + + override fun closeManageAuthorizedSpaces() { + backStack.pop() + } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt index ed49e048aa..513ecc980a 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt @@ -36,7 +36,6 @@ 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.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar -import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings @@ -80,11 +79,11 @@ fun ManageAuthorizedSpacesView( } ) } - if(state.unknownSpaceIds.isNotEmpty()){ + if (state.unknownSpaceIds.isNotEmpty()) { item { ListSectionHeader( title = stringResource(R.string.screen_manage_authorized_spaces_unknown_spaces_section_title), - hasDivider = false, + hasDivider = true, ) } items(items = state.unknownSpaceIds) { @@ -140,7 +139,7 @@ private fun CheckableSpaceListItem( Text(text = supportingText) } }, - leadingContent = avatarData?.let{ + leadingContent = avatarData?.let { ListItemContent.Custom { Avatar( avatarData = avatarData, @@ -158,7 +157,6 @@ private fun CheckableSpaceListItem( ) } - @OptIn(ExperimentalMaterial3Api::class) @Composable private fun ManageAuthorizedSpacesTopBar( diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt index 39abedab8c..0c56a834de 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt @@ -10,10 +10,13 @@ package io.element.android.features.securityandprivacy.impl.root sealed interface SecurityAndPrivacyEvent { data object EditRoomAddress : SecurityAndPrivacyEvent + data object ManageAuthorizedSpaces : SecurityAndPrivacyEvent data object Save : SecurityAndPrivacyEvent data object Exit : SecurityAndPrivacyEvent data object DismissExitConfirmation : SecurityAndPrivacyEvent data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvent + // Special case for "Space Members" + data object SelectSpaceMemberAccess : SecurityAndPrivacyEvent data object ToggleEncryptionState : SecurityAndPrivacyEvent data object CancelEnableEncryption : SecurityAndPrivacyEvent data object ConfirmEnableEncryption : SecurityAndPrivacyEvent diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index e627fef40c..d9038133e6 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue @@ -37,9 +38,15 @@ import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility +import io.element.android.libraries.matrix.api.room.join.AllowRule import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility +import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.persistentSetOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -86,7 +93,7 @@ class SecurityAndPrivacyPresenter( } } - var editedRoomAccess by remember(savedSettings.roomAccess) { + val editedRoomAccess = remember(savedSettings.roomAccess) { mutableStateOf(savedSettings.roomAccess) } var editedHistoryVisibility by remember(savedSettings.historyVisibility) { @@ -99,13 +106,26 @@ class SecurityAndPrivacyPresenter( mutableStateOf(savedIsVisibleInRoomDirectory.value) } val editedSettings = SecurityAndPrivacySettings( - roomAccess = editedRoomAccess, + roomAccess = editedRoomAccess.value, isEncrypted = editedIsEncrypted, isVisibleInRoomDirectory = editedVisibleInRoomDirectory, historyVisibility = editedHistoryVisibility, address = savedSettings.address, ) + val selectableJoinedSpaces by produceState(persistentSetOf()) { + val joinedParentSpaces = matrixClient + .spaceService + .joinedParents(room.roomId) + .getOrDefault(emptyList()) + + val nonParentJoinedSpaces = savedSettings.roomAccess + .spaceIds() + .mapNotNull { spaceId -> matrixClient.spaceService.getSpaceRoom(spaceId) } + + value = (joinedParentSpaces + nonParentJoinedSpaces).toImmutableSet() + } + var showEnableEncryptionConfirmation by remember(savedSettings.isEncrypted) { mutableStateOf(false) } val permissions by room.permissionsAsState(SecurityAndPrivacyPermissions.DEFAULT) { perms -> perms.securityAndPrivacyPermissions() @@ -122,7 +142,7 @@ class SecurityAndPrivacyPresenter( ) } is SecurityAndPrivacyEvent.ChangeRoomAccess -> { - editedRoomAccess = event.roomAccess + editedRoomAccess.value = event.roomAccess } is SecurityAndPrivacyEvent.ToggleEncryptionState -> { if (editedIsEncrypted) { @@ -161,6 +181,12 @@ class SecurityAndPrivacyPresenter( SecurityAndPrivacyEvent.DismissExitConfirmation -> { saveAction.value = AsyncAction.Uninitialized } + SecurityAndPrivacyEvent.ManageAuthorizedSpaces -> navigator.openManageAuthorizedSpaces() + SecurityAndPrivacyEvent.SelectSpaceMemberAccess -> handleSpaceMemberAccessSelection( + selectableJoinedSpaces = selectableJoinedSpaces, + savedAccess = savedSettings.roomAccess, + editedAccess = editedRoomAccess, + ) } } @@ -179,13 +205,14 @@ class SecurityAndPrivacyPresenter( saveAction = saveAction.value, permissions = permissions, isSpace = roomInfo.isSpace, + selectableJoinedSpaces = selectableJoinedSpaces, eventSink = ::handleEvent, ) // Revert changes that the user is not allowed to make anymore LaunchedEffect(permissions, state.editedSettings.roomAccess) { if (!state.showRoomAccessSection) { - editedRoomAccess = savedSettings.roomAccess + editedRoomAccess.value = savedSettings.roomAccess } if (!state.showEncryptionSection) { editedIsEncrypted = savedSettings.isEncrypted @@ -202,6 +229,51 @@ class SecurityAndPrivacyPresenter( return state } + private fun handleSpaceMemberAccessSelection( + selectableJoinedSpaces: Set, + savedAccess: SecurityAndPrivacyRoomAccess, + editedAccess: MutableState, + ) { + if(editedAccess.value is SecurityAndPrivacyRoomAccess.SpaceMember) { + return + } + val spaceSelection = getSpaceSelection(selectableJoinedSpaces, savedAccess) + when(spaceSelection){ + is SpaceSelection.None -> Unit + is SpaceSelection.Multiple -> navigator.openManageAuthorizedSpaces() + is SpaceSelection.Single -> { + val newRoomAccess = SecurityAndPrivacyRoomAccess.SpaceMember( + spaceIds = persistentListOf(spaceSelection.spaceId) + ) + editedAccess.value = newRoomAccess + } + } + } + + private fun getSpaceSelection( + selectableJoinedSpaces: Set, + savedAccess: SecurityAndPrivacyRoomAccess, + ): SpaceSelection { + val selectableSpacesCount = (selectableJoinedSpaces.map { it.roomId } + savedAccess.spaceIds()).toSet().size + return when { + selectableSpacesCount == 0 -> SpaceSelection.None + selectableSpacesCount > 1 -> SpaceSelection.Multiple + else -> { + val joinedSpace = selectableJoinedSpaces.firstOrNull() + if (joinedSpace != null) { + SpaceSelection.Single(joinedSpace.roomId, joinedSpace) + } else { + val spaceId = savedAccess.spaceIds().firstOrNull() + if (spaceId == null) { + SpaceSelection.None + } else { + SpaceSelection.Single(spaceId, null) + } + } + } + } + } + private fun CoroutineScope.isRoomVisibleInRoomDirectory(isRoomVisible: MutableState>) = launch { isRoomVisible.runUpdatingState { room.getRoomVisibility().map { it == RoomVisibility.Public } @@ -280,7 +352,12 @@ private fun JoinRule?.map(): SecurityAndPrivacyRoomAccess { return when (this) { JoinRule.Public -> SecurityAndPrivacyRoomAccess.Anyone JoinRule.Knock, is JoinRule.KnockRestricted -> SecurityAndPrivacyRoomAccess.AskToJoin - is JoinRule.Restricted -> SecurityAndPrivacyRoomAccess.SpaceMember + is JoinRule.Restricted -> SecurityAndPrivacyRoomAccess.SpaceMember( + spaceIds = this.rules + .filterIsInstance() + .map { it.roomId } + .toImmutableList() + ) JoinRule.Invite -> SecurityAndPrivacyRoomAccess.InviteOnly // All other cases are not supported so we default to InviteOnly is JoinRule.Custom, @@ -294,8 +371,9 @@ private fun SecurityAndPrivacyRoomAccess.map(): JoinRule? { SecurityAndPrivacyRoomAccess.Anyone -> JoinRule.Public SecurityAndPrivacyRoomAccess.AskToJoin -> JoinRule.Knock SecurityAndPrivacyRoomAccess.InviteOnly -> JoinRule.Private - // SpaceMember can't be selected in the ui - SecurityAndPrivacyRoomAccess.SpaceMember -> null + is SecurityAndPrivacyRoomAccess.SpaceMember -> JoinRule.Restricted( + rules = this.spaceIds.map { AllowRule.RoomMembership(it) }.toImmutableList() + ) } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index e64cf633a8..b71f375fe7 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -11,6 +11,11 @@ package io.element.android.features.securityandprivacy.impl.root import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.ImmutableSet +import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList data class SecurityAndPrivacyState( @@ -24,8 +29,10 @@ data class SecurityAndPrivacyState( val saveAction: AsyncAction, val isSpace: Boolean, private val permissions: SecurityAndPrivacyPermissions, + private val selectableJoinedSpaces: ImmutableSet, val eventSink: (SecurityAndPrivacyEvent) -> Unit ) { + val canBeSaved = savedSettings != editedSettings // Logic is in https://github.com/element-hq/element-meta/issues/3029 @@ -76,18 +83,31 @@ enum class SecurityAndPrivacyHistoryVisibility { } } -enum class SecurityAndPrivacyRoomAccess { - InviteOnly, - AskToJoin, - Anyone, - SpaceMember; +sealed interface SpaceSelection { + data object None : SpaceSelection + data class Single(val spaceId: RoomId, val spaceRoom: SpaceRoom?) : SpaceSelection + data object Multiple : SpaceSelection +} + +sealed interface SecurityAndPrivacyRoomAccess { + data object InviteOnly : SecurityAndPrivacyRoomAccess + data object AskToJoin : SecurityAndPrivacyRoomAccess + data object Anyone : SecurityAndPrivacyRoomAccess + data class SpaceMember(val spaceIds: ImmutableList) : SecurityAndPrivacyRoomAccess fun canConfigureRoomVisibility(): Boolean { return when (this) { - InviteOnly, SpaceMember -> false + InviteOnly, is SpaceMember -> false AskToJoin, Anyone -> true } } + + fun spaceIds(): ImmutableList { + return when (this) { + is SpaceMember -> spaceIds + else -> persistentListOf() + } + } } sealed class SecurityAndPrivacyFailures : Exception() { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index 223d524ca3..2c984fd16a 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -12,6 +12,10 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toImmutableSet open class SecurityAndPrivacyStateProvider : PreviewParameterProvider { override val values: Sequence @@ -61,7 +65,7 @@ private fun commonSecurityAndPrivacyStates(isSpace: Boolean): Sequence = emptySet(), eventSink: (SecurityAndPrivacyEvent) -> Unit = {} ) = SecurityAndPrivacyState( editedSettings = editedSettings, @@ -127,5 +132,6 @@ fun aSecurityAndPrivacyState( isKnockEnabled = isKnockEnabled, permissions = permissions, isSpace = isSpace, + selectableJoinedSpaces = selectableJoinedSpaces.toImmutableSet(), eventSink = eventSink, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index bf6a5ffdf2..dc8c349bbe 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -50,6 +50,7 @@ import io.element.android.libraries.designsystem.text.stringWithLink import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator 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.ListSectionHeader 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.TextButton @@ -95,6 +96,8 @@ fun SecurityAndPrivacyView( saved = state.savedSettings.roomAccess, isKnockEnabled = state.isKnockEnabled, onSelectOption = { state.eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(it)) }, + onManageSpacesClick = { state.eventSink(SecurityAndPrivacyEvent.ManageAuthorizedSpaces) }, + onSpaceMemberAccessClick = { state.eventSink(SecurityAndPrivacyEvent.SelectSpaceMemberAccess) } ) } if (state.showRoomVisibilitySections) { @@ -212,6 +215,8 @@ private fun RoomAccessSection( saved: SecurityAndPrivacyRoomAccess, isKnockEnabled: Boolean, onSelectOption: (SecurityAndPrivacyRoomAccess) -> Unit, + onSpaceMemberAccessClick: () -> Unit, + onManageSpacesClick: () -> Unit, modifier: Modifier = Modifier, ) { SecurityAndPrivacySection( @@ -226,17 +231,15 @@ private fun RoomAccessSection( onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.Anyone) }, ) // Show space member option, but disabled as we don't support this option for now. - if (saved == SecurityAndPrivacyRoomAccess.SpaceMember) { ListItem( headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_title)) }, supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_unavailable_description)) }, - trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.SpaceMember, enabled = false), + trailingContent = ListItemContent.RadioButton(selected = edited is SecurityAndPrivacyRoomAccess.SpaceMember), leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Space())), - enabled = false, + onClick = onSpaceMemberAccessClick, ) - } // Show Ask to join option in two cases: // - the Knock FF is enabled // - AskToJoin is the current saved value @@ -257,6 +260,19 @@ private fun RoomAccessSection( leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Lock())), onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.InviteOnly) }, ) + if (edited is SecurityAndPrivacyRoomAccess.SpaceMember) { + val footerText = stringWithLink( + textRes = R.string.screen_security_and_privacy_room_access_footer, + url = stringResource(R.string.screen_security_and_privacy_room_access_footer_manage_spaces_action), + onLinkClick = { onManageSpacesClick()}, + ) + Text( + text = footerText, + style = ElementTheme.typography.fontBodySmRegular, + color = ElementTheme.colors.textSecondary, + modifier = Modifier.padding(bottom = 12.dp, start = 56.dp, end = 24.dp) + ) + } } } From ad0b1e33f919635d80cb3a1be45c05d2b496a98e Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 30 Dec 2025 15:59:04 +0100 Subject: [PATCH 275/347] quality : move canUnban logic to the permission class --- .../api/RoomMemberModerationPermissions.kt | 3 +++ .../roommembermoderation/impl/RoomMemberModerationPresenter.kt | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt index 223456de69..87414b836e 100644 --- a/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt +++ b/features/roommembermoderation/api/src/main/kotlin/io/element/android/features/roommembermoderation/api/RoomMemberModerationPermissions.kt @@ -13,6 +13,9 @@ data class RoomMemberModerationPermissions( val canKick: Boolean, val canBan: Boolean, ) { + // Unban requires both kick and ban permission instead of a dedicated unban permission + val canUnban = canBan && canKick + companion object { val DEFAULT = RoomMemberModerationPermissions( canKick = false, diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt index 3a5c364b31..2a876fc484 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationPresenter.kt @@ -163,8 +163,7 @@ class RoomMemberModerationPresenter( val membership = member?.membership ?: RoomMembershipState.JOIN when (membership) { RoomMembershipState.BAN -> { - // Unban requires both kick and ban permission instead of a dedicated unban permission - if (permissions.canBan && permissions.canKick) { + if (permissions.canUnban) { add(ModerationActionState(action = ModerationAction.UnbanUser, isEnabled = canModerateThisUser)) } } From d524cd4a747fdf47bc5fb108904bc2022859ec72 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 30 Dec 2025 16:46:32 +0100 Subject: [PATCH 276/347] Make the notification silent when the message is an outgoing message (quick reply). The boolean isUpdated will be passed to setOnlyAlertOnce(), and when the value is true, the notification does not ring/vibrate again. --- .../push/impl/notifications/RoomGroupMessageCreator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt index 8683b58493..150f4a9a2d 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt @@ -75,7 +75,7 @@ class DefaultRoomGroupMessageCreator( hasSmartReplyError = smartReplyErrors.isNotEmpty(), shouldBing = events.any { it.noisy }, customSound = events.last().soundName, - isUpdated = events.last().isUpdated, + isUpdated = events.last().let { it.isUpdated || it.outGoingMessage }, ), threadId = threadId, largeIcon = largeBitmap, From 32d2d312e98495f9333624322f3749c897a656bd Mon Sep 17 00:00:00 2001 From: Florian Date: Tue, 30 Dec 2025 21:24:41 +0100 Subject: [PATCH 277/347] Increase clickable area of playback speed button --- .../impl/timeline/components/event/TimelineItemVoiceView.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index e12887eab1..f231988f90 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -204,8 +204,8 @@ private fun PlaybackSpeedButton( color = ElementTheme.colors.bgCanvasDefault, shape = RoundedCornerShape(12.dp) ) - .padding(horizontal = 8.dp, vertical = 4.dp) - .clickable(onClick = onClick), + .clickable(onClick = onClick) + .padding(horizontal = 8.dp, vertical = 4.dp), contentAlignment = Alignment.Center, ) { Text( From bbe8e112cd48856ce02c014c952f9cf4aad47d37 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:17:40 +0100 Subject: [PATCH 278/347] Extract PlaybackSpeedButton as an Atom. --- .../components/event/TimelineItemVoiceView.kt | 44 +------------ .../atomic/atoms/PlaybackSpeedButton.kt | 65 +++++++++++++++++++ .../impl/gallery/ui/VoiceItemView.kt | 43 +----------- 3 files changed, 67 insertions(+), 85 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index 1010075803..45534e9591 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -9,7 +9,6 @@ package io.element.android.features.messages.impl.timeline.components.event import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -19,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.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -45,6 +43,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContentProvider +import io.element.android.libraries.designsystem.atomic.atoms.PlaybackSpeedButton import io.element.android.libraries.designsystem.components.media.WaveformPlaybackView import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -187,36 +186,6 @@ private fun RetryButton( } } -@Composable -private fun PlaybackSpeedButton( - speed: Float, - onClick: () -> Unit, -) { - val speedText = when (speed) { - 0.5f -> "0.5×" - 1.0f -> "1×" - 1.5f -> "1.5×" - 2.0f -> "2×" - else -> "${speed}×" - } - androidx.compose.foundation.layout.Box( - modifier = Modifier - .background( - color = ElementTheme.colors.bgCanvasDefault, - shape = RoundedCornerShape(12.dp) - ) - .clickable(onClick = onClick) - .padding(horizontal = 8.dp, vertical = 4.dp), - contentAlignment = Alignment.Center, - ) { - Text( - text = speedText, - color = ElementTheme.colors.iconSecondary, - style = ElementTheme.typography.fontBodyXsMedium, - ) - } -} - @Composable private fun ControlIcon( imageVector: ImageVector, @@ -340,14 +309,3 @@ internal fun ProgressButtonPreview() = ElementPreview { ProgressButton(displayImmediately = false) } } - -@PreviewsDayNight -@Composable -internal fun PlaybackSpeedButtonPreview() = ElementPreview { - Row { - PlaybackSpeedButton(speed = 0.5f, onClick = {}) - PlaybackSpeedButton(speed = 1.0f, onClick = {}) - PlaybackSpeedButton(speed = 1.5f, onClick = {}) - PlaybackSpeedButton(speed = 2.0f, onClick = {}) - } -} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt new file mode 100644 index 0000000000..bfc876d13a --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt @@ -0,0 +1,65 @@ +/* + * 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.designsystem.atomic.atoms + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Text + +@Composable +fun PlaybackSpeedButton( + speed: Float, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + val speedText = when (speed) { + 0.5f -> "0.5×" + 1.0f -> "1×" + 1.5f -> "1.5×" + 2.0f -> "2×" + else -> "${speed}×" + } + Box( + modifier = modifier + .background( + color = ElementTheme.colors.bgCanvasDefault, + shape = RoundedCornerShape(12.dp) + ) + .clickable(onClick = onClick) + .padding(horizontal = 8.dp, vertical = 4.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = speedText, + color = ElementTheme.colors.iconSecondary, + style = ElementTheme.typography.fontBodyXsMedium, + ) + } +} + +@PreviewsDayNight +@Composable +internal fun PlaybackSpeedButtonPreview() = ElementPreview { + Row { + PlaybackSpeedButton(speed = 0.5f, onClick = {}) + PlaybackSpeedButton(speed = 1.0f, onClick = {}) + PlaybackSpeedButton(speed = 1.5f, onClick = {}) + PlaybackSpeedButton(speed = 2.0f, onClick = {}) + } +} diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt index 878c8ffd3a..9b2eaa2b32 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt @@ -10,7 +10,6 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -40,6 +39,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.libraries.designsystem.atomic.atoms.PlaybackSpeedButton import io.element.android.libraries.designsystem.components.media.WaveformPlaybackView import io.element.android.libraries.designsystem.modifiers.onKeyboardContextMenuAction import io.element.android.libraries.designsystem.preview.ElementPreview @@ -235,36 +235,6 @@ private fun RetryButton( } } -@Composable -private fun PlaybackSpeedButton( - speed: Float, - onClick: () -> Unit, -) { - val speedText = when (speed) { - 0.5f -> "0.5×" - 1.0f -> "1×" - 1.5f -> "1.5×" - 2.0f -> "2×" - else -> "${speed}×" - } - androidx.compose.foundation.layout.Box( - modifier = Modifier - .background( - color = ElementTheme.colors.bgCanvasDefault, - shape = RoundedCornerShape(12.dp) - ) - .padding(horizontal = 8.dp, vertical = 4.dp) - .clickable(onClick = onClick), - contentAlignment = Alignment.Center, - ) { - Text( - text = speedText, - color = ElementTheme.colors.iconSecondary, - style = ElementTheme.typography.fontBodyXsMedium, - ) - } -} - @Composable private fun ControlIcon( imageVector: ImageVector, @@ -325,14 +295,3 @@ internal fun VoiceItemViewPlayPreview( onLongClick = {}, ) } - -@PreviewsDayNight -@Composable -internal fun PlaybackSpeedButtonPreview() = ElementPreview { - Row { - PlaybackSpeedButton(speed = 0.5f, onClick = {}) - PlaybackSpeedButton(speed = 1.0f, onClick = {}) - PlaybackSpeedButton(speed = 1.5f, onClick = {}) - PlaybackSpeedButton(speed = 2.0f, onClick = {}) - } -} From 8a52d2b8ce9252f909e2f4b16ab3cc24f1696928 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:23:08 +0100 Subject: [PATCH 279/347] Improve preview. --- .../atomic/atoms/PlaybackSpeedButton.kt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt index bfc876d13a..66bdf6505d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.designsystem.atomic.atoms import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding @@ -21,6 +22,7 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.theme.messageFromMeBackground @Composable fun PlaybackSpeedButton( @@ -56,10 +58,17 @@ fun PlaybackSpeedButton( @PreviewsDayNight @Composable internal fun PlaybackSpeedButtonPreview() = ElementPreview { - Row { - PlaybackSpeedButton(speed = 0.5f, onClick = {}) - PlaybackSpeedButton(speed = 1.0f, onClick = {}) - PlaybackSpeedButton(speed = 1.5f, onClick = {}) - PlaybackSpeedButton(speed = 2.0f, onClick = {}) + Row( + modifier = Modifier + .background(ElementTheme.colors.messageFromMeBackground) + .padding(4.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + listOf(0.5f, 1.0f, 1.5f, 2.0f, 3.0f).forEach { speed -> + PlaybackSpeedButton( + speed = speed, + onClick = {}, + ) + } } } From f59e979aab63200caa863b392465a5d9956047a5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:43:25 +0100 Subject: [PATCH 280/347] Create VoicePlayerConfig. --- .../voiceplayer/impl/VoiceMessagePresenter.kt | 14 +++++--------- .../voiceplayer/impl/VoicePlayerConfig.kt | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerConfig.kt diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt index 089e7fa533..95c9554731 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import io.element.android.libraries.architecture.AsyncData @@ -38,9 +39,7 @@ class VoiceMessagePresenter( private val duration: Duration, ) : Presenter { private val play = mutableStateOf>(AsyncData.Uninitialized) - private val playbackSpeed = mutableStateOf(1.0f) - - private val availablePlaybackSpeeds = listOf(0.5f, 1.0f, 1.5f, 2.0f) + private val playbackSpeedIndex = mutableIntStateOf(0) @Composable override fun present(): VoiceMessageState { @@ -116,11 +115,8 @@ class VoiceMessagePresenter( player.seekTo((event.percentage * duration).toLong()) } is VoiceMessageEvents.ChangePlaybackSpeed -> { - val currentIndex = availablePlaybackSpeeds.indexOf(playbackSpeed.value) - val nextIndex = (currentIndex + 1) % availablePlaybackSpeeds.size - val newSpeed = availablePlaybackSpeeds[nextIndex] - playbackSpeed.value = newSpeed - player.setPlaybackSpeed(newSpeed) + playbackSpeedIndex.intValue = (playbackSpeedIndex.intValue + 1) % VoicePlayerConfig.availablePlaybackSpeeds.size + player.setPlaybackSpeed(VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue]) } } } @@ -130,7 +126,7 @@ class VoiceMessagePresenter( progress = progress, time = time, showCursor = showCursor, - playbackSpeed = playbackSpeed.value, + playbackSpeed = VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue], eventSink = ::handleEvent, ) } diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerConfig.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerConfig.kt new file mode 100644 index 0000000000..3ade34d99f --- /dev/null +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerConfig.kt @@ -0,0 +1,14 @@ +/* + * 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.voiceplayer.impl + +object VoicePlayerConfig { + // Available playback speeds for voice messages, the first one is the default speed, and + // the UI will allow to change to the next speed in the list, in loop. + val availablePlaybackSpeeds = listOf(1.0f, 1.5f, 2.0f, 0.5f) +} From 7e4b4e4076cd00bb96d0a231b132e0c8db4bb86e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:46:44 +0100 Subject: [PATCH 281/347] Avoid reusing the initialState to send event. --- .../impl/VoiceMessagePresenterTest.kt | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index fe680422f6..ac35e77ee4 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -212,10 +212,9 @@ class VoiceMessagePresenterTest { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) assertThat(it.progress).isEqualTo(0.1f) assertThat(it.time).isEqualTo("0:01") + it.eventSink(VoiceMessageEvents.Seek(0.5f)) } - initialState.eventSink(VoiceMessageEvents.Seek(0.5f)) - awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) assertThat(it.progress).isEqualTo(0.5f) @@ -232,26 +231,22 @@ class VoiceMessagePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = awaitItem().also { + awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) + it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) } - - initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.5f) + it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) } - - initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(2.0f) + it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) } - - initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(0.5f) + it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) } - - initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) } From 9e25db97f744a5db3fa49a6fcbbefb41b3e6a7fc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:47:45 +0100 Subject: [PATCH 282/347] Use test extension --- .../impl/VoiceMessagePresenterTest.kt | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index ac35e77ee4..87f7ffbc34 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -8,9 +8,6 @@ package io.element.android.libraries.voiceplayer.impl -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow -import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.matrix.api.core.EventId @@ -21,6 +18,7 @@ import io.element.android.libraries.voiceplayer.api.VoiceMessageException import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.test import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test @@ -31,9 +29,7 @@ class VoiceMessagePresenterTest { @Test fun `initial state has proper default values`() = runTest { val presenter = createVoiceMessagePresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().let { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -48,9 +44,7 @@ class VoiceMessagePresenterTest { mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000), duration = 2_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -86,9 +80,7 @@ class VoiceMessagePresenterTest { analyticsService = analyticsService, duration = 2_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -122,9 +114,7 @@ class VoiceMessagePresenterTest { mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000), duration = 2_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -154,9 +144,7 @@ class VoiceMessagePresenterTest { val presenter = createVoiceMessagePresenter( eventId = null, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Disabled) assertThat(it.progress).isEqualTo(0f) @@ -171,9 +159,7 @@ class VoiceMessagePresenterTest { mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000), duration = 10_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -195,9 +181,7 @@ class VoiceMessagePresenterTest { val presenter = createVoiceMessagePresenter( duration = 10_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -228,9 +212,7 @@ class VoiceMessagePresenterTest { val presenter = createVoiceMessagePresenter( duration = 10_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) From 4f44edf6af14cf2577f1864832704905c4b0c875 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:48:46 +0100 Subject: [PATCH 283/347] VoiceMessageEvents -> VoiceMessageEvent --- .../components/event/TimelineItemVoiceView.kt | 8 +++---- .../impl/gallery/ui/VoiceItemView.kt | 8 +++---- ...eMessageEvents.kt => VoiceMessageEvent.kt} | 8 +++---- .../voiceplayer/api/VoiceMessageState.kt | 2 +- .../voiceplayer/impl/VoiceMessagePresenter.kt | 10 ++++---- .../impl/VoiceMessagePresenterTest.kt | 24 +++++++++---------- 6 files changed, 30 insertions(+), 30 deletions(-) rename libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/{VoiceMessageEvents.kt => VoiceMessageEvent.kt} (58%) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index 45534e9591..203fd8f1da 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -53,7 +53,7 @@ import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.utils.time.isTalkbackActive -import io.element.android.libraries.voiceplayer.api.VoiceMessageEvents +import io.element.android.libraries.voiceplayer.api.VoiceMessageEvent import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.libraries.voiceplayer.api.VoiceMessageStateProvider import kotlinx.coroutines.delay @@ -66,7 +66,7 @@ fun TimelineItemVoiceView( modifier: Modifier = Modifier, ) { fun playPause() { - state.eventSink(VoiceMessageEvents.PlayPause) + state.eventSink(VoiceMessageEvent.PlayPause) } val a11y = stringResource(CommonStrings.common_voice_message) @@ -118,7 +118,7 @@ fun TimelineItemVoiceView( ) { PlaybackSpeedButton( speed = state.playbackSpeed, - onClick = { state.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) }, + onClick = { state.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) }, ) Text( text = state.time, @@ -137,7 +137,7 @@ fun TimelineItemVoiceView( .weight(1f) .height(34.dp), seekEnabled = !isTalkbackActive(), - onSeek = { state.eventSink(VoiceMessageEvents.Seek(it)) }, + onSeek = { state.eventSink(VoiceMessageEvent.Seek(it)) }, ) } } diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt index 9b2eaa2b32..f608236e49 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt @@ -52,7 +52,7 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.mediaviewer.impl.model.MediaItem import io.element.android.libraries.mediaviewer.impl.model.aMediaItemVoice import io.element.android.libraries.ui.strings.CommonStrings -import io.element.android.libraries.voiceplayer.api.VoiceMessageEvents +import io.element.android.libraries.voiceplayer.api.VoiceMessageEvent import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.libraries.voiceplayer.api.VoiceMessageStateProvider import io.element.android.libraries.voiceplayer.api.aVoiceMessageState @@ -94,7 +94,7 @@ private fun VoiceInfoRow( onLongClick: () -> Unit, ) { fun playPause() { - state.eventSink(VoiceMessageEvents.PlayPause) + state.eventSink(VoiceMessageEvent.PlayPause) } Row( @@ -128,7 +128,7 @@ private fun VoiceInfoRow( ) { PlaybackSpeedButton( speed = state.playbackSpeed, - onClick = { state.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) }, + onClick = { state.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) }, ) Text( text = if (state.progress > 0f) state.time else voice.mediaInfo.duration ?: state.time, @@ -147,7 +147,7 @@ private fun VoiceInfoRow( playbackProgress = state.progress, waveform = voice.mediaInfo.waveform.orEmpty().toImmutableList(), onSeek = { - state.eventSink(VoiceMessageEvents.Seek(it)) + state.eventSink(VoiceMessageEvent.Seek(it)) }, seekEnabled = true, ) diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvent.kt similarity index 58% rename from libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt rename to libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvent.kt index 01910ddcd6..bec03f3943 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvent.kt @@ -8,8 +8,8 @@ package io.element.android.libraries.voiceplayer.api -sealed interface VoiceMessageEvents { - data object PlayPause : VoiceMessageEvents - data class Seek(val percentage: Float) : VoiceMessageEvents - data object ChangePlaybackSpeed : VoiceMessageEvents +sealed interface VoiceMessageEvent { + data object PlayPause : VoiceMessageEvent + data class Seek(val percentage: Float) : VoiceMessageEvent + data object ChangePlaybackSpeed : VoiceMessageEvent } diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt index a66209c5db..36fa13a268 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt @@ -14,7 +14,7 @@ data class VoiceMessageState( val time: String, val showCursor: Boolean, val playbackSpeed: Float, - val eventSink: (event: VoiceMessageEvents) -> Unit, + val eventSink: (event: VoiceMessageEvent) -> Unit, ) { enum class Button { Play, diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt index 95c9554731..c58838963a 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt @@ -22,7 +22,7 @@ import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.ui.utils.time.formatShort -import io.element.android.libraries.voiceplayer.api.VoiceMessageEvents +import io.element.android.libraries.voiceplayer.api.VoiceMessageEvent import io.element.android.libraries.voiceplayer.api.VoiceMessageException import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.services.analytics.api.AnalyticsService @@ -87,9 +87,9 @@ class VoiceMessagePresenter( } } - fun handleEvent(event: VoiceMessageEvents) { + fun handleEvent(event: VoiceMessageEvent) { when (event) { - is VoiceMessageEvents.PlayPause -> { + is VoiceMessageEvent.PlayPause -> { if (playerState.isPlaying) { player.pause() } else if (playerState.isReady) { @@ -111,10 +111,10 @@ class VoiceMessagePresenter( } } } - is VoiceMessageEvents.Seek -> { + is VoiceMessageEvent.Seek -> { player.seekTo((event.percentage * duration).toLong()) } - is VoiceMessageEvents.ChangePlaybackSpeed -> { + is VoiceMessageEvent.ChangePlaybackSpeed -> { playbackSpeedIndex.intValue = (playbackSpeedIndex.intValue + 1) % VoicePlayerConfig.availablePlaybackSpeeds.size player.setPlaybackSpeed(VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue]) } diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index 87f7ffbc34..3d9c452c2a 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -13,7 +13,7 @@ import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer -import io.element.android.libraries.voiceplayer.api.VoiceMessageEvents +import io.element.android.libraries.voiceplayer.api.VoiceMessageEvent import io.element.android.libraries.voiceplayer.api.VoiceMessageException import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.services.analytics.api.AnalyticsService @@ -51,7 +51,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:02") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) @@ -87,7 +87,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:02") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) @@ -121,7 +121,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:02") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) skipItems(2) // skip downloading states val playingState = awaitItem().also { @@ -130,7 +130,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:01") } - playingState.eventSink(VoiceMessageEvents.PlayPause) + playingState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0.5f) @@ -166,7 +166,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:10") } - initialState.eventSink(VoiceMessageEvents.Seek(0.5f)) + initialState.eventSink(VoiceMessageEvent.Seek(0.5f)) awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) @@ -188,7 +188,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:10") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) skipItems(2) // skip downloading states @@ -196,7 +196,7 @@ class VoiceMessagePresenterTest { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) assertThat(it.progress).isEqualTo(0.1f) assertThat(it.time).isEqualTo("0:01") - it.eventSink(VoiceMessageEvents.Seek(0.5f)) + it.eventSink(VoiceMessageEvent.Seek(0.5f)) } awaitItem().also { @@ -215,19 +215,19 @@ class VoiceMessagePresenterTest { presenter.test { awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) - it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) } awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.5f) - it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) } awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(2.0f) - it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) } awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(0.5f) - it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) } awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) From 4c0b02ce23a389e319ac384b5967b1388022650b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:51:38 +0100 Subject: [PATCH 284/347] Rename Button to ButtonType to avoid confusion. --- .../components/event/TimelineItemVoiceView.kt | 28 +++++++-------- .../impl/gallery/ui/VoiceItemView.kt | 12 +++---- .../voiceplayer/api/VoiceMessageState.kt | 4 +-- .../api/VoiceMessageStateProvider.kt | 14 ++++---- .../voiceplayer/impl/VoiceMessagePresenter.kt | 14 ++++---- .../impl/VoiceMessagePresenterTest.kt | 34 +++++++++---------- 6 files changed, 53 insertions(+), 53 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index 203fd8f1da..5dbd0c478f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -71,21 +71,21 @@ fun TimelineItemVoiceView( val a11y = stringResource(CommonStrings.common_voice_message) val a11yActionLabel = stringResource( - when (state.button) { - VoiceMessageState.Button.Play -> CommonStrings.a11y_play - VoiceMessageState.Button.Pause -> CommonStrings.a11y_pause - VoiceMessageState.Button.Downloading -> CommonStrings.common_downloading - VoiceMessageState.Button.Retry -> CommonStrings.action_retry - VoiceMessageState.Button.Disabled -> CommonStrings.error_unknown + when (state.buttonType) { + VoiceMessageState.ButtonType.Play -> CommonStrings.a11y_play + VoiceMessageState.ButtonType.Pause -> CommonStrings.a11y_pause + VoiceMessageState.ButtonType.Downloading -> CommonStrings.common_downloading + VoiceMessageState.ButtonType.Retry -> CommonStrings.action_retry + VoiceMessageState.ButtonType.Disabled -> CommonStrings.error_unknown } ) Row( modifier = modifier .clearAndSetSemantics { contentDescription = a11y - if (state.button == VoiceMessageState.Button.Disabled) { + if (state.buttonType == VoiceMessageState.ButtonType.Disabled) { disabled() - } else if (state.button in listOf(VoiceMessageState.Button.Play, VoiceMessageState.Button.Pause)) { + } else if (state.buttonType in listOf(VoiceMessageState.ButtonType.Play, VoiceMessageState.ButtonType.Pause)) { onClick(label = a11yActionLabel) { playPause() true @@ -103,12 +103,12 @@ fun TimelineItemVoiceView( verticalAlignment = Alignment.CenterVertically, ) { if (!isTalkbackActive()) { - when (state.button) { - VoiceMessageState.Button.Play -> PlayButton(onClick = ::playPause) - VoiceMessageState.Button.Pause -> PauseButton(onClick = ::playPause) - VoiceMessageState.Button.Downloading -> ProgressButton() - VoiceMessageState.Button.Retry -> RetryButton(onClick = ::playPause) - VoiceMessageState.Button.Disabled -> PlayButton(onClick = {}, enabled = false) + when (state.buttonType) { + VoiceMessageState.ButtonType.Play -> PlayButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Pause -> PauseButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Downloading -> ProgressButton() + VoiceMessageState.ButtonType.Retry -> RetryButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Disabled -> PlayButton(onClick = {}, enabled = false) } } Spacer(Modifier.width(8.dp)) diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt index f608236e49..dbbeb28b80 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt @@ -114,12 +114,12 @@ private fun VoiceInfoRow( .padding(start = 12.dp, end = 36.dp, top = 8.dp, bottom = 8.dp), verticalAlignment = Alignment.CenterVertically, ) { - when (state.button) { - VoiceMessageState.Button.Play -> PlayButton(onClick = ::playPause) - VoiceMessageState.Button.Pause -> PauseButton(onClick = ::playPause) - VoiceMessageState.Button.Downloading -> ProgressButton() - VoiceMessageState.Button.Retry -> RetryButton(onClick = ::playPause) - VoiceMessageState.Button.Disabled -> PlayButton(onClick = {}, enabled = false) + when (state.buttonType) { + VoiceMessageState.ButtonType.Play -> PlayButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Pause -> PauseButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Downloading -> ProgressButton() + VoiceMessageState.ButtonType.Retry -> RetryButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Disabled -> PlayButton(onClick = {}, enabled = false) } Spacer(Modifier.width(8.dp)) Column( diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt index 36fa13a268..2faf35f91f 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt @@ -9,14 +9,14 @@ package io.element.android.libraries.voiceplayer.api data class VoiceMessageState( - val button: Button, + val buttonType: ButtonType, val progress: Float, val time: String, val showCursor: Boolean, val playbackSpeed: Float, val eventSink: (event: VoiceMessageEvent) -> Unit, ) { - enum class Button { + enum class ButtonType { Play, Pause, Downloading, diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt index d8ccb85832..dd8d222e69 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt @@ -14,29 +14,29 @@ open class VoiceMessageStateProvider : PreviewParameterProvider get() = sequenceOf( aVoiceMessageState( - VoiceMessageState.Button.Downloading, + VoiceMessageState.ButtonType.Downloading, progress = 0f, time = "0:00", ), aVoiceMessageState( - VoiceMessageState.Button.Retry, + VoiceMessageState.ButtonType.Retry, progress = 0.5f, time = "0:01", ), aVoiceMessageState( - VoiceMessageState.Button.Play, + VoiceMessageState.ButtonType.Play, progress = 1f, time = "1:00", showCursor = true, ), aVoiceMessageState( - VoiceMessageState.Button.Pause, + VoiceMessageState.ButtonType.Pause, progress = 0.2f, time = "10:00", showCursor = true, ), aVoiceMessageState( - VoiceMessageState.Button.Disabled, + VoiceMessageState.ButtonType.Disabled, progress = 0.2f, time = "30:00", ), @@ -44,13 +44,13 @@ open class VoiceMessageStateProvider : PreviewParameterProvider VoiceMessageState.Button.Disabled - playerState.isPlaying -> VoiceMessageState.Button.Pause - play.value is AsyncData.Loading -> VoiceMessageState.Button.Downloading - play.value is AsyncData.Failure -> VoiceMessageState.Button.Retry - else -> VoiceMessageState.Button.Play + eventId == null -> VoiceMessageState.ButtonType.Disabled + playerState.isPlaying -> VoiceMessageState.ButtonType.Pause + play.value is AsyncData.Loading -> VoiceMessageState.ButtonType.Downloading + play.value is AsyncData.Failure -> VoiceMessageState.ButtonType.Retry + else -> VoiceMessageState.ButtonType.Play } } } @@ -122,7 +122,7 @@ class VoiceMessagePresenter( } return VoiceMessageState( - button = button, + buttonType = buttonType, progress = progress, time = time, showCursor = showCursor, diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index 3d9c452c2a..e6ae760b53 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -31,7 +31,7 @@ class VoiceMessagePresenterTest { val presenter = createVoiceMessagePresenter() presenter.test { awaitItem().let { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("1:01") } @@ -46,7 +46,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } @@ -54,17 +54,17 @@ class VoiceMessagePresenterTest { initialState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Downloading) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Downloading) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:00") } awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Pause) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:01") } @@ -82,7 +82,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } @@ -90,12 +90,12 @@ class VoiceMessagePresenterTest { initialState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Downloading) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Retry) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Retry) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } @@ -116,7 +116,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } @@ -125,14 +125,14 @@ class VoiceMessagePresenterTest { skipItems(2) // skip downloading states val playingState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Pause) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:01") } playingState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:01") } @@ -146,7 +146,7 @@ class VoiceMessagePresenterTest { ) presenter.test { awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Disabled) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Disabled) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("1:01") } @@ -161,7 +161,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:10") } @@ -169,7 +169,7 @@ class VoiceMessagePresenterTest { initialState.eventSink(VoiceMessageEvent.Seek(0.5f)) awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:05") } @@ -183,7 +183,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:10") } @@ -193,14 +193,14 @@ class VoiceMessagePresenterTest { skipItems(2) // skip downloading states awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Pause) assertThat(it.progress).isEqualTo(0.1f) assertThat(it.time).isEqualTo("0:01") it.eventSink(VoiceMessageEvent.Seek(0.5f)) } awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Pause) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:05") } From c9b3a19a90d96125e9fb4d1154c5c1455192e22f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 10:02:58 +0100 Subject: [PATCH 285/347] Improve click effect. --- .../libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt index 66bdf6505d..e00d0c92d7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt @@ -17,6 +17,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.preview.ElementPreview @@ -39,9 +40,9 @@ fun PlaybackSpeedButton( } Box( modifier = modifier + .clip(RoundedCornerShape(12.dp)) .background( color = ElementTheme.colors.bgCanvasDefault, - shape = RoundedCornerShape(12.dp) ) .clickable(onClick = onClick) .padding(horizontal = 8.dp, vertical = 4.dp), From 325d7d5fdea14c3bc0897a68723f9db9e2f21a47 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 11:24:49 +0100 Subject: [PATCH 286/347] Remove useless curly braces --- .../libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt index e00d0c92d7..dfd98dd5da 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt @@ -36,7 +36,7 @@ fun PlaybackSpeedButton( 1.0f -> "1×" 1.5f -> "1.5×" 2.0f -> "2×" - else -> "${speed}×" + else -> "$speed×" } Box( modifier = modifier From 152b351bf3bb5d8c4864a08db7484955c56163f0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 11:28:26 +0100 Subject: [PATCH 287/347] Store voice player playback index in a datastore. --- libraries/voiceplayer/impl/build.gradle.kts | 2 + .../DefaultVoiceMessagePresenterFactory.kt | 2 + .../voiceplayer/impl/VoiceMessagePresenter.kt | 21 +++++++--- .../voiceplayer/impl/VoicePlayerStore.kt | 41 +++++++++++++++++++ .../impl/InMemoryVoicePlayerStore.kt | 26 ++++++++++++ .../impl/VoiceMessagePresenterTest.kt | 2 + 6 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerStore.kt create mode 100644 libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/InMemoryVoicePlayerStore.kt diff --git a/libraries/voiceplayer/impl/build.gradle.kts b/libraries/voiceplayer/impl/build.gradle.kts index 679e8206d9..4aa00e188b 100644 --- a/libraries/voiceplayer/impl/build.gradle.kts +++ b/libraries/voiceplayer/impl/build.gradle.kts @@ -26,10 +26,12 @@ dependencies { implementation(projects.libraries.di) implementation(projects.libraries.matrix.api) implementation(projects.libraries.mediaplayer.api) + implementation(projects.libraries.preferences.api) implementation(projects.libraries.uiUtils) implementation(projects.services.analytics.api) implementation(libs.androidx.annotationjvm) + implementation(libs.androidx.datastore.preferences) implementation(libs.coroutines.core) testCommonDependencies(libs) diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/DefaultVoiceMessagePresenterFactory.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/DefaultVoiceMessagePresenterFactory.kt index b2518eaca0..0a262b8145 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/DefaultVoiceMessagePresenterFactory.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/DefaultVoiceMessagePresenterFactory.kt @@ -26,6 +26,7 @@ class DefaultVoiceMessagePresenterFactory( @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, private val voiceMessagePlayerFactory: VoiceMessagePlayer.Factory, + private val voicePlayerStore: VoicePlayerStore, ) : VoiceMessagePresenterFactory { override fun createVoiceMessagePresenter( eventId: EventId?, @@ -44,6 +45,7 @@ class DefaultVoiceMessagePresenterFactory( return VoiceMessagePresenter( analyticsService = analyticsService, sessionCoroutineScope = sessionCoroutineScope, + voicePlayerStore = voicePlayerStore, player = player, eventId = eventId, duration = duration, diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt index 37952d34b5..be93ab6526 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt @@ -9,12 +9,13 @@ package io.element.android.libraries.voiceplayer.impl 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.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runUpdatingState @@ -34,15 +35,16 @@ import kotlin.time.Duration.Companion.milliseconds class VoiceMessagePresenter( private val analyticsService: AnalyticsService, private val sessionCoroutineScope: CoroutineScope, + private val voicePlayerStore: VoicePlayerStore, private val player: VoiceMessagePlayer, private val eventId: EventId?, private val duration: Duration, ) : Presenter { private val play = mutableStateOf>(AsyncData.Uninitialized) - private val playbackSpeedIndex = mutableIntStateOf(0) @Composable override fun present(): VoiceMessageState { + val localCoroutineScope = rememberCoroutineScope() val playerState by player.state.collectAsState( VoiceMessagePlayer.State( isReady = false, @@ -53,6 +55,12 @@ class VoiceMessagePresenter( ) ) + val playbackSpeedIndex by voicePlayerStore.playBackSpeedIndex().collectAsState(0) + + LaunchedEffect(playbackSpeedIndex) { + player.setPlaybackSpeed(VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex]) + } + val buttonType by remember { derivedStateOf { when { @@ -114,9 +122,10 @@ class VoiceMessagePresenter( is VoiceMessageEvent.Seek -> { player.seekTo((event.percentage * duration).toLong()) } - is VoiceMessageEvent.ChangePlaybackSpeed -> { - playbackSpeedIndex.intValue = (playbackSpeedIndex.intValue + 1) % VoicePlayerConfig.availablePlaybackSpeeds.size - player.setPlaybackSpeed(VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue]) + is VoiceMessageEvent.ChangePlaybackSpeed -> localCoroutineScope.launch { + voicePlayerStore.setPlayBackSpeedIndex( + (playbackSpeedIndex + 1) % VoicePlayerConfig.availablePlaybackSpeeds.size + ) } } } @@ -126,7 +135,7 @@ class VoiceMessagePresenter( progress = progress, time = time, showCursor = showCursor, - playbackSpeed = VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue], + playbackSpeed = VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex], eventSink = ::handleEvent, ) } diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerStore.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerStore.kt new file mode 100644 index 0000000000..3c400b3e92 --- /dev/null +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerStore.kt @@ -0,0 +1,41 @@ +/* + * 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.voiceplayer.impl + +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.intPreferencesKey +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFactory +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +interface VoicePlayerStore { + suspend fun setPlayBackSpeedIndex(index: Int) + fun playBackSpeedIndex(): Flow +} + +@ContributesBinding(AppScope::class) +class PreferencesVoicePlayerStore( + preferenceDataStoreFactory: PreferenceDataStoreFactory, +) : VoicePlayerStore { + private val store = preferenceDataStoreFactory.create("elementx_voice_player") + private val playbackSpeedIndex = intPreferencesKey("playback_speed_index") + + override fun playBackSpeedIndex(): Flow { + return store.data.map { prefs -> + prefs[playbackSpeedIndex] ?: 0 + } + } + + override suspend fun setPlayBackSpeedIndex(index: Int) { + store.edit { prefs -> + prefs[playbackSpeedIndex] = index + } + } +} diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/InMemoryVoicePlayerStore.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/InMemoryVoicePlayerStore.kt new file mode 100644 index 0000000000..e746b5acf5 --- /dev/null +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/InMemoryVoicePlayerStore.kt @@ -0,0 +1,26 @@ +/* + * 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.voiceplayer.impl + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow + +internal class InMemoryVoicePlayerStore( + defaultPlaybackSpeedIndex: Int = 0, +) : VoicePlayerStore { + private val playBackSpeedIndex = MutableStateFlow(defaultPlaybackSpeedIndex) + + override fun playBackSpeedIndex(): Flow { + return playBackSpeedIndex.asStateFlow() + } + + override suspend fun setPlayBackSpeedIndex(index: Int) { + playBackSpeedIndex.emit(index) + } +} diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index e6ae760b53..8054677937 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -240,6 +240,7 @@ fun TestScope.createVoiceMessagePresenter( mediaPlayer: FakeMediaPlayer = FakeMediaPlayer(), voiceMessageMediaRepo: VoiceMessageMediaRepo = FakeVoiceMessageMediaRepo(), analyticsService: AnalyticsService = FakeAnalyticsService(), + voicePlayerStore: VoicePlayerStore = InMemoryVoicePlayerStore(), eventId: EventId? = EventId("\$anEventId"), filename: String = "filename doesn't really matter for a voice message", duration: Duration = 61_000.milliseconds, @@ -257,6 +258,7 @@ fun TestScope.createVoiceMessagePresenter( mimeType = mimeType, filename = filename ), + voicePlayerStore = voicePlayerStore, eventId = eventId, duration = duration, ) From c154d55047abf1e228abb27f607c7f626df96f65 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 31 Dec 2025 10:43:57 +0000 Subject: [PATCH 288/347] Update screenshots --- ...components.event_TimelineItemVoiceViewUnified_Day_0_en.png | 4 ++-- ...mponents.event_TimelineItemVoiceViewUnified_Night_0_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_0_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_10_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_11_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_12_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_13_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_14_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_1_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_2_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_3_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_4_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_5_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_6_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_7_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_8_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_9_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_0_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_10_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_11_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_12_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_13_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_14_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_1_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_2_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_3_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_4_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_5_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_6_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_7_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_8_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_9_en.png | 4 ++-- .../features.messages.impl.timeline_TimelineView_Day_8_en.png | 4 ++-- ...eatures.messages.impl.timeline_TimelineView_Night_8_en.png | 4 ++-- ...designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png | 3 +++ ...signsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png | 3 +++ ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png | 4 ++-- ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png | 4 ++-- ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png | 4 ++-- ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png | 4 ++-- ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png | 4 ++-- ...s.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png | 4 ++-- ...s.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png | 4 ++-- ...s.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png | 4 ++-- ...s.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png | 4 ++-- ...s.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png | 4 ++-- 56 files changed, 114 insertions(+), 108 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Day_0_en.png index 71aafa8951..e50176c971 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45f61d7b50a14b483d9459846f002b9ac94c6ccb632c636f891616629ad47248 -size 39899 +oid sha256:21cfef3eb8bb8a0493b1bf22a2b01d7c94a152c7e7e0d1bb558fae1e64e177c5 +size 43941 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Night_0_en.png index 5067f5b5d3..f875628537 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80ce1738cf56d99afbe781c82e32cdef03564a31fec0450aa66a84c56085ce81 -size 39956 +oid sha256:3caf6bcec609664f2f2e39b1f51b8b08af00d59c7d1f66836e9e0e1751853c2f +size 45675 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_0_en.png index 0140615ab0..fab08239b1 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a7a5c1978ed1ea48e849e0de8023ac588a29e84152946a9eb0ee6c0680d7a1c -size 4927 +oid sha256:6aa352e97a7f4ffba249fb4da75e508c264aa75335dc27b473b7cc54d56474ab +size 5212 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_10_en.png index 343e3ddd19..393231091f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d1cb7c04c321146e7425bc095b9344edf913eeec3588600e500466e326a8107 -size 8165 +oid sha256:0e2aaee1ad3bc909945881c352ad92669f2385d311be551ab0b961011d86e994 +size 8380 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_11_en.png index a2f4e5c84a..eae2d640d4 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68c8f0a94de98773a3dae69fd44fa87fd3eeee5c6bc44afa710a2ba32eacde7e -size 8620 +oid sha256:2cb0fc5226b16779d984986d8944bead8b4541a1922dcd81892ccc731d0c7b49 +size 8845 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_12_en.png index 320efac4d0..92eaf6b1df 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b98fde923272c2959c407fb3f62cb150f1b0fac3f54d29d94f30646096d889d2 -size 8261 +oid sha256:4528b5800ad94ad7d6880adbb99430b11e3724fbcf3a1732529a8673d9ad63bf +size 8465 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_13_en.png index bafbe2ad5f..47f3bd2de0 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:473877bac2a76f565fed0056ee27b8fa91380b5661fd772d17e110caed0fecff -size 8425 +oid sha256:d1e6ae40a1f540c16c5482040c36dc4fe5f03b5b8271a3755129d7cd4a5825ac +size 8779 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_14_en.png index c1d138f7ad..aa05215cf4 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f6e969ae817abeaa153edbc06cbe873439cd3e65be31184f22db1d8becc7953a -size 8487 +oid sha256:706d26007463123c7afbb7b151f07deca03bb1924a27eea4544aac0b932b922c +size 8821 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_1_en.png index 4b84f30648..3eac64c395 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd514ccd8d00f7f1ea2dc0bce9b786be8fe99c98b44a1b99add18e132d0dc1c1 -size 5171 +oid sha256:33eeb6ecf24ce156fa12dc204f7443bf65682fd1ff8471460b851ae62e6e8a8e +size 5455 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_2_en.png index 07cf2c5161..6ac15f19b5 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e69b5e773119af8ab4749064e68f6584aac0aa41c11a054db9e9c14e7e9aab0 -size 4908 +oid sha256:cbbe58a0d2c4052af93d199f5501176c79d42aa17765ac623894a9c59beda46a +size 5194 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_3_en.png index 023fe9f470..983aee397a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07745c25bce426e0736b7546836e67cb5cb6d8da79b4f26448b4fef0486a13c7 -size 5108 +oid sha256:d099ae7db3d850ff78122b5bcc2a7bbe50c7197a30e5aeadfba1174933f85dc2 +size 5408 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_4_en.png index b49506008e..71cfe52e3d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:df2ac9c5cbee9a350f54ca6892f42c6685d91d9d4fbe46943143b99c915e8ae1 -size 5223 +oid sha256:2d09efdfad91b328c5d480a6e8e9652dea8ccd6f8af617734782ea61a07bb2ba +size 5496 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_5_en.png index 99bf3c83bc..d94f65f3e7 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5ebd66819a916fa8eeac654281b432b46de3218243d9831666ff962d412e04d -size 5486 +oid sha256:4baec63d3fa378db139ac563a10e414a463500fa3b6240543505a59b598b70ab +size 5742 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_6_en.png index 771495367c..dc0775522a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:93a441c65d9ae6cfba78c4a89a72c037bfe1759325a7bbc0bee05dfbc40e96c7 -size 5732 +oid sha256:35a46a9254a012efdea69e0336e6b9d536ea88265fbc933c23bcbca951f55be9 +size 6006 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_7_en.png index b379bf3ca9..96737074af 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a82b644e43af13b60c98ccd565873cfbe1c46e3391426bafcd5d71881fabe34c -size 5434 +oid sha256:da9749249afc0c35a171b1a41f1a6189f7e9f7906079be2fd3634f0da1867181 +size 5708 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_8_en.png index 9d0f1121f8..cc48f3e890 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:257b45fa5de31badce26360dd3c48b502b5ce928bc4d13434f9b42703f29dbb1 -size 5640 +oid sha256:bbb6613af390663a0cbc3a8342cc44baf1b07e0388bafc20281fdeeca9a644b3 +size 5953 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en.png index fc9b835afa..ccb999411a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11adeb3f01fa93c159d692cc2323761873bfba37ad6a3a014e2fdbe80cd108b1 -size 5779 +oid sha256:51fca90e22f3dcb48a3d7a958facb523bb20812f009bc384f1ccb70433aec035 +size 6083 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_0_en.png index 90e1e354da..7cc0515466 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b13c460c659bc743e7aec561ba090ee6174b1acb49821417d13375feee46c6f7 -size 4910 +oid sha256:b282fcfd5e7d4172b0880f2858cabeb6088cd132843ee735230a2739563910fa +size 5304 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_10_en.png index 7f46d49328..5e578bb7e3 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bebeecb0d945b5b66535c6b1ef63c46a45232f304deb5e48e7fb4e0f92045716 -size 7786 +oid sha256:b3e2391ad08c944c655c9a93b9aabb45bbd4b7c199f97eeb39daf87dd6bf1170 +size 8163 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_11_en.png index bb12277d62..62b6d1be67 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b13a02e83748f671aa4aec7eb8052bd3637eeb8c898ded100e29aa219ffc1fbb -size 8337 +oid sha256:e4b9d60e3074cfbc779f9d789cbb33feccbafe6ca2fa55dbd81d2436b60eed9e +size 8753 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_12_en.png index b2ed5f6991..072d54a372 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ef577bfe5233d1194c7bfbaedb38b3690964fe8d3325a9f1c71c3e83fc81d8f -size 8149 +oid sha256:0d30758cd59e52f0b9e5c0d2e23cce3b489db2fc784bbe62df4bd91f38de910f +size 8416 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_13_en.png index f1740ae350..d15fc5042d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4788f5817016607483304bcc4557921da51e801d5378d6c410e8c2a5a700b713 -size 8087 +oid sha256:8de312bc408bb1717042d0902469493d262f3df6e6a025b15b28a1129d801197 +size 8511 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_14_en.png index 92476e7b4b..4d73a4910b 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0464770461d9a59015fa3bd2149bdd17c00600ae256fe4d6b2eaec12a029d04d -size 8121 +oid sha256:2c3edf08e3a769fa3603a31d8c21cb2f8a105087bca91967629dbe73f966a904 +size 8522 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_1_en.png index c9da9a4b6f..ac64fad4ae 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b79152dddd997e11c52b910c19c02d21cf504d2a8ae228e11c9546f2496596da -size 5109 +oid sha256:a442a45bd1b80846060575e10377df39401e7496c306f1b44d6de955cf60b1e2 +size 5543 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_2_en.png index 89e7d512c1..158fb99afc 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ebee4fdf176801a756018e9c4ea80a7e506e9a58dc789f1fb0b9df8306abacf0 -size 4918 +oid sha256:4dfb8f775a2fbac7f7d7478107e25457b76cd1b9131da8fff50971d06c0a8ab2 +size 5295 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_3_en.png index 3f8edf9b44..adbd49e48c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a4c30619c89ec5af57edf09b48429171eaeee88c04334b336e45b8478c1ebc0 -size 5106 +oid sha256:fc51049f759f3248a4c376e608c3108e1fff496237de6b3061b2f4f1ff904698 +size 5525 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_4_en.png index ba74381c3c..fa51877d06 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e1098a584fec0ec74838c2cebf0db3f1c6d75eea8575e2d0e946657cd065395 -size 5184 +oid sha256:3cdadd897dfcf88848e3c8294afa7c5d34d0af8e5cfc6684a1239d4a53171b0a +size 5579 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_5_en.png index a4654a5547..2c202c1f99 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0d3ffddd38f5318e64b9adceecc5f09cf2f6a718327463ecde5b3495ff9bdb0 -size 5455 +oid sha256:a5a6f5c94a4308e4fe3e66c6620b582726aeea0eec3ca7e84216f41fde9d42ac +size 5803 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_6_en.png index 7c2d0128ff..0d667ac9bb 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d530adf3152141fafb258bad3cc45349fc2726bd1c5a51440d1608a654dd031 -size 5707 +oid sha256:333cafb2282afb0fdb076f5f8528df9bed46987a6f53993b6689425b60da767b +size 6100 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_7_en.png index 11bd395271..a060d89e00 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d397a13c3fba112e8bd2f3045c4e9fc9de10869204451b33cc7a88b2938b9797 -size 5451 +oid sha256:b857f3c9a84373b292faae437ede2de4244fd7f5baa3bf7eb14f8978fd575c99 +size 5809 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_8_en.png index dfedab0787..b5db68c328 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c87ecb2cbb0bee46b088f1e253e1c969e20cc407bb64827dd98294871f22b92 -size 5635 +oid sha256:6abc6eb10edfbbf0145e291689679eee6c25521564fc4458f402ec98d34af5f7 +size 6024 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en.png index 7aa2ec7227..98ac3b747b 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:614d88406ef318b65475837e79b10759f3c9ee038dcfea963677d371874a7a1b -size 5774 +oid sha256:98a5873e4696e628f2c79f0c5dbb95d602a6e2facc3a60dee4c24ba4dc4a09c3 +size 6153 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_8_en.png index 0264fd4296..29819ddfa2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a908b65efa9cfa89d121f3e23a0bfad0926d269d9600fe6e58455e2e70a4fac -size 54687 +oid sha256:24dd95b2320c849a5de7d6b23c4c5c429400dbbeb4bd9619eda115e940d8f547 +size 55922 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_8_en.png index 8708028b79..d60e21920c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c40bba2d435777c6d990b8cb699c19a2384b64c4c27e65d8baee6ef3dfd8b86f -size 52591 +oid sha256:25d2342f4bbd9adca42ae92f54dc3281e4a9c37f5fb5650c52cdd6a488855ad0 +size 53943 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png new file mode 100644 index 0000000000..675f286746 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bfa11446dc195a1912857a553f57df926660d32562e9d4af133e7f039cf37d8 +size 8304 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png new file mode 100644 index 0000000000..7ae98066c6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c8ab3d7799fedc07b9fc39e22af4d61c237426b999e39663444944865954b67 +size 8176 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png index 8ade8b3f8f..29759f506c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0d4913ae2a0dc42a4c116f731a3b4d822801271423e1248728f86b9cb17eed1 -size 8620 +oid sha256:511c0cb8323fb971989138aa25d0323102de60f43b8635953a12a6301091aac3 +size 9332 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png index 9d5231f601..5fe27b2fe6 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0d9b0271872bb405ec0d6f8afa475404c9612b8d42dc5bb835ce8dcc8b1fa0a -size 9223 +oid sha256:9def0ceeac3ad39fb5c03d7d525c012e3c592ec988a9baa8fd5e424f49438119 +size 9874 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png index 643331cb01..33292b60c5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f969aeedd303cf4c6b90e3ab3b2144c7eddb7860e69af2c1ff395ff2202793f -size 8892 +oid sha256:1ae1bd729e7b91acdc57636a0fc8bd105403af99f4c37c1954917646dc13f54d +size 9644 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png index 2c9c62876a..8450cb430c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:509f29fbd03496acb78f18d4fb51c207981d145a6c675e02a9d0b7b96811c2f8 -size 9014 +oid sha256:266acb20ed53b40bd5fce5698e29e357442823a528db52781641d1e4ee9d7079 +size 9763 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png index 4a13245252..264e629b33 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4d16acd7a9caed097bb7e352c290cb543f70b330800ef2b29b235bd52a0a4dc -size 9213 +oid sha256:d34d9a892baeb6443b390b623f2d355e758f07292d7ca742210032313307b309 +size 9882 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png index 4e05dcce15..21eee169b5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59784cf1d8c167ecdbe78e3db46b20aa8770a17ffd794193ab9ded221120d301 -size 8054 +oid sha256:451677cf50c127f97fc37a1a1dfadaf62229d8d35d55554c6da0d085f78c4a99 +size 8777 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png index 3512b11bf8..18d5582697 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f36874223538e2d4e5ee1c383ef3c1b83638a6e3c2d1791b46f9393e4bd7afea -size 8675 +oid sha256:193a50065c69de27fed36c7b3151351e6606c4006545b773b89e2c9ca96f68ea +size 9336 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png index b3ef224941..1259b2b518 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:874579b131a2956564603ba279803c4f753736a4545f50f9a1eff93ff2e414a3 -size 8417 +oid sha256:e39948d6cf139439013100ba0559387591656b23b2cff14320f9edfd90c20a65 +size 9105 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png index 431ccbef29..d1cf96241b 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d3da9ef5ffa433a5eaadc964e6d097a474c9b1245e2ebb60c067cc97a0f054b -size 8431 +oid sha256:71c08ef07e6bd0da6cc80de847507bd1f39d161365883eed986f0f600217e765 +size 9211 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png index 8c61303e96..ad202e44bf 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf3ab6dc97d3f34b7e25062885a49eeecc563a69f6c337d346ad1d9ad0c45fd1 -size 8583 +oid sha256:0858764ff6bda5d7a693336315023c7a216ffa5f59b2070a2f8d7342aeac6416 +size 9340 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png index 35651f3733..0d2345b4e8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83593ae45c35e34d5057d45b8a7e66b582b3b52adc7f05fa2d9c3ecdc0bece9c -size 8676 +oid sha256:97818e454a5848c9bf1a1b8d5c4328cf1671b86131b93bb64888b1b28fa28869 +size 9400 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png index c427f30780..50bec8ddb9 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69a4678aba6913f981f344eb730add0f4fdbe0529f7be015019150bac15f4709 -size 11009 +oid sha256:cdc03c9793f1198aa6efdb3a93eb8982cf365055e21bc86553ae83cdcea0b99f +size 11731 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png index d9b62e60e8..9371f2fae7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dac10693719b9cfe5f3644c25cbb9d1a59ed7c2f89e791eec17bf635c4d59efc -size 36507 +oid sha256:2ce01af104e3ce49a78b6fb9eab021f998938c59e487135a1b4d18f4b4a01b73 +size 37319 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png index 4a7563b96d..f22741654d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d234492829a729dcb05657af65a3fe97fe025ff42c79d9cf862e4e9925ddd832 -size 6944 +oid sha256:3816f44134580eb501d2a6abb91d713f5209fea3b1c35e500db88bbde1a6003d +size 7691 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png index 1e9225a8b8..d241221cfb 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:af28ed6a8b9d3b399531bf82d7be3c5a5b23ecc750654c241b7acc95a036132b -size 8115 +oid sha256:b7ddddb2a610a152474cd01c41b8dd50c7a9befee4f5a206f7ed91633f2d9fbd +size 8841 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png index 423ae8cbd0..5ab196c09c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44b0989e9ddb097d3a5ef0f331221a12a90f69ff017e3447e31ef5cccc53af68 -size 10290 +oid sha256:c5686ac15dbfc6cd805662f5e30d17bef529b2fbe84630e158306c1c2ca579f9 +size 11008 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png index f234f447da..8199266700 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98eb5d83d322022956b684699683f25ef6c09be55c60224689685589e0051983 -size 34883 +oid sha256:91f5c2d2fc15eac0c52a6088427bc8ccebe2e2ac966e59d36c17f85023fe3c75 +size 35660 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png index b7ea22436f..7bd5a22139 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:263371af4d0ac7efcd840a793e663505865d32c425d5b2efe9489a63655e33e1 -size 6563 +oid sha256:ea7e795366ebbd6730f2621b748238f6914c7d83fd76f69f98a6a6f5c785b8a1 +size 7311 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png index d92b8c569d..466a60982a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e4d1d09321fb1220d1be07e6f0ba54495764c935dcf6dc75bb3e7e5879770e46 -size 32646 +oid sha256:1dfe35935e328d87472211f1c6af5ddef99342c4a032dcb6aebab95a2efb0796 +size 33445 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png index 0c9b92ca30..264d00e03e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:46ab31307298aa5ce72f71db8eedefbde78eeebb3ff1426833bcb0a7c6af9ae3 -size 31131 +oid sha256:394bde203edc4e5b91060e0c3ce22291ac550855a8a7d5162ed5a442161e0ae9 +size 31867 From 475abd4a3b09791313397ba2473de7843d40dc56 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 12:00:57 +0100 Subject: [PATCH 289/347] fix(deps): update roborazzi to v1.53.0 (#5962) 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 ffabfc9446..285698eaad 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,7 +32,7 @@ accompanist = "0.37.3" # Test test_core = "1.7.0" -roborazzi = "1.52.0" +roborazzi = "1.53.0" # Jetbrain datetime = "0.7.1" From 78ad8056a1fbeb19063d050d1748ffb08217e575 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 2 Jan 2026 16:07:45 +0100 Subject: [PATCH 290/347] Cleanup --- .../io/element/android/codegen/ContributesNodeProcessor.kt | 2 +- .../messages/impl/timeline/components/group/GroupHeaderView.kt | 2 +- .../designsystem/atomic/atoms/SelectedIndicatorAtom.kt | 2 +- .../designsystem/components/avatar/internal/ImageAvatar.kt | 2 +- .../designsystem/theme/components/NavigationBarItem.kt | 2 +- .../io/element/android/tests/testutils/node/TestParentNode.kt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/codegen/src/main/kotlin/io/element/android/codegen/ContributesNodeProcessor.kt b/codegen/src/main/kotlin/io/element/android/codegen/ContributesNodeProcessor.kt index 7ddf80b92c..8b537a53fe 100644 --- a/codegen/src/main/kotlin/io/element/android/codegen/ContributesNodeProcessor.kt +++ b/codegen/src/main/kotlin/io/element/android/codegen/ContributesNodeProcessor.kt @@ -91,7 +91,7 @@ class ContributesNodeProcessor( .addAnnotation(Binds::class) .addAnnotation(IntoMap::class) .addAnnotation( - AnnotationSpec.Companion.builder(ClassName.bestGuess(nodeKeyFqName.asString())).addMember( + AnnotationSpec.builder(ClassName.bestGuess(nodeKeyFqName.asString())).addMember( CLASS_PLACEHOLDER, ClassName.bestGuess(ksClass.qualifiedName!!.asString()) ).build() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt index 0c13214a7d..883c591fd2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt @@ -49,7 +49,7 @@ fun GroupHeaderView( modifier: Modifier = Modifier ) { // Ignore isHighlighted for now, we need a design decision on it. - val backgroundColor = Color.Companion.Transparent + val backgroundColor = Color.Transparent val shape = RoundedCornerShape(CORNER_RADIUS) Box( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/SelectedIndicatorAtom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/SelectedIndicatorAtom.kt index b2e25af0fb..1a2e60cad5 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/SelectedIndicatorAtom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/SelectedIndicatorAtom.kt @@ -34,7 +34,7 @@ fun SelectedIndicatorAtom( Icon( modifier = modifier.toggleable( value = true, - role = Role.Companion.Checkbox, + role = Role.Checkbox, enabled = enabled, onValueChange = {}, ), 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 ebd81f61b1..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 @@ -36,7 +36,7 @@ internal fun ImageAvatar( SubcomposeAsyncImage( model = avatarData, contentDescription = contentDescription, - contentScale = ContentScale.Companion.Crop, + contentScale = ContentScale.Crop, modifier = modifier .size(size) .clip(avatarShape) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/NavigationBarItem.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/NavigationBarItem.kt index 40407602a8..7f74944fce 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/NavigationBarItem.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/NavigationBarItem.kt @@ -50,6 +50,6 @@ object ElementNavigationBarItemDefaults { selectedTextColor = ElementTheme.colors.textPrimary, unselectedIconColor = ElementTheme.colors.iconTertiary, unselectedTextColor = ElementTheme.colors.textDisabled, - selectedIndicatorColor = Color.Companion.Transparent, + selectedIndicatorColor = Color.Transparent, ) } diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/node/TestParentNode.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/node/TestParentNode.kt index c994733340..3daec9b3b5 100644 --- a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/node/TestParentNode.kt +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/node/TestParentNode.kt @@ -27,7 +27,7 @@ class TestParentNode( private val childNodeFactory: (buildContext: BuildContext, plugins: List) -> Child, ) : DependencyInjectionGraphOwner, Node( - buildContext = BuildContext.Companion.root(savedStateMap = null), + buildContext = BuildContext.root(savedStateMap = null), plugins = emptyList(), view = EmptyNodeView, ) { From 5b6dfca5d33e0afb9415f62a4942bee7b019c37a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 2 Jan 2026 16:23:15 +0100 Subject: [PATCH 291/347] Ensure that room / space avatar always have a contentDescription. --- .../android/features/roomdetails/impl/RoomDetailsView.kt | 2 +- .../android/features/space/impl/settings/SpaceSettingsView.kt | 2 +- .../features/userprofile/shared/UserProfileHeaderSection.kt | 2 +- .../libraries/designsystem/components/avatar/DmAvatars.kt | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 046c64d906..05f26daedb 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -404,7 +404,7 @@ private fun RoomHeaderSection( }.toImmutableList(), isTombstoned = isTombstoned, ), - contentDescription = avatarUrl?.let { stringResource(CommonStrings.a11y_room_avatar) }, + contentDescription = stringResource(CommonStrings.a11y_room_avatar), modifier = Modifier .clickable( enabled = avatarUrl != null, diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsView.kt index 5a8aac4a30..63b83516ac 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsView.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/settings/SpaceSettingsView.kt @@ -115,7 +115,7 @@ private fun SpaceInfoSection( Avatar( avatarData = AvatarData(roomId.value, name, avatarUrl, AvatarSize.SpaceListItem), avatarType = AvatarType.Space(), - contentDescription = avatarUrl?.let { stringResource(CommonStrings.a11y_avatar) }, + contentDescription = stringResource(CommonStrings.a11y_avatar), ) Spacer(Modifier.width(16.dp)) Column { diff --git a/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/UserProfileHeaderSection.kt b/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/UserProfileHeaderSection.kt index b27d1ad091..ac146a36a7 100644 --- a/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/UserProfileHeaderSection.kt +++ b/features/userprofile/shared/src/main/kotlin/io/element/android/features/userprofile/shared/UserProfileHeaderSection.kt @@ -66,7 +66,7 @@ fun UserProfileHeaderSection( Avatar( avatarData = AvatarData(userId.value, userName, avatarUrl, AvatarSize.UserHeader), avatarType = AvatarType.User, - contentDescription = avatarUrl?.let { stringResource(CommonStrings.a11y_user_avatar) }, + contentDescription = stringResource(CommonStrings.a11y_user_avatar), modifier = Modifier .clip(CircleShape) .clickable( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/DmAvatars.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/DmAvatars.kt index 1cd024542c..c5b870507b 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/DmAvatars.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/DmAvatars.kt @@ -59,7 +59,7 @@ fun DmAvatars( Avatar( avatarData = userAvatarData, avatarType = AvatarType.User, - contentDescription = userAvatarData.url?.let { stringResource(CommonStrings.a11y_your_avatar) }, + contentDescription = stringResource(CommonStrings.a11y_your_avatar), modifier = Modifier .align(Alignment.BottomStart) .graphicsLayer { @@ -94,7 +94,7 @@ fun DmAvatars( Avatar( avatarData = otherUserAvatarData, avatarType = AvatarType.User, - contentDescription = otherUserAvatarData.url?.let { stringResource(CommonStrings.a11y_other_user_avatar) }, + contentDescription = stringResource(CommonStrings.a11y_other_user_avatar), modifier = Modifier .align(Alignment.TopEnd) .clip(CircleShape) From 2a4eb6d1a7603cc59fea4482cb28f662e3009349 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 08:58:42 +0100 Subject: [PATCH 292/347] fix(deps): update roborazzi to v1.54.0 (#5970) 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 285698eaad..b435abdc51 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,7 +32,7 @@ accompanist = "0.37.3" # Test test_core = "1.7.0" -roborazzi = "1.53.0" +roborazzi = "1.54.0" # Jetbrain datetime = "0.7.1" From 860390beb09cd2c605e2cbb01bc2ca2ff9efa99b Mon Sep 17 00:00:00 2001 From: ElementBot <110224175+ElementBot@users.noreply.github.com> Date: Mon, 5 Jan 2026 13:57:09 +0100 Subject: [PATCH 293/347] Sync Strings from Localazy (#5971) Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com> --- .../src/main/res/values-hr/translations.xml | 4 +- .../src/main/res/values-fr/translations.xml | 19 + .../src/main/res/values-fr/translations.xml | 2 + .../src/main/res/values-fr/translations.xml | 9 +- .../src/main/res/values-hr/translations.xml | 2 +- .../src/main/res/values-fr/translations.xml | 9 +- .../src/main/res/values-fr/translations.xml | 2 + .../src/main/res/values-fr/translations.xml | 6 +- .../src/main/res/values-hr/translations.xml | 4 +- ...ons_ChangeRoomPermissionsView_Day_1_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_2_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_3_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_4_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_5_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_6_de.png | 3 + screenshots/html/data.js | 1950 ++++++++--------- 16 files changed, 1033 insertions(+), 997 deletions(-) create mode 100644 screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_de.png diff --git a/features/home/impl/src/main/res/values-hr/translations.xml b/features/home/impl/src/main/res/values-hr/translations.xml index dd1769b998..233cac78d8 100644 --- a/features/home/impl/src/main/res/values-hr/translations.xml +++ b/features/home/impl/src/main/res/values-hr/translations.xml @@ -30,13 +30,13 @@ "Još nema razgovora." "Favoriti" "Razgovor možete dodati u favorite u postavkama razgovora. -Zasad možete poništiti odabir filtera kako biste vidjeli ostale razgovore." +Zasad možete poništiti odabir filtara kako biste vidjeli ostale razgovore." "Još nemate omiljenih razgovora" "Pozivnice" "Nemate pozivnica na čekanju." "Nizak prioritet" "Još nemate razgovora niskog prioriteta" - "Možete poništiti odabir filtera kako biste vidjeli ostale razgovore" + "Možete poništiti odabir filtara kako biste vidjeli ostale razgovore" "Nemate razgovora za ovaj odabir" "Osobe" "Nemate još nijednu izravnu poruku" diff --git a/features/linknewdevice/impl/src/main/res/values-fr/translations.xml b/features/linknewdevice/impl/src/main/res/values-fr/translations.xml index f1ffe128cc..2b6774dfd4 100644 --- a/features/linknewdevice/impl/src/main/res/values-fr/translations.xml +++ b/features/linknewdevice/impl/src/main/res/values-fr/translations.xml @@ -1,16 +1,33 @@ "Scannez le QR code" + "Ouvrir %1$s sur un ordinateur" "Scanner le QR code avec cet appareil" "Prêt à scanner" + "Ouvrir %1$s sur un ordinateur pour obtenir le code QR" + "Les nombres ne correspondent pas" + "Saisissez le code à 2 chiffres" + "Cela permettra de vérifier que la connexion à votre autre appareil est sécurisée." + "Saisir le nombre affiché sur votre autre appareil" "Votre fournisseur de compte ne supporte pas %1$s." "%1$s n’est pas supporté" + "Votre fournisseur de compte ne prend pas en charge la connexion à un nouvel appareil à l’aide d’un code QR." "QR code non supporté" "La connexion a été annulée sur l’autre appareil." "Demande de connexion annulée" "Connexion expirée. Veuillez essayer à nouveau." "La connexion a pris trop de temps." + "Ouvrez %1$s sur l’autre appareil" "Choisissez %1$s" + "« Se connecter avec un code QR »" + "Scannez ce code QR avec l’autre appareil." + "Ouvrez %1$s sur l’autre appareil" + "Ordinateur de bureau" + "Chargement du code QR…" + "Appareil mobile" + "Quel type d’appareil souhaitez-vous associer ?" + "Veuillez réessayer et assurez-vous d’avoir saisi correctement le code à 2 chiffres. Si les chiffres ne correspondent toujours pas, veuillez contacter votre fournisseur de compte." + "Les nombres ne correspondent pas" "Aucune connexion sécurisée n’a pu être établie avec la nouvelle session. Vos sessions existantes sont toujours en sécurité et vous n’avez pas à vous en soucier." "Et maintenant ?" "Essayez de vous connecter à nouveau à l’aide du QR code au cas où il s’agirait d’un problème réseau" @@ -21,6 +38,8 @@ "Demande de connexion annulée" "La connexion a été refusée sur l’autre appareil." "Connexion refusée" + "Vous n’avez rien d’autre à faire." + "Votre autre appareil est déjà connecté" "Connexion expirée. Veuillez essayer à nouveau." "La connexion a pris trop de temps." "Votre autre appareil ne supporte pas la connexion à %s avec un QR code. Essayer de vous connecter manuellement, ou scanner le QR code avec un autre appareil." diff --git a/features/login/impl/src/main/res/values-fr/translations.xml b/features/login/impl/src/main/res/values-fr/translations.xml index 3410e56ece..c58e00b521 100644 --- a/features/login/impl/src/main/res/values-fr/translations.xml +++ b/features/login/impl/src/main/res/values-fr/translations.xml @@ -60,6 +60,8 @@ "Demande de connexion annulée" "La connexion a été refusée sur l’autre appareil." "Connexion refusée" + "Vous n’avez rien d’autre à faire." + "Votre autre appareil est déjà connecté" "Connexion expirée. Veuillez essayer à nouveau." "La connexion a pris trop de temps." "Votre autre appareil ne supporte pas la connexion à %s avec un QR code. Essayer de vous connecter manuellement, ou scanner le QR code avec un autre appareil." diff --git a/features/roomdetails/impl/src/main/res/values-fr/translations.xml b/features/roomdetails/impl/src/main/res/values-fr/translations.xml index 75c8592d0e..2feda357a1 100644 --- a/features/roomdetails/impl/src/main/res/values-fr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fr/translations.xml @@ -129,8 +129,10 @@ "Détails du salon" "Rôles & autorisations" "Ajouter une adresse" + "Toute personne se trouvant dans un espace autorisé peut participer, mais toutes les autres doivent demander l’accès." "Tout le monde doit demander un accès." "Demander à rejoindre" + "Tout membre de %1$s peut rejoindre l’espace, mais les autres doivent demander un accès." "Oui, activer le chiffrement" "Une fois activé, le chiffrement d’un salon ne peut pas être désactivé. L’historique des messages ne sera visible que pour les membres depuis qu’ils ont été invités ou depuis qu’ils ont rejoint le salon. Personne d’autre que les membres du salon ne pourra lire les messages. Cela peut empêcher les bots et les bridges de fonctionner correctement. @@ -155,10 +157,11 @@ Nous ne recommandons pas d’activer le chiffrement pour les salons que tout le "Autoriser le salon à apparaître dans les résultats de recherche dans le répertoire %1$s des salons publics" "Permet d’être trouvé en recherchant dans l’annuaire public." "Visible dans l’annuaire public" - "Tout le monde" + "Tout le monde (l’historique est public)" + "Les changements n’affecteront pas les anciens messages, seulement les nouveaux. %1$s" "Qui peux lire l’historique" - "Les membres uniquement depuis qu’ils ont été invités" - "Les membres uniquement depuis la sélection de cette option" + "Seulement les membres, depuis leur invitation" + "Membres (historique complet)" "Les adresses de salon sont un moyen de trouver et d’accéder aux salons. Cela vous permet également de partager facilement votre salon avec d’autres personnes. Vous pouvez choisir de publier votre salon dans l’annuaire des salons publics de votre serveur d’accueil." "Publication du salon" diff --git a/features/securebackup/impl/src/main/res/values-hr/translations.xml b/features/securebackup/impl/src/main/res/values-hr/translations.xml index dcdfe830a7..d225c2f837 100644 --- a/features/securebackup/impl/src/main/res/values-hr/translations.xml +++ b/features/securebackup/impl/src/main/res/values-hr/translations.xml @@ -42,7 +42,7 @@ "Pazite da nitko ne vidi ovaj zaslon!" "Pokušajte ponovno potvrditi pristup pohrani ključeva." "Neispravan ključ za oporavak" - "Ako imate sigurnosni ključ ili sigurnosnu frazu, i ovo će funkcionirati." + "Ako imate sigurnosni ključ ili sigurnosni izraz, i ovo će funkcionirati." "Unos…" "Izgubili ste ključ za oporavak?" "Ključ za oporavak je potvrđen" diff --git a/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml index 5426d71706..eaf52430c7 100644 --- a/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml @@ -3,8 +3,10 @@ "Vous aurez besoin d’une adresse pour le rendre visible dans l’annuaire public." "Modifier l’adresse" "Ajouter une adresse" + "Toute personne se trouvant dans un espace autorisé peut participer, mais toutes les autres doivent demander l’accès." "Tout le monde doit demander un accès." "Demander à rejoindre" + "Tout membre de %1$s peut rejoindre l’espace, mais les autres doivent demander un accès." "Oui, activer le chiffrement" "Une fois activé, le chiffrement d’un salon ne peut pas être désactivé. L’historique des messages ne sera visible que pour les membres depuis qu’ils ont été invités ou depuis qu’ils ont rejoint le salon. Personne d’autre que les membres du salon ne pourra lire les messages. Cela peut empêcher les bots et les bridges de fonctionner correctement. @@ -29,10 +31,11 @@ Nous ne recommandons pas d’activer le chiffrement pour les salons que tout le "Autoriser le salon à apparaître dans les résultats de recherche dans le répertoire %1$s des salons publics" "Permet d’être trouvé en recherchant dans l’annuaire public." "Visible dans l’annuaire public" - "Tout le monde" + "Tout le monde (l’historique est public)" + "Les changements n’affecteront pas les anciens messages, seulement les nouveaux. %1$s" "Qui peux lire l’historique" - "Les membres uniquement depuis qu’ils ont été invités" - "Les membres uniquement depuis la sélection de cette option" + "Seulement les membres, depuis leur invitation" + "Membres (historique complet)" "Les adresses de salon sont un moyen de trouver et d’accéder aux salons. Cela vous permet également de partager facilement votre salon avec d’autres personnes. Vous pouvez choisir de publier votre salon dans l’annuaire des salons publics de votre serveur d’accueil." "Publication du salon" diff --git a/libraries/push/impl/src/main/res/values-fr/translations.xml b/libraries/push/impl/src/main/res/values-fr/translations.xml index 8927f9eccc..85146e259d 100644 --- a/libraries/push/impl/src/main/res/values-fr/translations.xml +++ b/libraries/push/impl/src/main/res/values-fr/translations.xml @@ -38,6 +38,8 @@ "%1$s vous a invité à rejoindre le salon" "Moi" "%1$s mentionné ou en réponse" + "Vous a invité à rejoindre l’espace" + "%1$s vous a invité à rejoindre l’espace" "Vous êtes en train de voir la notification ! Cliquez-moi !" "Discussion dans %1$s" "%1$s : %2$s" 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 9392933cf8..f5083fd707 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -161,6 +161,7 @@ "Cliquez pour charger la carte" "Prendre une photo" "Appuyez pour afficher les options" + "Traduire" "Essayer à nouveau" "Désépingler" "Voir" @@ -235,6 +236,7 @@ Raison : %1$s." "Clair" "Ligne copiée dans le presse-papiers" "Lien copié dans le presse-papiers" + "Associer un nouvel appareil" "Chargement…" "Chargement…" @@ -252,6 +254,7 @@ Raison : %1$s." "Message supprimé" "Moderne" "Mettre en sourdine" + "Nom" "%1$s (%2$s)" "Aucun résultat" "Salon sans nom" @@ -326,6 +329,7 @@ Raison : %1$s." "Une erreur s’est produite" "Nous avons rencontré un problème. Veuillez réessayer." "Espace" + "Quel est le sujet de cet espace ?" "%1$d Espace" "%1$d Espaces" @@ -370,7 +374,7 @@ Raison : %1$s." "En attente…" "En attente de la clé de déchiffrement" "Vous" - "Les messages que vous enverrez seront partagés avec les nouveaux membres invités dans ce salon. %1$s" + "Ce salon a été configuré pour que les nouveaux membres puissent lire l’historique. %1$s" "L’identité de %1$s a été réinitialisée. %2$s" "L’identité de %1$s %2$s a été réinitialisée. %3$s" "(%1$s)" diff --git a/libraries/ui-strings/src/main/res/values-hr/translations.xml b/libraries/ui-strings/src/main/res/values-hr/translations.xml index 91caf1b6f9..c8b3c10cbc 100644 --- a/libraries/ui-strings/src/main/res/values-hr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hr/translations.xml @@ -11,7 +11,7 @@ "Uredi avatar" "Potpuna adresa bit će %1$s" - "Pojedinosti šifriranja" + "Pojedinosti o šifriranju" "Proširi tekstno polje poruke" "Sakrij zaporku" "Pridruži se pozivu" @@ -58,7 +58,7 @@ "Vaš avatar" "Prihvati" "Dodaj opis" - "Dodaj na vremensku crtu" + "Dodaj na vremensku traku" "Natrag" "Poziv" "Odustani" diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png index 875ef8326c..80e56f1da6 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d95bf342ddba5663a36a1f435351e7a3017cad73f7cd58504913681feced1ce2 -size 65157 +oid sha256:9c2a9304396e74bc9bb11174efbcc8ce6cff94fb028c0c4f0dfa5589922dae39 +size 62950 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png index a04a0cd23a..875ef8326c 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5ab43cd09460063624d2e583b71af3bb3a286890cbf07744d101042aa7c45f5 -size 56783 +oid sha256:d95bf342ddba5663a36a1f435351e7a3017cad73f7cd58504913681feced1ce2 +size 65157 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png index 7da0708b92..a04a0cd23a 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41d2484c7ddee013f9cf001dc2eb0ff8a99ac22b7e70816752c97893d1db4c95 -size 54265 +oid sha256:e5ab43cd09460063624d2e583b71af3bb3a286890cbf07744d101042aa7c45f5 +size 56783 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png index 6d24520c56..7da0708b92 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3afe4b55dd9e11397b9f4b5a99cfc6f5a1a4cebcbdc8cdfb0f81f43eb6912f15 -size 63039 +oid sha256:41d2484c7ddee013f9cf001dc2eb0ff8a99ac22b7e70816752c97893d1db4c95 +size 54265 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png index c0656d9b7e..6d24520c56 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ad55fc63c50a403a3218e9168df15c92f91430e60bd4adde45247080cf50543 -size 62971 +oid sha256:3afe4b55dd9e11397b9f4b5a99cfc6f5a1a4cebcbdc8cdfb0f81f43eb6912f15 +size 63039 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_de.png new file mode 100644 index 0000000000..c0656d9b7e --- /dev/null +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ad55fc63c50a403a3218e9168df15c92f91430e60bd4adde45247080cf50543 +size 62971 diff --git a/screenshots/html/data.js b/screenshots/html/data.js index 42d529aec6..73bb02be34 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,80 +1,80 @@ // 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",20445,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20453,], ["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",20445,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20445,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20445,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20445,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20445,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20445,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20445,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20445,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20445,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20445,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20445,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20453,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20453,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20453,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20453,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20453,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20453,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20453,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20453,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20453,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20453,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20453,], ["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",20445,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20445,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20453,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20453,], ["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",20445,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20445,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20453,], ["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",20445,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20445,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20445,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20445,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20445,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20445,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20445,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20445,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20445,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20445,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20445,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20445,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20445,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20445,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20445,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20453,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20453,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20453,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20453,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20453,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20453,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20453,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20453,], ["libraries.designsystem.theme.components_AllIcons_Icons_en","",0,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20445,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20445,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20445,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20445,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20445,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20453,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20453,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20453,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20453,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20453,], ["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",20445,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20453,], ["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",20445,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20453,], ["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",20445,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20453,], ["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",20445,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20453,], ["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",20445,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20453,], ["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,], @@ -84,19 +84,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","",20445,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en","",20445,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en","",20445,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en","",20445,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en","",20445,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en","",20445,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en","",20445,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en","",20445,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en","",20445,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_0_en","",20453,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en","",20453,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en","",20453,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en","",20453,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en","",20453,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en","",20453,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en","",20453,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en","",20453,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en","",20453,], ["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",20445,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20453,], ["libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en","",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_0_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_1_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_1_en",0,], @@ -123,22 +123,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",20445,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20453,], ["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",20445,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20445,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20445,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20445,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20445,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20445,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20445,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20453,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20453,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20453,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20453,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20453,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20453,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20453,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20445,], -["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20445,], -["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20445,], -["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20445,], -["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20445,], +["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20453,], +["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20453,], +["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20453,], +["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20453,], +["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20453,], ["features.rageshake.impl.bugreport_BugReportViewNight_0_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_1_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_2_en","",0,], @@ -148,137 +148,137 @@ export const screenshots = [ ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20445,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20445,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20453,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20453,], ["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], ["features.call.impl.ui_CallScreenView_Day_0_en","features.call.impl.ui_CallScreenView_Night_0_en",0,], -["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20445,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20445,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20445,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20445,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20445,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20445,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20453,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20453,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20453,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20453,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20453,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20453,], ["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",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20445,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20445,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20445,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20445,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20445,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20445,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20445,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en",20445,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en",0,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20453,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20453,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20453,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20453,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20453,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20453,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20453,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en",20453,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en",20458,], ["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",20445,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20445,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20445,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20445,], -["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20445,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20453,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20453,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20453,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20453,], +["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20453,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20445,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20453,], ["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",20445,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20445,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20445,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20445,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20445,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20445,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20445,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20445,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20453,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20453,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20453,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20453,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20453,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20453,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20453,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20453,], ["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",20445,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20445,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20445,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20445,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20445,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20445,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20445,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20445,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20445,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20445,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20453,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20453,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20453,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20453,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20453,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20453,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20453,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20453,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20453,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20453,], ["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","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20445,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20445,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20445,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20445,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20445,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20445,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20453,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20453,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20453,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20453,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20453,], ["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",20445,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20445,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20445,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20445,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20445,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20445,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20445,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20445,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20445,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20445,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20445,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20445,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20445,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20445,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20445,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20445,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20445,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20445,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20445,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20445,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20453,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20453,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20453,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20453,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20453,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20453,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20453,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20453,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20453,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20453,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20453,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20453,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20453,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20453,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20453,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20453,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20453,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20453,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20453,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20453,], ["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","",20445,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20445,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20445,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20445,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20445,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20445,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20445,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20453,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20453,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20453,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20453,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20453,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20453,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20453,], ["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",20445,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20445,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20445,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20453,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20453,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20453,], ["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",20445,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20453,], ["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",20445,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20445,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20445,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20445,], -["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en",20445,], -["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en",20445,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20445,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20445,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20445,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20445,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20453,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20453,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20453,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20453,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en",20453,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en",20453,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20453,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20453,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20453,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20453,], ["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,], @@ -293,19 +293,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",20445,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20445,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20445,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20445,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20445,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20445,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20445,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20445,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20445,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20445,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20445,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20445,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20445,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20453,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20453,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20453,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20453,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20453,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20453,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20453,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20453,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20453,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20453,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20453,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20453,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20453,], ["libraries.matrix.ui.components_EditableAvatarView_Day_0_en","libraries.matrix.ui.components_EditableAvatarView_Night_0_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_1_en","libraries.matrix.ui.components_EditableAvatarView_Night_1_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_2_en","libraries.matrix.ui.components_EditableAvatarView_Night_2_en",0,], @@ -316,28 +316,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",20445,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20445,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20453,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20453,], ["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",20445,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en",20445,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en",20445,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en",20445,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en",20445,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en",20445,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20445,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20445,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20445,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_0_en","features.linknewdevice.impl.screens.error_ErrorView_Night_0_en",20445,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_1_en","features.linknewdevice.impl.screens.error_ErrorView_Night_1_en",20445,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_2_en","features.linknewdevice.impl.screens.error_ErrorView_Night_2_en",20445,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_3_en","features.linknewdevice.impl.screens.error_ErrorView_Night_3_en",20445,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_4_en","features.linknewdevice.impl.screens.error_ErrorView_Night_4_en",20445,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_5_en","features.linknewdevice.impl.screens.error_ErrorView_Night_5_en",20445,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_6_en","features.linknewdevice.impl.screens.error_ErrorView_Night_6_en",20445,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_7_en","features.linknewdevice.impl.screens.error_ErrorView_Night_7_en",20445,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en",20453,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en",20453,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en",20453,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en",20453,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en",20453,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en",20453,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20453,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20453,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20453,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_0_en","features.linknewdevice.impl.screens.error_ErrorView_Night_0_en",20453,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_1_en","features.linknewdevice.impl.screens.error_ErrorView_Night_1_en",20453,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_2_en","features.linknewdevice.impl.screens.error_ErrorView_Night_2_en",20453,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_3_en","features.linknewdevice.impl.screens.error_ErrorView_Night_3_en",20453,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_4_en","features.linknewdevice.impl.screens.error_ErrorView_Night_4_en",20453,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_5_en","features.linknewdevice.impl.screens.error_ErrorView_Night_5_en",20453,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_6_en","features.linknewdevice.impl.screens.error_ErrorView_Night_6_en",20453,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_7_en","features.linknewdevice.impl.screens.error_ErrorView_Night_7_en",20453,], ["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,], @@ -356,44 +356,44 @@ 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",20445,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20445,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20445,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20453,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20453,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20453,], ["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",20445,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20445,], +["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20453,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20453,], ["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.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en","features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en",20445,], -["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20445,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20445,], -["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20445,], -["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20445,], -["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20445,], +["features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en","features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en",20453,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20453,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20453,], +["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20453,], +["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20453,], +["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20453,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20445,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20445,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20453,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20453,], ["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",20445,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20445,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20445,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20445,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20445,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20445,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20445,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20445,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20445,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20445,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20445,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20445,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20453,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20453,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20453,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20453,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20453,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20453,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20453,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20453,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20453,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20453,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20453,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20453,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.ruler_HorizontalRuler_Day_0_en","libraries.designsystem.ruler_HorizontalRuler_Night_0_en",0,], ["libraries.designsystem.theme.components_IconButton_Buttons_en","",0,], @@ -406,8 +406,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",20445,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20445,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20453,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20453,], ["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,], @@ -415,115 +415,115 @@ 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",20445,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20453,], ["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",20445,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20453,], ["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",20445,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20453,], ["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20445,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20445,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20453,], ["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",20445,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20445,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20445,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20453,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20453,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20453,], ["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",20445,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20445,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20445,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20445,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20453,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20453,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20453,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20453,], ["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",20445,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20445,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20445,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20445,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20445,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20445,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20445,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20445,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20453,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20453,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20453,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20453,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20453,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20453,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20453,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20453,], ["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",20445,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20445,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20445,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20445,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20445,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20445,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20445,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20445,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20445,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20445,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20445,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20453,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20453,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20453,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20453,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20453,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20453,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20453,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20453,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20453,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], -["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20445,], -["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20445,], +["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20453,], +["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20453,], ["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",20445,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20445,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20445,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20445,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20445,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20445,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20445,], -["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20445,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20453,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20453,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20453,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20453,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20453,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20453,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20453,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20453,], ["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",20445,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_0_en",20453,], ["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en",0,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en",20445,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en",20445,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en",20453,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en",20453,], ["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en",0,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en",20445,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en",20453,], ["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",20445,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20453,], ["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,], @@ -578,38 +578,38 @@ 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",20445,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20445,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20445,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20445,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20453,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20453,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20453,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20453,], ["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",20445,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20445,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20445,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20445,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20445,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20445,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20445,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20445,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20445,], -["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20445,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20445,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20445,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20445,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20445,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20445,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20445,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20445,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20445,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20445,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20445,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20445,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20445,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20445,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20445,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20445,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20453,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20453,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20453,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20453,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20453,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20453,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20453,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20453,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20453,], +["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20453,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20453,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20453,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20453,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20453,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20453,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20453,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20453,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20453,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20453,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20453,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20453,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20453,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20453,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20453,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20453,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20445,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20453,], ["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,], @@ -622,22 +622,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",20445,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20445,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20453,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20453,], ["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",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20445,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20445,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20453,], ["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,], @@ -645,14 +645,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","",20445,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20445,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20453,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20453,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20445,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20453,], ["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","",20445,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20453,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -666,7 +666,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",20445,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20453,], ["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,], @@ -675,7 +675,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",20445,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20453,], ["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,], @@ -683,26 +683,26 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessagesReactionButton_Day_1_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_1_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_2_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_2_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_3_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_3_en",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20445,], -["features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en","features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en",20445,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20445,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20445,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20445,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20445,], -["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20445,], -["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20445,], -["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20445,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20445,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20445,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20445,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20445,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20445,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20445,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20445,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20445,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20445,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20453,], +["features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en","features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en",20453,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20453,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20453,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20453,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20453,], +["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20453,], +["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20453,], +["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20453,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20453,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20453,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20453,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20453,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20453,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20453,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20453,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20453,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20453,], ["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",20445,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20453,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], @@ -713,112 +713,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",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20445,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20445,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20445,], +["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20453,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20453,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20453,], ["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",20445,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20445,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20445,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20445,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20445,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20445,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20445,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20445,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20453,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20453,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20453,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20453,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20453,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20453,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20453,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20453,], ["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",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20445,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20453,], ["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",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20445,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20445,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20453,], ["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",20445,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20453,], ["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",0,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20445,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20445,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20445,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20445,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20453,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20453,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20453,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20453,], ["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",20445,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20445,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20445,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20453,], ["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",20445,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20445,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20445,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20445,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20445,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20445,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20445,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20445,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20445,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20445,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20445,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20445,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20445,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20445,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20453,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20453,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20453,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20453,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20453,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20445,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20445,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20445,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20445,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20445,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20453,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20453,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20453,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20453,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20453,], ["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",20445,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20445,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20445,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20445,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20445,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20445,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20445,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20445,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20445,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20445,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20445,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20453,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20453,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20453,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20453,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20453,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20453,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20453,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20453,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20453,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20453,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20453,], ["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,], @@ -832,207 +832,207 @@ export const screenshots = [ ["libraries.designsystem.components.preferences_PreferenceRow_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSlide_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en","",0,], -["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20445,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20445,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20445,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20445,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20453,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20453,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20453,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20453,], ["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","",20445,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20445,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20453,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20453,], ["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",20445,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20445,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20445,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20445,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20445,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20445,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20445,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20445,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20445,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20445,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20445,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20445,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20445,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20445,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20445,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20445,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20445,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20445,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20445,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20445,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20445,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20445,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20445,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20445,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20445,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20445,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20445,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20453,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20453,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20453,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20453,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20453,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20453,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20453,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20453,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20453,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20453,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20453,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20453,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20453,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20453,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20453,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20453,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20453,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20453,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20453,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20453,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20453,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20453,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20453,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20453,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20453,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20453,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20453,], ["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",20445,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20445,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20453,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20453,], ["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",20445,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20445,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20445,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20445,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20445,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20445,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20445,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20453,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20453,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20453,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20453,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20453,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20453,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20453,], ["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",20445,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20445,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20445,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20445,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20445,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20445,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20445,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20445,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20445,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20445,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20445,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20445,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20445,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20445,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20445,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20445,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20445,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20453,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20453,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20453,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20453,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20453,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20453,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20453,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20453,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20453,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20453,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20453,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20453,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20453,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20453,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20453,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20453,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20453,], ["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",20445,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20445,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20445,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20445,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20445,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20445,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20445,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20445,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20445,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20445,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20445,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20445,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20445,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20453,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20453,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20453,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20453,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20453,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20453,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20453,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20453,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20453,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20453,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20453,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20453,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20453,], ["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",20445,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20445,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20445,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20445,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20445,], -["features.roomdetails.impl_RoomDetails_0_en","",20445,], -["features.roomdetails.impl_RoomDetails_10_en","",20445,], -["features.roomdetails.impl_RoomDetails_11_en","",20445,], -["features.roomdetails.impl_RoomDetails_12_en","",20445,], -["features.roomdetails.impl_RoomDetails_13_en","",20445,], -["features.roomdetails.impl_RoomDetails_14_en","",20445,], -["features.roomdetails.impl_RoomDetails_15_en","",20445,], -["features.roomdetails.impl_RoomDetails_16_en","",20445,], -["features.roomdetails.impl_RoomDetails_17_en","",20445,], -["features.roomdetails.impl_RoomDetails_18_en","",20445,], -["features.roomdetails.impl_RoomDetails_19_en","",20445,], -["features.roomdetails.impl_RoomDetails_1_en","",20445,], -["features.roomdetails.impl_RoomDetails_2_en","",20445,], -["features.roomdetails.impl_RoomDetails_3_en","",20445,], -["features.roomdetails.impl_RoomDetails_4_en","",20445,], -["features.roomdetails.impl_RoomDetails_5_en","",20445,], -["features.roomdetails.impl_RoomDetails_6_en","",20445,], -["features.roomdetails.impl_RoomDetails_7_en","",20445,], -["features.roomdetails.impl_RoomDetails_8_en","",20445,], -["features.roomdetails.impl_RoomDetails_9_en","",20445,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20445,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20445,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20445,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20445,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20445,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20445,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20445,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20445,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20445,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20453,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20453,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20453,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20453,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20453,], +["features.roomdetails.impl_RoomDetails_0_en","",20453,], +["features.roomdetails.impl_RoomDetails_10_en","",20453,], +["features.roomdetails.impl_RoomDetails_11_en","",20453,], +["features.roomdetails.impl_RoomDetails_12_en","",20453,], +["features.roomdetails.impl_RoomDetails_13_en","",20453,], +["features.roomdetails.impl_RoomDetails_14_en","",20453,], +["features.roomdetails.impl_RoomDetails_15_en","",20453,], +["features.roomdetails.impl_RoomDetails_16_en","",20453,], +["features.roomdetails.impl_RoomDetails_17_en","",20453,], +["features.roomdetails.impl_RoomDetails_18_en","",20453,], +["features.roomdetails.impl_RoomDetails_19_en","",20453,], +["features.roomdetails.impl_RoomDetails_1_en","",20453,], +["features.roomdetails.impl_RoomDetails_2_en","",20453,], +["features.roomdetails.impl_RoomDetails_3_en","",20453,], +["features.roomdetails.impl_RoomDetails_4_en","",20453,], +["features.roomdetails.impl_RoomDetails_5_en","",20453,], +["features.roomdetails.impl_RoomDetails_6_en","",20453,], +["features.roomdetails.impl_RoomDetails_7_en","",20453,], +["features.roomdetails.impl_RoomDetails_8_en","",20453,], +["features.roomdetails.impl_RoomDetails_9_en","",20453,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20453,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20453,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20453,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20453,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20453,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20453,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20453,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20453,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20453,], ["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",20445,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20445,], -["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20445,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20445,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20445,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20445,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20445,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20445,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20445,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20453,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20453,], +["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20453,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20453,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20453,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20453,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20453,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20453,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20453,], ["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",20445,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20445,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20445,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20445,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20445,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20445,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20445,], -["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20445,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20445,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20445,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20445,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20445,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20445,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20445,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20445,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20445,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20445,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20453,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20453,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20453,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20453,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20453,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20453,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20453,], +["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20453,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20453,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20453,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20453,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20453,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20453,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20453,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20453,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20453,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20453,], ["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",20445,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20445,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20445,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20445,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20445,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20445,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20445,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20445,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20445,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20445,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20445,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20445,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20445,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20445,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20453,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20453,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20453,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20453,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20453,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20453,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20453,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20453,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20453,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20453,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20453,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20453,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20453,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20453,], ["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,], @@ -1055,14 +1055,14 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_26_en","features.home.impl.components_RoomSummaryRow_Night_26_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_27_en","features.home.impl.components_RoomSummaryRow_Night_27_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_28_en","features.home.impl.components_RoomSummaryRow_Night_28_en",0,], -["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20445,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20445,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20445,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20445,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20445,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20445,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20445,], -["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20445,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20453,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20453,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20453,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20453,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20453,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20453,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20453,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20453,], ["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",0,], ["features.home.impl.components_RoomSummaryRow_Day_3_en","features.home.impl.components_RoomSummaryRow_Night_3_en",0,], @@ -1072,109 +1072,109 @@ 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",20445,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20445,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20445,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20453,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20453,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20453,], ["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",20445,], -["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20445,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en",20445,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en",20445,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en",20445,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en",20445,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20445,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20445,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20453,], +["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20453,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en",20453,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en",20453,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en",20453,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en",20453,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20453,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20453,], ["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","",20445,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20453,], ["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","",20445,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20445,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20445,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20445,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20445,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20445,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20445,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20445,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20445,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20445,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20445,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20445,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20445,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20445,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20453,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20453,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20453,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20453,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20453,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20453,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20453,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20453,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20453,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20453,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20453,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20453,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20453,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20453,], ["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,], @@ -1188,11 +1188,11 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_1_en","libraries.matrix.ui.components_SelectedUser_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedUsersRowList_Day_0_en","libraries.matrix.ui.components_SelectedUsersRowList_Night_0_en",0,], ["libraries.textcomposer.components_SendButton_Day_0_en","libraries.textcomposer.components_SendButton_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20445,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20445,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20445,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20445,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20445,], +["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20453,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20453,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20453,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20453,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20453,], ["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,], @@ -1202,28 +1202,28 @@ 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",20445,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20445,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20445,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20445,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20445,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20445,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20445,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20445,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20453,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20453,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20453,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20453,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20453,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20453,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20453,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20453,], ["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",20445,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20445,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20445,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20445,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20445,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20445,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20445,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20445,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20445,], -["features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en","features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en",20445,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20445,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20453,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20453,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20453,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20453,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20453,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20453,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20453,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20453,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20453,], +["features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en","features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en",20453,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20453,], ["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,], @@ -1233,102 +1233,102 @@ 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",20445,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20453,], ["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",20445,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20453,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20445,], -["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20445,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20445,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20453,], +["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20453,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20453,], ["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",20445,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20445,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20445,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20445,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20445,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20445,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20445,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20445,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20445,], -["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20445,], -["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20445,], -["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20445,], -["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20445,], -["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20445,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20445,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20445,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20445,], -["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20445,], -["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20445,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20453,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20453,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20453,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20453,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20453,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20453,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20453,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20453,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20453,], +["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20453,], +["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20453,], +["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20453,], +["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20453,], +["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20453,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20453,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20453,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20453,], +["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20453,], +["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20453,], ["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",20445,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20445,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20445,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20445,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20445,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20445,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20445,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20453,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20453,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20453,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20453,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20453,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20453,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20453,], ["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",20445,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20453,], ["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",20445,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20453,], ["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",20445,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20445,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20445,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20445,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20445,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20445,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20445,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20445,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20445,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20445,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20445,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20445,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20445,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20445,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20445,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20453,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20453,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20453,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20453,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20453,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20453,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20453,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20453,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20453,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20453,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20453,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20453,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20453,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20453,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20453,], ["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",20445,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20445,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20453,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20453,], ["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,], @@ -1340,16 +1340,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",20445,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20445,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20445,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20445,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20445,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20453,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20453,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20453,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20453,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20453,], ["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",20445,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20445,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20453,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20453,], ["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,], @@ -1359,18 +1359,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",20445,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20453,], ["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",20445,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20453,], ["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,], @@ -1378,18 +1378,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",20445,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20453,], ["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",20445,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20445,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20453,], ["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",20445,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20453,], ["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,], @@ -1398,41 +1398,41 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20453,], ["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",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20453,], ["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",20445,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20453,], ["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","",20445,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20453,], ["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",20445,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20445,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20453,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20453,], ["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",20445,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20453,], ["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",20445,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20445,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20445,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20453,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20453,], ["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",20445,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20445,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20453,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20453,], ["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",20445,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20453,], ["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,], @@ -1441,8 +1441,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",20445,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20453,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20453,], ["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,], @@ -1457,8 +1457,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",20445,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20445,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20453,], ["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,], @@ -1481,85 +1481,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",20445,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20445,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20453,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20453,], ["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",20445,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20445,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20445,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20445,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20445,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20445,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20445,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20445,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20453,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20453,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20453,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20453,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20453,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20453,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20453,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20453,], ["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",20445,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20453,], ["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",20445,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20453,], ["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",20445,], +["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20453,], ["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",20445,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20445,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20445,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20445,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20445,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20445,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20445,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20445,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20453,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20453,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20453,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20453,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20453,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20453,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20453,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20453,], ["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",20445,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20445,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20445,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20445,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20445,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20445,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20453,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20453,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20453,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20453,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20453,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20453,], ["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","",20445,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20453,], ["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], ["libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en","libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en",0,], -["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20445,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20445,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20445,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20445,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20453,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20453,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20453,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20453,], ["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",20445,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20453,], ["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",20445,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20453,], ["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",20445,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20445,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20445,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20445,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20445,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20445,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20445,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20445,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20445,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20445,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20445,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20445,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20453,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20453,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20453,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20453,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20453,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20453,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20453,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20453,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20453,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20453,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20453,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20453,], ["features.verifysession.impl.ui_VerificationUserProfileContent_Day_0_en","features.verifysession.impl.ui_VerificationUserProfileContent_Night_0_en",0,], ["libraries.designsystem.ruler_VerticalRuler_Day_0_en","libraries.designsystem.ruler_VerticalRuler_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_1_en",0,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20445,], -["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20445,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20453,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20453,], ["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",20445,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20453,], ["features.viewfolder.impl.file_ViewFileView_Day_4_en","features.viewfolder.impl.file_ViewFileView_Night_4_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_5_en","features.viewfolder.impl.file_ViewFileView_Night_5_en",0,], ["features.viewfolder.impl.folder_ViewFolderView_Day_0_en","features.viewfolder.impl.folder_ViewFolderView_Night_0_en",0,], From c31e149f2b53341912f6f0cbf178563c238b36fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 12:59:05 +0000 Subject: [PATCH 294/347] fix(deps): update dependency org.unifiedpush.android:connector to v3.2.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 b435abdc51..57ba97b8da 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -201,7 +201,7 @@ sqldelight-driver-jvm = { module = "app.cash.sqldelight:sqlite-driver", version. sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqldelight" } sqlcipher = "net.zetetic:sqlcipher-android:4.12.0" sqlite = "androidx.sqlite:sqlite-ktx:2.6.2" -unifiedpush = "org.unifiedpush.android:connector:3.1.2" +unifiedpush = "org.unifiedpush.android:connector:3.2.0" vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0" telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" } telephoto_flick = { module = "me.saket.telephoto:flick-android", version.ref = "telephoto" } From acdbec2de2ae322fca10b3c0d771db8bde2df9ef Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 5 Jan 2026 16:06:00 +0100 Subject: [PATCH 295/347] Use `VerificationState.VERIFIED` as soon as it's available (#5973) This can't be a false positive like `VerificationState.UNKNOWN` or `VerificationState.UNVERIFIED`, so it makes sense to return it as fast as possible instead of waiting for the whole encryption layer to be fully loaded. --- .../matrix/impl/verification/RustSessionVerificationService.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt index f613ce8dff..7fb2935897 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt @@ -72,7 +72,8 @@ class RustSessionVerificationService( // Listen for changes in verification status and update accordingly private val verificationStateListenerTaskHandle = encryptionService.verificationStateListener(object : VerificationStateListener { override fun onUpdate(status: VerificationState) { - if (!isInitialized.get()) { + // If the status is verified, just use it. It can't be a false positive like unknown or unverified + if (!isInitialized.get() && status != VerificationState.VERIFIED) { Timber.d("Discarding new verifications state: $status. E2EE is not initialised yet") return } From 71031008dd6400a769c5f7845d8fcecd3f2aba62 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 5 Jan 2026 16:23:26 +0100 Subject: [PATCH 296/347] Adjust metrics to the new specifications (#5937) * Add `AnalyticsTransactions` with a set of `TransactionDefinition` items matching those in the user story * Use that for `AnalyticsLongRunningTransactions`, make sure we send the right fields (name, operation, description) * Add `AnalyticsSendMessageWatcher` to track how long it takes for an event to be sent and for us to get a call back for that from sync * Add `Noop` implementation for enterprise --- appnav/build.gradle.kts | 1 + .../io/element/android/appnav/RootFlowNode.kt | 2 +- .../android/appnav/di/TimelineBindings.kt | 2 + .../android/appnav/room/RoomFlowNode.kt | 4 +- .../room/joined/JoinedRoomLoadedFlowNode.kt | 4 + .../appnav/JoinedRoomLoadedFlowNodeTest.kt | 22 ++++- .../impl/timeline/TimelinePresenter.kt | 4 +- .../FakePinnedEventsTimelineProvider.kt | 19 +++++ .../libraries/matrix/api/room/JoinedRoom.kt | 5 ++ .../matrix/api/room/SendQueueUpdate.kt | 22 +++++ .../matrix/impl/room/JoinedRustRoom.kt | 13 +++ .../matrix/impl/room/SendQueueUpdatesExt.kt | 29 +++++++ .../matrix/test/room/FakeJoinedRoom.kt | 12 +++ .../api/AnalyticsLongRunningTransaction.kt | 21 +++-- .../analytics/api/AnalyticsService.kt | 7 +- .../watchers/AnalyticsSendMessageWatcher.kt | 23 ++++++ .../analytics/impl/DefaultAnalyticsService.kt | 8 +- .../DefaultAnalyticsColdStartWatcher.kt | 6 +- .../DefaultAnalyticsRoomListStateWatcher.kt | 4 +- .../DefaultAnalyticsSendMessageWatcher.kt | 82 +++++++++++++++++++ .../DefaultAnalyticsColdStartWatcherTest.kt | 14 ++-- ...efaultAnalyticsRoomListStateWatcherTest.kt | 14 ++-- .../DefaultAnalyticsSendMessageWatcherTest.kt | 66 +++++++++++++++ .../analytics/noop/NoopAnalyticsService.kt | 2 +- .../NoopAnalyticsSendMessageWatcher.kt | 18 ++++ .../analytics/test/FakeAnalyticsService.kt | 7 +- .../FakeAnalyticsSendMessageWatcher.kt | 18 ++++ .../api/AnalyticsProvider.kt | 2 +- .../api/AnalyticsTransactions.kt | 46 +++++++++++ .../posthog/PosthogAnalyticsProvider.kt | 2 +- .../sentry/SentryAnalyticsProvider.kt | 4 +- .../sentry/SentryAnalyticsTransaction.kt | 6 +- .../test/FakeAnalyticsProvider.kt | 2 +- 33 files changed, 443 insertions(+), 48 deletions(-) create mode 100644 features/messages/test/src/main/kotlin/io/element/android/features/messages/test/pinned/FakePinnedEventsTimelineProvider.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/SendQueueUpdate.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/SendQueueUpdatesExt.kt create mode 100644 services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsSendMessageWatcher.kt create mode 100644 services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsSendMessageWatcher.kt create mode 100644 services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsSendMessageWatcherTest.kt create mode 100644 services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsSendMessageWatcher.kt create mode 100644 services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/watchers/FakeAnalyticsSendMessageWatcher.kt create mode 100644 services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransactions.kt diff --git a/appnav/build.gradle.kts b/appnav/build.gradle.kts index 84d614b3d9..8bc821f933 100644 --- a/appnav/build.gradle.kts +++ b/appnav/build.gradle.kts @@ -63,6 +63,7 @@ dependencies { testImplementation(projects.libraries.push.test) testImplementation(projects.libraries.pushproviders.test) testImplementation(projects.features.forward.test) + testImplementation(projects.features.messages.test) testImplementation(projects.features.networkmonitor.test) testImplementation(projects.features.rageshake.test) testImplementation(projects.services.appnavstate.impl) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 4687946367..1ec1678d71 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -320,7 +320,7 @@ class RootFlowNode( is ResolvedIntent.Navigation -> { val openingRoomFromNotification = intent.getBooleanExtra(ROOM_OPENED_FROM_NOTIFICATION, false) if (openingRoomFromNotification && resolvedIntent.deeplinkData is DeeplinkData.Room) { - analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationTapOpensTimeline) + analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationToMessage) } navigateTo(resolvedIntent.deeplinkData) } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/di/TimelineBindings.kt b/appnav/src/main/kotlin/io/element/android/appnav/di/TimelineBindings.kt index cb78760a0f..371b067637 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/di/TimelineBindings.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/di/TimelineBindings.kt @@ -10,8 +10,10 @@ package io.element.android.appnav.di import io.element.android.features.messages.api.pinned.PinnedEventsTimelineProvider import io.element.android.libraries.matrix.api.timeline.TimelineProvider +import io.element.android.services.analytics.api.watchers.AnalyticsSendMessageWatcher interface TimelineBindings { val timelineProvider: TimelineProvider val pinnedEventsTimelineProvider: PinnedEventsTimelineProvider + val analyticsSendMessageWatcher: AnalyticsSendMessageWatcher } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt index 1bf3516900..6446f754b0 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt @@ -49,7 +49,7 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias import io.element.android.libraries.matrix.ui.room.LoadingRoomState import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadJoinedRoomFlow -import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationToMessage import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.flow.SharingStarted @@ -128,7 +128,7 @@ class RoomFlowNode( override fun onBuilt() { super.onBuilt() - val parentTransaction = analyticsService.getLongRunningTransaction(NotificationTapOpensTimeline) + val parentTransaction = analyticsService.getLongRunningTransaction(NotificationToMessage) val openRoomTransaction = analyticsService.startLongRunningTransaction(OpenRoom, parentTransaction) analyticsService.startLongRunningTransaction(LoadJoinedRoomFlow, openRoomTransaction) resolveRoomId() diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt index 0b3ba57776..05ebab2b10 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt @@ -98,6 +98,8 @@ class JoinedRoomLoadedFlowNode( private val callback: Callback = callback() override val graph = roomGraphFactory.create(inputs.room) + private val sendMessageWatcher = (graph as? TimelineBindings)?.analyticsSendMessageWatcher + // This is an ugly hack to check activity recreation private var currentActivity: Activity? = null @@ -109,6 +111,7 @@ class JoinedRoomLoadedFlowNode( Timber.v("OnCreate => ${inputs.room.roomId}") appNavigationStateService.onNavigateToRoom(id, inputs.room.roomId) activeRoomsHolder.addRoom(inputs.room) + sendMessageWatcher?.start() fetchRoomMembers() trackVisitedRoom() }, @@ -120,6 +123,7 @@ class JoinedRoomLoadedFlowNode( }, onDestroy = { Timber.v("OnDestroy") + sendMessageWatcher?.stop() // If we're just going through an activity recreation there's no need to destroy the Room object // Destroying it would actually cause an issue where its methods can no longer be called if (currentActivity?.isChangingConfigurations != true) { diff --git a/appnav/src/test/kotlin/io/element/android/appnav/JoinedRoomLoadedFlowNodeTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/JoinedRoomLoadedFlowNodeTest.kt index 6cd7df025b..8d514a2c0f 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/JoinedRoomLoadedFlowNodeTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/JoinedRoomLoadedFlowNodeTest.kt @@ -19,22 +19,29 @@ import com.bumble.appyx.testing.junit4.util.MainDispatcherRule import com.bumble.appyx.testing.unit.common.helper.parentNodeTestHelper import com.google.common.truth.Truth.assertThat import io.element.android.appnav.di.RoomGraphFactory +import io.element.android.appnav.di.TimelineBindings import io.element.android.appnav.room.RoomNavigationTarget import io.element.android.appnav.room.joined.FakeJoinedRoomLoadedFlowNodeCallback import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode import io.element.android.features.forward.api.ForwardEntryPoint import io.element.android.features.forward.test.FakeForwardEntryPoint import io.element.android.features.messages.api.MessagesEntryPoint +import io.element.android.features.messages.api.pinned.PinnedEventsTimelineProvider +import io.element.android.features.messages.test.pinned.FakePinnedEventsTimelineProvider import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint import io.element.android.features.space.api.SpaceEntryPoint import io.element.android.libraries.architecture.childNode import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.timeline.TimelineProvider import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.timeline.FakeTimelineProvider +import io.element.android.services.analytics.api.watchers.AnalyticsSendMessageWatcher import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.services.analytics.test.watchers.FakeAnalyticsSendMessageWatcher import io.element.android.services.appnavstate.api.ActiveRoomsHolder import io.element.android.services.appnavstate.impl.DefaultActiveRoomsHolder import io.element.android.services.appnavstate.test.FakeAppNavigationStateService @@ -72,9 +79,20 @@ class JoinedRoomLoadedFlowNodeTest { } } - private class FakeRoomGraphFactory : RoomGraphFactory { + private class FakeRoomGraphFactory( + private val timelineProvider: FakeTimelineProvider = FakeTimelineProvider(), + private val pinnedEventsTimelineProvider: FakePinnedEventsTimelineProvider = FakePinnedEventsTimelineProvider(), + private val analyticsSendMessageWatcher: FakeAnalyticsSendMessageWatcher = FakeAnalyticsSendMessageWatcher(), + ) : RoomGraphFactory { override fun create(room: JoinedRoom): Any { - return Unit + return object : TimelineBindings { + override val timelineProvider: TimelineProvider + get() = this@FakeRoomGraphFactory.timelineProvider + override val pinnedEventsTimelineProvider: PinnedEventsTimelineProvider + get() = this@FakeRoomGraphFactory.pinnedEventsTimelineProvider + override val analyticsSendMessageWatcher: AnalyticsSendMessageWatcher + get() = this@FakeRoomGraphFactory.analyticsSendMessageWatcher + } } } 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 5bafaf3e88..fd7d200a52 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 @@ -56,7 +56,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin import io.element.android.libraries.preferences.api.store.SessionPreferencesStore import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.DisplayFirstTimelineItems -import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationToMessage import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.finishLongRunningTransaction @@ -205,7 +205,7 @@ class TimelinePresenter( }.start() is TimelineEvents.OnFocusEventRender -> { // If there was a pending 'notification tap opens timeline' transaction, finish it now we're focused in the required event - analyticsService.finishLongRunningTransaction(NotificationTapOpensTimeline) + analyticsService.finishLongRunningTransaction(NotificationToMessage) focusRequestState.value = focusRequestState.value.onFocusEventRender() } diff --git a/features/messages/test/src/main/kotlin/io/element/android/features/messages/test/pinned/FakePinnedEventsTimelineProvider.kt b/features/messages/test/src/main/kotlin/io/element/android/features/messages/test/pinned/FakePinnedEventsTimelineProvider.kt new file mode 100644 index 0000000000..cb90db29af --- /dev/null +++ b/features/messages/test/src/main/kotlin/io/element/android/features/messages/test/pinned/FakePinnedEventsTimelineProvider.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.features.messages.test.pinned + +import io.element.android.features.messages.api.pinned.PinnedEventsTimelineProvider +import io.element.android.libraries.matrix.api.timeline.Timeline +import io.element.android.libraries.matrix.test.timeline.FakeTimelineProvider +import kotlinx.coroutines.flow.StateFlow + +class FakePinnedEventsTimelineProvider( + private val fakeTimelineProvider: FakeTimelineProvider = FakeTimelineProvider(), +) : PinnedEventsTimelineProvider { + override fun activeTimelineFlow(): StateFlow = fakeTimelineProvider.activeTimelineFlow() +} 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 1cfcfc46f2..b804bdf46d 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 @@ -177,4 +177,9 @@ interface JoinedRoom : BaseRoom { * */ suspend fun withdrawVerificationAndResend(userIds: List, sendHandle: SendHandle): Result + + /** + * Subscribe to a [Flow] of [SendQueueUpdate] related to this room. + */ + fun subscribeToSendQueueUpdates(): Flow } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/SendQueueUpdate.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/SendQueueUpdate.kt new file mode 100644 index 0000000000..41e1e5643b --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/SendQueueUpdate.kt @@ -0,0 +1,22 @@ +/* + * 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 + +import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.TransactionId +import io.element.android.libraries.matrix.api.media.MediaSource + +sealed interface SendQueueUpdate { + data class NewLocalEvent(val transactionId: TransactionId) : SendQueueUpdate + data class CancelledLocalEvent(val transactionId: TransactionId) : SendQueueUpdate + data class ReplacedLocalEvent(val transactionId: TransactionId) : SendQueueUpdate + data class SendError(val transactionId: TransactionId) : SendQueueUpdate + data class RetrySendingEvent(val transactionId: TransactionId) : SendQueueUpdate + data class SentEvent(val transactionId: TransactionId, val eventId: EventId) : SendQueueUpdate + data class MediaUpload(val relatedTo: EventId, val file: MediaSource?, val index: Long, val progress: Float) : SendQueueUpdate +} 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 770efb3918..00d4175ee3 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 @@ -26,6 +26,7 @@ import io.element.android.libraries.matrix.api.room.CreateTimelineParams import io.element.android.libraries.matrix.api.room.IntentionalMention import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomNotificationSettingsState +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 @@ -66,6 +67,8 @@ import org.matrix.rustcomponents.sdk.DateDividerMode import org.matrix.rustcomponents.sdk.IdentityStatusChangeListener import org.matrix.rustcomponents.sdk.KnockRequestsListener import org.matrix.rustcomponents.sdk.RoomMessageEventMessageType +import org.matrix.rustcomponents.sdk.RoomSendQueueUpdate +import org.matrix.rustcomponents.sdk.SendQueueListener import org.matrix.rustcomponents.sdk.TimelineConfiguration import org.matrix.rustcomponents.sdk.TimelineFilter import org.matrix.rustcomponents.sdk.TimelineFocus @@ -486,6 +489,16 @@ class JoinedRustRoom( } } + override fun subscribeToSendQueueUpdates(): Flow { + return mxCallbackFlow { + innerRoom.subscribeToSendQueueUpdates(object : SendQueueListener { + override fun onUpdate(update: RoomSendQueueUpdate) { + trySend(update.map()) + } + }) + } + } + override fun close() = destroy() override fun destroy() { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/SendQueueUpdatesExt.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/SendQueueUpdatesExt.kt new file mode 100644 index 0000000000..efc723e1df --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/SendQueueUpdatesExt.kt @@ -0,0 +1,29 @@ +/* + * 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 + +import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.TransactionId +import io.element.android.libraries.matrix.api.room.SendQueueUpdate +import io.element.android.libraries.matrix.impl.media.map +import org.matrix.rustcomponents.sdk.RoomSendQueueUpdate + +fun RoomSendQueueUpdate.map(): SendQueueUpdate = when (this) { + is RoomSendQueueUpdate.NewLocalEvent -> SendQueueUpdate.NewLocalEvent(TransactionId(transactionId)) + is RoomSendQueueUpdate.CancelledLocalEvent -> SendQueueUpdate.CancelledLocalEvent(TransactionId(transactionId)) + is RoomSendQueueUpdate.MediaUpload -> SendQueueUpdate.MediaUpload( + relatedTo = EventId(relatedTo), + file = file?.map(), + index = index.toLong(), + progress = progress.current.toFloat() / progress.total.toFloat(), + ) + is RoomSendQueueUpdate.ReplacedLocalEvent -> SendQueueUpdate.ReplacedLocalEvent(TransactionId(transactionId)) + is RoomSendQueueUpdate.RetryEvent -> SendQueueUpdate.RetrySendingEvent(TransactionId(transactionId)) + is RoomSendQueueUpdate.SendError -> SendQueueUpdate.SendError(TransactionId(transactionId)) + is RoomSendQueueUpdate.SentEvent -> SendQueueUpdate.SentEvent(TransactionId(transactionId), EventId(eventId)) +} 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 2d9694c909..9c97e7787b 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 @@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomMembersState import io.element.android.libraries.matrix.api.room.RoomNotificationSettingsState +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 @@ -39,6 +40,7 @@ import io.element.android.tests.testutils.simulateLongTask import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.test.TestScope @@ -83,6 +85,8 @@ class FakeJoinedRoom( private val updateJoinRuleResult: (JoinRule) -> Result = { lambdaError() }, private val setSendQueueEnabledResult: (Boolean) -> Unit = { _: Boolean -> }, ) : JoinedRoom, BaseRoom by baseRoom { + private val sendQueueUpdates = MutableSharedFlow(extraBufferCapacity = 10) + fun givenRoomMembersState(state: RoomMembersState) { baseRoom.givenRoomMembersState(state) } @@ -219,6 +223,10 @@ class FakeJoinedRoom( withdrawVerificationAndResendResult(userIds, sendHandle) } + override fun subscribeToSendQueueUpdates(): Flow { + return sendQueueUpdates + } + private suspend fun simulateSendMediaProgress(progressCallback: ProgressCallback?) { progressCallbackValues.forEach { (current, total) -> progressCallback?.onProgress(current, total) @@ -229,4 +237,8 @@ class FakeJoinedRoom( fun emitSyncUpdate() { (syncUpdateFlow as MutableStateFlow).value = syncUpdateFlow.value + 1 } + + suspend fun givenSendQueueUpdate(sendQueueUpdate: SendQueueUpdate) { + sendQueueUpdates.emit(sendQueueUpdate) + } } diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt index b318807a45..9c991cfce2 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt @@ -7,15 +7,24 @@ package io.element.android.services.analytics.api +import io.element.android.services.analyticsproviders.api.AnalyticsTransactions +import io.element.android.services.analyticsproviders.api.TransactionDefinition + sealed class AnalyticsLongRunningTransaction( val name: String, - val operation: String?, + val operation: String? = null, + val description: String? = null, ) { - data object ColdStartUntilCachedRoomList : AnalyticsLongRunningTransaction("Cold start until cached room list is displayed", null) - data object FirstRoomsDisplayed : AnalyticsLongRunningTransaction("First rooms displayed after login or restoration", null) - data object ResumeAppUntilNewRoomsReceived : AnalyticsLongRunningTransaction("App was resumed and new room list items arrived", null) - data object NotificationTapOpensTimeline : AnalyticsLongRunningTransaction("A notification was tapped and it opened a timeline", null) - data object OpenRoom : AnalyticsLongRunningTransaction("Open a room and see loaded items in the timeline", null) + constructor(definition: TransactionDefinition) : this(definition.name, definition.operation, definition.description) + + // UX flows + data object ColdStart : AnalyticsLongRunningTransaction(AnalyticsTransactions.coldStart) + data object CatchUp : AnalyticsLongRunningTransaction(AnalyticsTransactions.catchUp) + data object NotificationToMessage : AnalyticsLongRunningTransaction(AnalyticsTransactions.notificationToMessage) + data object OpenRoom : AnalyticsLongRunningTransaction(AnalyticsTransactions.openRoom) + + // Technical flows + data object FirstRoomsDisplayed : AnalyticsLongRunningTransaction("First rooms displayed after login or restoration", null, null) data object LoadJoinedRoomFlow : AnalyticsLongRunningTransaction("Load joined room UI", "ui.load") data object LoadMessagesUi : AnalyticsLongRunningTransaction("Load messages UI", "ui.load") data object DisplayFirstTimelineItems : AnalyticsLongRunningTransaction("Get and display first timeline items", null) diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt index 365300d679..1449977d91 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt @@ -53,7 +53,7 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker { /** * Starts a transaction to measure the performance of an operation. */ - fun startTransaction(name: String, operation: String? = null): AnalyticsTransaction + fun startTransaction(name: String, operation: String? = null, description: String? = null): AnalyticsTransaction /** * Starts an [AnalyticsLongRunningTransaction], that can be shared with other components. @@ -80,11 +80,12 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker { inline fun AnalyticsService.recordTransaction( name: String, operation: String, + description: String? = null, parentTransaction: AnalyticsTransaction? = null, block: (AnalyticsTransaction) -> T ): T { - val transaction = parentTransaction?.startChild(name, operation) - ?: startTransaction(name, operation) + val transaction = parentTransaction?.startChild(operation, description) + ?: startTransaction(name, operation, description) try { val result = block(transaction) return result diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsSendMessageWatcher.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsSendMessageWatcher.kt new file mode 100644 index 0000000000..4c3010f22e --- /dev/null +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsSendMessageWatcher.kt @@ -0,0 +1,23 @@ +/* + * 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.services.analytics.api.watchers + +/** + * An analytics watcher tracking the time it took the client to send a message. + */ +interface AnalyticsSendMessageWatcher { + /** + * Start listening to send queue updates and tracking the sending states of the events. + */ + fun start() + + /** + * Stop observing the sending states of the events. + */ + fun stop() +} diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt index 5db1eb1b31..64fdb1b3cd 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt @@ -161,9 +161,9 @@ class DefaultAnalyticsService( } } - override fun startTransaction(name: String, operation: String?): AnalyticsTransaction { + override fun startTransaction(name: String, operation: String?, description: String?): AnalyticsTransaction { return if (userConsent.get()) { - analyticsProviders.firstNotNullOfOrNull { it.startTransaction(name, operation) } + analyticsProviders.firstNotNullOfOrNull { it.startTransaction(name, operation, description) } } else { null } ?: NoopAnalyticsTransaction @@ -173,8 +173,8 @@ class DefaultAnalyticsService( longRunningTransaction: AnalyticsLongRunningTransaction, parentTransaction: AnalyticsTransaction?, ): AnalyticsTransaction { - val transaction = parentTransaction?.startChild(longRunningTransaction.name, longRunningTransaction.operation) - ?: startTransaction(longRunningTransaction.name, longRunningTransaction.operation) + val transaction = parentTransaction?.startChild(longRunningTransaction.operation.orEmpty(), longRunningTransaction.name) + ?: startTransaction(longRunningTransaction.name, longRunningTransaction.operation, longRunningTransaction.description) pendingLongRunningTransactions[longRunningTransaction] = transaction return transaction diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt index c53e28918b..e596bc35a5 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt @@ -37,7 +37,7 @@ class DefaultAnalyticsColdStartWatcher( if (hasConsent) { if (isColdStart.get()) { Timber.d("Starting cold start check") - analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) + analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStart) } else { error("The app is no longer in a cold start state") } @@ -49,7 +49,7 @@ class DefaultAnalyticsColdStartWatcher( override fun whenLoggingIn() { if (isColdStart.getAndSet(false)) { - analyticsService.cancelLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) + analyticsService.cancelLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStart) Timber.d("Canceled cold start check: user is logging in") } } @@ -57,7 +57,7 @@ class DefaultAnalyticsColdStartWatcher( override fun onRoomListVisible() { if (isColdStart.getAndSet(false)) { Timber.d("Room list is visible, finishing cold start check") - analyticsService.finishLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) + analyticsService.finishLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStart) } } } diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt index 97e438fcee..7e11e703ec 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt @@ -52,7 +52,7 @@ class DefaultAnalyticsRoomListStateWatcher( .withPreviousValue() .onEach { (wasInForeground, isInForeground) -> if (isInForeground && roomListService.state.value != RoomListService.State.Running) { - analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived) + analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.CatchUp) } if (wasInForeground == false && isInForeground) { @@ -64,7 +64,7 @@ class DefaultAnalyticsRoomListStateWatcher( roomListService.state .onEach { state -> if (state == RoomListService.State.Running && isWarmState.get()) { - analyticsService.finishLongRunningTransaction(AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived) + analyticsService.finishLongRunningTransaction(AnalyticsLongRunningTransaction.CatchUp) } } .launchIn(coroutineScope) diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsSendMessageWatcher.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsSendMessageWatcher.kt new file mode 100644 index 0000000000..642107cdec --- /dev/null +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsSendMessageWatcher.kt @@ -0,0 +1,82 @@ +/* + * 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.services.analytics.impl.watchers + +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.SingleIn +import io.element.android.libraries.di.RoomScope +import io.element.android.libraries.di.annotations.RoomCoroutineScope +import io.element.android.libraries.matrix.api.core.TransactionId +import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.libraries.matrix.api.room.SendQueueUpdate +import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.watchers.AnalyticsSendMessageWatcher +import io.element.android.services.analyticsproviders.api.AnalyticsTransaction +import io.element.android.services.analyticsproviders.api.AnalyticsTransactions +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import timber.log.Timber +import java.util.concurrent.ConcurrentHashMap + +private const val TAG = "SendMessageWatcher" + +@SingleIn(RoomScope::class) +@ContributesBinding(RoomScope::class) +class DefaultAnalyticsSendMessageWatcher( + private val room: JoinedRoom, + private val analyticsService: AnalyticsService, + @RoomCoroutineScope private val coroutineScope: CoroutineScope, +) : AnalyticsSendMessageWatcher { + private val pendingEvents = ConcurrentHashMap() + private var sendQueueWatchJob: Job? = null + + @OptIn(ExperimentalCoroutinesApi::class) + override fun start() { + Timber.tag(TAG).d("Starting SendMessageWatcher") + sendQueueWatchJob?.cancel() + sendQueueWatchJob = room.subscribeToSendQueueUpdates() + .onEach { update -> + // We received a new local event + when (update) { + is SendQueueUpdate.NewLocalEvent -> { + Timber.tag(TAG).d("Event with transaction id ${update.transactionId} sent") + watch(update.transactionId) + } + is SendQueueUpdate.SentEvent -> { + val pendingTransaction = pendingEvents.remove(update.transactionId) + if (pendingTransaction != null) { + Timber.tag(TAG).d("Sent event with transaction id ${update.transactionId} received in sync") + pendingTransaction.finish() + } + } + else -> Unit + } + } + .launchIn(coroutineScope) + } + + override fun stop() { + Timber.tag(TAG).d("Stopping SendMessageWatcher") + sendQueueWatchJob?.cancel() + sendQueueWatchJob = null + pendingEvents.clear() + } + + private fun watch(transactionId: TransactionId) { + pendingEvents[transactionId] = with(AnalyticsTransactions.sendMessage) { + analyticsService.startTransaction( + name = name, + operation = operation, + description = description, + ) + } + } +} diff --git a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcherTest.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcherTest.kt index 325316b45c..88d6be010f 100644 --- a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcherTest.kt +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcherTest.kt @@ -8,7 +8,7 @@ package io.element.android.services.analytics.impl.watchers import com.google.common.truth.Truth.assertThat -import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ColdStart import io.element.android.services.analytics.test.FakeAnalyticsService import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope @@ -31,14 +31,14 @@ class DefaultAnalyticsColdStartWatcherTest { runCurrent() // The transaction is running - assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNotNull() + assertThat(analyticsService.getLongRunningTransaction(ColdStart)).isNotNull() // As soon as the room list is visible watcher.onRoomListVisible() runCurrent() // The transaction is now finished - assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNull() + assertThat(analyticsService.getLongRunningTransaction(ColdStart)).isNull() } @Test @@ -54,14 +54,14 @@ class DefaultAnalyticsColdStartWatcherTest { runCurrent() // The transaction is running - assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNotNull() + assertThat(analyticsService.getLongRunningTransaction(ColdStart)).isNotNull() // If the user starts a login flow watcher.whenLoggingIn() runCurrent() // The transaction is gone - assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNull() + assertThat(analyticsService.getLongRunningTransaction(ColdStart)).isNull() } @Test @@ -80,7 +80,7 @@ class DefaultAnalyticsColdStartWatcherTest { runCurrent() // The transaction never starts - assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNull() + assertThat(analyticsService.getLongRunningTransaction(ColdStart)).isNull() } @Test @@ -95,7 +95,7 @@ class DefaultAnalyticsColdStartWatcherTest { runCurrent() // The transaction is not running in that case - assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNull() + assertThat(analyticsService.getLongRunningTransaction(ColdStart)).isNull() } private fun TestScope.createAnalyticsColdStartWatcher( diff --git a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcherTest.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcherTest.kt index 3b1f562c67..8796d6a2ee 100644 --- a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcherTest.kt +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcherTest.kt @@ -10,7 +10,7 @@ package io.element.android.services.analytics.impl.watchers import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService -import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.CatchUp import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.appnavstate.api.AppNavigationState import io.element.android.services.appnavstate.api.NavigationState @@ -49,14 +49,14 @@ class DefaultAnalyticsRoomListStateWatcherTest { runCurrent() // The transaction should be present now - assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNotNull() + assertThat(analyticsService.getLongRunningTransaction(CatchUp)).isNotNull() // And now the room list service running roomListService.postState(RoomListService.State.Running) runCurrent() // And the transaction should now be gone - assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNull() + assertThat(analyticsService.getLongRunningTransaction(CatchUp)).isNull() watcher.stop() } @@ -86,7 +86,7 @@ class DefaultAnalyticsRoomListStateWatcherTest { runCurrent() // The transaction was never present - assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNull() + assertThat(analyticsService.getLongRunningTransaction(CatchUp)).isNull() watcher.stop() } @@ -116,12 +116,12 @@ class DefaultAnalyticsRoomListStateWatcherTest { runCurrent() // The transaction should be present now - assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNotNull() + assertThat(analyticsService.getLongRunningTransaction(CatchUp)).isNotNull() runCurrent() // But without the room list syncing, it never finishes - assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNotNull() + assertThat(analyticsService.getLongRunningTransaction(CatchUp)).isNotNull() watcher.stop() } @@ -151,7 +151,7 @@ class DefaultAnalyticsRoomListStateWatcherTest { runCurrent() // The transaction was never added - assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNull() + assertThat(analyticsService.getLongRunningTransaction(CatchUp)).isNull() watcher.stop() } diff --git a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsSendMessageWatcherTest.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsSendMessageWatcherTest.kt new file mode 100644 index 0000000000..b0e996c4c0 --- /dev/null +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsSendMessageWatcherTest.kt @@ -0,0 +1,66 @@ +/* + * 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.services.analytics.impl.watchers + +import io.element.android.libraries.matrix.api.room.SendQueueUpdate +import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.A_TRANSACTION_ID +import io.element.android.libraries.matrix.test.room.FakeJoinedRoom +import io.element.android.services.analytics.api.NoopAnalyticsTransaction +import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) +class DefaultAnalyticsSendMessageWatcherTest { + @Test + fun `test start listens to send queue updates`() = runTest { + val mockedTransaction = mockk(relaxed = true) + val startTransactionRecorder = lambdaRecorder { _: String, _: String?, _: String? -> mockedTransaction } + val room = FakeJoinedRoom() + val analyticsService = FakeAnalyticsService(startTransactionLambda = startTransactionRecorder) + + val watcher = createDefaultAnalyticsSendMessageWatcher(room = room, analyticsService = analyticsService) + + // When we start listening, we don't trigger any analyticsService.startTransaction calls + watcher.start() + runCurrent() + + startTransactionRecorder.assertions().isNeverCalled() + + // When we receive a new local event, we start a new transaction for it + room.givenSendQueueUpdate(SendQueueUpdate.NewLocalEvent(A_TRANSACTION_ID)) + runCurrent() + + startTransactionRecorder.assertions().isCalledOnce() + + // And we receive an 'event sent' update with the event's id, we finish the transaction + room.givenSendQueueUpdate(SendQueueUpdate.SentEvent(A_TRANSACTION_ID, AN_EVENT_ID)) + runCurrent() + + verify { mockedTransaction.finish() } + + // We also stop the watcher for cleanup + watcher.stop() + } + + private fun TestScope.createDefaultAnalyticsSendMessageWatcher( + room: FakeJoinedRoom = FakeJoinedRoom(), + analyticsService: FakeAnalyticsService = FakeAnalyticsService(), + ) = DefaultAnalyticsSendMessageWatcher( + room = room, + analyticsService = analyticsService, + coroutineScope = backgroundScope, + ) +} diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt index 004a472de3..b0c6d29b63 100644 --- a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt @@ -40,7 +40,7 @@ class NoopAnalyticsService : AnalyticsService { override fun updateUserProperties(userProperties: UserProperties) = Unit override fun trackError(throwable: Throwable) = Unit override fun updateSuperProperties(updatedProperties: SuperProperties) = Unit - override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction + override fun startTransaction(name: String, operation: String?, description: String?): AnalyticsTransaction = NoopAnalyticsTransaction override fun startLongRunningTransaction( longRunningTransaction: AnalyticsLongRunningTransaction, parentTransaction: AnalyticsTransaction?, diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsSendMessageWatcher.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsSendMessageWatcher.kt new file mode 100644 index 0000000000..6e9bf8058f --- /dev/null +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsSendMessageWatcher.kt @@ -0,0 +1,18 @@ +/* + * 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.services.analytics.noop.watchers + +import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.di.RoomScope +import io.element.android.services.analytics.api.watchers.AnalyticsSendMessageWatcher + +@ContributesBinding(RoomScope::class) +class NoopAnalyticsSendMessageWatcher : AnalyticsSendMessageWatcher { + override fun start() = Unit + override fun stop() = Unit +} diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt index b9b33744e8..f0dd9e0d4a 100644 --- a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt +++ b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt @@ -26,6 +26,7 @@ import kotlinx.coroutines.flow.asStateFlow class FakeAnalyticsService( isEnabled: Boolean = false, didAskUserConsent: Boolean = false, + private val startTransactionLambda: (String, String?, String?) -> AnalyticsTransaction = { _, _, _ -> NoopAnalyticsTransaction }, ) : AnalyticsService { private val isEnabledFlow = MutableStateFlow(isEnabled) override val didAskUserConsentFlow = MutableStateFlow(didAskUserConsent) @@ -72,7 +73,11 @@ class FakeAnalyticsService( // No op } - override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction + override fun startTransaction(name: String, operation: String?, description: String?): AnalyticsTransaction = startTransactionLambda( + name, + operation, + description + ) override fun startLongRunningTransaction( longRunningTransaction: AnalyticsLongRunningTransaction, parentTransaction: AnalyticsTransaction? diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/watchers/FakeAnalyticsSendMessageWatcher.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/watchers/FakeAnalyticsSendMessageWatcher.kt new file mode 100644 index 0000000000..6320e8522e --- /dev/null +++ b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/watchers/FakeAnalyticsSendMessageWatcher.kt @@ -0,0 +1,18 @@ +/* + * 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.services.analytics.test.watchers + +import io.element.android.services.analytics.api.watchers.AnalyticsSendMessageWatcher + +class FakeAnalyticsSendMessageWatcher( + private val startLambda: () -> Unit = {}, + private val stopLambda: () -> Unit = {}, +) : AnalyticsSendMessageWatcher { + override fun start() = startLambda() + override fun stop() = stopLambda() +} diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsProvider.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsProvider.kt index f90d924c81..593d62f40f 100644 --- a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsProvider.kt +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsProvider.kt @@ -21,5 +21,5 @@ interface AnalyticsProvider : AnalyticsTracker, ErrorTracker { fun stop() - fun startTransaction(name: String, operation: String? = null): AnalyticsTransaction? + fun startTransaction(name: String, operation: String? = null, description: String? = null): AnalyticsTransaction? } diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransactions.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransactions.kt new file mode 100644 index 0000000000..5e188263fa --- /dev/null +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransactions.kt @@ -0,0 +1,46 @@ +/* + * 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.services.analyticsproviders.api + +object AnalyticsTransactions { + val coldStart = TransactionDefinition( + name = "Cold start", + operation = "ux", + description = "Cold start until the cached room list is displayed", + ) + + val catchUp = TransactionDefinition( + name = "Catch-up", + operation = "ux", + description = "The app syncs and the room list becomes up-to-date", + ) + + val notificationToMessage = TransactionDefinition( + name = "Notification to message", + operation = "ux", + description = "A notification was tapped and it opened a timeline", + ) + + val openRoom = TransactionDefinition( + name = "Open a room", + operation = "ux", + description = "Open a room and see loaded items in the timeline", + ) + + val sendMessage = TransactionDefinition( + name = "Send a message", + operation = "ux", + description = "Send to sent state in timeline", + ) +} + +data class TransactionDefinition( + val name: String, + val operation: String? = null, + val description: String?, +) diff --git a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt index 9185b906c4..49edc9b1a0 100644 --- a/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt +++ b/services/analyticsproviders/posthog/src/main/kotlin/io/element/android/services/analyticsproviders/posthog/PosthogAnalyticsProvider.kt @@ -124,7 +124,7 @@ class PosthogAnalyticsProvider( return withSuperProperties.takeIf { it.isEmpty().not() } } - override fun startTransaction(name: String, operation: String?): AnalyticsTransaction? = null + override fun startTransaction(name: String, operation: String?, description: String?): AnalyticsTransaction? = null } private fun Map.keepOnlyNonNullValues(): Map { diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index 7545563736..f3e3f0c9e1 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -112,8 +112,8 @@ class SentryAnalyticsProvider( Sentry.captureException(throwable) } - override fun startTransaction(name: String, operation: String?): AnalyticsTransaction? { - return SentryAnalyticsTransaction(name, operation) + override fun startTransaction(name: String, operation: String?, description: String?): AnalyticsTransaction? { + return SentryAnalyticsTransaction(name, operation, description) } @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt index 84314ee35f..6477b2cc5c 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt @@ -14,7 +14,9 @@ import io.sentry.Sentry import timber.log.Timber class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTransaction { - constructor(name: String, operation: String?) : this(Sentry.startTransaction(name, operation.orEmpty())) + constructor(name: String, operation: String?, description: String? = null) : this( + Sentry.startTransaction(name, operation.orEmpty()).also { it.description = description } + ) private val inner = span override fun startChild(operation: String, description: String?): AnalyticsTransaction = SentryAnalyticsTransaction( @@ -30,7 +32,7 @@ class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTra } override fun finish() { val name = if (inner is ITransaction) inner.name else inner.operation - Timber.d("Finishing transaction: $name") + Timber.d("Finishing transaction: '$name'") inner.finish() } } diff --git a/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt b/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt index 9b0374bd9b..06a8f8e7aa 100644 --- a/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt +++ b/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt @@ -33,5 +33,5 @@ class FakeAnalyticsProvider( override fun updateUserProperties(userProperties: UserProperties) = updateUserPropertiesLambda(userProperties) override fun trackError(throwable: Throwable) = trackErrorLambda(throwable) override fun updateSuperProperties(updatedProperties: SuperProperties) = updateSuperPropertiesLambda(updatedProperties) - override fun startTransaction(name: String, operation: String?): AnalyticsTransaction? = null + override fun startTransaction(name: String, operation: String?, description: String?): AnalyticsTransaction? = null } From 2f119012ef530c2cd6fa638a2796625269bae930 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 18:12:43 +0100 Subject: [PATCH 297/347] fix(deps): update metro to v0.9.3 (#5967) * fix(deps): update metro to v0.9.3 * R8: allowshrinking to fix compilation issue. --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Benoit Marty --- app/proguard-rules.pro | 8 ++++---- gradle/libs.versions.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 9207e06edc..b09ecf69ca 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -66,10 +66,10 @@ -dontwarn androidx.window.sidecar.SidecarWindowLayoutInfo # Also needed after AGP 8.13.1 upgrade, it seems like proguard is now more aggressive on removing unused code --keep class org.matrix.rustcomponents.sdk.** { *;} --keep class uniffi.** { *;} --keep class io.element.android.x.di.** { *; } +-keep,allowshrinking class org.matrix.rustcomponents.sdk.** { *;} +-keep,allowshrinking class uniffi.** { *;} +-keep,allowshrinking class io.element.android.x.di.** { *; } -keepclasseswithmembernames,allowoptimization,allowshrinking class io.element.android.** { *; } # Keep Metro classes --keep class dev.zacsweers.metro.** { *; } +-keep,allowshrinking class dev.zacsweers.metro.** { *; } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 57ba97b8da..8541cf67e5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -52,7 +52,7 @@ haze = "1.7.1" dependencyAnalysis = "3.5.1" # DI -metro = "0.9.2" +metro = "0.9.3" # Auto service autoservice = "1.1.1" From f4528c9dd3792850c638ef08673529afcbec4c17 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 5 Jan 2026 18:12:56 +0100 Subject: [PATCH 298/347] Upgrade compose to 2025.12.01 (#5969) --- 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 8541cf67e5..fb55176b9e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ camera = "1.5.2" work = "2.11.0" # Compose -compose_bom = "2025.12.00" +compose_bom = "2025.12.01" # Coroutines coroutines = "1.10.2" From 2be6b6ce24779caef1695ce21fe268198672f5b8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 5 Jan 2026 20:01:21 +0100 Subject: [PATCH 299/347] quality: rename class --- .../impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt | 2 +- .../manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt index 3b52c2ac3f..dfb7d6c833 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt @@ -25,7 +25,7 @@ import io.element.android.libraries.di.RoomScope class ManageAuthorizedSpacesNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenterFactory: EditRoomAddressPresenter.Factory, + presenterFactory: ManageAuthorizedSpacesPresenter.Factory, ) : Node(buildContext, plugins = plugins) { private val navigator = plugins().first() private val presenter = presenterFactory.create(navigator) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt index 527393c9d3..c815bb91b7 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt @@ -21,14 +21,14 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom import kotlinx.collections.immutable.persistentListOf @AssistedInject -class EditRoomAddressPresenter( +class ManageAuthorizedSpacesPresenter( @Assisted private val navigator: SecurityAndPrivacyNavigator, private val client: MatrixClient, private val room: JoinedRoom, ) : Presenter { @AssistedFactory interface Factory { - fun create(navigator: SecurityAndPrivacyNavigator): EditRoomAddressPresenter + fun create(navigator: SecurityAndPrivacyNavigator): ManageAuthorizedSpacesPresenter } @Composable From 8e08c6108da3751dd0739270cf3435592bb6271b Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 5 Jan 2026 20:01:38 +0100 Subject: [PATCH 300/347] feature(security&privacy): make spaceSelection part of the state --- .../impl/root/SecurityAndPrivacyPresenter.kt | 18 +++++++++++------- .../impl/root/SecurityAndPrivacyState.kt | 1 + .../root/SecurityAndPrivacyStateProvider.kt | 2 ++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index d9038133e6..c1a7bbeb33 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -126,6 +126,12 @@ class SecurityAndPrivacyPresenter( value = (joinedParentSpaces + nonParentJoinedSpaces).toImmutableSet() } + val spaceSelection by remember { + derivedStateOf { + getSpaceSelection(selectableJoinedSpaces, savedSettings.roomAccess) + } + } + var showEnableEncryptionConfirmation by remember(savedSettings.isEncrypted) { mutableStateOf(false) } val permissions by room.permissionsAsState(SecurityAndPrivacyPermissions.DEFAULT) { perms -> perms.securityAndPrivacyPermissions() @@ -183,8 +189,7 @@ class SecurityAndPrivacyPresenter( } SecurityAndPrivacyEvent.ManageAuthorizedSpaces -> navigator.openManageAuthorizedSpaces() SecurityAndPrivacyEvent.SelectSpaceMemberAccess -> handleSpaceMemberAccessSelection( - selectableJoinedSpaces = selectableJoinedSpaces, - savedAccess = savedSettings.roomAccess, + spaceSelection = spaceSelection, editedAccess = editedRoomAccess, ) } @@ -206,6 +211,7 @@ class SecurityAndPrivacyPresenter( permissions = permissions, isSpace = roomInfo.isSpace, selectableJoinedSpaces = selectableJoinedSpaces, + spaceSelection = spaceSelection, eventSink = ::handleEvent, ) @@ -230,15 +236,13 @@ class SecurityAndPrivacyPresenter( } private fun handleSpaceMemberAccessSelection( - selectableJoinedSpaces: Set, - savedAccess: SecurityAndPrivacyRoomAccess, + spaceSelection: SpaceSelection, editedAccess: MutableState, ) { - if(editedAccess.value is SecurityAndPrivacyRoomAccess.SpaceMember) { + if (editedAccess.value is SecurityAndPrivacyRoomAccess.SpaceMember) { return } - val spaceSelection = getSpaceSelection(selectableJoinedSpaces, savedAccess) - when(spaceSelection){ + when (spaceSelection) { is SpaceSelection.None -> Unit is SpaceSelection.Multiple -> navigator.openManageAuthorizedSpaces() is SpaceSelection.Single -> { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index b71f375fe7..70a2a72179 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -30,6 +30,7 @@ data class SecurityAndPrivacyState( val isSpace: Boolean, private val permissions: SecurityAndPrivacyPermissions, private val selectableJoinedSpaces: ImmutableSet, + private val spaceSelection: SpaceSelection, val eventSink: (SecurityAndPrivacyEvent) -> Unit ) { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index 2c984fd16a..11c4054ac5 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -122,6 +122,7 @@ fun aSecurityAndPrivacyState( isKnockEnabled: Boolean = true, isSpace: Boolean = false, selectableJoinedSpaces: Set = emptySet(), + spaceSelection: SpaceSelection = SpaceSelection.None, eventSink: (SecurityAndPrivacyEvent) -> Unit = {} ) = SecurityAndPrivacyState( editedSettings = editedSettings, @@ -133,5 +134,6 @@ fun aSecurityAndPrivacyState( permissions = permissions, isSpace = isSpace, selectableJoinedSpaces = selectableJoinedSpaces.toImmutableSet(), + spaceSelection = SpaceSelection.None, eventSink = eventSink, ) From 96745c765ac09f1469989d786e1e883f7b50bc41 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 5 Jan 2026 21:20:26 +0100 Subject: [PATCH 301/347] feature(security&privacy): check SpaceSettings ff --- .../impl/root/SecurityAndPrivacyPresenter.kt | 5 +++++ .../impl/root/SecurityAndPrivacyState.kt | 1 + .../impl/root/SecurityAndPrivacyStateProvider.kt | 2 ++ .../impl/root/SecurityAndPrivacyView.kt | 11 ++++++++--- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index c1a7bbeb33..e025914801 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -72,6 +72,10 @@ class SecurityAndPrivacyPresenter( val isKnockEnabled by remember { featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock) }.collectAsState(false) + val isSpaceSettingsEnabled by remember { + featureFlagService.isFeatureEnabledFlow(FeatureFlags.SpaceSettings) + }.collectAsState(false) + val saveAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } val homeserverName = remember { matrixClient.userIdServerName() } val roomInfo by room.roomInfoFlow.collectAsState() @@ -210,6 +214,7 @@ class SecurityAndPrivacyPresenter( saveAction = saveAction.value, permissions = permissions, isSpace = roomInfo.isSpace, + isSpaceSettingsEnabled = isSpaceSettingsEnabled, selectableJoinedSpaces = selectableJoinedSpaces, spaceSelection = spaceSelection, eventSink = ::handleEvent, diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index 70a2a72179..bcbee0203d 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -26,6 +26,7 @@ data class SecurityAndPrivacyState( val homeserverName: String, val showEnableEncryptionConfirmation: Boolean, val isKnockEnabled: Boolean, + val isSpaceSettingsEnabled: Boolean, val saveAction: AsyncAction, val isSpace: Boolean, private val permissions: SecurityAndPrivacyPermissions, diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index 11c4054ac5..312043324e 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -123,6 +123,7 @@ fun aSecurityAndPrivacyState( isSpace: Boolean = false, selectableJoinedSpaces: Set = emptySet(), spaceSelection: SpaceSelection = SpaceSelection.None, + isSpaceSettingsEnabled: Boolean = true, eventSink: (SecurityAndPrivacyEvent) -> Unit = {} ) = SecurityAndPrivacyState( editedSettings = editedSettings, @@ -135,5 +136,6 @@ fun aSecurityAndPrivacyState( isSpace = isSpace, selectableJoinedSpaces = selectableJoinedSpaces.toImmutableSet(), spaceSelection = SpaceSelection.None, + isSpaceSettingsEnabled = isSpaceSettingsEnabled, eventSink = eventSink, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index dc8c349bbe..374a4e3911 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -50,7 +50,6 @@ import io.element.android.libraries.designsystem.text.stringWithLink import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator 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.ListSectionHeader 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.TextButton @@ -95,6 +94,7 @@ fun SecurityAndPrivacyView( edited = state.editedSettings.roomAccess, saved = state.savedSettings.roomAccess, isKnockEnabled = state.isKnockEnabled, + isSpaceSettingsEnabled = state.isSpaceSettingsEnabled, onSelectOption = { state.eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(it)) }, onManageSpacesClick = { state.eventSink(SecurityAndPrivacyEvent.ManageAuthorizedSpaces) }, onSpaceMemberAccessClick = { state.eventSink(SecurityAndPrivacyEvent.SelectSpaceMemberAccess) } @@ -214,6 +214,7 @@ private fun RoomAccessSection( edited: SecurityAndPrivacyRoomAccess, saved: SecurityAndPrivacyRoomAccess, isKnockEnabled: Boolean, + isSpaceSettingsEnabled: Boolean, onSelectOption: (SecurityAndPrivacyRoomAccess) -> Unit, onSpaceMemberAccessClick: () -> Unit, onManageSpacesClick: () -> Unit, @@ -230,7 +231,10 @@ private fun RoomAccessSection( leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Public())), onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.Anyone) }, ) - // Show space member option, but disabled as we don't support this option for now. + // Show SpaceMember option in two cases: + // - the SpaceSettings FF is enabled + // - SpaceMember is the current saved value + if (saved is SecurityAndPrivacyRoomAccess.SpaceMember || isSpaceSettingsEnabled) ListItem( headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_title)) }, supportingContent = { @@ -239,6 +243,7 @@ private fun RoomAccessSection( trailingContent = ListItemContent.RadioButton(selected = edited is SecurityAndPrivacyRoomAccess.SpaceMember), leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Space())), onClick = onSpaceMemberAccessClick, + enabled = isSpaceSettingsEnabled, ) // Show Ask to join option in two cases: // - the Knock FF is enabled @@ -264,7 +269,7 @@ private fun RoomAccessSection( val footerText = stringWithLink( textRes = R.string.screen_security_and_privacy_room_access_footer, url = stringResource(R.string.screen_security_and_privacy_room_access_footer_manage_spaces_action), - onLinkClick = { onManageSpacesClick()}, + onLinkClick = { onManageSpacesClick() }, ) Text( text = footerText, From 1930877a81241da06827e7b3bee9baf458797bdc Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 6 Jan 2026 15:15:38 +0100 Subject: [PATCH 302/347] feature(security&privacy): iterate on SpaceMember option --- .../impl/SecurityAndPrivacyFlowNode.kt | 21 ++++++- .../impl/SecurityAndPrivacyNavigator.kt | 7 ++- .../ManageAuthorizedSpacesEvent.kt | 1 + .../ManageAuthorizedSpacesNode.kt | 21 ++++++- .../ManageAuthorizedSpacesPresenter.kt | 35 ++++++++--- .../ManageAuthorizedSpacesState.kt | 14 +++-- .../ManageAuthorizedSpacesStateProvider.kt | 27 ++++++--- .../ManageAuthorizedSpacesView.kt | 10 ++-- .../impl/root/SecurityAndPrivacyNode.kt | 14 +++++ .../impl/root/SecurityAndPrivacyPresenter.kt | 43 +++++++------ .../impl/root/SecurityAndPrivacyState.kt | 60 ++++++++++++++++--- .../root/SecurityAndPrivacyStateProvider.kt | 5 +- .../impl/root/SecurityAndPrivacyView.kt | 56 +++++++++-------- 13 files changed, 226 insertions(+), 88 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index 844c4f1a70..d29a7ffd20 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -12,12 +12,14 @@ import android.os.Parcelable import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.lifecycle.Lifecycle +import androidx.lifecycle.coroutineScope import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.navmodel.backstack.BackStack +import com.bumble.appyx.navmodel.backstack.operation.pop import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode @@ -31,12 +33,15 @@ import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.RoomScope +import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.powerlevels.use +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize @ContributesNode(RoomScope::class) @@ -61,7 +66,7 @@ class SecurityAndPrivacyFlowNode( data object EditRoomAddress : NavTarget @Parcelize - data object ManageAuthorizedSpaces : NavTarget + data class ManageAuthorizedSpaces(val initialSelection: List) : NavTarget } private val callback: SecurityAndPrivacyEntryPoint.Callback = callback() @@ -83,6 +88,18 @@ class SecurityAndPrivacyFlowNode( callback.onDone() } } + whenChildrenAttached { commonLifecycle: Lifecycle, + securityAndPrivacyNode: SecurityAndPrivacyNode, + manageAuthorizedSpacesNode: ManageAuthorizedSpacesNode -> + commonLifecycle.coroutineScope.launch { + val authorizedSpacesData = securityAndPrivacyNode.getAuthorizedSpacesData() + val selectedSpaces = manageAuthorizedSpacesNode.waitForCompletion(authorizedSpacesData) + withContext(NonCancellable) { + backstack.pop() + securityAndPrivacyNode.onAuthorizedSpacesSelected(selectedSpaces) + } + } + } } override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { @@ -93,7 +110,7 @@ class SecurityAndPrivacyFlowNode( NavTarget.EditRoomAddress -> { createNode(buildContext, plugins = listOf(navigator)) } - NavTarget.ManageAuthorizedSpaces -> { + is NavTarget.ManageAuthorizedSpaces -> { createNode(buildContext, plugins = listOf(navigator)) } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt index 274bf0b823..da6ca379e8 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt @@ -13,12 +13,13 @@ import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.operation.pop import com.bumble.appyx.navmodel.backstack.operation.push import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint +import io.element.android.libraries.matrix.api.core.RoomId interface SecurityAndPrivacyNavigator : Plugin { fun onDone() fun openEditRoomAddress() fun closeEditRoomAddress() - fun openManageAuthorizedSpaces() + fun openManageAuthorizedSpaces(initialSelection: List) fun closeManageAuthorizedSpaces() } @@ -38,8 +39,8 @@ class BackstackSecurityAndPrivacyNavigator( backStack.pop() } - override fun openManageAuthorizedSpaces() { - backStack.push(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces) + override fun openManageAuthorizedSpaces(initialSelection: List) { + backStack.push(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces(initialSelection)) } override fun closeManageAuthorizedSpaces() { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt index 0515878ade..47abe2fbce 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt @@ -11,6 +11,7 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspac import io.element.android.libraries.matrix.api.core.RoomId sealed interface ManageAuthorizedSpacesEvent { + data class SetData(val data: AuthorizedSpacesSelection) : ManageAuthorizedSpacesEvent data object Done : ManageAuthorizedSpacesEvent data class ToggleSpace(val roomId: RoomId) : ManageAuthorizedSpacesEvent } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt index dfb7d6c833..5608c0ce16 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt @@ -9,6 +9,8 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node @@ -18,7 +20,12 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator +import io.element.android.libraries.architecture.NodeInputs +import io.element.android.libraries.architecture.appyx.launchMolecule import io.element.android.libraries.di.RoomScope +import io.element.android.libraries.matrix.api.core.RoomId +import kotlinx.collections.immutable.ImmutableList +import kotlinx.coroutines.flow.first @ContributesNode(RoomScope::class) @AssistedInject @@ -27,12 +34,24 @@ class ManageAuthorizedSpacesNode( @Assisted plugins: List, presenterFactory: ManageAuthorizedSpacesPresenter.Factory, ) : Node(buildContext, plugins = plugins) { + + data class Params( + val initialSelection: List + ) : NodeInputs + private val navigator = plugins().first() private val presenter = presenterFactory.create(navigator) + private val stateFlow = launchMolecule { presenter.present() } + + suspend fun waitForCompletion(data: AuthorizedSpacesSelection): ImmutableList { + stateFlow.value.eventSink(ManageAuthorizedSpacesEvent.SetData(data)) + return stateFlow.first { it.isSelectionComplete }.selectedIds + } + @Composable override fun View(modifier: Modifier) { - val state = presenter.present() + val state by stateFlow.collectAsState() ManageAuthorizedSpacesView( state = state, onBackClick = ::navigateUp, diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt index c815bb91b7..09869cdf09 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt @@ -9,16 +9,21 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +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.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.JoinedRoom +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList @AssistedInject class ManageAuthorizedSpacesPresenter( @@ -33,19 +38,33 @@ class ManageAuthorizedSpacesPresenter( @Composable override fun present(): ManageAuthorizedSpacesState { - val roomInfo by room.roomInfoFlow.collectAsState() + var currentSelection: ImmutableList by remember { mutableStateOf(persistentListOf()) } + var spacesData by remember { mutableStateOf(AuthorizedSpacesSelection()) } + var isSelectionComplete by remember { mutableStateOf(false) } + fun handleEvent(event: ManageAuthorizedSpacesEvent) { when (event) { - ManageAuthorizedSpacesEvent.Done -> TODO() - is ManageAuthorizedSpacesEvent.ToggleSpace -> TODO() + ManageAuthorizedSpacesEvent.Done -> { + isSelectionComplete = true + } + is ManageAuthorizedSpacesEvent.ToggleSpace -> { + currentSelection = if (currentSelection.contains(event.roomId)) { + currentSelection.minus(event.roomId).toPersistentList() + } else { + currentSelection.plus(event.roomId).toPersistentList() + } + } + is ManageAuthorizedSpacesEvent.SetData -> { + spacesData = event.data + currentSelection = event.data.initialSelectedIds + } } } return ManageAuthorizedSpacesState( - joinedSpaces = persistentListOf(), - unknownSpaceIds = persistentListOf(), - currentSelection = persistentListOf(), - initialSelection = persistentListOf(), + selection = spacesData, + selectedIds = currentSelection, + isSelectionComplete = isSelectionComplete, eventSink = ::handleEvent, ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt index 688ef6e6e9..7564fabae9 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt @@ -11,11 +11,17 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspac import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.spaces.SpaceRoom import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf data class ManageAuthorizedSpacesState( - val joinedSpaces: ImmutableList, - val unknownSpaceIds: ImmutableList, - val currentSelection: ImmutableList, - val initialSelection: ImmutableList, + val selection: AuthorizedSpacesSelection, + val selectedIds: ImmutableList, + val isSelectionComplete: Boolean, val eventSink: (ManageAuthorizedSpacesEvent) -> Unit ) + +data class AuthorizedSpacesSelection( + val joinedSpaces: ImmutableList = persistentListOf(), + val unknownSpaceIds: ImmutableList = persistentListOf(), + val initialSelectedIds: ImmutableList = persistentListOf() +) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt index d91e16f3e6..e232d02022 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt @@ -20,11 +20,15 @@ open class ManageAuthorizedSpacesStateProvider : PreviewParameterProvider { } } -private fun aManageAuthorizedSpacesState( +fun anAuthorizedSpacesData( joinedSpaces: List = aSpaceRoomList(5), unknownSpaceIds: List = emptyList(), - currentSelection: List = emptyList(), initialSelection: List = emptyList(), - eventSink: (ManageAuthorizedSpacesEvent) -> Unit = {}, -) = ManageAuthorizedSpacesState( +) = AuthorizedSpacesSelection( joinedSpaces = joinedSpaces.toImmutableList(), unknownSpaceIds = unknownSpaceIds.toImmutableList(), - currentSelection = currentSelection.toImmutableList(), - initialSelection = initialSelection.toImmutableList(), + initialSelectedIds = initialSelection.toImmutableList(), +) + +private fun aManageAuthorizedSpacesState( + authorizedSpacesData: AuthorizedSpacesSelection = anAuthorizedSpacesData(), + currentSelection: List = emptyList(), + eventSink: (ManageAuthorizedSpacesEvent) -> Unit = {}, +) = ManageAuthorizedSpacesState( + selection = authorizedSpacesData, + selectedIds = currentSelection.toImmutableList(), + isSelectionComplete = false, eventSink = eventSink, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt index 513ecc980a..1c4ff7bc77 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt @@ -66,12 +66,12 @@ fun ManageAuthorizedSpacesView( hasDivider = false, ) } - items(items = state.joinedSpaces) { space -> + items(items = state.selection.joinedSpaces) { space -> CheckableSpaceListItem( headlineText = space.displayName, supportingText = space.canonicalAlias?.value, avatarData = space.getAvatarData(AvatarSize.SpaceMember), - checked = state.currentSelection.contains(space.roomId), + checked = state.selectedIds.contains(space.roomId), onCheckedChange = { _ -> state.eventSink( ManageAuthorizedSpacesEvent.ToggleSpace(space.roomId) @@ -79,19 +79,19 @@ fun ManageAuthorizedSpacesView( } ) } - if (state.unknownSpaceIds.isNotEmpty()) { + if (state.selection.unknownSpaceIds.isNotEmpty()) { item { ListSectionHeader( title = stringResource(R.string.screen_manage_authorized_spaces_unknown_spaces_section_title), hasDivider = true, ) } - items(items = state.unknownSpaceIds) { + items(items = state.selection.unknownSpaceIds) { CheckableSpaceListItem( headlineText = stringResource(R.string.screen_manage_authorized_spaces_unknown_space), supportingText = it.value, avatarData = null, - checked = state.currentSelection.contains(it), + checked = state.selectedIds.contains(it), onCheckedChange = { _ -> state.eventSink( ManageAuthorizedSpacesEvent.ToggleSpace(it) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt index d5fb72e72e..1e5e6e0943 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt @@ -23,9 +23,12 @@ import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.compound.theme.ElementTheme import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator +import io.element.android.features.securityandprivacy.impl.manageauthorizedspaces.AuthorizedSpacesSelection import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab import io.element.android.libraries.architecture.appyx.launchMolecule import io.element.android.libraries.di.RoomScope +import io.element.android.libraries.matrix.api.core.RoomId +import kotlinx.collections.immutable.ImmutableList @ContributesNode(RoomScope::class) @AssistedInject @@ -43,6 +46,16 @@ class SecurityAndPrivacyNode( activity.openUrlInChromeCustomTab(null, darkTheme, url) } + fun getAuthorizedSpacesData(): AuthorizedSpacesSelection{ + return stateFlow.value.getAuthorizedSpaceData() + } + + fun onAuthorizedSpacesSelected(selectedSpaces: ImmutableList) { + stateFlow.value.eventSink( + SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.SpaceMember(selectedSpaces)) + ) + } + @Composable override fun View(modifier: Modifier) { val activity = requireNotNull(LocalActivity.current) @@ -56,4 +69,5 @@ class SecurityAndPrivacyNode( modifier = modifier ) } + } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index e025914801..bc7688dab3 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -35,6 +35,7 @@ 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.RoomAlias +import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility @@ -130,9 +131,9 @@ class SecurityAndPrivacyPresenter( value = (joinedParentSpaces + nonParentJoinedSpaces).toImmutableSet() } - val spaceSelection by remember { + val spaceSelectionMode by remember { derivedStateOf { - getSpaceSelection(selectableJoinedSpaces, savedSettings.roomAccess) + getSpaceSelectionMode(selectableJoinedSpaces, savedSettings.roomAccess) } } @@ -191,9 +192,12 @@ class SecurityAndPrivacyPresenter( SecurityAndPrivacyEvent.DismissExitConfirmation -> { saveAction.value = AsyncAction.Uninitialized } - SecurityAndPrivacyEvent.ManageAuthorizedSpaces -> navigator.openManageAuthorizedSpaces() + SecurityAndPrivacyEvent.ManageAuthorizedSpaces -> { + navigator.openManageAuthorizedSpaces(editedSettings.roomAccess.spaceIds()) + } SecurityAndPrivacyEvent.SelectSpaceMemberAccess -> handleSpaceMemberAccessSelection( - spaceSelection = spaceSelection, + spaceSelectionMode = spaceSelectionMode, + spaceIds = editedSettings.roomAccess.spaceIds(), editedAccess = editedRoomAccess, ) } @@ -216,7 +220,7 @@ class SecurityAndPrivacyPresenter( isSpace = roomInfo.isSpace, isSpaceSettingsEnabled = isSpaceSettingsEnabled, selectableJoinedSpaces = selectableJoinedSpaces, - spaceSelection = spaceSelection, + spaceSelectionMode = spaceSelectionMode, eventSink = ::handleEvent, ) @@ -241,42 +245,45 @@ class SecurityAndPrivacyPresenter( } private fun handleSpaceMemberAccessSelection( - spaceSelection: SpaceSelection, + spaceSelectionMode: SpaceSelectionMode, + spaceIds: List, editedAccess: MutableState, ) { if (editedAccess.value is SecurityAndPrivacyRoomAccess.SpaceMember) { return } - when (spaceSelection) { - is SpaceSelection.None -> Unit - is SpaceSelection.Multiple -> navigator.openManageAuthorizedSpaces() - is SpaceSelection.Single -> { + when (spaceSelectionMode) { + is SpaceSelectionMode.None -> Unit + is SpaceSelectionMode.Multiple -> navigator.openManageAuthorizedSpaces( + initialSelection = spaceIds , + ) + is SpaceSelectionMode.Single -> { val newRoomAccess = SecurityAndPrivacyRoomAccess.SpaceMember( - spaceIds = persistentListOf(spaceSelection.spaceId) + spaceIds = persistentListOf(spaceSelectionMode.spaceId) ) editedAccess.value = newRoomAccess } } } - private fun getSpaceSelection( + private fun getSpaceSelectionMode( selectableJoinedSpaces: Set, savedAccess: SecurityAndPrivacyRoomAccess, - ): SpaceSelection { + ): SpaceSelectionMode { val selectableSpacesCount = (selectableJoinedSpaces.map { it.roomId } + savedAccess.spaceIds()).toSet().size return when { - selectableSpacesCount == 0 -> SpaceSelection.None - selectableSpacesCount > 1 -> SpaceSelection.Multiple + selectableSpacesCount == 0 -> SpaceSelectionMode.None + selectableSpacesCount > 1 -> SpaceSelectionMode.Multiple else -> { val joinedSpace = selectableJoinedSpaces.firstOrNull() if (joinedSpace != null) { - SpaceSelection.Single(joinedSpace.roomId, joinedSpace) + SpaceSelectionMode.Single(joinedSpace.roomId, joinedSpace) } else { val spaceId = savedAccess.spaceIds().firstOrNull() if (spaceId == null) { - SpaceSelection.None + SpaceSelectionMode.None } else { - SpaceSelection.Single(spaceId, null) + SpaceSelectionMode.Single(spaceId, null) } } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index bcbee0203d..d14d83b16b 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -8,7 +8,11 @@ package io.element.android.features.securityandprivacy.impl.root +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions +import io.element.android.features.securityandprivacy.impl.R +import io.element.android.features.securityandprivacy.impl.manageauthorizedspaces.AuthorizedSpacesSelection import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.RoomId @@ -25,16 +29,32 @@ data class SecurityAndPrivacyState( val editedSettings: SecurityAndPrivacySettings, val homeserverName: String, val showEnableEncryptionConfirmation: Boolean, - val isKnockEnabled: Boolean, - val isSpaceSettingsEnabled: Boolean, + private val isKnockEnabled: Boolean, + private val isSpaceSettingsEnabled: Boolean, val saveAction: AsyncAction, val isSpace: Boolean, private val permissions: SecurityAndPrivacyPermissions, private val selectableJoinedSpaces: ImmutableSet, - private val spaceSelection: SpaceSelection, + private val spaceSelectionMode: SpaceSelectionMode, val eventSink: (SecurityAndPrivacyEvent) -> Unit ) { + val isSpaceMemberSelectable = isSpaceSettingsEnabled && spaceSelectionMode != SpaceSelectionMode.None + + // Show SpaceMember option in two cases: + // - the SpaceSettings FF is enabled + // - SpaceMember is the current saved value + val showSpaceMemberOption = savedSettings.roomAccess is SecurityAndPrivacyRoomAccess.SpaceMember || isSpaceMemberSelectable + + val showManageSpaceAction = spaceSelectionMode is SpaceSelectionMode.Multiple && editedSettings.roomAccess is SecurityAndPrivacyRoomAccess.SpaceMember + + val isAskToJoinSelectable = isKnockEnabled + + // Show Ask to join option in two cases: + // - the Knock FF is enabled + // - AskToJoin is the current saved value + val showAskToJoinOption = savedSettings.roomAccess == SecurityAndPrivacyRoomAccess.AskToJoin || isAskToJoinSelectable + val canBeSaved = savedSettings != editedSettings // Logic is in https://github.com/element-hq/element-meta/issues/3029 @@ -57,6 +77,32 @@ data class SecurityAndPrivacyState( val showHistoryVisibilitySection = permissions.canChangeHistoryVisibility && !isSpace val showEncryptionSection = permissions.canChangeEncryption && !isSpace + + @Composable + fun spaceMemberDescription(): String { + return if (isSpaceMemberSelectable) { + when (spaceSelectionMode) { + is SpaceSelectionMode.Single -> { + val spaceName = spaceSelectionMode.spaceRoom?.displayName ?: spaceSelectionMode.spaceId.value + stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_single_parent_description, spaceName) + } + is SpaceSelectionMode.None, + is SpaceSelectionMode.Multiple -> stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_multiple_parents_description) + } + } else { + stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_unavailable_description) + } + } + + fun getAuthorizedSpaceData(): AuthorizedSpacesSelection { + return AuthorizedSpacesSelection( + joinedSpaces = selectableJoinedSpaces.toImmutableList(), + unknownSpaceIds = savedSettings.roomAccess.spaceIds().filter { spaceId -> + selectableJoinedSpaces.none { it.roomId == spaceId } + }.toImmutableList(), + initialSelectedIds = editedSettings.roomAccess.spaceIds().toImmutableList() + ) + } } data class SecurityAndPrivacySettings( @@ -85,10 +131,10 @@ enum class SecurityAndPrivacyHistoryVisibility { } } -sealed interface SpaceSelection { - data object None : SpaceSelection - data class Single(val spaceId: RoomId, val spaceRoom: SpaceRoom?) : SpaceSelection - data object Multiple : SpaceSelection +sealed interface SpaceSelectionMode { + data object None : SpaceSelectionMode + data class Single(val spaceId: RoomId, val spaceRoom: SpaceRoom?) : SpaceSelectionMode + data object Multiple : SpaceSelectionMode } sealed interface SecurityAndPrivacyRoomAccess { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index 312043324e..61218e8897 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -14,7 +14,6 @@ import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.spaces.SpaceRoom import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableSet open class SecurityAndPrivacyStateProvider : PreviewParameterProvider { @@ -122,7 +121,7 @@ fun aSecurityAndPrivacyState( isKnockEnabled: Boolean = true, isSpace: Boolean = false, selectableJoinedSpaces: Set = emptySet(), - spaceSelection: SpaceSelection = SpaceSelection.None, + spaceSelectionMode: SpaceSelectionMode = SpaceSelectionMode.None, isSpaceSettingsEnabled: Boolean = true, eventSink: (SecurityAndPrivacyEvent) -> Unit = {} ) = SecurityAndPrivacyState( @@ -135,7 +134,7 @@ fun aSecurityAndPrivacyState( permissions = permissions, isSpace = isSpace, selectableJoinedSpaces = selectableJoinedSpaces.toImmutableSet(), - spaceSelection = SpaceSelection.None, + spaceSelectionMode = spaceSelectionMode, isSpaceSettingsEnabled = isSpaceSettingsEnabled, eventSink = eventSink, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 374a4e3911..aedea1879c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -90,14 +90,8 @@ fun SecurityAndPrivacyView( ) { if (state.showRoomAccessSection) { RoomAccessSection( + state = state, modifier = Modifier.padding(top = 24.dp), - edited = state.editedSettings.roomAccess, - saved = state.savedSettings.roomAccess, - isKnockEnabled = state.isKnockEnabled, - isSpaceSettingsEnabled = state.isSpaceSettingsEnabled, - onSelectOption = { state.eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(it)) }, - onManageSpacesClick = { state.eventSink(SecurityAndPrivacyEvent.ManageAuthorizedSpaces) }, - onSpaceMemberAccessClick = { state.eventSink(SecurityAndPrivacyEvent.SelectSpaceMemberAccess) } ) } if (state.showRoomVisibilitySections) { @@ -211,15 +205,25 @@ private fun SecurityAndPrivacySection( @Composable private fun RoomAccessSection( - edited: SecurityAndPrivacyRoomAccess, - saved: SecurityAndPrivacyRoomAccess, - isKnockEnabled: Boolean, - isSpaceSettingsEnabled: Boolean, - onSelectOption: (SecurityAndPrivacyRoomAccess) -> Unit, - onSpaceMemberAccessClick: () -> Unit, - onManageSpacesClick: () -> Unit, + state: SecurityAndPrivacyState, modifier: Modifier = Modifier, ) { + + val edited = state.editedSettings.roomAccess + val saved = state.savedSettings.roomAccess + + fun onSelectOption(option: SecurityAndPrivacyRoomAccess) { + state.eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(option)) + } + + fun onSpaceMemberAccessClick() { + state.eventSink(SecurityAndPrivacyEvent.SelectSpaceMemberAccess) + } + + fun onManageSpacesClick() { + state.eventSink(SecurityAndPrivacyEvent.ManageAuthorizedSpaces) + } + SecurityAndPrivacySection( title = stringResource(R.string.screen_security_and_privacy_room_access_section_header), modifier = modifier, @@ -231,31 +235,25 @@ private fun RoomAccessSection( leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Public())), onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.Anyone) }, ) - // Show SpaceMember option in two cases: - // - the SpaceSettings FF is enabled - // - SpaceMember is the current saved value - if (saved is SecurityAndPrivacyRoomAccess.SpaceMember || isSpaceSettingsEnabled) + if (state.showSpaceMemberOption) ListItem( headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_title)) }, supportingContent = { - Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_unavailable_description)) + Text(text = state.spaceMemberDescription()) }, - trailingContent = ListItemContent.RadioButton(selected = edited is SecurityAndPrivacyRoomAccess.SpaceMember), + trailingContent = ListItemContent.RadioButton(selected = state.editedSettings.roomAccess is SecurityAndPrivacyRoomAccess.SpaceMember), leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Space())), - onClick = onSpaceMemberAccessClick, - enabled = isSpaceSettingsEnabled, + onClick = ::onSpaceMemberAccessClick, + enabled = state.isSpaceMemberSelectable, ) - // Show Ask to join option in two cases: - // - the Knock FF is enabled - // - AskToJoin is the current saved value - if (saved == SecurityAndPrivacyRoomAccess.AskToJoin || isKnockEnabled) { + if (state.showAskToJoinOption) { ListItem( headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_ask_to_join_option_title)) }, supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_ask_to_join_option_description)) }, trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.AskToJoin), onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.AskToJoin) }, leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.UserAdd())), - enabled = isKnockEnabled, + enabled = state.isAskToJoinSelectable, ) } ListItem( @@ -265,11 +263,11 @@ private fun RoomAccessSection( leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Lock())), onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.InviteOnly) }, ) - if (edited is SecurityAndPrivacyRoomAccess.SpaceMember) { + if (state.showManageSpaceAction) { val footerText = stringWithLink( textRes = R.string.screen_security_and_privacy_room_access_footer, url = stringResource(R.string.screen_security_and_privacy_room_access_footer_manage_spaces_action), - onLinkClick = { onManageSpacesClick() }, + onLinkClick = {onManageSpacesClick()}, ) Text( text = footerText, From 75ab79162953a041570931c5c3d667cc909d0b34 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 7 Jan 2026 11:38:57 +0100 Subject: [PATCH 303/347] feature(security&privacy): working SpaceMember selection --- .../impl/SecurityAndPrivacyFlowNode.kt | 6 +-- .../impl/SecurityAndPrivacyNavigator.kt | 7 ++-- .../ManageAuthorizedSpacesNode.kt | 11 +---- .../ManageAuthorizedSpacesPresenter.kt | 41 ++++++------------- .../ManageAuthorizedSpacesState.kt | 4 +- .../ManageAuthorizedSpacesView.kt | 3 ++ .../impl/root/SecurityAndPrivacyNode.kt | 2 +- .../impl/root/SecurityAndPrivacyPresenter.kt | 8 ++-- .../impl/root/SecurityAndPrivacyState.kt | 9 ++-- 9 files changed, 37 insertions(+), 54 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index d29a7ffd20..79c0c68ad3 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -66,7 +66,7 @@ class SecurityAndPrivacyFlowNode( data object EditRoomAddress : NavTarget @Parcelize - data class ManageAuthorizedSpaces(val initialSelection: List) : NavTarget + data object ManageAuthorizedSpaces: NavTarget } private val callback: SecurityAndPrivacyEntryPoint.Callback = callback() @@ -95,7 +95,7 @@ class SecurityAndPrivacyFlowNode( val authorizedSpacesData = securityAndPrivacyNode.getAuthorizedSpacesData() val selectedSpaces = manageAuthorizedSpacesNode.waitForCompletion(authorizedSpacesData) withContext(NonCancellable) { - backstack.pop() + navigator.closeManageAuthorizedSpaces() securityAndPrivacyNode.onAuthorizedSpacesSelected(selectedSpaces) } } @@ -110,7 +110,7 @@ class SecurityAndPrivacyFlowNode( NavTarget.EditRoomAddress -> { createNode(buildContext, plugins = listOf(navigator)) } - is NavTarget.ManageAuthorizedSpaces -> { + NavTarget.ManageAuthorizedSpaces -> { createNode(buildContext, plugins = listOf(navigator)) } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt index da6ca379e8..274bf0b823 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt @@ -13,13 +13,12 @@ import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.operation.pop import com.bumble.appyx.navmodel.backstack.operation.push import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint -import io.element.android.libraries.matrix.api.core.RoomId interface SecurityAndPrivacyNavigator : Plugin { fun onDone() fun openEditRoomAddress() fun closeEditRoomAddress() - fun openManageAuthorizedSpaces(initialSelection: List) + fun openManageAuthorizedSpaces() fun closeManageAuthorizedSpaces() } @@ -39,8 +38,8 @@ class BackstackSecurityAndPrivacyNavigator( backStack.pop() } - override fun openManageAuthorizedSpaces(initialSelection: List) { - backStack.push(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces(initialSelection)) + override fun openManageAuthorizedSpaces() { + backStack.push(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces) } override fun closeManageAuthorizedSpaces() { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt index 5608c0ce16..b8f7150d86 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt @@ -20,7 +20,6 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator -import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.appyx.launchMolecule import io.element.android.libraries.di.RoomScope import io.element.android.libraries.matrix.api.core.RoomId @@ -32,16 +31,10 @@ import kotlinx.coroutines.flow.first class ManageAuthorizedSpacesNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, - presenterFactory: ManageAuthorizedSpacesPresenter.Factory, + presenter: ManageAuthorizedSpacesPresenter, ) : Node(buildContext, plugins = plugins) { - data class Params( - val initialSelection: List - ) : NodeInputs - private val navigator = plugins().first() - private val presenter = presenterFactory.create(navigator) - private val stateFlow = launchMolecule { presenter.present() } suspend fun waitForCompletion(data: AuthorizedSpacesSelection): ImmutableList { @@ -54,7 +47,7 @@ class ManageAuthorizedSpacesNode( val state by stateFlow.collectAsState() ManageAuthorizedSpacesView( state = state, - onBackClick = ::navigateUp, + onBackClick = { navigator.closeManageAuthorizedSpaces() }, modifier = modifier ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt index 09869cdf09..0679c72066 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt @@ -13,57 +13,42 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember 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.securityandprivacy.impl.SecurityAndPrivacyNavigator +import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.room.JoinedRoom import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList -@AssistedInject -class ManageAuthorizedSpacesPresenter( - @Assisted private val navigator: SecurityAndPrivacyNavigator, - private val client: MatrixClient, - private val room: JoinedRoom, -) : Presenter { - @AssistedFactory - interface Factory { - fun create(navigator: SecurityAndPrivacyNavigator): ManageAuthorizedSpacesPresenter - } +@Inject +class ManageAuthorizedSpacesPresenter() : Presenter { @Composable override fun present(): ManageAuthorizedSpacesState { - var currentSelection: ImmutableList by remember { mutableStateOf(persistentListOf()) } - var spacesData by remember { mutableStateOf(AuthorizedSpacesSelection()) } + var selectedIds: ImmutableList by remember { mutableStateOf(persistentListOf()) } + var spacesSelection by remember { mutableStateOf(AuthorizedSpacesSelection()) } var isSelectionComplete by remember { mutableStateOf(false) } fun handleEvent(event: ManageAuthorizedSpacesEvent) { when (event) { - ManageAuthorizedSpacesEvent.Done -> { - isSelectionComplete = true - } + ManageAuthorizedSpacesEvent.Done ->isSelectionComplete = true is ManageAuthorizedSpacesEvent.ToggleSpace -> { - currentSelection = if (currentSelection.contains(event.roomId)) { - currentSelection.minus(event.roomId).toPersistentList() + selectedIds = if (selectedIds.contains(event.roomId)) { + selectedIds.minus(event.roomId).toPersistentList() } else { - currentSelection.plus(event.roomId).toPersistentList() + selectedIds.plus(event.roomId).toPersistentList() } } is ManageAuthorizedSpacesEvent.SetData -> { - spacesData = event.data - currentSelection = event.data.initialSelectedIds + spacesSelection = event.data + selectedIds = event.data.initialSelectedIds } } } return ManageAuthorizedSpacesState( - selection = spacesData, - selectedIds = currentSelection, + selection = spacesSelection, + selectedIds = selectedIds, isSelectionComplete = isSelectionComplete, eventSink = ::handleEvent, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt index 7564fabae9..291cd7c760 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt @@ -18,7 +18,9 @@ data class ManageAuthorizedSpacesState( val selectedIds: ImmutableList, val isSelectionComplete: Boolean, val eventSink: (ManageAuthorizedSpacesEvent) -> Unit -) +) { + val isDoneButtonEnabled = selectedIds.isNotEmpty() +} data class AuthorizedSpacesSelection( val joinedSpaces: ImmutableList = persistentListOf(), diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt index 1c4ff7bc77..022010f267 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt @@ -53,6 +53,7 @@ fun ManageAuthorizedSpacesView( onDoneClick = { state.eventSink(ManageAuthorizedSpacesEvent.Done) }, + isDoneButtonEnabled = state.isDoneButtonEnabled ) } ) { padding -> @@ -160,6 +161,7 @@ private fun CheckableSpaceListItem( @OptIn(ExperimentalMaterial3Api::class) @Composable private fun ManageAuthorizedSpacesTopBar( + isDoneButtonEnabled: Boolean, onBackClick: () -> Unit, onDoneClick: () -> Unit, modifier: Modifier = Modifier, @@ -170,6 +172,7 @@ private fun ManageAuthorizedSpacesTopBar( navigationIcon = { BackButton(onClick = onBackClick) }, actions = { TextButton( + enabled = isDoneButtonEnabled, text = stringResource(CommonStrings.action_done), onClick = onDoneClick, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt index 1e5e6e0943..8c41992e7a 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt @@ -47,7 +47,7 @@ class SecurityAndPrivacyNode( } fun getAuthorizedSpacesData(): AuthorizedSpacesSelection{ - return stateFlow.value.getAuthorizedSpaceData() + return stateFlow.value.getAuthorizedSpacesSelection() } fun onAuthorizedSpacesSelected(selectedSpaces: ImmutableList) { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index bc7688dab3..9e2bd6c375 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -118,7 +118,7 @@ class SecurityAndPrivacyPresenter( address = savedSettings.address, ) - val selectableJoinedSpaces by produceState(persistentSetOf()) { + val selectableJoinedSpaces by produceState(initialValue = persistentSetOf(), key1 = savedSettings.roomAccess.spaceIds()) { val joinedParentSpaces = matrixClient .spaceService .joinedParents(room.roomId) @@ -193,7 +193,7 @@ class SecurityAndPrivacyPresenter( saveAction.value = AsyncAction.Uninitialized } SecurityAndPrivacyEvent.ManageAuthorizedSpaces -> { - navigator.openManageAuthorizedSpaces(editedSettings.roomAccess.spaceIds()) + navigator.openManageAuthorizedSpaces() } SecurityAndPrivacyEvent.SelectSpaceMemberAccess -> handleSpaceMemberAccessSelection( spaceSelectionMode = spaceSelectionMode, @@ -254,9 +254,7 @@ class SecurityAndPrivacyPresenter( } when (spaceSelectionMode) { is SpaceSelectionMode.None -> Unit - is SpaceSelectionMode.Multiple -> navigator.openManageAuthorizedSpaces( - initialSelection = spaceIds , - ) + is SpaceSelectionMode.Multiple -> navigator.openManageAuthorizedSpaces() is SpaceSelectionMode.Single -> { val newRoomAccess = SecurityAndPrivacyRoomAccess.SpaceMember( spaceIds = persistentListOf(spaceSelectionMode.spaceId) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index d14d83b16b..d74ecb13d9 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -42,8 +42,8 @@ data class SecurityAndPrivacyState( val isSpaceMemberSelectable = isSpaceSettingsEnabled && spaceSelectionMode != SpaceSelectionMode.None // Show SpaceMember option in two cases: - // - the SpaceSettings FF is enabled // - SpaceMember is the current saved value + // - SpaceMember option is selectable (ie. the FF is enabled and there is at least one space to select) val showSpaceMemberOption = savedSettings.roomAccess is SecurityAndPrivacyRoomAccess.SpaceMember || isSpaceMemberSelectable val showManageSpaceAction = spaceSelectionMode is SpaceSelectionMode.Multiple && editedSettings.roomAccess is SecurityAndPrivacyRoomAccess.SpaceMember @@ -94,13 +94,16 @@ data class SecurityAndPrivacyState( } } - fun getAuthorizedSpaceData(): AuthorizedSpacesSelection { + fun getAuthorizedSpacesSelection(): AuthorizedSpacesSelection { return AuthorizedSpacesSelection( joinedSpaces = selectableJoinedSpaces.toImmutableList(), unknownSpaceIds = savedSettings.roomAccess.spaceIds().filter { spaceId -> selectableJoinedSpaces.none { it.roomId == spaceId } }.toImmutableList(), - initialSelectedIds = editedSettings.roomAccess.spaceIds().toImmutableList() + initialSelectedIds = when (editedSettings.roomAccess) { + is SecurityAndPrivacyRoomAccess.SpaceMember -> editedSettings.roomAccess.spaceIds + else -> savedSettings.roomAccess.spaceIds() + } ) } } From ea6a15543c03b68bffa283373ba475201e522ae6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 12:37:57 +0000 Subject: [PATCH 304/347] fix(deps): update roborazzi to v1.55.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 fb55176b9e..ef31c099f5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,7 +32,7 @@ accompanist = "0.37.3" # Test test_core = "1.7.0" -roborazzi = "1.54.0" +roborazzi = "1.55.0" # Jetbrain datetime = "0.7.1" From 26ef42523422dc4fec15db6f416b9e9d92c4af89 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 7 Jan 2026 15:43:27 +0100 Subject: [PATCH 305/347] A11Y: ensure a11y focus is not lost and reset to the back button when the user start playing a pending voice message. --- .../components/VoiceMessagePreview.kt | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessagePreview.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessagePreview.kt index d893979889..8ca90843a4 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessagePreview.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessagePreview.kt @@ -67,22 +67,12 @@ internal fun VoiceMessagePreview( .heightIn(26.dp), verticalAlignment = Alignment.CenterVertically, ) { - if (isPlaying) { - PlayerButton( - type = PlayerButtonType.Pause, - onClick = onPauseClick, - enabled = isInteractive, - ) - } else { - PlayerButton( - type = PlayerButtonType.Play, - onClick = onPlayClick, - enabled = isInteractive - ) - } - + PlayerButton( + type = if (isPlaying) PlayerButtonType.Pause else PlayerButtonType.Play, + onClick = if (isPlaying) onPauseClick else onPlayClick, + enabled = isInteractive, + ) Spacer(modifier = Modifier.width(8.dp)) - Text( text = time.formatShort(), color = ElementTheme.colors.textSecondary, @@ -90,9 +80,7 @@ internal fun VoiceMessagePreview( maxLines = 1, overflow = TextOverflow.Ellipsis, ) - Spacer(modifier = Modifier.width(12.dp)) - WaveformPlaybackView( modifier = Modifier .weight(1f) From 92acf1edeaa5601b514a34bee39d49fd85e2511f Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 7 Jan 2026 17:05:09 +0100 Subject: [PATCH 306/347] feature(security&privacy): support KnockRestricted join rule --- .../impl/SecurityAndPrivacyFlowNode.kt | 8 ++-- .../impl/SecurityAndPrivacyNavigator.kt | 6 +-- .../impl/root/SecurityAndPrivacyEvent.kt | 2 + .../impl/root/SecurityAndPrivacyNode.kt | 11 +++-- .../impl/root/SecurityAndPrivacyPresenter.kt | 37 +++++++++++++++- .../impl/root/SecurityAndPrivacyState.kt | 42 ++++++++++++++++--- .../root/SecurityAndPrivacyStateProvider.kt | 13 ++++++ .../impl/root/SecurityAndPrivacyView.kt | 19 ++++++++- .../impl/FakeSecurityAndPrivacyNavigator.kt | 10 +++++ 9 files changed, 128 insertions(+), 20 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index 79c0c68ad3..f7bdde7aa0 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -19,6 +19,7 @@ import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.navmodel.backstack.BackStack +import com.bumble.appyx.navmodel.backstack.activeElement import com.bumble.appyx.navmodel.backstack.operation.pop import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject @@ -66,7 +67,7 @@ class SecurityAndPrivacyFlowNode( data object EditRoomAddress : NavTarget @Parcelize - data object ManageAuthorizedSpaces: NavTarget + data class ManageAuthorizedSpaces(val forKnockRestricted: Boolean = false) : NavTarget } private val callback: SecurityAndPrivacyEntryPoint.Callback = callback() @@ -94,9 +95,10 @@ class SecurityAndPrivacyFlowNode( commonLifecycle.coroutineScope.launch { val authorizedSpacesData = securityAndPrivacyNode.getAuthorizedSpacesData() val selectedSpaces = manageAuthorizedSpacesNode.waitForCompletion(authorizedSpacesData) + val forKnock = (backstack.activeElement as? NavTarget.ManageAuthorizedSpaces)?.forKnockRestricted ?: false withContext(NonCancellable) { navigator.closeManageAuthorizedSpaces() - securityAndPrivacyNode.onAuthorizedSpacesSelected(selectedSpaces) + securityAndPrivacyNode.onAuthorizedSpacesSelected(selectedSpaces, forKnock = forKnock) } } } @@ -110,7 +112,7 @@ class SecurityAndPrivacyFlowNode( NavTarget.EditRoomAddress -> { createNode(buildContext, plugins = listOf(navigator)) } - NavTarget.ManageAuthorizedSpaces -> { + is NavTarget.ManageAuthorizedSpaces -> { createNode(buildContext, plugins = listOf(navigator)) } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt index 274bf0b823..9690c915d5 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt @@ -18,7 +18,7 @@ interface SecurityAndPrivacyNavigator : Plugin { fun onDone() fun openEditRoomAddress() fun closeEditRoomAddress() - fun openManageAuthorizedSpaces() + fun openManageAuthorizedSpaces(forKnockRestricted: Boolean = false) fun closeManageAuthorizedSpaces() } @@ -38,8 +38,8 @@ class BackstackSecurityAndPrivacyNavigator( backStack.pop() } - override fun openManageAuthorizedSpaces() { - backStack.push(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces) + override fun openManageAuthorizedSpaces(forKnockRestricted: Boolean) { + backStack.push(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces(forKnockRestricted)) } override fun closeManageAuthorizedSpaces() { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt index 0c56a834de..25045a72c1 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt @@ -17,6 +17,8 @@ sealed interface SecurityAndPrivacyEvent { data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvent // Special case for "Space Members" data object SelectSpaceMemberAccess : SecurityAndPrivacyEvent + // Special case for "Ask to join with Space Members" + data object SelectAskToJoinWithSpaceMembersAccess : SecurityAndPrivacyEvent data object ToggleEncryptionState : SecurityAndPrivacyEvent data object CancelEnableEncryption : SecurityAndPrivacyEvent data object ConfirmEnableEncryption : SecurityAndPrivacyEvent diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt index 8c41992e7a..7d3c115be5 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt @@ -50,10 +50,13 @@ class SecurityAndPrivacyNode( return stateFlow.value.getAuthorizedSpacesSelection() } - fun onAuthorizedSpacesSelected(selectedSpaces: ImmutableList) { - stateFlow.value.eventSink( - SecurityAndPrivacyEvent.ChangeRoomAccess(SecurityAndPrivacyRoomAccess.SpaceMember(selectedSpaces)) - ) + fun onAuthorizedSpacesSelected(selectedSpaces: ImmutableList, forKnock: Boolean) { + val roomAccess = if (forKnock) { + SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember(selectedSpaces) + } else { + SecurityAndPrivacyRoomAccess.SpaceMember(selectedSpaces) + } + stateFlow.value.eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(roomAccess)) } @Composable diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index 9e2bd6c375..a27884a1ab 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -200,6 +200,10 @@ class SecurityAndPrivacyPresenter( spaceIds = editedSettings.roomAccess.spaceIds(), editedAccess = editedRoomAccess, ) + SecurityAndPrivacyEvent.SelectAskToJoinWithSpaceMembersAccess -> handleAskToJoinWithSpaceMembersAccessSelection( + spaceSelectionMode = spaceSelectionMode, + editedAccess = editedRoomAccess, + ) } } @@ -254,7 +258,7 @@ class SecurityAndPrivacyPresenter( } when (spaceSelectionMode) { is SpaceSelectionMode.None -> Unit - is SpaceSelectionMode.Multiple -> navigator.openManageAuthorizedSpaces() + is SpaceSelectionMode.Multiple -> navigator.openManageAuthorizedSpaces(forKnockRestricted = false) is SpaceSelectionMode.Single -> { val newRoomAccess = SecurityAndPrivacyRoomAccess.SpaceMember( spaceIds = persistentListOf(spaceSelectionMode.spaceId) @@ -264,6 +268,25 @@ class SecurityAndPrivacyPresenter( } } + private fun handleAskToJoinWithSpaceMembersAccessSelection( + spaceSelectionMode: SpaceSelectionMode, + editedAccess: MutableState, + ) { + if (editedAccess.value is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember) { + return + } + when (spaceSelectionMode) { + is SpaceSelectionMode.None -> Unit + is SpaceSelectionMode.Multiple -> navigator.openManageAuthorizedSpaces(forKnockRestricted = true) + is SpaceSelectionMode.Single -> { + val newRoomAccess = SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember( + spaceIds = persistentListOf(spaceSelectionMode.spaceId) + ) + editedAccess.value = newRoomAccess + } + } + } + private fun getSpaceSelectionMode( selectableJoinedSpaces: Set, savedAccess: SecurityAndPrivacyRoomAccess, @@ -328,6 +351,7 @@ class SecurityAndPrivacyPresenter( // the room should be automatically made invisible (private) in the room directory. val editedIsVisibleInRoomDirectory = when (editedSettings.roomAccess) { SecurityAndPrivacyRoomAccess.AskToJoin, + is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember, SecurityAndPrivacyRoomAccess.Anyone -> editedSettings.isVisibleInRoomDirectory.dataOrNull() else -> false } @@ -365,7 +389,13 @@ class SecurityAndPrivacyPresenter( private fun JoinRule?.map(): SecurityAndPrivacyRoomAccess { return when (this) { JoinRule.Public -> SecurityAndPrivacyRoomAccess.Anyone - JoinRule.Knock, is JoinRule.KnockRestricted -> SecurityAndPrivacyRoomAccess.AskToJoin + JoinRule.Knock -> SecurityAndPrivacyRoomAccess.AskToJoin + is JoinRule.KnockRestricted -> SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember( + spaceIds = this.rules + .filterIsInstance() + .map { it.roomId } + .toImmutableList() + ) is JoinRule.Restricted -> SecurityAndPrivacyRoomAccess.SpaceMember( spaceIds = this.rules .filterIsInstance() @@ -388,6 +418,9 @@ private fun SecurityAndPrivacyRoomAccess.map(): JoinRule? { is SecurityAndPrivacyRoomAccess.SpaceMember -> JoinRule.Restricted( rules = this.spaceIds.map { AllowRule.RoomMembership(it) }.toImmutableList() ) + is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember -> JoinRule.KnockRestricted( + rules = this.spaceIds.map { AllowRule.RoomMembership(it) }.toImmutableList() + ) } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index d74ecb13d9..9d47e57846 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -46,14 +46,25 @@ data class SecurityAndPrivacyState( // - SpaceMember option is selectable (ie. the FF is enabled and there is at least one space to select) val showSpaceMemberOption = savedSettings.roomAccess is SecurityAndPrivacyRoomAccess.SpaceMember || isSpaceMemberSelectable - val showManageSpaceAction = spaceSelectionMode is SpaceSelectionMode.Multiple && editedSettings.roomAccess is SecurityAndPrivacyRoomAccess.SpaceMember + val showManageSpaceFooter = spaceSelectionMode is SpaceSelectionMode.Multiple && + (editedSettings.roomAccess is SecurityAndPrivacyRoomAccess.SpaceMember || + editedSettings.roomAccess is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember) val isAskToJoinSelectable = isKnockEnabled - // Show Ask to join option in two cases: - // - the Knock FF is enabled - // - AskToJoin is the current saved value - val showAskToJoinOption = savedSettings.roomAccess == SecurityAndPrivacyRoomAccess.AskToJoin || isAskToJoinSelectable + val isAskToJoinWithSpaceMembersSelectable = isAskToJoinSelectable && isSpaceMemberSelectable + + // Show Ask to join option only when: + // - AskToJoin is the current saved value (legacy), OR + // - Knock FF enabled BUT (SpaceSettings FF disabled OR no spaces available) + val showAskToJoinOption = savedSettings.roomAccess == SecurityAndPrivacyRoomAccess.AskToJoin || + (isAskToJoinSelectable && !isAskToJoinWithSpaceMembersSelectable) + + // Show AskToJoinWithSpaceMember option when: + // - It's the current saved value, OR + // - Both FFs enabled AND spaces available + val showAskToJoinWithSpaceMemberOption = savedSettings.roomAccess is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember || + isAskToJoinWithSpaceMembersSelectable val canBeSaved = savedSettings != editedSettings @@ -94,6 +105,22 @@ data class SecurityAndPrivacyState( } } + @Composable + fun askToJoinWithSpaceMembersDescription(): String { + return if (isAskToJoinWithSpaceMembersSelectable) { + when (spaceSelectionMode) { + is SpaceSelectionMode.Single -> { + val spaceName = spaceSelectionMode.spaceRoom?.displayName ?: spaceSelectionMode.spaceId.value + stringResource(R.string.screen_security_and_privacy_ask_to_join_single_space_members_option_description, spaceName) + } + is SpaceSelectionMode.None, + is SpaceSelectionMode.Multiple -> stringResource(R.string.screen_security_and_privacy_ask_to_join_multiple_spaces_members_option_description) + } + } else { + stringResource(R.string.screen_security_and_privacy_ask_to_join_option_description) + } + } + fun getAuthorizedSpacesSelection(): AuthorizedSpacesSelection { return AuthorizedSpacesSelection( joinedSpaces = selectableJoinedSpaces.toImmutableList(), @@ -102,6 +129,7 @@ data class SecurityAndPrivacyState( }.toImmutableList(), initialSelectedIds = when (editedSettings.roomAccess) { is SecurityAndPrivacyRoomAccess.SpaceMember -> editedSettings.roomAccess.spaceIds + is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember -> editedSettings.roomAccess.spaceIds else -> savedSettings.roomAccess.spaceIds() } ) @@ -145,17 +173,19 @@ sealed interface SecurityAndPrivacyRoomAccess { data object AskToJoin : SecurityAndPrivacyRoomAccess data object Anyone : SecurityAndPrivacyRoomAccess data class SpaceMember(val spaceIds: ImmutableList) : SecurityAndPrivacyRoomAccess + data class AskToJoinWithSpaceMember(val spaceIds: ImmutableList) : SecurityAndPrivacyRoomAccess fun canConfigureRoomVisibility(): Boolean { return when (this) { InviteOnly, is SpaceMember -> false - AskToJoin, Anyone -> true + AskToJoin, Anyone, is AskToJoinWithSpaceMember -> true } } fun spaceIds(): ImmutableList { return when (this) { is SpaceMember -> spaceIds + is AskToJoinWithSpaceMember -> spaceIds else -> persistentListOf() } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index 61218e8897..d253021143 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -69,6 +69,19 @@ private fun commonSecurityAndPrivacyStates(isSpace: Boolean): Sequence Unit = { lambdaError() }, private val openEditRoomAddressLambda: () -> Unit = { lambdaError() }, private val closeEditRoomAddressLambda: () -> Unit = { lambdaError() }, + private val openManageAuthorizedSpacesLambda: (Boolean) -> Unit = { lambdaError() }, + private val closeManageAuthorizedSpacesLambda: () -> Unit = { lambdaError() }, ) : SecurityAndPrivacyNavigator { override fun onDone() { onDoneLambda() @@ -26,4 +28,12 @@ class FakeSecurityAndPrivacyNavigator( override fun closeEditRoomAddress() { closeEditRoomAddressLambda() } + + override fun openManageAuthorizedSpaces(forKnockRestricted: Boolean) { + openManageAuthorizedSpacesLambda(forKnockRestricted) + } + + override fun closeManageAuthorizedSpaces() { + closeManageAuthorizedSpacesLambda() + } } From d67aee23c36f121d3b4f917718abf52e1f90d0e6 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 7 Jan 2026 17:24:01 +0100 Subject: [PATCH 307/347] Use `TextFieldState` for room list search (#5975) * Add new `FilledTextField` variant using `TextFieldState` * Use `TextFieldState` for `RoomListSearchState.query` - it seems like this is the best practice for this kind of data * Bonus: fix the clear button being misaligned --- .../home/impl/search/RoomListSearchEvents.kt | 1 - .../impl/search/RoomListSearchPresenter.kt | 17 +++---- .../home/impl/search/RoomListSearchState.kt | 3 +- .../search/RoomListSearchStateProvider.kt | 3 +- .../home/impl/search/RoomListSearchView.kt | 33 ++++-------- .../search/RoomListSearchPresenterTest.kt | 8 +-- .../theme/components/FilledTextField.kt | 51 +++++++++++++++++++ 7 files changed, 75 insertions(+), 41 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchEvents.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchEvents.kt index 20222c144d..d8269fbc04 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchEvents.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchEvents.kt @@ -10,6 +10,5 @@ package io.element.android.features.home.impl.search sealed interface RoomListSearchEvents { data object ToggleSearchVisibility : RoomListSearchEvents - data class QueryChanged(val query: String) : RoomListSearchEvents data object ClearQuery : RoomListSearchEvents } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenter.kt index ad06b12f5e..49047ffaed 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenter.kt @@ -8,6 +8,8 @@ package io.element.android.features.home.impl.search +import androidx.compose.foundation.text.input.clearText +import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -29,29 +31,24 @@ class RoomListSearchPresenter( var isSearchActive by remember { mutableStateOf(false) } - var searchQuery by remember { - mutableStateOf("") - } + val searchQuery = rememberTextFieldState() LaunchedEffect(isSearchActive) { dataSource.setIsActive(isSearchActive) } - LaunchedEffect(searchQuery) { - dataSource.setSearchQuery(searchQuery) + LaunchedEffect(searchQuery.text) { + dataSource.setSearchQuery(searchQuery.text.toString()) } fun handleEvent(event: RoomListSearchEvents) { when (event) { RoomListSearchEvents.ClearQuery -> { - searchQuery = "" - } - is RoomListSearchEvents.QueryChanged -> { - searchQuery = event.query + searchQuery.clearText() } RoomListSearchEvents.ToggleSearchVisibility -> { isSearchActive = !isSearchActive - searchQuery = "" + searchQuery.clearText() } } } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchState.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchState.kt index 92e8c1ff03..c2d889388b 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchState.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchState.kt @@ -8,12 +8,13 @@ package io.element.android.features.home.impl.search +import androidx.compose.foundation.text.input.TextFieldState import io.element.android.features.home.impl.model.RoomListRoomSummary import kotlinx.collections.immutable.ImmutableList data class RoomListSearchState( val isSearchActive: Boolean, - val query: String, + val query: TextFieldState, val results: ImmutableList, val eventSink: (RoomListSearchEvents) -> Unit ) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchStateProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchStateProvider.kt index a5015a5003..645eb791ba 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchStateProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchStateProvider.kt @@ -8,6 +8,7 @@ package io.element.android.features.home.impl.search +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.home.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.roomlist.aRoomListRoomSummaryList @@ -33,7 +34,7 @@ fun aRoomListSearchState( eventSink: (RoomListSearchEvents) -> Unit = { }, ) = RoomListSearchState( isSearchActive = isSearchActive, - query = query, + query = TextFieldState(initialText = query), results = results, eventSink = eventSink, ) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchView.kt index 58d6ba7e00..f013b602dd 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchView.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/search/RoomListSearchView.kt @@ -18,16 +18,13 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.text.input.TextFieldLineLimits import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.focus.FocusRequester @@ -35,7 +32,6 @@ import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.tokens.generated.CompoundIcons @@ -112,23 +108,14 @@ private fun RoomListSearchContent( }, navigationIcon = { BackButton(onClick = ::onBackButtonClick) }, title = { - // TODO replace `state.query` with TextFieldState when it's available for M3 TextField // The stateSaver will keep the selection state when returning to this UI - var value by rememberSaveable(stateSaver = TextFieldValue.Saver) { - mutableStateOf(TextFieldValue(state.query)) - } - val focusRequester = remember { FocusRequester() } FilledTextField( modifier = Modifier .fillMaxWidth() .focusRequester(focusRequester), - value = value, - singleLine = true, - onValueChange = { - value = it - state.eventSink(RoomListSearchEvents.QueryChanged(it.text)) - }, + state = state.query, + lineLimits = TextFieldLineLimits.SingleLine, colors = TextFieldDefaults.colors( focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color.Transparent, @@ -138,20 +125,18 @@ private fun RoomListSearchContent( disabledIndicatorColor = Color.Transparent, errorIndicatorColor = Color.Transparent, ), - trailingIcon = { - if (value.text.isNotEmpty()) { - IconButton(onClick = { - state.eventSink(RoomListSearchEvents.ClearQuery) - // Clear local state too - value = value.copy(text = "") - }) { + trailingIcon = if (state.query.text.isNotEmpty()) { + @Composable { + IconButton(onClick = { state.eventSink(RoomListSearchEvents.ClearQuery) }) { Icon( imageVector = CompoundIcons.Close(), contentDescription = stringResource(CommonStrings.action_cancel) ) } } - } + } else { + null + }, ) LaunchedEffect(Unit) { diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenterTest.kt index dee0601915..0fd6459057 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenterTest.kt @@ -33,7 +33,7 @@ class RoomListSearchPresenterTest { }.test { awaitItem().let { state -> assertThat(state.isSearchActive).isFalse() - assertThat(state.query).isEmpty() + assertThat(state.query.text.toString()).isEmpty() assertThat(state.results).isEmpty() } } @@ -72,10 +72,10 @@ class RoomListSearchPresenterTest { ).isEqualTo( RoomListFilter.None ) - state.eventSink(RoomListSearchEvents.QueryChanged("Search")) + state.query.edit { append("Search") } } awaitItem().let { state -> - assertThat(state.query).isEqualTo("Search") + assertThat(state.query.text).isEqualTo("Search") assertThat( roomListService.allRooms.currentFilter.value ).isEqualTo( @@ -84,7 +84,7 @@ class RoomListSearchPresenterTest { state.eventSink(RoomListSearchEvents.ClearQuery) } awaitItem().let { state -> - assertThat(state.query).isEmpty() + assertThat(state.query.text.toString()).isEmpty() assertThat( roomListService.allRooms.currentFilter.value ).isEqualTo( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FilledTextField.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FilledTextField.kt index cbd25c1aeb..d9f4256687 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FilledTextField.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FilledTextField.kt @@ -15,9 +15,15 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.input.InputTransformation +import androidx.compose.foundation.text.input.KeyboardActionHandler +import androidx.compose.foundation.text.input.OutputTransformation +import androidx.compose.foundation.text.input.TextFieldLineLimits +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.TextFieldColors import androidx.compose.material3.TextFieldDefaults +import androidx.compose.material3.TextFieldLabelScope import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -135,6 +141,51 @@ fun FilledTextField( ) } +@Composable +fun FilledTextField( + state: TextFieldState, + modifier: Modifier = Modifier, + enabled: Boolean = true, + readOnly: Boolean = false, + textStyle: TextStyle = LocalTextStyle.current, + label: @Composable (TextFieldLabelScope.() -> Unit)? = null, + placeholder: @Composable (() -> Unit)? = null, + leadingIcon: @Composable (() -> Unit)? = null, + trailingIcon: @Composable (() -> Unit)? = null, + supportingText: @Composable (() -> Unit)? = null, + isError: Boolean = false, + inputTransformation: InputTransformation? = null, + outputTransformation: OutputTransformation? = null, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActionHandler? = null, + lineLimits: TextFieldLineLimits = TextFieldLineLimits.Default, + interactionSource: MutableInteractionSource? = null, + shape: Shape = TextFieldDefaults.shape, + colors: TextFieldColors = TextFieldDefaults.colors() +) { + androidx.compose.material3.TextField( + state = state, + modifier = modifier, + enabled = enabled, + readOnly = readOnly, + textStyle = textStyle, + label = label, + placeholder = placeholder, + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, + supportingText = supportingText, + isError = isError, + inputTransformation = inputTransformation, + outputTransformation = outputTransformation, + keyboardOptions = keyboardOptions, + onKeyboardAction = keyboardActions, + lineLimits = lineLimits, + interactionSource = interactionSource, + shape = shape, + colors = colors, + ) +} + @Preview(group = PreviewGroup.TextFields) @Composable internal fun FilledTextFieldLightPreview() = From ac594b35d60318b860d343884a8d4a8f7fdef995 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 17:29:18 +0000 Subject: [PATCH 308/347] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26 (#5977) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26 * Fix API breaks: `ShieldStateCode` is now `TimelineEventShieldStateCode` --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jorge Martín --- gradle/libs.versions.toml | 2 +- .../item/event/EventTimelineItemMapper.kt | 18 +++++++++--------- .../fixtures/factories/EventTimelineItem.kt | 8 ++++++-- .../fakes/FakeFfiLazyTimelineItemProvider.kt | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fb55176b9e..8b49ec1602 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -177,7 +177,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.19" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:26.1.7" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt index 6715169899..a95b2acccc 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt @@ -30,7 +30,7 @@ import org.matrix.rustcomponents.sdk.QueueWedgeError import org.matrix.rustcomponents.sdk.Reaction import org.matrix.rustcomponents.sdk.ShieldState import org.matrix.rustcomponents.sdk.TimelineItemContent -import uniffi.matrix_sdk_common.ShieldStateCode +import uniffi.matrix_sdk_ui.TimelineEventShieldStateCode import org.matrix.rustcomponents.sdk.EventSendState as RustEventSendState import org.matrix.rustcomponents.sdk.EventTimelineItem as RustEventTimelineItem import org.matrix.rustcomponents.sdk.EventTimelineItemDebugInfo as RustEventTimelineItemDebugInfo @@ -58,7 +58,7 @@ class EventTimelineItemMapper( content = contentMapper.map(content), origin = origin?.map(), timelineItemDebugInfoProvider = { lazyProvider.debugInfo().map() }, - messageShieldProvider = { strict -> lazyProvider.getShields(strict)?.map() }, + messageShieldProvider = { strict -> lazyProvider.getShields(strict).map() }, sendHandleProvider = { lazyProvider.getSendHandle()?.let(::RustSendHandle) } ) } @@ -182,13 +182,13 @@ private fun ShieldState?.map(): MessageShield? { is ShieldState.Red -> true } return when (shieldStateCode) { - ShieldStateCode.AUTHENTICITY_NOT_GUARANTEED -> MessageShield.AuthenticityNotGuaranteed(isCritical) - ShieldStateCode.UNKNOWN_DEVICE -> MessageShield.UnknownDevice(isCritical) - ShieldStateCode.UNSIGNED_DEVICE -> MessageShield.UnsignedDevice(isCritical) - ShieldStateCode.UNVERIFIED_IDENTITY -> MessageShield.UnverifiedIdentity(isCritical) - ShieldStateCode.SENT_IN_CLEAR -> MessageShield.SentInClear(isCritical) - ShieldStateCode.VERIFICATION_VIOLATION -> MessageShield.VerificationViolation(isCritical) - ShieldStateCode.MISMATCHED_SENDER -> MessageShield.MismatchedSender(isCritical) + TimelineEventShieldStateCode.AUTHENTICITY_NOT_GUARANTEED -> MessageShield.AuthenticityNotGuaranteed(isCritical) + TimelineEventShieldStateCode.UNKNOWN_DEVICE -> MessageShield.UnknownDevice(isCritical) + TimelineEventShieldStateCode.UNSIGNED_DEVICE -> MessageShield.UnsignedDevice(isCritical) + TimelineEventShieldStateCode.UNVERIFIED_IDENTITY -> MessageShield.UnverifiedIdentity(isCritical) + TimelineEventShieldStateCode.SENT_IN_CLEAR -> MessageShield.SentInClear(isCritical) + TimelineEventShieldStateCode.VERIFICATION_VIOLATION -> MessageShield.VerificationViolation(isCritical) + TimelineEventShieldStateCode.MISMATCHED_SENDER -> MessageShield.MismatchedSender(isCritical) } } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt index c106b6b39e..41823a0fbb 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt @@ -35,8 +35,10 @@ internal fun aRustEventTimelineItem( readReceipts: Map = emptyMap(), origin: EventItemOrigin? = EventItemOrigin.SYNC, canBeRepliedTo: Boolean = true, - shieldsState: ShieldState? = null, + shieldsState: ShieldState = ShieldState.None, localCreatedAt: ULong? = null, + forwarder: String? = null, + forwarderProfile: ProfileDetails? = null, ) = EventTimelineItem( isRemote = isRemote, eventOrTransactionId = eventOrTransactionId, @@ -54,5 +56,7 @@ internal fun aRustEventTimelineItem( lazyProvider = FakeFfiLazyTimelineItemProvider( debugInfo = debugInfo, shieldsState = shieldsState, - ) + ), + forwarder = forwarder, + forwarderProfile = forwarderProfile, ) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiLazyTimelineItemProvider.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiLazyTimelineItemProvider.kt index 8ee167d769..a62f1a5f61 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiLazyTimelineItemProvider.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiLazyTimelineItemProvider.kt @@ -17,7 +17,7 @@ import org.matrix.rustcomponents.sdk.ShieldState class FakeFfiLazyTimelineItemProvider( private val debugInfo: EventTimelineItemDebugInfo = anEventTimelineItemDebugInfo(), - private val shieldsState: ShieldState? = null, + private val shieldsState: ShieldState = ShieldState.None, ) : LazyTimelineItemProvider(NoHandle) { override fun getShields(strict: Boolean) = shieldsState override fun debugInfo() = debugInfo From cbb91500f32d88952dbec76474e0cb4c117a2da2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 7 Jan 2026 20:12:41 +0100 Subject: [PATCH 309/347] quality: add bunch of tests for Security&Privacy new features --- .../impl/SecurityAndPrivacyFlowNode.kt | 5 +- .../ManageAuthorizedSpacesStateProvider.kt | 22 +- .../impl/SecurityAndPrivacyFlowNodeTest.kt | 120 ++++++ .../impl/SecurityAndPrivacyPresenterTest.kt | 376 +++++++++++++++++- .../impl/SecurityAndPrivacyViewTest.kt | 45 +++ .../ManageAuthorizedSpacesPresenterTest.kt | 96 +++++ .../ManageAuthorizedSpacesViewTest.kt | 109 +++++ 7 files changed, 752 insertions(+), 21 deletions(-) create mode 100644 features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt create mode 100644 features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt create mode 100644 features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesViewTest.kt diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index f7bdde7aa0..2c21964f48 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -9,6 +9,7 @@ package io.element.android.features.securityandprivacy.impl import android.os.Parcelable +import androidx.annotation.VisibleForTesting import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.lifecycle.Lifecycle @@ -71,7 +72,9 @@ class SecurityAndPrivacyFlowNode( } private val callback: SecurityAndPrivacyEntryPoint.Callback = callback() - private val navigator = BackstackSecurityAndPrivacyNavigator(callback, backstack) + + @VisibleForTesting + val navigator = BackstackSecurityAndPrivacyNavigator(callback, backstack) override fun onBuilt() { super.onBuilt() diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt index e232d02022..2e062c186a 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt @@ -20,14 +20,14 @@ open class ManageAuthorizedSpacesStateProvider : PreviewParameterProvider { } } -fun anAuthorizedSpacesData( +fun anAuthorizedSpaceSelection( joinedSpaces: List = aSpaceRoomList(5), unknownSpaceIds: List = emptyList(), - initialSelection: List = emptyList(), + initialSelectedIds: List = emptyList(), ) = AuthorizedSpacesSelection( joinedSpaces = joinedSpaces.toImmutableList(), unknownSpaceIds = unknownSpaceIds.toImmutableList(), - initialSelectedIds = initialSelection.toImmutableList(), + initialSelectedIds = initialSelectedIds.toImmutableList(), ) private fun aManageAuthorizedSpacesState( - authorizedSpacesData: AuthorizedSpacesSelection = anAuthorizedSpacesData(), - currentSelection: List = emptyList(), + authorizedSpacesSelection: AuthorizedSpacesSelection = anAuthorizedSpaceSelection(), + selectedIds: List = emptyList(), eventSink: (ManageAuthorizedSpacesEvent) -> Unit = {}, ) = ManageAuthorizedSpacesState( - selection = authorizedSpacesData, - selectedIds = currentSelection.toImmutableList(), + selection = authorizedSpacesSelection, + selectedIds = selectedIds.toImmutableList(), isSelectionComplete = false, eventSink = eventSink, ) diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt new file mode 100644 index 0000000000..cc32b59684 --- /dev/null +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.bumble.appyx.core.modality.AncestryInfo +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.navmodel.backstack.BackStack +import com.bumble.appyx.navmodel.backstack.activeElement +import com.bumble.appyx.utils.customisations.NodeCustomisationDirectoryImpl +import com.google.common.truth.Truth.assertThat +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint +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.test.room.FakeBaseRoom +import io.element.android.libraries.matrix.test.room.FakeJoinedRoom +import io.element.android.libraries.matrix.test.room.aRoomInfo +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class SecurityAndPrivacyFlowNodeTest { + + @Test + fun `initial backstack contains SecurityAndPrivacy`() = runTest { + val flowNode = createFlowNode() + assertThat(flowNode.currentNavTarget()).isEqualTo(SecurityAndPrivacyFlowNode.NavTarget.SecurityAndPrivacy) + } + + @Test + fun `openEditRoomAddress navigates to EditRoomAddress`() = runTest { + val flowNode = createFlowNode() + flowNode.navigator.openEditRoomAddress() + assertThat(flowNode.currentNavTarget()).isEqualTo(SecurityAndPrivacyFlowNode.NavTarget.EditRoomAddress) + } + + @Test + fun `closeEditRoomAddress pops backstack`() = runTest { + val flowNode = createFlowNode() + flowNode.navigator.openEditRoomAddress() + assertThat(flowNode.currentNavTarget()).isEqualTo(SecurityAndPrivacyFlowNode.NavTarget.EditRoomAddress) + flowNode.navigator.closeEditRoomAddress() + assertThat(flowNode.currentNavTarget()).isEqualTo(SecurityAndPrivacyFlowNode.NavTarget.SecurityAndPrivacy) + } + + @Test + fun `openManageAuthorizedSpaces navigates with forKnockRestricted false`() = runTest { + val flowNode = createFlowNode() + flowNode.navigator.openManageAuthorizedSpaces(forKnockRestricted = false) + assertThat(flowNode.currentNavTarget()).isEqualTo( + SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces(forKnockRestricted = false) + ) + } + + @Test + fun `openManageAuthorizedSpaces navigates with forKnockRestricted true`() = runTest { + val flowNode = createFlowNode() + flowNode.navigator.openManageAuthorizedSpaces(forKnockRestricted = true) + assertThat(flowNode.currentNavTarget()).isEqualTo( + SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces(forKnockRestricted = true) + ) + } + + @Test + fun `closeManageAuthorizedSpaces pops backstack`() = runTest { + val flowNode = createFlowNode() + flowNode.navigator.openManageAuthorizedSpaces(forKnockRestricted = false) + assertThat(flowNode.currentNavTarget()) + .isInstanceOf(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces::class.java) + flowNode.navigator.closeManageAuthorizedSpaces() + assertThat(flowNode.currentNavTarget()).isEqualTo(SecurityAndPrivacyFlowNode.NavTarget.SecurityAndPrivacy) + } + + @Test + fun `onDone invokes callback`() = runTest { + var onDoneCalled = false + val callback = object : SecurityAndPrivacyEntryPoint.Callback { + override fun onDone() { + onDoneCalled = true + } + } + val flowNode = createFlowNode(callback = callback) + flowNode.navigator.onDone() + assertThat(onDoneCalled).isTrue() + } + + private fun createFlowNode( + callback: SecurityAndPrivacyEntryPoint.Callback = object : SecurityAndPrivacyEntryPoint.Callback { + override fun onDone() {} + }, + ): SecurityAndPrivacyFlowNode { + val buildContext = BuildContext( + ancestryInfo = AncestryInfo.Root, + savedStateMap = null, + customisations = NodeCustomisationDirectoryImpl() + ) + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + initialRoomInfo = aRoomInfo( + joinRule = JoinRule.Invite, + historyVisibility = RoomHistoryVisibility.Shared + ) + ) + ) + return SecurityAndPrivacyFlowNode( + buildContext = buildContext, + plugins = listOf(callback), + room = room, + ) + } + + private fun SecurityAndPrivacyFlowNode.currentNavTarget() = backstack.activeElement +} diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index c035b5510d..9a166e4daf 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -18,21 +18,29 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility +import io.element.android.libraries.matrix.api.room.join.AllowRule import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import io.element.android.libraries.matrix.test.A_ROOM_ALIAS +import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions +import io.element.android.libraries.matrix.test.spaces.FakeSpaceService +import io.element.android.libraries.previewutils.room.aSpaceRoom import io.element.android.tests.testutils.lambda.assert import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test +import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest import org.junit.Test @@ -50,7 +58,6 @@ class SecurityAndPrivacyPresenterTest { assertThat(showRoomVisibilitySections).isFalse() assertThat(showHistoryVisibilitySection).isFalse() assertThat(showEncryptionSection).isFalse() - assertThat(isKnockEnabled).isFalse() } with(awaitItem()) { assertThat(editedSettings).isEqualTo(savedSettings) @@ -61,7 +68,6 @@ class SecurityAndPrivacyPresenterTest { assertThat(showRoomVisibilitySections).isFalse() assertThat(showHistoryVisibilitySection).isTrue() assertThat(showEncryptionSection).isTrue() - assertThat(isKnockEnabled).isFalse() } } } @@ -364,17 +370,364 @@ class SecurityAndPrivacyPresenterTest { } @Test - fun `present - isKnockEnabled is true if the Knock feature flag is enabled`() = runTest { + fun `present - Restricted join rule maps to SpaceMember`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + joinRule = JoinRule.Restricted( + rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)) + ), + historyVisibility = RoomHistoryVisibility.Shared, + ) + ) + ) + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.SpaceMember::class.java) + val access = editedSettings.roomAccess as SecurityAndPrivacyRoomAccess.SpaceMember + assertThat(access.spaceIds).containsExactly(A_ROOM_ID) + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - SelectSpaceMemberAccess with single space auto-selects`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite + ) + ) + ) + val client = FakeMatrixClient( + userIdServerNameLambda = { "matrix.org" }, + spaceService = FakeSpaceService( + joinedParentsResult = { _ -> + Result.success(listOf(aSpaceRoom(roomId = A_ROOM_ID))) + } + ) + ) val presenter = createSecurityAndPrivacyPresenter( + room = room, + matrixClient = client, featureFlagService = FakeFeatureFlagService( initialState = mapOf( - FeatureFlags.Knock.key to true, + FeatureFlags.SpaceSettings.key to true, ) ) ) presenter.test { - assertThat(awaitItem().isKnockEnabled).isFalse() - assertThat(awaitItem().isKnockEnabled).isTrue() + skipItems(1) + val state = awaitItem() + assertThat(state.isSpaceMemberSelectable).isTrue() + state.eventSink(SecurityAndPrivacyEvent.SelectSpaceMemberAccess) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.SpaceMember::class.java) + val access = editedSettings.roomAccess as SecurityAndPrivacyRoomAccess.SpaceMember + assertThat(access.spaceIds).containsExactly(A_ROOM_ID) + } + } + } + + @Test + fun `present - SelectSpaceMemberAccess with multiple spaces opens ManageAuthorizedSpaces`() = runTest { + val openManageAuthorizedSpacesLambda = lambdaRecorder { } + val navigator = FakeSecurityAndPrivacyNavigator(openManageAuthorizedSpacesLambda = openManageAuthorizedSpacesLambda) + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite + ) + ) + ) + val client = FakeMatrixClient( + userIdServerNameLambda = { "matrix.org" }, + spaceService = FakeSpaceService( + joinedParentsResult = { _ -> + Result.success(listOf(aSpaceRoom(roomId = A_ROOM_ID), aSpaceRoom(roomId = RoomId("!space2:matrix.org")))) + } + ) + ) + val presenter = createSecurityAndPrivacyPresenter( + room = room, + navigator = navigator, + matrixClient = client, + featureFlagService = FakeFeatureFlagService( + initialState = mapOf( + FeatureFlags.SpaceSettings.key to true, + ) + ) + ) + presenter.test { + skipItems(1) + val state = awaitItem() + assertThat(state.isSpaceMemberSelectable).isTrue() + state.eventSink(SecurityAndPrivacyEvent.SelectSpaceMemberAccess) + assert(openManageAuthorizedSpacesLambda).isCalledOnce().with(value(false)) + } + } + + @Test + fun `present - SpaceMember saves as Restricted join rule`() = runTest { + val updateJoinRuleLambda = lambdaRecorder> { Result.success(Unit) } + val updateRoomVisibilityLambda = lambdaRecorder> { Result.success(Unit) } + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite + ) + ), + updateJoinRuleResult = updateJoinRuleLambda, + updateRoomVisibilityResult = updateRoomVisibilityLambda, + ) + val onDoneLambda = lambdaRecorder { } + val navigator = FakeSecurityAndPrivacyNavigator(onDoneLambda = onDoneLambda) + val presenter = createSecurityAndPrivacyPresenter(room = room, navigator = navigator) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) + val spaceMemberAccess = SecurityAndPrivacyRoomAccess.SpaceMember( + spaceIds = persistentListOf(A_ROOM_ID) + ) + eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(spaceMemberAccess)) + } + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.SpaceMember::class.java) + assertThat(canBeSaved).isTrue() + eventSink(SecurityAndPrivacyEvent.Save) + } + with(awaitItem()) { + assertThat(saveAction).isEqualTo(AsyncAction.Loading) + } + room.givenRoomInfo( + aRoomInfo( + joinRule = JoinRule.Restricted( + rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)) + ), + historyVisibility = RoomHistoryVisibility.Shared, + ) + ) + skipItems(2) + with(awaitItem()) { + assertThat(saveAction).isEqualTo(AsyncAction.Success(Unit)) + } + assert(updateJoinRuleLambda).isCalledOnce().with( + value(JoinRule.Restricted(rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)))) + ) + onDoneLambda.assertions().isCalledOnce() + } + } + + @Test + fun `present - room visibility is NOT configurable for SpaceMember`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Restricted( + rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)) + ) + ) + ) + ) + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.SpaceMember::class.java) + assertThat(showRoomVisibilitySections).isFalse() + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - KnockRestricted join rule maps to AskToJoinWithSpaceMembers`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + joinRule = JoinRule.KnockRestricted( + rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)) + ), + historyVisibility = RoomHistoryVisibility.Shared, + ) + ) + ) + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember::class.java) + val access = editedSettings.roomAccess as SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember + assertThat(access.spaceIds).containsExactly(A_ROOM_ID) + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - showAskToJoinWithSpaceMembersOption is true when both FFs enabled and spaces available`() = runTest { + val presenter = createSecurityAndPrivacyPresenter( + featureFlagService = FakeFeatureFlagService( + initialState = mapOf( + FeatureFlags.Knock.key to true, + FeatureFlags.SpaceSettings.key to true, + ) + ) + ) + presenter.test { + skipItems(1) + // Without spaces available, AskToJoinWithSpaceMembers should not be selectable + with(awaitItem()) { + assertThat(isAskToJoinWithSpaceMembersSelectable).isFalse() + assertThat(showAskToJoinWithSpaceMemberOption).isFalse() + // AskToJoin should be shown instead + assertThat(showAskToJoinOption).isTrue() + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - SelectAskToJoinWithSpaceMembersAccess with multiple spaces opens ManageAuthorizedSpaces`() = runTest { + val openManageAuthorizedSpacesLambda = lambdaRecorder { } + val navigator = FakeSecurityAndPrivacyNavigator(openManageAuthorizedSpacesLambda = openManageAuthorizedSpacesLambda) + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite + ) + ) + ) + val client = FakeMatrixClient( + userIdServerNameLambda = { "matrix.org" }, + spaceService = FakeSpaceService( + joinedParentsResult = { _ -> + Result.success(listOf(aSpaceRoom(roomId = A_ROOM_ID), aSpaceRoom(roomId = RoomId("!space2:matrix.org")))) + } + ) + ) + val presenter = createSecurityAndPrivacyPresenter( + room = room, + navigator = navigator, + matrixClient = client, + featureFlagService = FakeFeatureFlagService( + initialState = mapOf( + FeatureFlags.Knock.key to true, + FeatureFlags.SpaceSettings.key to true, + ) + ) + ) + presenter.test { + skipItems(1) + // Wait for space selection mode to be set + val state = awaitItem() + assertThat(state.isAskToJoinWithSpaceMembersSelectable).isTrue() + state.eventSink(SecurityAndPrivacyEvent.SelectAskToJoinWithSpaceMembersAccess) + assert(openManageAuthorizedSpacesLambda).isCalledOnce().with(value(true)) + } + } + + @Test + fun `present - AskToJoinWithSpaceMember saves as KnockRestricted join rule`() = runTest { + val updateJoinRuleLambda = lambdaRecorder> { Result.success(Unit) } + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite + ) + ), + updateJoinRuleResult = updateJoinRuleLambda, + ) + val onDoneLambda = lambdaRecorder { } + val navigator = FakeSecurityAndPrivacyNavigator(onDoneLambda = onDoneLambda) + val presenter = createSecurityAndPrivacyPresenter(room = room, navigator = navigator) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) + val askToJoinAccess = SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember( + spaceIds = persistentListOf(A_ROOM_ID) + ) + eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(askToJoinAccess)) + } + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember::class.java) + assertThat(canBeSaved).isTrue() + eventSink(SecurityAndPrivacyEvent.Save) + } + with(awaitItem()) { + assertThat(saveAction).isEqualTo(AsyncAction.Loading) + } + room.givenRoomInfo( + aRoomInfo( + joinRule = JoinRule.KnockRestricted( + rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)) + ), + historyVisibility = RoomHistoryVisibility.Shared, + ) + ) + // Saved settings are updated multiple times to match the edited settings + skipItems(2) + with(awaitItem()) { + assertThat(saveAction).isEqualTo(AsyncAction.Success(Unit)) + } + assert(updateJoinRuleLambda).isCalledOnce().with( + value(JoinRule.KnockRestricted(rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)))) + ) + onDoneLambda.assertions().isCalledOnce() + } + } + + @Test + fun `present - room visibility is configurable for AskToJoinWithSpaceMember`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + getRoomVisibilityResult = { Result.success(RoomVisibility.Private) }, + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.KnockRestricted( + rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)) + ) + ) + ) + ) + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember::class.java) + assertThat(showRoomVisibilitySections).isTrue() + } + with(awaitItem()) { + assertThat(editedSettings.isVisibleInRoomDirectory).isEqualTo(AsyncData.Success(false)) + eventSink(SecurityAndPrivacyEvent.ToggleRoomVisibility) + } + with(awaitItem()) { + assertThat(editedSettings.isVisibleInRoomDirectory).isEqualTo(AsyncData.Success(true)) + assertThat(canBeSaved).isTrue() + } } } @@ -408,12 +761,17 @@ class SecurityAndPrivacyPresenterTest { ), navigator: SecurityAndPrivacyNavigator = FakeSecurityAndPrivacyNavigator(), featureFlagService: FeatureFlagService = FakeFeatureFlagService(), + matrixClient: MatrixClient = FakeMatrixClient( + userIdServerNameLambda = { serverName }, + spaceService = FakeSpaceService( + joinedParentsResult = { Result.success(emptyList()) }, + getSpaceRoomResult = { null } + ), + ), ): SecurityAndPrivacyPresenter { return SecurityAndPrivacyPresenter( room = room, - matrixClient = FakeMatrixClient( - userIdServerNameLambda = { serverName }, - ), + matrixClient = matrixClient, navigator = navigator, featureFlagService = featureFlagService, ) diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt index b15bc2fe37..10dac2213b 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt @@ -19,8 +19,11 @@ import io.element.android.features.securityandprivacy.impl.root.SecurityAndPriva import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyRoomAccess import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyState import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyView +import io.element.android.features.securityandprivacy.impl.root.SpaceSelectionMode import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacySettings import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacyState +import io.element.android.libraries.matrix.test.A_ROOM_ID +import kotlinx.collections.immutable.persistentListOf import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.ui.strings.CommonStrings @@ -179,6 +182,48 @@ class SecurityAndPrivacyViewTest { rule.clickOn(R.string.screen_security_and_privacy_enable_encryption_alert_confirm_button_title) recorder.assertSingle(SecurityAndPrivacyEvent.ConfirmEnableEncryption) } + + @Test + @Config(qualifiers = "h1024dp") + fun `click on space member access emits the expected event`() { + val recorder = EventsRecorder() + val state = aSecurityAndPrivacyState( + eventSink = recorder, + spaceSelectionMode = SpaceSelectionMode.Single(A_ROOM_ID, null), + ) + rule.setSecurityAndPrivacyView(state) + rule.clickOn(R.string.screen_security_and_privacy_room_access_space_members_option_title) + recorder.assertSingle(SecurityAndPrivacyEvent.SelectSpaceMemberAccess) + } + + @Test + @Config(qualifiers = "h1024dp") + fun `click on ask to join with space members emits the expected event`() { + val recorder = EventsRecorder() + val state = aSecurityAndPrivacyState( + eventSink = recorder, + spaceSelectionMode = SpaceSelectionMode.Single(A_ROOM_ID, null), + ) + rule.setSecurityAndPrivacyView(state) + rule.clickOn(R.string.screen_security_and_privacy_ask_to_join_option_title) + recorder.assertSingle(SecurityAndPrivacyEvent.SelectAskToJoinWithSpaceMembersAccess) + } + + @Test + @Config(qualifiers = "h1024dp") + fun `manage spaces footer is shown when space member access is selected`() { + val recorder = EventsRecorder(expectEvents = false) + val state = aSecurityAndPrivacyState( + eventSink = recorder, + spaceSelectionMode = SpaceSelectionMode.Multiple, + editedSettings = aSecurityAndPrivacySettings( + roomAccess = SecurityAndPrivacyRoomAccess.SpaceMember(persistentListOf(A_ROOM_ID)), + ), + ) + rule.setSecurityAndPrivacyView(state) + // The footer text uses AnnotatedString with a link. Verify the footer text is displayed. + rule.onNodeWithText("Choose which spaces", substring = true).assertExists() + } } private fun AndroidComposeTestRule.setSecurityAndPrivacyView( diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt new file mode 100644 index 0000000000..86a0b47fc5 --- /dev/null +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.test.A_ROOM_ID +import io.element.android.tests.testutils.test +import kotlinx.collections.immutable.persistentListOf +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class ManageAuthorizedSpacesPresenterTest { + @Test + fun `present - initial state has empty selection`() = runTest { + val presenter = ManageAuthorizedSpacesPresenter() + presenter.test { + with(awaitItem()) { + assertThat(selectedIds).isEmpty() + assertThat(isSelectionComplete).isFalse() + assertThat(isDoneButtonEnabled).isFalse() + } + } + } + + @Test + fun `present - SetData event updates selection and initial selectedIds`() = runTest { + val presenter = ManageAuthorizedSpacesPresenter() + presenter.test { + val initialState = awaitItem() + val roomId = A_ROOM_ID + val data = AuthorizedSpacesSelection( + joinedSpaces = persistentListOf(), + unknownSpaceIds = persistentListOf(), + initialSelectedIds = persistentListOf(roomId) + ) + initialState.eventSink(ManageAuthorizedSpacesEvent.SetData(data)) + // SetData updates two state variables, which may emit intermediate states + skipItems(1) + with(awaitItem()) { + assertThat(selection).isEqualTo(data) + assertThat(selectedIds).containsExactly(roomId) + assertThat(isDoneButtonEnabled).isTrue() + } + } + } + + @Test + fun `present - ToggleSpace event adds space to selectedIds`() = runTest { + val presenter = ManageAuthorizedSpacesPresenter() + presenter.test { + val initialState = awaitItem() + val roomId = A_ROOM_ID + initialState.eventSink(ManageAuthorizedSpacesEvent.ToggleSpace(roomId)) + with(awaitItem()) { + assertThat(selectedIds).containsExactly(roomId) + assertThat(isDoneButtonEnabled).isTrue() + } + } + } + + @Test + fun `present - ToggleSpace event removes space when already selected`() = runTest { + val presenter = ManageAuthorizedSpacesPresenter() + presenter.test { + val initialState = awaitItem() + val roomId = A_ROOM_ID + initialState.eventSink(ManageAuthorizedSpacesEvent.ToggleSpace(roomId)) + val stateWithSelection = awaitItem() + assertThat(stateWithSelection.selectedIds).containsExactly(roomId) + stateWithSelection.eventSink(ManageAuthorizedSpacesEvent.ToggleSpace(roomId)) + with(awaitItem()) { + assertThat(selectedIds).isEmpty() + assertThat(isDoneButtonEnabled).isFalse() + } + } + } + + @Test + fun `present - Done event sets isSelectionComplete to true`() = runTest { + val presenter = ManageAuthorizedSpacesPresenter() + presenter.test { + val initialState = awaitItem() + initialState.eventSink(ManageAuthorizedSpacesEvent.Done) + with(awaitItem()) { + assertThat(isSelectionComplete).isTrue() + } + } + } +} diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesViewTest.kt new file mode 100644 index 0000000000..515fe590a3 --- /dev/null +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesViewTest.kt @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.test.A_ROOM_ID +import io.element.android.libraries.previewutils.room.aSpaceRoom +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 kotlinx.collections.immutable.toImmutableList +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class ManageAuthorizedSpacesViewTest { + @get:Rule val rule = createAndroidComposeRule() + + @Test + fun `clicking back invokes callback`() { + ensureCalledOnce { callback -> + rule.setManageAuthorizedSpacesView(onBackClick = callback) + rule.pressBack() + } + } + + @Test + fun `clicking space checkbox emits ToggleSpace event`() { + val roomId = A_ROOM_ID + val space = aSpaceRoom(roomId = roomId, displayName = "Test Space") + val recorder = EventsRecorder() + val state = aManageAuthorizedSpacesState( + selection = anAuthorizedSpaceSelection( + joinedSpaces = listOf(space) + ), + eventSink = recorder + ) + rule.setManageAuthorizedSpacesView(state) + rule.onNodeWithText("Test Space").performClick() + recorder.assertSingle(ManageAuthorizedSpacesEvent.ToggleSpace(roomId)) + } + + @Test + fun `clicking done button emits Done event`() { + val recorder = EventsRecorder() + val state = aManageAuthorizedSpacesState( + selectedIds = listOf(A_ROOM_ID), + eventSink = recorder + ) + rule.setManageAuthorizedSpacesView(state) + rule.clickOn(CommonStrings.action_done) + recorder.assertSingle(ManageAuthorizedSpacesEvent.Done) + } + + @Test + fun `done button is disabled when no spaces selected`() { + val recorder = EventsRecorder(expectEvents = false) + val state = aManageAuthorizedSpacesState( + selectedIds = emptyList(), + eventSink = recorder + ) + rule.setManageAuthorizedSpacesView(state) + rule.clickOn(CommonStrings.action_done) + recorder.assertEmpty() + } +} + +private fun AndroidComposeTestRule.setManageAuthorizedSpacesView( + state: ManageAuthorizedSpacesState = aManageAuthorizedSpacesState( + eventSink = EventsRecorder(expectEvents = false) + ), + onBackClick: () -> Unit = EnsureNeverCalled(), +) { + setContent { + ManageAuthorizedSpacesView( + state = state, + onBackClick = onBackClick, + ) + } +} + +private fun aManageAuthorizedSpacesState( + selection: AuthorizedSpacesSelection = AuthorizedSpacesSelection(), + selectedIds: List = emptyList(), + isSelectionComplete: Boolean = false, + eventSink: (ManageAuthorizedSpacesEvent) -> Unit = {}, +) = ManageAuthorizedSpacesState( + selection = selection, + selectedIds = selectedIds.toImmutableList(), + isSelectionComplete = isSelectionComplete, + eventSink = eventSink, +) From 9cbc8cfa6755f0257201f3283fd3356a852efac0 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 7 Jan 2026 20:19:13 +0100 Subject: [PATCH 310/347] Fix SecurityAndPrivacy preview state configuration --- .../impl/root/SecurityAndPrivacyStateProvider.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index d253021143..95cb45d641 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -66,21 +66,24 @@ private fun commonSecurityAndPrivacyStates(isSpace: Boolean): Sequence Date: Wed, 7 Jan 2026 21:09:20 +0100 Subject: [PATCH 311/347] quality : format and clean --- .../impl/SecurityAndPrivacyFlowNode.kt | 8 ++++---- .../impl/SecurityAndPrivacyNavigator.kt | 2 +- .../ManageAuthorizedSpacesNode.kt | 1 - .../ManageAuthorizedSpacesPresenter.kt | 11 +++++------ .../ManageAuthorizedSpacesStateProvider.kt | 1 - .../impl/root/SecurityAndPrivacyEvent.kt | 2 ++ .../impl/root/SecurityAndPrivacyNode.kt | 3 +-- .../impl/root/SecurityAndPrivacyPresenter.kt | 7 +++---- .../impl/root/SecurityAndPrivacyState.kt | 7 ++++--- .../impl/root/SecurityAndPrivacyView.kt | 4 +--- .../impl/SecurityAndPrivacyFlowNodeTest.kt | 2 -- .../impl/SecurityAndPrivacyPresenterTest.kt | 1 + .../impl/SecurityAndPrivacyViewTest.kt | 4 ++-- .../ManageAuthorizedSpacesPresenterTest.kt | 1 - 14 files changed, 24 insertions(+), 30 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index 2c21964f48..4628974295 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -21,7 +21,6 @@ import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.activeElement -import com.bumble.appyx.navmodel.backstack.operation.pop import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode @@ -35,7 +34,6 @@ import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.RoomScope -import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.powerlevels.use import kotlinx.coroutines.NonCancellable @@ -92,9 +90,11 @@ class SecurityAndPrivacyFlowNode( callback.onDone() } } - whenChildrenAttached { commonLifecycle: Lifecycle, + whenChildrenAttached { + commonLifecycle: Lifecycle, securityAndPrivacyNode: SecurityAndPrivacyNode, - manageAuthorizedSpacesNode: ManageAuthorizedSpacesNode -> + manageAuthorizedSpacesNode: ManageAuthorizedSpacesNode + -> commonLifecycle.coroutineScope.launch { val authorizedSpacesData = securityAndPrivacyNode.getAuthorizedSpacesData() val selectedSpaces = manageAuthorizedSpacesNode.waitForCompletion(authorizedSpacesData) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt index 9690c915d5..0944ae92bd 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt @@ -18,7 +18,7 @@ interface SecurityAndPrivacyNavigator : Plugin { fun onDone() fun openEditRoomAddress() fun closeEditRoomAddress() - fun openManageAuthorizedSpaces(forKnockRestricted: Boolean = false) + fun openManageAuthorizedSpaces(forKnockRestricted: Boolean) fun closeManageAuthorizedSpaces() } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt index b8f7150d86..08c757b87d 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt @@ -33,7 +33,6 @@ class ManageAuthorizedSpacesNode( @Assisted plugins: List, presenter: ManageAuthorizedSpacesPresenter, ) : Node(buildContext, plugins = plugins) { - private val navigator = plugins().first() private val stateFlow = launchMolecule { presenter.present() } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt index 0679c72066..aa2251408f 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt @@ -18,11 +18,10 @@ import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.core.RoomId import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toPersistentList +import kotlinx.collections.immutable.toImmutableList @Inject -class ManageAuthorizedSpacesPresenter() : Presenter { - +class ManageAuthorizedSpacesPresenter : Presenter { @Composable override fun present(): ManageAuthorizedSpacesState { var selectedIds: ImmutableList by remember { mutableStateOf(persistentListOf()) } @@ -31,12 +30,12 @@ class ManageAuthorizedSpacesPresenter() : Presenter fun handleEvent(event: ManageAuthorizedSpacesEvent) { when (event) { - ManageAuthorizedSpacesEvent.Done ->isSelectionComplete = true + ManageAuthorizedSpacesEvent.Done -> isSelectionComplete = true is ManageAuthorizedSpacesEvent.ToggleSpace -> { selectedIds = if (selectedIds.contains(event.roomId)) { - selectedIds.minus(event.roomId).toPersistentList() + selectedIds.minus(event.roomId).toImmutableList() } else { - selectedIds.plus(event.roomId).toPersistentList() + selectedIds.plus(event.roomId).toImmutableList() } } is ManageAuthorizedSpacesEvent.SetData -> { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt index 2e062c186a..d818e31317 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt @@ -69,4 +69,3 @@ private fun aManageAuthorizedSpacesState( isSelectionComplete = false, eventSink = eventSink, ) - diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt index 25045a72c1..d61f063a26 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvent.kt @@ -15,8 +15,10 @@ sealed interface SecurityAndPrivacyEvent { data object Exit : SecurityAndPrivacyEvent data object DismissExitConfirmation : SecurityAndPrivacyEvent data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvent + // Special case for "Space Members" data object SelectSpaceMemberAccess : SecurityAndPrivacyEvent + // Special case for "Ask to join with Space Members" data object SelectAskToJoinWithSpaceMembersAccess : SecurityAndPrivacyEvent data object ToggleEncryptionState : SecurityAndPrivacyEvent diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt index 7d3c115be5..815b7bd35e 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt @@ -46,7 +46,7 @@ class SecurityAndPrivacyNode( activity.openUrlInChromeCustomTab(null, darkTheme, url) } - fun getAuthorizedSpacesData(): AuthorizedSpacesSelection{ + fun getAuthorizedSpacesData(): AuthorizedSpacesSelection { return stateFlow.value.getAuthorizedSpacesSelection() } @@ -72,5 +72,4 @@ class SecurityAndPrivacyNode( modifier = modifier ) } - } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index a27884a1ab..f80b96ca00 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -35,7 +35,6 @@ 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.RoomAlias -import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility @@ -193,11 +192,12 @@ class SecurityAndPrivacyPresenter( saveAction.value = AsyncAction.Uninitialized } SecurityAndPrivacyEvent.ManageAuthorizedSpaces -> { - navigator.openManageAuthorizedSpaces() + navigator.openManageAuthorizedSpaces( + forKnockRestricted = editedRoomAccess.value is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember + ) } SecurityAndPrivacyEvent.SelectSpaceMemberAccess -> handleSpaceMemberAccessSelection( spaceSelectionMode = spaceSelectionMode, - spaceIds = editedSettings.roomAccess.spaceIds(), editedAccess = editedRoomAccess, ) SecurityAndPrivacyEvent.SelectAskToJoinWithSpaceMembersAccess -> handleAskToJoinWithSpaceMembersAccessSelection( @@ -250,7 +250,6 @@ class SecurityAndPrivacyPresenter( private fun handleSpaceMemberAccessSelection( spaceSelectionMode: SpaceSelectionMode, - spaceIds: List, editedAccess: MutableState, ) { if (editedAccess.value is SecurityAndPrivacyRoomAccess.SpaceMember) { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index 9d47e57846..ff627f6a0e 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -38,7 +38,6 @@ data class SecurityAndPrivacyState( private val spaceSelectionMode: SpaceSelectionMode, val eventSink: (SecurityAndPrivacyEvent) -> Unit ) { - val isSpaceMemberSelectable = isSpaceSettingsEnabled && spaceSelectionMode != SpaceSelectionMode.None // Show SpaceMember option in two cases: @@ -58,7 +57,7 @@ data class SecurityAndPrivacyState( // - AskToJoin is the current saved value (legacy), OR // - Knock FF enabled BUT (SpaceSettings FF disabled OR no spaces available) val showAskToJoinOption = savedSettings.roomAccess == SecurityAndPrivacyRoomAccess.AskToJoin || - (isAskToJoinSelectable && !isAskToJoinWithSpaceMembersSelectable) + isAskToJoinSelectable && !isAskToJoinWithSpaceMembersSelectable // Show AskToJoinWithSpaceMember option when: // - It's the current saved value, OR @@ -98,7 +97,9 @@ data class SecurityAndPrivacyState( stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_single_parent_description, spaceName) } is SpaceSelectionMode.None, - is SpaceSelectionMode.Multiple -> stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_multiple_parents_description) + is SpaceSelectionMode.Multiple -> stringResource( + R.string.screen_security_and_privacy_room_access_space_members_option_multiple_parents_description + ) } } else { stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_unavailable_description) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 991fa8c133..3ebb2de282 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -208,9 +208,7 @@ private fun RoomAccessSection( state: SecurityAndPrivacyState, modifier: Modifier = Modifier, ) { - val edited = state.editedSettings.roomAccess - val saved = state.savedSettings.roomAccess fun onSelectOption(option: SecurityAndPrivacyRoomAccess) { state.eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(option)) @@ -282,7 +280,7 @@ private fun RoomAccessSection( val footerText = stringWithLink( textRes = R.string.screen_security_and_privacy_room_access_footer, url = stringResource(R.string.screen_security_and_privacy_room_access_footer_manage_spaces_action), - onLinkClick = {onManageSpacesClick()}, + onLinkClick = { onManageSpacesClick() }, ) Text( text = footerText, diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt index cc32b59684..baae82a586 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt @@ -11,7 +11,6 @@ package io.element.android.features.securityandprivacy.impl import androidx.test.ext.junit.runners.AndroidJUnit4 import com.bumble.appyx.core.modality.AncestryInfo import com.bumble.appyx.core.modality.BuildContext -import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.activeElement import com.bumble.appyx.utils.customisations.NodeCustomisationDirectoryImpl import com.google.common.truth.Truth.assertThat @@ -27,7 +26,6 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class SecurityAndPrivacyFlowNodeTest { - @Test fun `initial backstack contains SecurityAndPrivacy`() = runTest { val flowNode = createFlowNode() diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index 9a166e4daf..70c86b9525 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -44,6 +44,7 @@ import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest import org.junit.Test +@Suppress("LargeClass") class SecurityAndPrivacyPresenterTest { @Test fun `present - initial states`() = runTest { diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt index 10dac2213b..7cd9b154cf 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt @@ -22,15 +22,15 @@ import io.element.android.features.securityandprivacy.impl.root.SecurityAndPriva import io.element.android.features.securityandprivacy.impl.root.SpaceSelectionMode import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacySettings import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacyState -import io.element.android.libraries.matrix.test.A_ROOM_ID -import kotlinx.collections.immutable.persistentListOf import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalledWithParam import io.element.android.tests.testutils.EventsRecorder import io.element.android.tests.testutils.clickOn import io.element.android.tests.testutils.pressBack +import kotlinx.collections.immutable.persistentListOf import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt index 86a0b47fc5..7d678b23bb 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt @@ -9,7 +9,6 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.tests.testutils.test import kotlinx.collections.immutable.persistentListOf From 1b217d464936eded43a5318f453440f555a3c27b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jan 2026 10:01:23 +0100 Subject: [PATCH 312/347] A11Y: ensure a11y focus is not lost and reset to the back button when the user use the keyboard to focus the send button and press the space bar to perform a click. --- .../libraries/textcomposer/TextComposer.kt | 62 ++++++++++++--- .../textcomposer/components/SendButton.kt | 76 +++++++++--------- .../components/VoiceMessageRecorderButton.kt | 78 +++++++------------ 3 files changed, 114 insertions(+), 102 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index f2070c9610..200c6e63fb 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -39,6 +39,8 @@ 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.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.SemanticsPropertyReceiver @@ -61,6 +63,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.HorizontalDivider 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.IconColorButton import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.EventId @@ -123,9 +126,6 @@ fun TextComposer( is TextEditorState.Markdown -> state.state.text.value() is TextEditorState.Rich -> state.richTextEditorState.messageMarkdown } - val onSendClick = { - onSendMessage() - } val onPlayVoiceMessageClick = { onVoicePlayerEvent(VoiceMessagePlayerEvent.Play) @@ -238,20 +238,17 @@ fun TextComposer( val sendButton = @Composable { SendButton( canSendMessage = canSendMessage, - onClick = onSendClick, composerMode = composerMode, ) } val recordVoiceButton = @Composable { VoiceMessageRecorderButton( isRecording = voiceMessageState is VoiceMessageState.Recording, - onEvent = onVoiceRecorderEvent, ) } val sendVoiceButton = @Composable { SendButton( canSendMessage = voiceMessageState is VoiceMessageState.Preview, - onClick = onSendVoiceMessage, composerMode = composerMode, ) } @@ -265,6 +262,39 @@ fun TextComposer( @Composable { TextFormatting(state = it.richTextEditorState) } } + val hapticFeedback = LocalHapticFeedback.current + + fun performHapticFeedback() { + hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) + } + + fun endButtonClickStandard() = when { + !canSendMessage -> + when (voiceMessageState) { + VoiceMessageState.Idle -> { + performHapticFeedback() + onVoiceRecorderEvent.invoke(VoiceMessageRecorderEvent.Start) + } + is VoiceMessageState.Recording -> { + performHapticFeedback() + onVoiceRecorderEvent.invoke(VoiceMessageRecorderEvent.Stop) + } + is VoiceMessageState.Preview -> when (voiceMessageState.isSending) { + true -> { + // No op + } + false -> onSendVoiceMessage() + } + } + else -> onSendMessage() + } + + fun endButtonClickFormatting() { + if (canSendMessage) { + onSendMessage() + } + } + val sendOrRecordButton = when { !canSendMessage -> when (voiceMessageState) { @@ -330,8 +360,9 @@ fun TextComposer( ) }, textFormatting = textFormattingOptions, - endButtonA11y = endButtonA11y, sendButton = sendButton, + endButtonClick = ::endButtonClickFormatting, + endButtonA11y = endButtonA11y, ) } else { StandardLayout( @@ -341,6 +372,7 @@ fun TextComposer( composerOptionsButton = composerOptionsButton, textInput = textInput, endButton = sendOrRecordButton, + endButtonClick = ::endButtonClickStandard, endButtonA11y = endButtonA11y, voiceRecording = voiceRecording, voiceDeleteButton = voiceDeleteButton, @@ -409,6 +441,7 @@ private fun StandardLayout( voiceRecording: @Composable () -> Unit, voiceDeleteButton: @Composable () -> Unit, endButton: @Composable () -> Unit, + endButtonClick: () -> Unit, endButtonA11y: (SemanticsPropertyReceiver.() -> Unit), modifier: Modifier = Modifier, ) { @@ -454,12 +487,13 @@ private fun StandardLayout( textInput() } } - Box( - Modifier + // To avoid loosing keyboard focus, the IconButton has to be defined here and has to be always enabled. + IconButton( + modifier = Modifier .padding(bottom = 5.dp, top = 5.dp, end = 6.dp, start = 6.dp) .size(48.dp) .clearAndSetSemantics(endButtonA11y), - contentAlignment = Alignment.Center, + onClick = endButtonClick, ) { endButton() } @@ -496,6 +530,7 @@ private fun TextFormattingLayout( dismissTextFormattingButton: @Composable () -> Unit, textFormatting: @Composable () -> Unit, sendButton: @Composable () -> Unit, + endButtonClick: () -> Unit, endButtonA11y: (SemanticsPropertyReceiver.() -> Unit), modifier: Modifier = Modifier ) { @@ -527,13 +562,16 @@ private fun TextFormattingLayout( Box(modifier = Modifier.weight(1f)) { textFormatting() } - Box( + // To avoid loosing keyboard focus, the IconButton has to be defined here and has to be always enabled. + IconButton( modifier = Modifier .padding( start = 14.dp, end = 6.dp, ) - .clearAndSetSemantics(endButtonA11y) + .size(48.dp) + .clearAndSetSemantics(endButtonA11y), + onClick = endButtonClick, ) { sendButton() } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt index a136f63b09..e3ccd383f3 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt @@ -41,48 +41,40 @@ import io.element.android.libraries.textcomposer.model.MessageComposerMode @Composable internal fun SendButton( canSendMessage: Boolean, - onClick: () -> Unit, composerMode: MessageComposerMode, modifier: Modifier = Modifier, ) { - IconButton( + val iconVector = when { + composerMode.isEditing -> CompoundIcons.Check() + else -> CompoundIcons.SendSolid() + } + val iconStartPadding = when { + composerMode.isEditing -> 0.dp + else -> 2.dp + } + Box( modifier = modifier - .size(48.dp), - onClick = onClick, - enabled = canSendMessage, + .clip(CircleShape) + .size(36.dp) + .buttonBackgroundModifier(canSendMessage) ) { - val iconVector = when { - composerMode.isEditing -> CompoundIcons.Check() - else -> CompoundIcons.SendSolid() - } - val iconStartPadding = when { - composerMode.isEditing -> 0.dp - else -> 2.dp - } - Box( + Icon( modifier = Modifier - .clip(CircleShape) - .size(36.dp) - .buttonBackgroundModifier(canSendMessage) - ) { - Icon( - modifier = Modifier - .padding(start = iconStartPadding) - .align(Alignment.Center), - imageVector = iconVector, - // Note: accessibility is managed in TextComposer. - contentDescription = null, - tint = if (canSendMessage) { - if (ElementTheme.colors.isLight) { - ElementTheme.colors.iconOnSolidPrimary - } else { - ElementTheme.colors.iconPrimary - } + .padding(start = iconStartPadding) + .align(Alignment.Center), + imageVector = iconVector, + // Note: accessibility is managed in TextComposer. + contentDescription = null, + tint = if (canSendMessage) { + if (ElementTheme.colors.isLight) { + ElementTheme.colors.iconOnSolidPrimary } else { - ElementTheme.colors.iconQuaternary + ElementTheme.colors.iconPrimary } - ) - } + } else { + ElementTheme.colors.iconQuaternary + } + ) } } @@ -117,9 +109,17 @@ internal fun SendButtonPreview() = ElementPreview { val normalMode = MessageComposerMode.Normal val editMode = MessageComposerMode.Edit(EventId("\$id").toEventOrTransactionId(), "") Row { - SendButton(canSendMessage = true, onClick = {}, composerMode = normalMode) - SendButton(canSendMessage = false, onClick = {}, composerMode = normalMode) - SendButton(canSendMessage = true, onClick = {}, composerMode = editMode) - SendButton(canSendMessage = false, onClick = {}, composerMode = editMode) + IconButton(onClick = {}) { + SendButton(canSendMessage = true, composerMode = normalMode) + } + IconButton(onClick = {}) { + SendButton(canSendMessage = false, composerMode = normalMode) + } + IconButton(onClick = {}) { + SendButton(canSendMessage = true, composerMode = editMode) + } + IconButton(onClick = {}) { + SendButton(canSendMessage = false, composerMode = editMode) + } } } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButton.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButton.kt index 32fe2847c2..b512154375 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButton.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButton.kt @@ -14,9 +14,8 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons @@ -25,49 +24,25 @@ 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.utils.CommonDrawables -import io.element.android.libraries.textcomposer.model.VoiceMessageRecorderEvent @Composable internal fun VoiceMessageRecorderButton( isRecording: Boolean, - onEvent: (VoiceMessageRecorderEvent) -> Unit, modifier: Modifier = Modifier, ) { - val hapticFeedback = LocalHapticFeedback.current - - val performHapticFeedback = { - hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) - } - if (isRecording) { - StopButton( - modifier = modifier, - onClick = { - performHapticFeedback() - onEvent(VoiceMessageRecorderEvent.Stop) - } - ) + StopButton(modifier) } else { - StartButton( - modifier = modifier, - onClick = { - performHapticFeedback() - onEvent(VoiceMessageRecorderEvent.Start) - } - ) + StartButton(modifier) } } @Composable private fun StartButton( - onClick: () -> Unit, modifier: Modifier = Modifier, -) = IconButton( - modifier = modifier.size(48.dp), - onClick = onClick, ) { Icon( - modifier = Modifier.size(24.dp), + modifier = modifier.size(24.dp), imageVector = CompoundIcons.MicOn(), // Note: accessibility is managed in TextComposer. contentDescription = null, @@ -77,41 +52,40 @@ private fun StartButton( @Composable private fun StopButton( - onClick: () -> Unit, modifier: Modifier = Modifier, -) = IconButton( - modifier = modifier - .size(48.dp), - onClick = onClick, ) { Box( - Modifier + modifier .size(36.dp) .background( color = ElementTheme.colors.bgActionPrimaryRest, shape = CircleShape, - ) - ) - Icon( - modifier = Modifier.size(24.dp), - resourceId = CommonDrawables.ic_stop, - // Note: accessibility is managed in TextComposer. - contentDescription = null, - tint = ElementTheme.colors.iconOnSolidPrimary, - ) + ), + contentAlignment = Alignment.Center, + ) { + Icon( + modifier = Modifier.size(24.dp), + resourceId = CommonDrawables.ic_stop, + // Note: accessibility is managed in TextComposer. + contentDescription = null, + tint = ElementTheme.colors.iconOnSolidPrimary, + ) + } } @PreviewsDayNight @Composable internal fun VoiceMessageRecorderButtonPreview() = ElementPreview { Row { - VoiceMessageRecorderButton( - isRecording = false, - onEvent = {}, - ) - VoiceMessageRecorderButton( - isRecording = true, - onEvent = {}, - ) + IconButton(onClick = {}) { + VoiceMessageRecorderButton( + isRecording = false, + ) + } + IconButton(onClick = {}) { + VoiceMessageRecorderButton( + isRecording = true, + ) + } } } From 83f72684247209ad6f7d447a09163348b7dbae43 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jan 2026 11:35:52 +0100 Subject: [PATCH 313/347] Cleanup code. This if was not necessary. --- .../libraries/textcomposer/TextComposer.kt | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 200c6e63fb..2bc8e27320 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -453,17 +453,13 @@ private fun StandardLayout( } Row(verticalAlignment = Alignment.Bottom) { if (voiceMessageState !is VoiceMessageState.Idle) { - if (voiceMessageState is VoiceMessageState.Preview || voiceMessageState is VoiceMessageState.Recording) { - Box( - modifier = Modifier - .padding(bottom = 5.dp, top = 5.dp, end = 3.dp, start = 3.dp) - .size(48.dp), - contentAlignment = Alignment.Center, - ) { - voiceDeleteButton() - } - } else { - Spacer(modifier = Modifier.width(16.dp)) + Box( + modifier = Modifier + .padding(bottom = 5.dp, top = 5.dp, end = 3.dp, start = 3.dp) + .size(48.dp), + contentAlignment = Alignment.Center, + ) { + voiceDeleteButton() } Box( modifier = Modifier From 9f9a017ffa6f2cdf498819a7db0e0fb3c73ce8b0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jan 2026 11:42:05 +0100 Subject: [PATCH 314/347] Small rework to prepare a bugfix. No behavior / UI change. --- .../libraries/textcomposer/TextComposer.kt | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 2bc8e27320..b96a7e1462 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -452,7 +452,14 @@ private fun StandardLayout( Spacer(Modifier.height(4.dp)) } Row(verticalAlignment = Alignment.Bottom) { - if (voiceMessageState !is VoiceMessageState.Idle) { + if (voiceMessageState is VoiceMessageState.Idle) { + Box( + Modifier + .padding(bottom = 5.dp, top = 5.dp, start = 3.dp) + ) { + composerOptionsButton() + } + } else { Box( modifier = Modifier .padding(bottom = 5.dp, top = 5.dp, end = 3.dp, start = 3.dp) @@ -461,26 +468,16 @@ private fun StandardLayout( ) { voiceDeleteButton() } - Box( - modifier = Modifier - .padding(bottom = 8.dp, top = 8.dp) - .weight(1f) - ) { - voiceRecording() - } - } else { - Box( - Modifier - .padding(bottom = 5.dp, top = 5.dp, start = 3.dp) - ) { - composerOptionsButton() - } - Box( - modifier = Modifier - .padding(bottom = 8.dp, top = 8.dp) - .weight(1f) - ) { + } + Box( + modifier = Modifier + .padding(bottom = 8.dp, top = 8.dp) + .weight(1f) + ) { + if (voiceMessageState is VoiceMessageState.Idle) { textInput() + } else { + voiceRecording() } } // To avoid loosing keyboard focus, the IconButton has to be defined here and has to be always enabled. From 75fc734892fcdb7778f7473b9220eeab96bc66a4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jan 2026 12:09:29 +0100 Subject: [PATCH 315/347] Ensure that the keyboard focus and accessibility focus is not lost when deleting a pending voice message. --- .../libraries/textcomposer/TextComposer.kt | 104 ++++++++++-------- .../components/VoiceMessageDeleteButton.kt | 46 ++++---- 2 files changed, 76 insertions(+), 74 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index b96a7e1462..4438715444 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.requiredHeightIn import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.ReadOnlyComposable @@ -143,26 +144,6 @@ fun TextComposer( .fillMaxSize() .height(IntrinsicSize.Min) - val composerOptionsButton: @Composable () -> Unit = remember(composerMode) { - @Composable { - when (composerMode) { - is MessageComposerMode.Attachment -> { - Spacer(modifier = Modifier.width(9.dp)) - } - is MessageComposerMode.EditCaption -> { - Spacer(modifier = Modifier.width(16.dp)) - } - else -> { - IconColorButton( - onClick = onAddAttachment, - imageVector = CompoundIcons.Plus(), - contentDescription = stringResource(R.string.rich_text_editor_a11y_add_attachment), - ) - } - } - } - } - val placeholder = if (composerMode.inThread) { stringResource(id = CommonStrings.action_reply_in_thread) } else if (composerMode is MessageComposerMode.Attachment || composerMode is MessageComposerMode.EditCaption) { @@ -337,16 +318,6 @@ fun TextComposer( } } - val voiceDeleteButton = @Composable { - when (voiceMessageState) { - is VoiceMessageState.Preview -> - VoiceMessageDeleteButton(enabled = !voiceMessageState.isSending, onClick = onDeleteVoiceMessage) - is VoiceMessageState.Recording -> - VoiceMessageDeleteButton(enabled = true, onClick = { onVoiceRecorderEvent(VoiceMessageRecorderEvent.Cancel) }) - else -> {} - } - } - if (showTextFormatting && textFormattingOptions != null) { TextFormattingLayout( modifier = layoutModifier, @@ -366,16 +337,18 @@ fun TextComposer( ) } else { StandardLayout( + composerMode = composerMode, voiceMessageState = voiceMessageState, isRoomEncrypted = state.isRoomEncrypted, modifier = layoutModifier, - composerOptionsButton = composerOptionsButton, textInput = textInput, endButton = sendOrRecordButton, endButtonClick = ::endButtonClickStandard, endButtonA11y = endButtonA11y, voiceRecording = voiceRecording, - voiceDeleteButton = voiceDeleteButton, + onAddAttachment = onAddAttachment, + onDeleteVoiceMessage = onDeleteVoiceMessage, + onVoiceRecorderEvent = onVoiceRecorderEvent, ) } @@ -434,15 +407,17 @@ private fun endButtonA11y( @Composable private fun StandardLayout( + composerMode: MessageComposerMode, voiceMessageState: VoiceMessageState, isRoomEncrypted: Boolean?, textInput: @Composable () -> Unit, - composerOptionsButton: @Composable () -> Unit, voiceRecording: @Composable () -> Unit, - voiceDeleteButton: @Composable () -> Unit, endButton: @Composable () -> Unit, endButtonClick: () -> Unit, endButtonA11y: (SemanticsPropertyReceiver.() -> Unit), + onAddAttachment: () -> Unit, + onDeleteVoiceMessage: () -> Unit, + onVoiceRecorderEvent: (VoiceMessageRecorderEvent) -> Unit, modifier: Modifier = Modifier, ) { Column(modifier = modifier) { @@ -452,21 +427,54 @@ private fun StandardLayout( Spacer(Modifier.height(4.dp)) } Row(verticalAlignment = Alignment.Bottom) { - if (voiceMessageState is VoiceMessageState.Idle) { - Box( - Modifier - .padding(bottom = 5.dp, top = 5.dp, start = 3.dp) - ) { - composerOptionsButton() + when (composerMode) { + is MessageComposerMode.Attachment -> { + Spacer(modifier = Modifier.width(12.dp)) } - } else { - Box( - modifier = Modifier - .padding(bottom = 5.dp, top = 5.dp, end = 3.dp, start = 3.dp) - .size(48.dp), - contentAlignment = Alignment.Center, - ) { - voiceDeleteButton() + is MessageComposerMode.EditCaption -> { + Spacer(modifier = Modifier.width(19.dp)) + } + else -> { + val endPadding = if (voiceMessageState is VoiceMessageState.Idle) 0.dp else 3.dp + // To avoid loosing keyboard focus, the IconButton has to be defined here and has to be always enabled. + IconButton( + modifier = Modifier + .padding(top = 5.dp, bottom = 5.dp, start = 3.dp, end = endPadding) + .size(48.dp), + onClick = { + if (voiceMessageState is VoiceMessageState.Idle) { + onAddAttachment() + } else { + when (voiceMessageState) { + is VoiceMessageState.Preview -> if (!voiceMessageState.isSending) { + onDeleteVoiceMessage() + } + is VoiceMessageState.Recording -> + onVoiceRecorderEvent(VoiceMessageRecorderEvent.Cancel) + } + } + }, + ) { + if (voiceMessageState is VoiceMessageState.Idle) { + Icon( + modifier = Modifier + .clip(CircleShape) + .size(30.dp) + .background(ElementTheme.colors.iconPrimary) + .padding(3.dp), + imageVector = CompoundIcons.Plus(), + contentDescription = stringResource(R.string.rich_text_editor_a11y_add_attachment), + tint = ElementTheme.colors.iconOnSolidPrimary + ) + } else { + when (voiceMessageState) { + is VoiceMessageState.Preview -> + VoiceMessageDeleteButton(enabled = !voiceMessageState.isSending) + is VoiceMessageState.Recording -> + VoiceMessageDeleteButton(enabled = true) + } + } + } } } Box( diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButton.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButton.kt index af5f443cc7..3e72b309fe 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButton.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButton.kt @@ -25,39 +25,33 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable fun VoiceMessageDeleteButton( enabled: Boolean, - onClick: () -> Unit, modifier: Modifier = Modifier, ) { - IconButton( - modifier = modifier - .size(48.dp), - enabled = enabled, - onClick = onClick, - ) { - Icon( - modifier = Modifier.size(24.dp), - imageVector = CompoundIcons.Delete(), - contentDescription = stringResource(CommonStrings.a11y_delete), - tint = if (enabled) { - ElementTheme.colors.iconCriticalPrimary - } else { - ElementTheme.colors.iconDisabled - }, - ) - } + Icon( + modifier = modifier.size(24.dp), + imageVector = CompoundIcons.Delete(), + contentDescription = stringResource(CommonStrings.a11y_delete), + tint = if (enabled) { + ElementTheme.colors.iconCriticalPrimary + } else { + ElementTheme.colors.iconDisabled + }, + ) } @PreviewsDayNight @Composable internal fun VoiceMessageDeleteButtonPreview() = ElementPreview { Row { - VoiceMessageDeleteButton( - enabled = true, - onClick = {}, - ) - VoiceMessageDeleteButton( - enabled = false, - onClick = {}, - ) + IconButton(onClick = {}) { + VoiceMessageDeleteButton( + enabled = true, + ) + } + IconButton(onClick = {}) { + VoiceMessageDeleteButton( + enabled = false, + ) + } } } From d7eb302d497dcbadc3ef8ce43b3d084f7eb2d389 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 8 Jan 2026 12:44:36 +0000 Subject: [PATCH 316/347] Update screenshots --- ...es.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png | 4 ++-- ....textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerVoice_Day_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerVoice_Night_0_en.png | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png index 8301d09a79..82584525f2 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09faeef5f5864f93d81f271a67826acf417b228987c6f918b95b31f91a468cb1 -size 36097 +oid sha256:74c638ff6c7ea4961af24b176c3f0b2b40ce123c5f058c4f1ba06c6b823cb16f +size 36090 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png index 943d0abc8e..5a65d27d21 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:246d4bf81c16bbbcfc82dd23b23bb1471e3d5e078bc7ecaba3c68d2ab3bb75c2 -size 34307 +oid sha256:8d220ce93b1e7a7a7330ee90f59415a07f49d040ad5c85ff8086b3dba882452d +size 34313 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Day_0_en.png index 24be8a7dbc..39bffa708a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:274f54991bbd79c4220d945964caf7fc523ce99a70b748ef992cc15ee030fdf5 -size 25124 +oid sha256:75d285698529499a08b5a6107bed61de35b30a0e225951fc93edc1c632a5c7ba +size 25121 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Night_0_en.png index 433550b84b..e77b5da5e1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:258643d514aeb7a53788ba2addc53fe46f888193ced2970c73887f9eb1584753 -size 24039 +oid sha256:77ac0f986e20bea03f10f00a699484c31a7959eba2ffb4764f8c1e71428159ed +size 24040 From 13cce209ab7db136b13109e52f7fc98d1e4ca539 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 8 Jan 2026 13:49:53 +0000 Subject: [PATCH 317/347] Update screenshots --- ...geauthorizedspaces_ManageAuthorizedSpacesView_Day_0_en.png | 3 +++ ...geauthorizedspaces_ManageAuthorizedSpacesView_Day_1_en.png | 3 +++ ...geauthorizedspaces_ManageAuthorizedSpacesView_Day_2_en.png | 3 +++ ...authorizedspaces_ManageAuthorizedSpacesView_Night_0_en.png | 3 +++ ...authorizedspaces_ManageAuthorizedSpacesView_Night_1_en.png | 3 +++ ...authorizedspaces_ManageAuthorizedSpacesView_Night_2_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png | 2 +- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_20_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_21_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_22_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_23_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_20_en.png | 3 +++ ...andprivacy.impl.root_SecurityAndPrivacyViewLight_21_en.png | 3 +++ ...andprivacy.impl.root_SecurityAndPrivacyViewLight_22_en.png | 3 +++ ...andprivacy.impl.root_SecurityAndPrivacyViewLight_23_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png | 4 ++-- 46 files changed, 105 insertions(+), 63 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_en.png new file mode 100644 index 0000000000..1fb6e305bc --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e09986f8b500061cfc9108af757b581334d8babb3c5c17433dd53dd3a8f52f3 +size 48709 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_en.png new file mode 100644 index 0000000000..1fb6e305bc --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e09986f8b500061cfc9108af757b581334d8babb3c5c17433dd53dd3a8f52f3 +size 48709 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_en.png new file mode 100644 index 0000000000..327f317576 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f953609cb044e439198f7072a4468c54269b646e3c39686440334903eb12797d +size 49279 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_0_en.png new file mode 100644 index 0000000000..0e84fd507e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c481049fcd33ca40aac538bf82ca56ef27cce2448c148cc45ba95493b668ef03 +size 47890 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_1_en.png new file mode 100644 index 0000000000..0e84fd507e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c481049fcd33ca40aac538bf82ca56ef27cce2448c148cc45ba95493b668ef03 +size 47890 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_2_en.png new file mode 100644 index 0000000000..85f1bc55ea --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15ed6659fbf148a23b4090ba8896bad91d82279df71552c2798755b190a0cdca +size 48369 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png index 5015b5c995..46ad8a30d5 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bef6e6c4cdd362577cf5dc91914a84c72465014a71a08f48c1f4a526be44c85c -size 39535 +oid sha256:67bd76421dcb3e8a6c2c0a6aeda024dacb392b2f6d8bea278d6ffae7de5b4e8f +size 20023 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png index fbef6afae3..6b5c72706b 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:39222fd299a2dec3cc60863878906eba5c9d86100a3e4bad781633a1a0372cc5 +oid sha256:48f50c8053f0f15228899e8bce1656a90cfaf936e6bc8ca725c676aff5578575 size 39874 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png index 8abe7a325a..5015b5c995 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c9bf91f57bb68ae3341acecd62d418d1654a8d4cf271eeda9e87bc5e4998891 -size 20225 +oid sha256:bef6e6c4cdd362577cf5dc91914a84c72465014a71a08f48c1f4a526be44c85c +size 39535 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png index 3989ce8d6e..fbef6afae3 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:495fff852c9549125b3d3a681a880147f680d4604eee3cb13a8fc3dc47e7c729 -size 40476 +oid sha256:39222fd299a2dec3cc60863878906eba5c9d86100a3e4bad781633a1a0372cc5 +size 39874 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png index fbef6afae3..71f935b3c0 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:39222fd299a2dec3cc60863878906eba5c9d86100a3e4bad781633a1a0372cc5 -size 39874 +oid sha256:3b2a019695bb544f7bfbb2b2c5fddc5140a25a770695d1354c2b393e942ebba5 +size 24687 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png index 8bb18a4153..8b34eb8946 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cdd805d857d590437bde9be2a7df252ff42571d3b08be8085aae81dc75e896c3 -size 40235 +oid sha256:adaadbcdcb1d281683fcd7cfb69604ed875ffd4a48233dfd2941d3997ab097de +size 51431 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png index 81ed09d87e..8b34eb8946 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:507eec1e5125056ca4980ae67f904dd30bcb88ef6d66d5968aafbb3c1449e4b8 -size 33779 +oid sha256:adaadbcdcb1d281683fcd7cfb69604ed875ffd4a48233dfd2941d3997ab097de +size 51431 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png index 14683ef0b0..3989ce8d6e 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d300a9854096634ea0e6722db487607a75f6e0c46d7341f044a190a212d95307 -size 32373 +oid sha256:495fff852c9549125b3d3a681a880147f680d4604eee3cb13a8fc3dc47e7c729 +size 40476 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png index 810bb5531a..fbef6afae3 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b42e3df9fec259210b63431e295e8c7d1a7640149c9616b572b90c0b40392a60 -size 34637 +oid sha256:39222fd299a2dec3cc60863878906eba5c9d86100a3e4bad781633a1a0372cc5 +size 39874 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png index 0bd3c0413d..8bb18a4153 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3bb107a37b14dcbc6aa530a8d47f58c809df7719a0c8a416a268ffd2df165681 -size 41602 +oid sha256:cdd805d857d590437bde9be2a7df252ff42571d3b08be8085aae81dc75e896c3 +size 40235 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_en.png new file mode 100644 index 0000000000..81ed09d87e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:507eec1e5125056ca4980ae67f904dd30bcb88ef6d66d5968aafbb3c1449e4b8 +size 33779 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_en.png new file mode 100644 index 0000000000..14683ef0b0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d300a9854096634ea0e6722db487607a75f6e0c46d7341f044a190a212d95307 +size 32373 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_en.png new file mode 100644 index 0000000000..810bb5531a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b42e3df9fec259210b63431e295e8c7d1a7640149c9616b572b90c0b40392a60 +size 34637 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_en.png new file mode 100644 index 0000000000..0bd3c0413d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bb107a37b14dcbc6aa530a8d47f58c809df7719a0c8a416a268ffd2df165681 +size 41602 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png index beeea22486..00573c56c2 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b67ebf4536e36571b0867e71533b2fe1953ca2b88f15fe3531f3ddb9043f69ec -size 39418 +oid sha256:1605f3269a888d8cbcab71615816b7564072f26846e481cf3576f9de4b61f2e1 +size 44182 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png index b39a2f040c..9b03e75694 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5fb16ef839b9f93caddbc984c8be260846e7fd7d68ae3b31dcc97c7644b41b4 -size 56670 +oid sha256:77213c9b75eea8880c5fac86c3345e7056f304c8ad5beb6cf2057cb5d67b5415 +size 58621 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png index f29bc630f1..9b03e75694 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9402ad99b181b99083abff78d078e9fbb010144e07f80ff995db7884a61fa853 -size 56060 +oid sha256:77213c9b75eea8880c5fac86c3345e7056f304c8ad5beb6cf2057cb5d67b5415 +size 58621 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png index e5fda5dfd7..b39a2f040c 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cadacec9344f3ca2c029006c620cd8c309bb7f4b38cbb7b47c7c336ca265a141 -size 56424 +oid sha256:e5fb16ef839b9f93caddbc984c8be260846e7fd7d68ae3b31dcc97c7644b41b4 +size 56670 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png index 46ad8a30d5..f29bc630f1 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:67bd76421dcb3e8a6c2c0a6aeda024dacb392b2f6d8bea278d6ffae7de5b4e8f -size 20023 +oid sha256:9402ad99b181b99083abff78d078e9fbb010144e07f80ff995db7884a61fa853 +size 56060 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png index 6b5c72706b..e5fda5dfd7 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48f50c8053f0f15228899e8bce1656a90cfaf936e6bc8ca725c676aff5578575 -size 39874 +oid sha256:cadacec9344f3ca2c029006c620cd8c309bb7f4b38cbb7b47c7c336ca265a141 +size 56424 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png index da192161cb..83f51a3be7 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:342cc313605f43325a0720fe9c9fa969ed7edd41258ce0768dc624fc4e74d66d -size 40636 +oid sha256:8303e863849a00c16f00850854e8d4d7ceaf3fb097c7b20fe349127d8ed3b082 +size 20651 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png index 4ddc1b913d..eea66871f9 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:adfd4213ac36d904a8a31b1c3bf5463ba72ad4760d084a4c412370d6d51cf250 -size 40996 +oid sha256:1626bffb649c204b0dcb1c92e7344d1b7f119b61ecac3c49840385f3a9a39515 +size 40998 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png index 32138581f7..da192161cb 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ef8e92812f6b65fc09ea4e77d44f9c32a74daebe8e2ef2a9e499588e46a43db -size 20823 +oid sha256:342cc313605f43325a0720fe9c9fa969ed7edd41258ce0768dc624fc4e74d66d +size 40636 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png index d274eddbe1..4ddc1b913d 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5547eb8b7f7ca596edf65bfd7703d1cb91fbf2e254374b9ea41d5c8754030e34 -size 41628 +oid sha256:adfd4213ac36d904a8a31b1c3bf5463ba72ad4760d084a4c412370d6d51cf250 +size 40996 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png index 4ddc1b913d..e050bddd3e 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:adfd4213ac36d904a8a31b1c3bf5463ba72ad4760d084a4c412370d6d51cf250 -size 40996 +oid sha256:c251b0e7daf758b0031c1c81b130d06f295126cb6bbc8efd13f43c6ef581ad8e +size 25132 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png index e939df2248..3a1c1d3bf9 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40c6334e01cc858f343f9046cfbb5079b79369002f5194965b6c2e75dd37b134 -size 41437 +oid sha256:cfadbdeaf77af829c19ae33338e91679acc8b34d2c8493d20994a740e2d2f3ee +size 52901 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png index 0ba776c5fd..3a1c1d3bf9 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:548950d915f6fbfdf1a17b81619d3d4cbefe93b79091d259bcec41ae6bbbc652 -size 35422 +oid sha256:cfadbdeaf77af829c19ae33338e91679acc8b34d2c8493d20994a740e2d2f3ee +size 52901 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png index 5932151ec4..d274eddbe1 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6b47bcab08cded6e857fe213ab2c90602e557a36feebb45b2b8d4d18115ac68b -size 34582 +oid sha256:5547eb8b7f7ca596edf65bfd7703d1cb91fbf2e254374b9ea41d5c8754030e34 +size 41628 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png index 8919639fe0..4ddc1b913d 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5cd5de47e285702bf3d2ee325fc83a1168a0367d9c6b54018565daa0ed503a77 -size 36876 +oid sha256:adfd4213ac36d904a8a31b1c3bf5463ba72ad4760d084a4c412370d6d51cf250 +size 40996 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png index bce9a377e8..e939df2248 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59b6d7d5e484b34e1ce7814432144df34b1cd3323d31c90db439cbb5d9f8dc83 -size 43588 +oid sha256:40c6334e01cc858f343f9046cfbb5079b79369002f5194965b6c2e75dd37b134 +size 41437 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_en.png new file mode 100644 index 0000000000..0ba776c5fd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:548950d915f6fbfdf1a17b81619d3d4cbefe93b79091d259bcec41ae6bbbc652 +size 35422 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_en.png new file mode 100644 index 0000000000..5932151ec4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b47bcab08cded6e857fe213ab2c90602e557a36feebb45b2b8d4d18115ac68b +size 34582 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_en.png new file mode 100644 index 0000000000..8919639fe0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cd5de47e285702bf3d2ee325fc83a1168a0367d9c6b54018565daa0ed503a77 +size 36876 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_en.png new file mode 100644 index 0000000000..bce9a377e8 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59b6d7d5e484b34e1ce7814432144df34b1cd3323d31c90db439cbb5d9f8dc83 +size 43588 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png index a3ddf8b354..97f3d826b9 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3bebec99f2b870e7a38333590f5cb776b30f4f9b976d99601a7fb3bfd05a71f -size 40913 +oid sha256:3cf16df2caf7cdf9ca4a2da151ffa4c7b362b9d22bf9706522dacbd4edf520e5 +size 45867 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png index 085ac47033..bd71e00714 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:853218e7ddc4d18b260f6ab047beb82778284851e230babc14113c6cb329d29a -size 58504 +oid sha256:b77f723d2c6c5eba85660d93cdcd63d785bccd61aab37f0784ca1fa646280743 +size 60462 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png index 0914a151e4..bd71e00714 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e7caee4430244e294b75e3b6a5830088dd25397b1c272666eb2bec47ecd1f382 -size 57895 +oid sha256:b77f723d2c6c5eba85660d93cdcd63d785bccd61aab37f0784ca1fa646280743 +size 60462 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png index c9a3183eea..085ac47033 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbb4224047c88d838de227e61332775e5efe0ce1380a7446c701f0db5b2d2dcc -size 58323 +oid sha256:853218e7ddc4d18b260f6ab047beb82778284851e230babc14113c6cb329d29a +size 58504 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png index 83f51a3be7..0914a151e4 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8303e863849a00c16f00850854e8d4d7ceaf3fb097c7b20fe349127d8ed3b082 -size 20651 +oid sha256:e7caee4430244e294b75e3b6a5830088dd25397b1c272666eb2bec47ecd1f382 +size 57895 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png index eea66871f9..c9a3183eea 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1626bffb649c204b0dcb1c92e7344d1b7f119b61ecac3c49840385f3a9a39515 -size 40998 +oid sha256:bbb4224047c88d838de227e61332775e5efe0ce1380a7446c701f0db5b2d2dcc +size 58323 From 59c175ebe0803506021612b5ecc3ff0be7874470 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jan 2026 15:53:09 +0100 Subject: [PATCH 318/347] Remove BigIcon loading state. Loading is rendered in the buttons now. --- .../impl/incoming/IncomingVerificationView.kt | 85 +++++++------------ .../impl/outgoing/OutgoingVerificationView.kt | 57 +++++-------- .../designsystem/components/BigIcon.kt | 85 +++++++------------ 3 files changed, 86 insertions(+), 141 deletions(-) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt index 286d826a6a..1d37daf82b 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt @@ -21,10 +21,8 @@ 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.semantics.ProgressBarRangeInfo import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.focused -import androidx.compose.ui.semantics.progressBarRangeInfo import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -45,7 +43,6 @@ 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.Button -import io.element.android.libraries.designsystem.theme.components.InvisibleButton import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar @@ -103,19 +100,11 @@ fun IncomingVerificationView( private fun IncomingVerificationHeader(step: Step, request: VerificationRequest.Incoming) { val iconStyle = when (step) { Step.Canceled -> BigIcon.Style.AlertSolid - is Step.Initial -> if (step.isWaiting) { - BigIcon.Style.Loading - } else { - when (request) { - is VerificationRequest.Incoming.OtherSession -> BigIcon.Style.Default(CompoundIcons.LockSolid()) - is VerificationRequest.Incoming.User -> BigIcon.Style.Default(CompoundIcons.UserProfileSolid()) - } - } - is Step.Verifying -> if (step.isWaiting) { - BigIcon.Style.Loading - } else { - BigIcon.Style.Default(CompoundIcons.ReactionSolid()) + is Step.Initial -> when (request) { + is VerificationRequest.Incoming.OtherSession -> BigIcon.Style.Default(CompoundIcons.LockSolid()) + is VerificationRequest.Incoming.User -> BigIcon.Style.Default(CompoundIcons.UserProfileSolid()) } + is Step.Verifying -> BigIcon.Style.Default(CompoundIcons.ReactionSolid()) Step.Completed -> BigIcon.Style.SuccessSolid Step.Failure -> BigIcon.Style.AlertSolid } @@ -159,10 +148,6 @@ private fun IncomingVerificationHeader(step: Step, request: VerificationRequest. .semantics(mergeDescendants = true) { contentDescription = timeLimitMessage focused = true - if (iconStyle == BigIcon.Style.Loading) { - // Same code than Modifier.progressSemantics() - progressBarRangeInfo = ProgressBarRangeInfo.Indeterminate - } } .focusable(), iconStyle = iconStyle, @@ -232,43 +217,37 @@ private fun IncomingVerificationBottomMenu( when (step) { is Step.Initial -> { - if (step.isWaiting) { - // Show nothing - } else { - VerificationBottomMenu { - Button( - modifier = Modifier.fillMaxWidth(), - text = stringResource(CommonStrings.action_start_verification), - onClick = { eventSink(IncomingVerificationViewEvents.StartVerification) }, - ) - TextButton( - modifier = Modifier.fillMaxWidth(), - text = stringResource(CommonStrings.action_ignore), - onClick = { eventSink(IncomingVerificationViewEvents.IgnoreVerification) }, - ) - } + VerificationBottomMenu { + Button( + modifier = Modifier.fillMaxWidth(), + text = stringResource(CommonStrings.action_start_verification), + enabled = !step.isWaiting, + showProgress = step.isWaiting, + onClick = { eventSink(IncomingVerificationViewEvents.StartVerification) }, + ) + TextButton( + modifier = Modifier.fillMaxWidth(), + text = stringResource(CommonStrings.action_ignore), + enabled = !step.isWaiting, + onClick = { eventSink(IncomingVerificationViewEvents.IgnoreVerification) }, + ) } } is Step.Verifying -> { - if (step.isWaiting) { - // Add invisible buttons to keep the same screen layout - VerificationBottomMenu { - InvisibleButton() - InvisibleButton() - } - } else { - VerificationBottomMenu { - Button( - modifier = Modifier.fillMaxWidth(), - text = stringResource(R.string.screen_session_verification_they_match), - onClick = { eventSink(IncomingVerificationViewEvents.ConfirmVerification) }, - ) - TextButton( - modifier = Modifier.fillMaxWidth(), - text = stringResource(R.string.screen_session_verification_they_dont_match), - onClick = { eventSink(IncomingVerificationViewEvents.DeclineVerification) }, - ) - } + VerificationBottomMenu { + Button( + modifier = Modifier.fillMaxWidth(), + text = stringResource(R.string.screen_session_verification_they_match), + enabled = !step.isWaiting, + showProgress = step.isWaiting, + onClick = { eventSink(IncomingVerificationViewEvents.ConfirmVerification) }, + ) + TextButton( + modifier = Modifier.fillMaxWidth(), + text = stringResource(R.string.screen_session_verification_they_dont_match), + enabled = !step.isWaiting, + onClick = { eventSink(IncomingVerificationViewEvents.DeclineVerification) }, + ) } } Step.Canceled, diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt index f2d3ccfee2..51f288b303 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt @@ -24,10 +24,8 @@ 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.semantics.ProgressBarRangeInfo import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.focused -import androidx.compose.ui.semantics.progressBarRangeInfo import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp @@ -129,20 +127,16 @@ fun OutgoingVerificationView( private fun OutgoingVerificationHeader(step: Step, request: VerificationRequest.Outgoing) { val iconStyle = when (step) { Step.Loading -> error("Should not happen") + Step.AwaitingOtherDeviceResponse, Step.Initial -> when (request) { is VerificationRequest.Outgoing.CurrentSession -> BigIcon.Style.Default(CompoundIcons.Devices()) is VerificationRequest.Outgoing.User -> BigIcon.Style.Default(CompoundIcons.LockSolid()) } - Step.AwaitingOtherDeviceResponse -> BigIcon.Style.Loading Step.Canceled -> BigIcon.Style.AlertSolid Step.Ready -> BigIcon.Style.Default(CompoundIcons.ReactionSolid()) Step.Completed -> BigIcon.Style.SuccessSolid is Step.Verifying -> { - if (step.state is AsyncData.Loading) { - BigIcon.Style.Loading - } else { - BigIcon.Style.Default(CompoundIcons.ReactionSolid()) - } + BigIcon.Style.Default(CompoundIcons.ReactionSolid()) } is Step.Exit -> return } @@ -201,10 +195,6 @@ private fun OutgoingVerificationHeader(step: Step, request: VerificationRequest. .semantics(mergeDescendants = true) { contentDescription = timeLimitMessage focused = true - if (iconStyle == BigIcon.Style.Loading) { - // Same code than Modifier.progressSemantics() - progressBarRangeInfo = ProgressBarRangeInfo.Indeterminate - } } .focusable(), iconStyle = iconStyle, @@ -264,11 +254,15 @@ private fun OutgoingVerificationViewBottomMenu( when (verificationViewState) { Step.Loading -> error("Should not happen") + is Step.AwaitingOtherDeviceResponse, is Step.Initial -> { VerificationBottomMenu { + val isWaiting = verificationViewState is Step.AwaitingOtherDeviceResponse Button( modifier = Modifier.fillMaxWidth(), text = stringResource(CommonStrings.action_start_verification), + enabled = !isWaiting, + showProgress = isWaiting, onClick = { eventSink(OutgoingVerificationViewEvents.RequestVerification) }, ) InvisibleButton() @@ -298,30 +292,23 @@ private fun OutgoingVerificationViewBottomMenu( ) } } - is Step.AwaitingOtherDeviceResponse -> Unit is Step.Verifying -> { - if (isVerifying) { - // Add invisible buttons to keep the same screen layout - VerificationBottomMenu { - InvisibleButton() - InvisibleButton() - } - } else { - VerificationBottomMenu { - Button( - modifier = Modifier.fillMaxWidth(), - text = stringResource(R.string.screen_session_verification_they_match), - onClick = { - eventSink(OutgoingVerificationViewEvents.ConfirmVerification) - }, - ) + VerificationBottomMenu { + Button( + modifier = Modifier.fillMaxWidth(), + text = stringResource(R.string.screen_session_verification_they_match), + enabled = !isVerifying, + showProgress = isVerifying, + onClick = { + eventSink(OutgoingVerificationViewEvents.ConfirmVerification) + }, + ) - TextButton( - modifier = Modifier.fillMaxWidth(), - text = stringResource(R.string.screen_session_verification_they_dont_match), - onClick = { eventSink(OutgoingVerificationViewEvents.DeclineVerification) }, - ) - } + TextButton( + modifier = Modifier.fillMaxWidth(), + text = stringResource(R.string.screen_session_verification_they_dont_match), + onClick = { eventSink(OutgoingVerificationViewEvents.DeclineVerification) }, + ) } } is Step.Completed -> { @@ -334,7 +321,7 @@ private fun OutgoingVerificationViewBottomMenu( InvisibleButton() } } - is Step.Exit -> return + is Step.Exit -> Unit } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/BigIcon.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/BigIcon.kt index 40e84b34c3..639d365625 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/BigIcon.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/BigIcon.kt @@ -34,7 +34,6 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.ui.strings.CommonStrings @@ -82,11 +81,6 @@ object BigIcon { * A success style with a tinted background. */ data object SuccessSolid : Style - - /** - * A loading style with the default background color. - */ - data object Loading : Style } /** @@ -110,7 +104,6 @@ object BigIcon { Style.Success -> Color.Transparent Style.AlertSolid -> ElementTheme.colors.bgCriticalSubtle Style.SuccessSolid -> ElementTheme.colors.bgSuccessSubtle - Style.Loading -> ElementTheme.colors.bgSubtleSecondary } Box( modifier = modifier @@ -119,52 +112,39 @@ object BigIcon { .background(backgroundColor), contentAlignment = Alignment.Center, ) { - if (style is Style.Loading) { - CircularProgressIndicator( - modifier = Modifier.size(27.dp), - color = ElementTheme.colors.iconSecondary, - trackColor = Color.Transparent, - strokeWidth = 3.dp, - ) - } else { - val icon = when (style) { - is Style.Default -> style.vectorIcon - Style.Alert, - Style.AlertSolid -> CompoundIcons.ErrorSolid() - Style.Success, - Style.SuccessSolid -> CompoundIcons.CheckCircleSolid() - Style.Loading -> error("This should never be reached") - } - val contentDescription = when (style) { - is Style.Default -> style.contentDescription - Style.Alert, - Style.AlertSolid -> stringResource(CommonStrings.common_error) - Style.Success, - Style.SuccessSolid -> stringResource(CommonStrings.common_success) - Style.Loading -> error("This should never be reached") - } - val iconTint = when (style) { - is Style.Default -> if (style.useCriticalTint) { - ElementTheme.colors.iconCriticalPrimary - } else if (style.usePrimaryTint) { - ElementTheme.colors.iconPrimary - } else { - ElementTheme.colors.iconSecondary - } - Style.Alert, - Style.AlertSolid -> ElementTheme.colors.iconCriticalPrimary - Style.Success, - Style.SuccessSolid -> ElementTheme.colors.iconSuccessPrimary - Style.Loading -> error("This should never be reached") - } - - Icon( - modifier = Modifier.size(32.dp), - tint = iconTint, - imageVector = icon, - contentDescription = contentDescription - ) + val icon = when (style) { + is Style.Default -> style.vectorIcon + Style.Alert, + Style.AlertSolid -> CompoundIcons.ErrorSolid() + Style.Success, + Style.SuccessSolid -> CompoundIcons.CheckCircleSolid() } + val contentDescription = when (style) { + is Style.Default -> style.contentDescription + Style.Alert, + Style.AlertSolid -> stringResource(CommonStrings.common_error) + Style.Success, + Style.SuccessSolid -> stringResource(CommonStrings.common_success) + } + val iconTint = when (style) { + is Style.Default -> if (style.useCriticalTint) { + ElementTheme.colors.iconCriticalPrimary + } else if (style.usePrimaryTint) { + ElementTheme.colors.iconPrimary + } else { + ElementTheme.colors.iconSecondary + } + Style.Alert, + Style.AlertSolid -> ElementTheme.colors.iconCriticalPrimary + Style.Success, + Style.SuccessSolid -> ElementTheme.colors.iconSuccessPrimary + } + Icon( + modifier = Modifier.size(32.dp), + tint = iconTint, + imageVector = icon, + contentDescription = contentDescription + ) } } } @@ -199,6 +179,5 @@ internal class BigIconStyleProvider : PreviewParameterProvider { BigIcon.Style.Default(Icons.Filled.CatchingPokemon, useCriticalTint = true), BigIcon.Style.Success, BigIcon.Style.SuccessSolid, - BigIcon.Style.Loading, ) } From 070c80bd51dbd70ca64cb1069694f9b8bd7a9e93 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jan 2026 16:14:53 +0100 Subject: [PATCH 319/347] Verification of other session: use Devices icon. Verification of other user: use UserProfileSolid icon. --- .../verifysession/impl/incoming/IncomingVerificationView.kt | 2 +- .../verifysession/impl/outgoing/OutgoingVerificationView.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt index 1d37daf82b..ca81e033d2 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt @@ -101,7 +101,7 @@ private fun IncomingVerificationHeader(step: Step, request: VerificationRequest. val iconStyle = when (step) { Step.Canceled -> BigIcon.Style.AlertSolid is Step.Initial -> when (request) { - is VerificationRequest.Incoming.OtherSession -> BigIcon.Style.Default(CompoundIcons.LockSolid()) + is VerificationRequest.Incoming.OtherSession -> BigIcon.Style.Default(CompoundIcons.Devices()) is VerificationRequest.Incoming.User -> BigIcon.Style.Default(CompoundIcons.UserProfileSolid()) } is Step.Verifying -> BigIcon.Style.Default(CompoundIcons.ReactionSolid()) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt index 51f288b303..072eb9451b 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt @@ -130,7 +130,7 @@ private fun OutgoingVerificationHeader(step: Step, request: VerificationRequest. Step.AwaitingOtherDeviceResponse, Step.Initial -> when (request) { is VerificationRequest.Outgoing.CurrentSession -> BigIcon.Style.Default(CompoundIcons.Devices()) - is VerificationRequest.Outgoing.User -> BigIcon.Style.Default(CompoundIcons.LockSolid()) + is VerificationRequest.Outgoing.User -> BigIcon.Style.Default(CompoundIcons.UserProfileSolid()) } Step.Canceled -> BigIcon.Style.AlertSolid Step.Ready -> BigIcon.Style.Default(CompoundIcons.ReactionSolid()) From 1dfe26e67a6d9caa537362dd566cc6125a4bb8df Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jan 2026 16:19:46 +0100 Subject: [PATCH 320/347] Verification: always render the back button. --- .../impl/incoming/IncomingVerificationView.kt | 26 ++++++++----------- .../impl/outgoing/OutgoingVerificationView.kt | 6 ++--- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt index ca81e033d2..bb8e65578e 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt @@ -70,11 +70,7 @@ fun IncomingVerificationView( TopAppBar( title = {}, navigationIcon = { - when { - step is Step.Initial && !step.isWaiting -> Unit - step is Step.Completed -> Unit - else -> BackButton(onClick = { state.eventSink(IncomingVerificationViewEvents.GoBack) }) - } + BackButton(onClick = { state.eventSink(IncomingVerificationViewEvents.GoBack) }) }, colors = topAppBarColors(containerColor = Color.Transparent), ) @@ -144,12 +140,12 @@ private fun IncomingVerificationHeader(step: Step, request: VerificationRequest. } IconTitleSubtitleMolecule( modifier = Modifier - .padding(bottom = 16.dp) - .semantics(mergeDescendants = true) { - contentDescription = timeLimitMessage - focused = true - } - .focusable(), + .padding(bottom = 16.dp) + .semantics(mergeDescendants = true) { + contentDescription = timeLimitMessage + focused = true + } + .focusable(), iconStyle = iconStyle, title = stringResource(id = titleTextId), subTitle = stringResource(id = subtitleTextId), @@ -186,8 +182,8 @@ private fun ContentInitial( ) Text( modifier = Modifier - .align(Alignment.CenterHorizontally) - .padding(bottom = 16.dp), + .align(Alignment.CenterHorizontally) + .padding(bottom = 16.dp), text = stringResource(R.string.screen_session_verification_request_footer), style = ElementTheme.typography.fontBodyMdMedium, textAlign = TextAlign.Center, @@ -197,8 +193,8 @@ private fun ContentInitial( is VerificationRequest.Incoming.User -> { Column( modifier = Modifier - .fillMaxWidth() - .padding(top = 24.dp), + .fillMaxWidth() + .padding(top = 24.dp), ) { VerificationUserProfileContent( user = request.details.senderProfile, diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt index 072eb9451b..d2bf5a4bba 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt @@ -94,10 +94,8 @@ fun OutgoingVerificationView( topBar = { TopAppBar( title = {}, - navigationIcon = if (step != Step.Completed) { - { BackButton(onClick = ::cancelOrResetFlow) } - } else { - {} + navigationIcon = { + BackButton(onClick = ::cancelOrResetFlow) }, colors = topAppBarColors(containerColor = Color.Transparent) ) From 49434c12a2b06ad8afe4a84c5558efa8c91cb1c8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jan 2026 16:31:56 +0100 Subject: [PATCH 321/347] tom --- .../verifysession/impl/outgoing/OutgoingVerificationView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt index d2bf5a4bba..95258ba336 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt @@ -301,10 +301,10 @@ private fun OutgoingVerificationViewBottomMenu( eventSink(OutgoingVerificationViewEvents.ConfirmVerification) }, ) - TextButton( modifier = Modifier.fillMaxWidth(), text = stringResource(R.string.screen_session_verification_they_dont_match), + enabled = !isVerifying, onClick = { eventSink(OutgoingVerificationViewEvents.DeclineVerification) }, ) } From 492e5d61e5737bbaadaba964952684b7ada520f9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jan 2026 16:34:09 +0100 Subject: [PATCH 322/347] Code cleanup. --- .../impl/incoming/IncomingVerificationView.kt | 40 +++++++++-------- .../impl/outgoing/OutgoingVerificationView.kt | 44 ++++++++----------- 2 files changed, 40 insertions(+), 44 deletions(-) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt index bb8e65578e..e86c83825b 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationView.kt @@ -140,12 +140,12 @@ private fun IncomingVerificationHeader(step: Step, request: VerificationRequest. } IconTitleSubtitleMolecule( modifier = Modifier - .padding(bottom = 16.dp) - .semantics(mergeDescendants = true) { - contentDescription = timeLimitMessage - focused = true - } - .focusable(), + .padding(bottom = 16.dp) + .semantics(mergeDescendants = true) { + contentDescription = timeLimitMessage + focused = true + } + .focusable(), iconStyle = iconStyle, title = stringResource(id = titleTextId), subTitle = stringResource(id = subtitleTextId), @@ -166,7 +166,7 @@ private fun IncomingVerificationContent( @Composable private fun ContentInitial( - initialIncoming: Step.Initial, + stepInitial: Step.Initial, request: VerificationRequest.Incoming, ) { when (request) { @@ -176,14 +176,14 @@ private fun ContentInitial( verticalArrangement = Arrangement.spacedBy(24.dp), ) { SessionDetailsView( - deviceName = initialIncoming.deviceDisplayName, - deviceId = initialIncoming.deviceId, - signInFormattedTimestamp = initialIncoming.formattedSignInTime, + deviceName = stepInitial.deviceDisplayName, + deviceId = stepInitial.deviceId, + signInFormattedTimestamp = stepInitial.formattedSignInTime, ) Text( modifier = Modifier - .align(Alignment.CenterHorizontally) - .padding(bottom = 16.dp), + .align(Alignment.CenterHorizontally) + .padding(bottom = 16.dp), text = stringResource(R.string.screen_session_verification_request_footer), style = ElementTheme.typography.fontBodyMdMedium, textAlign = TextAlign.Center, @@ -193,8 +193,8 @@ private fun ContentInitial( is VerificationRequest.Incoming.User -> { Column( modifier = Modifier - .fillMaxWidth() - .padding(top = 24.dp), + .fillMaxWidth() + .padding(top = 24.dp), ) { VerificationUserProfileContent( user = request.details.senderProfile, @@ -208,10 +208,8 @@ private fun ContentInitial( private fun IncomingVerificationBottomMenu( state: IncomingVerificationState, ) { - val step = state.step val eventSink = state.eventSink - - when (step) { + when (val step = state.step) { is Step.Initial -> { VerificationBottomMenu { Button( @@ -236,7 +234,9 @@ private fun IncomingVerificationBottomMenu( text = stringResource(R.string.screen_session_verification_they_match), enabled = !step.isWaiting, showProgress = step.isWaiting, - onClick = { eventSink(IncomingVerificationViewEvents.ConfirmVerification) }, + onClick = { + eventSink(IncomingVerificationViewEvents.ConfirmVerification) + }, ) TextButton( modifier = Modifier.fillMaxWidth(), @@ -253,7 +253,9 @@ private fun IncomingVerificationBottomMenu( Button( modifier = Modifier.fillMaxWidth(), text = stringResource(CommonStrings.action_done), - onClick = { eventSink(IncomingVerificationViewEvents.GoBack) }, + onClick = { + eventSink(IncomingVerificationViewEvents.GoBack) + }, ) } } diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt index 95258ba336..2dd2850174 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/outgoing/OutgoingVerificationView.kt @@ -35,7 +35,6 @@ import io.element.android.features.verifysession.impl.R import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationState.Step import io.element.android.features.verifysession.impl.ui.VerificationBottomMenu import io.element.android.features.verifysession.impl.ui.VerificationContentVerifying -import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage import io.element.android.libraries.designsystem.components.BigIcon @@ -97,15 +96,15 @@ fun OutgoingVerificationView( navigationIcon = { BackButton(onClick = ::cancelOrResetFlow) }, - colors = topAppBarColors(containerColor = Color.Transparent) + colors = topAppBarColors(containerColor = Color.Transparent), ) }, header = { OutgoingVerificationHeader(step = step, request = state.request) }, footer = { - OutgoingVerificationViewBottomMenu( - screenState = state, + OutgoingVerificationBottomMenu( + state = state, onCancelClick = ::cancelOrResetFlow, onContinueClick = onFinish, ) @@ -113,7 +112,7 @@ fun OutgoingVerificationView( isScrollable = true, ) { OutgoingVerificationContent( - flowState = step, + step = step, request = state.request, onLearnMoreClick = onLearnMoreClick, ) @@ -203,20 +202,16 @@ private fun OutgoingVerificationHeader(step: Step, request: VerificationRequest. @Composable private fun OutgoingVerificationContent( - flowState: Step, + step: Step, request: VerificationRequest.Outgoing, onLearnMoreClick: () -> Unit, ) { - when (flowState) { - is Step.Initial -> { - when (request) { - is VerificationRequest.Outgoing.CurrentSession -> Unit - is VerificationRequest.Outgoing.User -> ContentInitial(onLearnMoreClick) - } - } - is Step.Verifying -> { - VerificationContentVerifying(flowState.data) + when (step) { + is Step.Initial -> when (request) { + is VerificationRequest.Outgoing.CurrentSession -> Unit + is VerificationRequest.Outgoing.User -> ContentInitial(onLearnMoreClick) } + is Step.Verifying -> VerificationContentVerifying(step.data) else -> Unit } } @@ -240,22 +235,18 @@ private fun ContentInitial( } @Composable -private fun OutgoingVerificationViewBottomMenu( - screenState: OutgoingVerificationState, +private fun OutgoingVerificationBottomMenu( + state: OutgoingVerificationState, onCancelClick: () -> Unit, onContinueClick: () -> Unit, ) { - val verificationViewState = screenState.step - val eventSink = screenState.eventSink - - val isVerifying = (verificationViewState as? Step.Verifying)?.state is AsyncData.Loading - - when (verificationViewState) { + val eventSink = state.eventSink + when (val step = state.step) { Step.Loading -> error("Should not happen") is Step.AwaitingOtherDeviceResponse, is Step.Initial -> { VerificationBottomMenu { - val isWaiting = verificationViewState is Step.AwaitingOtherDeviceResponse + val isWaiting = step is Step.AwaitingOtherDeviceResponse Button( modifier = Modifier.fillMaxWidth(), text = stringResource(CommonStrings.action_start_verification), @@ -291,6 +282,7 @@ private fun OutgoingVerificationViewBottomMenu( } } is Step.Verifying -> { + val isVerifying = step.state.isLoading() VerificationBottomMenu { Button( modifier = Modifier.fillMaxWidth(), @@ -305,7 +297,9 @@ private fun OutgoingVerificationViewBottomMenu( modifier = Modifier.fillMaxWidth(), text = stringResource(R.string.screen_session_verification_they_dont_match), enabled = !isVerifying, - onClick = { eventSink(OutgoingVerificationViewEvents.DeclineVerification) }, + onClick = { + eventSink(OutgoingVerificationViewEvents.DeclineVerification) + }, ) } } From f33223559bcb26189bd9ea6bf610f3ec2f484b96 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 8 Jan 2026 15:49:32 +0000 Subject: [PATCH 323/347] Update screenshots --- ...ysession.impl.incoming_IncomingVerificationViewA11y_en.png | 4 ++-- ...ession.impl.incoming_IncomingVerificationView_Day_0_en.png | 4 ++-- ...ssion.impl.incoming_IncomingVerificationView_Day_10_en.png | 4 ++-- ...ssion.impl.incoming_IncomingVerificationView_Day_11_en.png | 4 ++-- ...ession.impl.incoming_IncomingVerificationView_Day_1_en.png | 4 ++-- ...ession.impl.incoming_IncomingVerificationView_Day_2_en.png | 4 ++-- ...ession.impl.incoming_IncomingVerificationView_Day_3_en.png | 4 ++-- ...ession.impl.incoming_IncomingVerificationView_Day_4_en.png | 4 ++-- ...ession.impl.incoming_IncomingVerificationView_Day_7_en.png | 4 ++-- ...ession.impl.incoming_IncomingVerificationView_Day_8_en.png | 4 ++-- ...sion.impl.incoming_IncomingVerificationView_Night_0_en.png | 4 ++-- ...ion.impl.incoming_IncomingVerificationView_Night_10_en.png | 4 ++-- ...ion.impl.incoming_IncomingVerificationView_Night_11_en.png | 4 ++-- ...sion.impl.incoming_IncomingVerificationView_Night_1_en.png | 4 ++-- ...sion.impl.incoming_IncomingVerificationView_Night_2_en.png | 4 ++-- ...sion.impl.incoming_IncomingVerificationView_Night_3_en.png | 4 ++-- ...sion.impl.incoming_IncomingVerificationView_Night_4_en.png | 4 ++-- ...sion.impl.incoming_IncomingVerificationView_Night_7_en.png | 4 ++-- ...sion.impl.incoming_IncomingVerificationView_Night_8_en.png | 4 ++-- ...ssion.impl.outgoing_OutgoingVerificationView_Day_10_en.png | 4 ++-- ...ssion.impl.outgoing_OutgoingVerificationView_Day_11_en.png | 4 ++-- ...ession.impl.outgoing_OutgoingVerificationView_Day_1_en.png | 4 ++-- ...ession.impl.outgoing_OutgoingVerificationView_Day_2_en.png | 4 ++-- ...ession.impl.outgoing_OutgoingVerificationView_Day_3_en.png | 4 ++-- ...ession.impl.outgoing_OutgoingVerificationView_Day_6_en.png | 4 ++-- ...ion.impl.outgoing_OutgoingVerificationView_Night_10_en.png | 4 ++-- ...ion.impl.outgoing_OutgoingVerificationView_Night_11_en.png | 4 ++-- ...sion.impl.outgoing_OutgoingVerificationView_Night_1_en.png | 4 ++-- ...sion.impl.outgoing_OutgoingVerificationView_Night_2_en.png | 4 ++-- ...sion.impl.outgoing_OutgoingVerificationView_Night_3_en.png | 4 ++-- ...sion.impl.outgoing_OutgoingVerificationView_Night_6_en.png | 4 ++-- .../libraries.designsystem.components_BigIcon_Day_0_en.png | 4 ++-- .../libraries.designsystem.components_BigIcon_Night_0_en.png | 4 ++-- 33 files changed, 66 insertions(+), 66 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationViewA11y_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationViewA11y_en.png index 48d1f990a4..2aeca4411f 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationViewA11y_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationViewA11y_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fc82b350fa0905ffa7fdb86042157aa9577e4b60dd04cd0c875d6c26f8f18a05 -size 74382 +oid sha256:b8edbc22543c204a226c3acc78dbe346c90a5806f374b97fce320777e6a4d97f +size 77061 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en.png index 8ab592672a..b21e718ace 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c51ecde00a75a74fb6b654f58f8c6507fe1af50f5f996c27bafa355d01f3f58 -size 42097 +oid sha256:1535ae46ff8d99e1205966bee0c7a0455505f4ab4499805350f7aeff4931a3e8 +size 42380 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en.png index c12918bef2..16c02a582c 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11df4acac503d00011ea5b0c3bf59495f5ad50268dc88b253bb60e4f47dcca10 -size 23217 +oid sha256:20f8ace2bb54a25e6044e6b63f09378b1ad9d6b8e0a8690aadb33d07aef32b2b +size 23595 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en.png index d281cca5e7..e0c6f6554f 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:42a9af1521e18b0edcd05743b9dc598324c68657afa293e304576348598f4b7b -size 24492 +oid sha256:e8e40d09036dfab63b0ce06886a4951958a00e4aa54cd8760201c71b32da0e60 +size 24895 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en.png index 8ab592672a..b21e718ace 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c51ecde00a75a74fb6b654f58f8c6507fe1af50f5f996c27bafa355d01f3f58 -size 42097 +oid sha256:1535ae46ff8d99e1205966bee0c7a0455505f4ab4499805350f7aeff4931a3e8 +size 42380 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en.png index b4dae88c36..8cde33fcb0 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c398ef341651bd7b0b067183b0b6566c515df3204512fd8f32df5abfe71f2e2e -size 38450 +oid sha256:e13e3252a9550a34dbf35c2f93f7bd19168597556f402bb8c3a4cf02c34b3603 +size 38850 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en.png index 71a7750d12..2566d896ff 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d731d3b312cd4535d953365b1de7817c2c6d07c1ae460567f3e333cd00f8d2e -size 37142 +oid sha256:1fec4bf898d1edc02c93cdf07dea16395cbb18779b2990fb234ce1f5d957aa2d +size 42228 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en.png index 090d0d88c1..1a1e10796b 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:323370a1128d2629752159610719fd49de99a448f0278bdcce85f4f836bf3ef5 -size 32384 +oid sha256:ddf2b23bd2990e6c30e5afada8a552af02aeaf5168f47fc8dd9dfd3a3b948c06 +size 38584 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en.png index 5402804a6a..c402304f17 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2cb056d627f504947058b3512873e91a792c98d6cc485d4d866fd63589c957bc -size 40073 +oid sha256:b3af87959334905f1de9e014978dafbd2fa5834db9c3296bc5353218bc09a3f5 +size 46207 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en.png index 2a156d2e59..aaebb6fcea 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:626d47274ead934c9c4d2831d14abc011954a627d63dac7193d881826371654c -size 40688 +oid sha256:d26dfb3d8efcc93b7e0f25cb2067b5288edba8a9a35edc3b74863f3cd2962ce5 +size 46820 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en.png index 2917893392..2a4761bd51 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a008fa7c1f333a1ea380d6d7b2401bd3cc3ac70e32c2618359640d73962c31a2 -size 40874 +oid sha256:b5816a7b77f64889d51988d286a05be318930076972b7a29c7506bedf091aebd +size 41107 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en.png index 1a73c71f81..6c3dfcc678 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f739091f305037dc09fb7b6a083a30172f45c576a2ccbc08b4de1d97c37523d6 -size 22569 +oid sha256:e765b16cfe3beca19b9f3f256512e6048a7cc22b0344f5e57d655409c2262156 +size 22893 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en.png index 5987a85f48..d549a5965f 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:320fecc889eb76fb0201dec4c299d2fd82f6a21e48544f5d45e537bec49fa3b6 -size 23870 +oid sha256:16699f8b48a72e2336a83e2fb80cd28cdc5b7b4b5a2e065767f2d6416a372b96 +size 24204 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en.png index 2917893392..2a4761bd51 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a008fa7c1f333a1ea380d6d7b2401bd3cc3ac70e32c2618359640d73962c31a2 -size 40874 +oid sha256:b5816a7b77f64889d51988d286a05be318930076972b7a29c7506bedf091aebd +size 41107 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en.png index 6c99c4bacb..e5e262843b 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d077bd218282f4d5d17d319efad0b921c7e3a17e94bee4fa220390f4988d7295 -size 37601 +oid sha256:454d58e8c2ec04dff4ba7410e284b4b7e5439df68996f42be6181036d799f739 +size 37916 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en.png index d1905ffbdb..e738748f23 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d87afe654be2a6d0cfb9a1fe5a900f01809dacf23f0639b87cfd08e90650e09 -size 36161 +oid sha256:d3420774cfe02db1e94c4bc71d41de8ab754c9de96ab8283bd8e6f7555f85ce2 +size 40908 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en.png index d337c136ef..6eb0f48cc3 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19f1f3eb197a48bcd1ec0ab3acc1d46ac2597fb3ffd325f221c3a87a2ae56b6b -size 31689 +oid sha256:082dff0fdb2c9d6de2fcbdd059b3f1d3859f2265df5fd92f9c74911a5852fcfc +size 37528 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en.png index 9005aa52dc..0b20aeaeb9 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08c9db896d4de76c9466675bad777591985e9b9d6d39dfae2711a95ae6de6be7 -size 39285 +oid sha256:14ea71faf7394d985620c36093a3015b23fafd6657213ebf243ba660ff99bea2 +size 44943 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en.png index fad6ffe0df..166ce71cc6 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fcda36810020f172928338753ad986294b17ff705b1720d3f358ca471a8f8fb1 -size 39930 +oid sha256:3aef62da412a0dea0108fc4f2edb84acb3e40eab6d44e69b74e9dee3689d9725 +size 45566 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en.png index f1872614ce..60e66d0f8f 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4db4fc94f8c80bc45d241ccb8e67b18f687b2fb00fef5f4c7de5fbfbc07ede05 -size 26551 +oid sha256:caa57bfcdb7f285e0b3e82844d83fb0b525d56ddb627c202f8d2eccdb5a79d84 +size 26912 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en.png index 59d977bcfa..2ec32fe145 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ca7819814008b5365e1c11cfd530587277fa8636e183eae35464c627c0a1d174 -size 25163 +oid sha256:0514ecaaf5a91487316e36a1549049b51e50dee20eed90bc9542a6e8672fbdb7 +size 25552 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en.png index 63af02a9b2..43d4cbb36f 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db7af309219038951c742535c24f2bf6995438a3e9850bd9f69aa8ac2636cbf5 -size 33037 +oid sha256:6c7de8a2a9ef5374d56fc641ac71d25be186082fa7b5a6ed979def8e3f59808e +size 33985 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en.png index ea3b9ed3fa..f88a2b853b 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da0a3a6b89ba22da85d8834a8b9dbc4216ee0085b7ef6f8e55203e0abb789b57 -size 23203 +oid sha256:fb0c099c3480108b8ce842618123e95e6f302a58a56633f2ed91ed96ad8639da +size 27074 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en.png index dad425d03d..aba82f25ac 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2993f8eb15e1d7dd869bad474a954db52a2b8f9769f4d1d3f0c6ab0449b7fbe -size 20421 +oid sha256:8834781b2e2d5d4811b0ff030d0c741d08c5659d94711d6d550f81c4b0d47ebe +size 25382 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en.png index 5402804a6a..c402304f17 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2cb056d627f504947058b3512873e91a792c98d6cc485d4d866fd63589c957bc -size 40073 +oid sha256:b3af87959334905f1de9e014978dafbd2fa5834db9c3296bc5353218bc09a3f5 +size 46207 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en.png index de49708cf6..62d6f23e20 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ee603c36dea38a3adda22c45294a45225e44f9638f7292159019993aafd1ec7 -size 25902 +oid sha256:465e7198dd7773d5dbd953cf3022e35f513add880d68af161a70df5ddfd00b17 +size 26234 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en.png index 45e9f22955..dd1983dca0 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc1980e0ce3bc900f6703fe4f5f12eabbcc351b0aca873215e414af86125a0fd -size 24521 +oid sha256:d2e530f6abdcbaf236f60aadcecaa97de715f39473069fa164c894ef0f899c35 +size 24852 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en.png index addf2b47cb..c4a26627ed 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4d968e867119149bb7cfcfdb2c993603c60b427f4f3810ecf9784198c6804b6 -size 32158 +oid sha256:96c4965a16f7c0d246586941230799cb4dae61ad18120420df11ea744e0730ec +size 32993 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en.png index 9e3ec35297..b74bf5aba6 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:352e0673fd2802c418657e9a0532a504d736234f28df1119437e3035dde06804 -size 22685 +oid sha256:8ef0a07a8d811cb6fb59160b0003cabbf6d3437a41f912dc31b63851be549e2d +size 26222 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en.png index b334380e3d..8a192d376c 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a477acdebee14e91f9e15ef9f10f318ae0fcb081a0f6bdacb91c68e5d9234b30 -size 20011 +oid sha256:e08c58571c5252779e3dd783f0c60768e408260dc901cf6310a927b3da948172 +size 24619 diff --git a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en.png index 9005aa52dc..0b20aeaeb9 100644 --- a/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08c9db896d4de76c9466675bad777591985e9b9d6d39dfae2711a95ae6de6be7 -size 39285 +oid sha256:14ea71faf7394d985620c36093a3015b23fafd6657213ebf243ba660ff99bea2 +size 44943 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_BigIcon_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_BigIcon_Day_0_en.png index cc09282faa..d2d1c16252 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_BigIcon_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_BigIcon_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ae5556afe4e26f417c598e116dee6c7c913fe668a15ec2d98d2f1ed81b5371f -size 14269 +oid sha256:29c51a698521fcc83604aafed9747c92b84f4077e7ea79ba35ce8a07b991fbcd +size 12563 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_BigIcon_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_BigIcon_Night_0_en.png index fff990dc70..ebad5af87d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_BigIcon_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components_BigIcon_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ec9f20978244f8b933140f074bf586a174b9448a602294b95f4773ee7758323 -size 14406 +oid sha256:f899705e82a54ee0525fd36dd5993538c51dcc9fa0b224a820407bd22827b33c +size 12724 From 0f628bef50d7a2a791f691fc1a872dd62b7c297e Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 8 Jan 2026 17:16:45 +0100 Subject: [PATCH 324/347] Add comprehensive presenter tests for SecurityAndPrivacy feature --- .../impl/SecurityAndPrivacyPresenterTest.kt | 400 ++++++++++++++++++ 1 file changed, 400 insertions(+) diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index 70c86b9525..bf8ab13bad 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -732,6 +732,406 @@ class SecurityAndPrivacyPresenterTest { } } + @Test + fun `present - availableHistoryVisibilities includes WorldReadable for Anyone without encryption`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + joinRule = JoinRule.Public, + historyVisibility = RoomHistoryVisibility.Shared, + ) + ) + ) + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.Anyone) + assertThat(editedSettings.isEncrypted).isFalse() + assertThat(availableHistoryVisibilities).contains(SecurityAndPrivacyHistoryVisibility.WorldReadable) + assertThat(availableHistoryVisibilities).doesNotContain(SecurityAndPrivacyHistoryVisibility.Invited) + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - availableHistoryVisibilities includes Invited for InviteOnly access`() = runTest { + val presenter = createSecurityAndPrivacyPresenter() + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) + assertThat(availableHistoryVisibilities).contains(SecurityAndPrivacyHistoryVisibility.Invited) + assertThat(availableHistoryVisibilities).doesNotContain(SecurityAndPrivacyHistoryVisibility.WorldReadable) + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - availableHistoryVisibilities excludes WorldReadable when encrypted`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + joinRule = JoinRule.Public, + historyVisibility = RoomHistoryVisibility.Shared, + isEncrypted = true, + ) + ) + ) + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.Anyone) + assertThat(editedSettings.isEncrypted).isTrue() + assertThat(availableHistoryVisibilities).contains(SecurityAndPrivacyHistoryVisibility.Invited) + assertThat(availableHistoryVisibilities).doesNotContain(SecurityAndPrivacyHistoryVisibility.WorldReadable) + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - showSpaceMemberOption is true when savedSettings has SpaceMember`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + joinRule = JoinRule.Restricted( + rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)) + ), + historyVisibility = RoomHistoryVisibility.Shared, + ) + ) + ) + // No spaces available, so isSpaceMemberSelectable should be false + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(savedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.SpaceMember::class.java) + assertThat(isSpaceMemberSelectable).isFalse() + // showSpaceMemberOption should still be true because savedSettings has SpaceMember + assertThat(showSpaceMemberOption).isTrue() + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - showSpaceMemberOption is false when not selectable and savedSettings is not SpaceMember`() = runTest { + // No spaces available, default InviteOnly join rule + val presenter = createSecurityAndPrivacyPresenter() + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(savedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.InviteOnly) + assertThat(isSpaceMemberSelectable).isFalse() + assertThat(showSpaceMemberOption).isFalse() + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - showManageSpaceFooter is true when Multiple mode and SpaceMember access`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite + ) + ) + ) + val client = FakeMatrixClient( + userIdServerNameLambda = { "matrix.org" }, + spaceService = FakeSpaceService( + joinedParentsResult = { _ -> + Result.success(listOf(aSpaceRoom(roomId = A_ROOM_ID), aSpaceRoom(roomId = RoomId("!space2:matrix.org")))) + } + ) + ) + val presenter = createSecurityAndPrivacyPresenter( + room = room, + matrixClient = client, + featureFlagService = FakeFeatureFlagService( + initialState = mapOf(FeatureFlags.SpaceSettings.key to true) + ) + ) + presenter.test { + skipItems(1) + val state = awaitItem() + // Change to SpaceMember access + val spaceMemberAccess = SecurityAndPrivacyRoomAccess.SpaceMember( + spaceIds = persistentListOf(A_ROOM_ID) + ) + state.eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(spaceMemberAccess)) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.SpaceMember::class.java) + assertThat(showManageSpaceFooter).isTrue() + } + } + } + + @Test + fun `present - showManageSpaceFooter is false when Single mode`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite + ) + ) + ) + // Single space available + val client = FakeMatrixClient( + userIdServerNameLambda = { "matrix.org" }, + spaceService = FakeSpaceService( + joinedParentsResult = { _ -> + Result.success(listOf(aSpaceRoom(roomId = A_ROOM_ID))) + } + ) + ) + val presenter = createSecurityAndPrivacyPresenter( + room = room, + matrixClient = client, + featureFlagService = FakeFeatureFlagService( + initialState = mapOf(FeatureFlags.SpaceSettings.key to true) + ) + ) + presenter.test { + skipItems(1) + val state = awaitItem() + // Select SpaceMember access (single space auto-selects) + state.eventSink(SecurityAndPrivacyEvent.SelectSpaceMemberAccess) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.SpaceMember::class.java) + // Single mode, so no footer + assertThat(showManageSpaceFooter).isFalse() + } + } + } + + @Test + fun `present - isAskToJoinSelectable is true when Knock FF enabled`() = runTest { + val presenter = createSecurityAndPrivacyPresenter( + featureFlagService = FakeFeatureFlagService( + initialState = mapOf(FeatureFlags.Knock.key to true) + ) + ) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(isAskToJoinSelectable).isTrue() + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - isAskToJoinSelectable is false when Knock FF disabled`() = runTest { + val presenter = createSecurityAndPrivacyPresenter( + featureFlagService = FakeFeatureFlagService( + initialState = mapOf(FeatureFlags.Knock.key to false) + ) + ) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(isAskToJoinSelectable).isFalse() + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - getAuthorizedSpacesSelection returns correct data for SpaceMember`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Restricted( + rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)) + ) + ) + ) + ) + val spaceRoom = aSpaceRoom(roomId = A_ROOM_ID) + val client = FakeMatrixClient( + userIdServerNameLambda = { "matrix.org" }, + spaceService = FakeSpaceService( + joinedParentsResult = { _ -> Result.success(listOf(spaceRoom)) }, + getSpaceRoomResult = { null } + ) + ) + val presenter = createSecurityAndPrivacyPresenter( + room = room, + matrixClient = client, + featureFlagService = FakeFeatureFlagService( + initialState = mapOf(FeatureFlags.SpaceSettings.key to true) + ) + ) + presenter.test { + skipItems(1) + with(awaitItem()) { + val selection = getAuthorizedSpacesSelection() + assertThat(selection.joinedSpaces).containsExactly(spaceRoom) + assertThat(selection.initialSelectedIds).containsExactly(A_ROOM_ID) + assertThat(selection.unknownSpaceIds).isEmpty() + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - getAuthorizedSpacesSelection identifies unknown space IDs`() = runTest { + val unknownSpaceId = RoomId("!unknown:matrix.org") + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Restricted( + rules = persistentListOf(AllowRule.RoomMembership(unknownSpaceId)) + ) + ) + ) + ) + // No spaces available (the space in the join rule is unknown) + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + val selection = getAuthorizedSpacesSelection() + assertThat(selection.joinedSpaces).isEmpty() + assertThat(selection.unknownSpaceIds).containsExactly(unknownSpaceId) + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - SelectAskToJoinWithSpaceMembersAccess with single space auto-selects`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite + ) + ) + ) + val client = FakeMatrixClient( + userIdServerNameLambda = { "matrix.org" }, + spaceService = FakeSpaceService( + joinedParentsResult = { _ -> + Result.success(listOf(aSpaceRoom(roomId = A_ROOM_ID))) + } + ) + ) + val presenter = createSecurityAndPrivacyPresenter( + room = room, + matrixClient = client, + featureFlagService = FakeFeatureFlagService( + initialState = mapOf( + FeatureFlags.Knock.key to true, + FeatureFlags.SpaceSettings.key to true, + ) + ) + ) + presenter.test { + skipItems(1) + val state = awaitItem() + assertThat(state.isAskToJoinWithSpaceMembersSelectable).isTrue() + state.eventSink(SecurityAndPrivacyEvent.SelectAskToJoinWithSpaceMembersAccess) + with(awaitItem()) { + assertThat(editedSettings.roomAccess).isInstanceOf(SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember::class.java) + val access = editedSettings.roomAccess as SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember + assertThat(access.spaceIds).containsExactly(A_ROOM_ID) + } + } + } + + @Test + fun `present - showAskToJoinOption is true when savedSettings is AskToJoin`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + joinRule = JoinRule.Knock, + historyVisibility = RoomHistoryVisibility.Shared, + ) + ) + ) + // Knock FF disabled, but showAskToJoinOption should still be true because savedSettings has AskToJoin + val presenter = createSecurityAndPrivacyPresenter( + room = room, + featureFlagService = FakeFeatureFlagService( + initialState = mapOf(FeatureFlags.Knock.key to false) + ) + ) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(savedSettings.roomAccess).isEqualTo(SecurityAndPrivacyRoomAccess.AskToJoin) + assertThat(isAskToJoinSelectable).isFalse() + assertThat(showAskToJoinOption).isTrue() + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - showHistoryVisibilitySection is false for space`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite, + isSpace = true, + ) + ) + ) + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(showHistoryVisibilitySection).isFalse() + } + cancelAndIgnoreRemainingEvents() + } + } + + @Test + fun `present - showEncryptionSection is false for space`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + roomPermissions = roomPermissions(), + initialRoomInfo = aRoomInfo( + historyVisibility = RoomHistoryVisibility.Shared, + joinRule = JoinRule.Invite, + isSpace = true, + ) + ) + ) + val presenter = createSecurityAndPrivacyPresenter(room = room) + presenter.test { + skipItems(1) + with(awaitItem()) { + assertThat(showEncryptionSection).isFalse() + } + cancelAndIgnoreRemainingEvents() + } + } + private fun roomPermissions( canChangeRoomAccess: Boolean = true, canChangeHistoryVisibility: Boolean = true, From b8ab0491b8ce160fe2614d4ea3d15eeec72d2208 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 8 Jan 2026 17:24:55 +0100 Subject: [PATCH 325/347] Fix SecurityAndPrivacy "manage spaces" footer text --- .../securityandprivacy/impl/root/SecurityAndPrivacyView.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 3ebb2de282..f4207ae3af 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -279,7 +279,8 @@ private fun RoomAccessSection( if (state.showManageSpaceFooter) { val footerText = stringWithLink( textRes = R.string.screen_security_and_privacy_room_access_footer, - url = stringResource(R.string.screen_security_and_privacy_room_access_footer_manage_spaces_action), + url = "", + linkTextRes = R.string.screen_security_and_privacy_room_access_footer_manage_spaces_action, onLinkClick = { onManageSpacesClick() }, ) Text( From fb29ae14be247f035c6bc463c7acd124356a5bbf Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 8 Jan 2026 17:25:24 +0100 Subject: [PATCH 326/347] quality: move tests to matching package --- .../SecurityAndPrivacyPresenterTest.kt | 20 +++++++++---------- .../{ => root}/SecurityAndPrivacyViewTest.kt | 18 ++++++----------- 2 files changed, 16 insertions(+), 22 deletions(-) rename features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/{ => root}/SecurityAndPrivacyPresenterTest.kt (98%) rename features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/{ => root}/SecurityAndPrivacyViewTest.kt (90%) diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenterTest.kt similarity index 98% rename from features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt rename to features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenterTest.kt index bf8ab13bad..2c1611fec8 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenterTest.kt @@ -1,18 +1,15 @@ /* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 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. */ -package io.element.android.features.securityandprivacy.impl +package io.element.android.features.securityandprivacy.impl.root import com.google.common.truth.Truth.assertThat -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyEvent -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyHistoryVisibility -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyPresenter -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyRoomAccess +import io.element.android.features.securityandprivacy.impl.FakeSecurityAndPrivacyNavigator +import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.featureflag.api.FeatureFlagService @@ -214,7 +211,8 @@ class SecurityAndPrivacyPresenterTest { @Test fun `present - edit room address`() = runTest { val openEditRoomAddressLambda = lambdaRecorder { } - val navigator = FakeSecurityAndPrivacyNavigator(openEditRoomAddressLambda = openEditRoomAddressLambda) + val navigator = + FakeSecurityAndPrivacyNavigator(openEditRoomAddressLambda = openEditRoomAddressLambda) val presenter = createSecurityAndPrivacyPresenter(navigator = navigator) presenter.test { skipItems(1) @@ -439,7 +437,8 @@ class SecurityAndPrivacyPresenterTest { @Test fun `present - SelectSpaceMemberAccess with multiple spaces opens ManageAuthorizedSpaces`() = runTest { val openManageAuthorizedSpacesLambda = lambdaRecorder { } - val navigator = FakeSecurityAndPrivacyNavigator(openManageAuthorizedSpacesLambda = openManageAuthorizedSpacesLambda) + val navigator = + FakeSecurityAndPrivacyNavigator(openManageAuthorizedSpacesLambda = openManageAuthorizedSpacesLambda) val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( roomPermissions = roomPermissions(), @@ -607,7 +606,8 @@ class SecurityAndPrivacyPresenterTest { @Test fun `present - SelectAskToJoinWithSpaceMembersAccess with multiple spaces opens ManageAuthorizedSpaces`() = runTest { val openManageAuthorizedSpacesLambda = lambdaRecorder { } - val navigator = FakeSecurityAndPrivacyNavigator(openManageAuthorizedSpacesLambda = openManageAuthorizedSpacesLambda) + val navigator = + FakeSecurityAndPrivacyNavigator(openManageAuthorizedSpacesLambda = openManageAuthorizedSpacesLambda) val room = FakeJoinedRoom( baseRoom = FakeBaseRoom( roomPermissions = roomPermissions(), diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyViewTest.kt similarity index 90% rename from features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt rename to features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyViewTest.kt index 7cd9b154cf..a1f46b2938 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyViewTest.kt @@ -1,12 +1,11 @@ /* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 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. */ -package io.element.android.features.securityandprivacy.impl +package io.element.android.features.securityandprivacy.impl.root import androidx.activity.ComponentActivity import androidx.compose.ui.test.junit4.AndroidComposeTestRule @@ -14,14 +13,7 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.test.ext.junit.runners.AndroidJUnit4 -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyEvent -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyHistoryVisibility -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyRoomAccess -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyState -import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyView -import io.element.android.features.securityandprivacy.impl.root.SpaceSelectionMode -import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacySettings -import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacyState +import io.element.android.features.securityandprivacy.impl.R import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -222,7 +214,9 @@ class SecurityAndPrivacyViewTest { ) rule.setSecurityAndPrivacyView(state) // The footer text uses AnnotatedString with a link. Verify the footer text is displayed. - rule.onNodeWithText("Choose which spaces", substring = true).assertExists() + val actionFooterText = rule.activity.getString(R.string.screen_security_and_privacy_room_access_footer_manage_spaces_action) + val footerText = rule.activity.getString(R.string.screen_security_and_privacy_room_access_footer, actionFooterText) + rule.onNodeWithText(footerText).assertExists() } } From c66f8c8c3425e81d473f430b52f44f4f6fd43dbf Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 8 Jan 2026 16:48:16 +0000 Subject: [PATCH 327/347] Update screenshots --- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png index 71f935b3c0..04d7a13388 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b2a019695bb544f7bfbb2b2c5fddc5140a25a770695d1354c2b393e942ebba5 -size 24687 +oid sha256:da260572a274c3fedcc81b055e1c52b8cf7467692287aa176b0dd9171be76937 +size 25139 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png index 8b34eb8946..8eb93a77e0 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:adaadbcdcb1d281683fcd7cfb69604ed875ffd4a48233dfd2941d3997ab097de -size 51431 +oid sha256:da888123f37a0dcc7d80849216044b82a442052c900d636d006020ad42469a71 +size 51849 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png index 8b34eb8946..8eb93a77e0 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:adaadbcdcb1d281683fcd7cfb69604ed875ffd4a48233dfd2941d3997ab097de -size 51431 +oid sha256:da888123f37a0dcc7d80849216044b82a442052c900d636d006020ad42469a71 +size 51849 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png index 00573c56c2..d320c0dc11 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1605f3269a888d8cbcab71615816b7564072f26846e481cf3576f9de4b61f2e1 -size 44182 +oid sha256:64134bc23ef38b73a087ec5679784516bfd66f23dd675a3771e1aa8cf6159836 +size 44729 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png index 9b03e75694..9de784287c 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77213c9b75eea8880c5fac86c3345e7056f304c8ad5beb6cf2057cb5d67b5415 -size 58621 +oid sha256:56d1614ce5e0da0bc29f8184f045339e263087676e9d7908a94007f410924b5d +size 59154 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png index 9b03e75694..9de784287c 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77213c9b75eea8880c5fac86c3345e7056f304c8ad5beb6cf2057cb5d67b5415 -size 58621 +oid sha256:56d1614ce5e0da0bc29f8184f045339e263087676e9d7908a94007f410924b5d +size 59154 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png index e050bddd3e..c200e6a21c 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c251b0e7daf758b0031c1c81b130d06f295126cb6bbc8efd13f43c6ef581ad8e -size 25132 +oid sha256:20a302e03d4f10c912c249f7c26f8ecc06472dd2a2ad4abe91607bb7527de732 +size 25577 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png index 3a1c1d3bf9..e0f67fd111 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cfadbdeaf77af829c19ae33338e91679acc8b34d2c8493d20994a740e2d2f3ee -size 52901 +oid sha256:9939e7a38e0e280d42a996576a3cfbeb773625cf43ddf8afd04aad6ab35fd955 +size 53555 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png index 3a1c1d3bf9..e0f67fd111 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cfadbdeaf77af829c19ae33338e91679acc8b34d2c8493d20994a740e2d2f3ee -size 52901 +oid sha256:9939e7a38e0e280d42a996576a3cfbeb773625cf43ddf8afd04aad6ab35fd955 +size 53555 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png index 97f3d826b9..264166a069 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3cf16df2caf7cdf9ca4a2da151ffa4c7b362b9d22bf9706522dacbd4edf520e5 -size 45867 +oid sha256:093bb9672ecd80432c7e6102bd5ed2d1184cd384c91e479d99d13c0ba773bf78 +size 46448 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png index bd71e00714..920c64d380 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b77f723d2c6c5eba85660d93cdcd63d785bccd61aab37f0784ca1fa646280743 -size 60462 +oid sha256:ee80f7a765a453c3704af6d1f38f90637528bcf1e5966dc1bd016f4d34f21fa4 +size 61069 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png index bd71e00714..920c64d380 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b77f723d2c6c5eba85660d93cdcd63d785bccd61aab37f0784ca1fa646280743 -size 60462 +oid sha256:ee80f7a765a453c3704af6d1f38f90637528bcf1e5966dc1bd016f4d34f21fa4 +size 61069 From 993cf838a05b80bf0ee04f1a2c1fee5d35196dec Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 9 Jan 2026 12:00:54 +0100 Subject: [PATCH 328/347] Refactor space selection to use SpaceSelectionStateHolder Move authorized space selection state to a shared StateHolder scoped to RoomScope. This simplifies communication between SecurityAndPrivacy and ManageAuthorizedSpaces nodes by replacing the complex coroutine-based parent-child coordination with a reactive state flow pattern. --- .../impl/SecurityAndPrivacyFlowNode.kt | 23 +---- .../impl/SecurityAndPrivacyNavigator.kt | 6 +- .../ManageAuthorizedSpacesEvent.kt | 2 +- .../ManageAuthorizedSpacesNode.kt | 11 --- .../ManageAuthorizedSpacesPresenter.kt | 39 ++++---- .../ManageAuthorizedSpacesState.kt | 12 +-- .../ManageAuthorizedSpacesStateProvider.kt | 25 ++--- .../ManageAuthorizedSpacesView.kt | 29 +++--- .../SpaceSelectionState.kt | 64 ++++++++++++ .../impl/root/SecurityAndPrivacyNode.kt | 16 --- .../impl/root/SecurityAndPrivacyPresenter.kt | 98 ++++++++++++++++--- .../impl/root/SecurityAndPrivacyState.kt | 15 --- .../impl/FakeSecurityAndPrivacyNavigator.kt | 6 +- .../impl/SecurityAndPrivacyFlowNodeTest.kt | 19 +--- .../ManageAuthorizedSpacesPresenterTest.kt | 85 +++++++++++----- .../ManageAuthorizedSpacesViewTest.kt | 33 +++---- .../root/SecurityAndPrivacyPresenterTest.kt | 78 ++------------- 17 files changed, 283 insertions(+), 278 deletions(-) create mode 100644 features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/SpaceSelectionState.kt diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index 4628974295..c306264773 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -13,14 +13,12 @@ import androidx.annotation.VisibleForTesting import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.lifecycle.Lifecycle -import androidx.lifecycle.coroutineScope import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.navmodel.backstack.BackStack -import com.bumble.appyx.navmodel.backstack.activeElement import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode @@ -36,12 +34,10 @@ import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.RoomScope import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.powerlevels.use -import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize @ContributesNode(RoomScope::class) @@ -66,7 +62,7 @@ class SecurityAndPrivacyFlowNode( data object EditRoomAddress : NavTarget @Parcelize - data class ManageAuthorizedSpaces(val forKnockRestricted: Boolean = false) : NavTarget + data object ManageAuthorizedSpaces : NavTarget } private val callback: SecurityAndPrivacyEntryPoint.Callback = callback() @@ -90,21 +86,6 @@ class SecurityAndPrivacyFlowNode( callback.onDone() } } - whenChildrenAttached { - commonLifecycle: Lifecycle, - securityAndPrivacyNode: SecurityAndPrivacyNode, - manageAuthorizedSpacesNode: ManageAuthorizedSpacesNode - -> - commonLifecycle.coroutineScope.launch { - val authorizedSpacesData = securityAndPrivacyNode.getAuthorizedSpacesData() - val selectedSpaces = manageAuthorizedSpacesNode.waitForCompletion(authorizedSpacesData) - val forKnock = (backstack.activeElement as? NavTarget.ManageAuthorizedSpaces)?.forKnockRestricted ?: false - withContext(NonCancellable) { - navigator.closeManageAuthorizedSpaces() - securityAndPrivacyNode.onAuthorizedSpacesSelected(selectedSpaces, forKnock = forKnock) - } - } - } } override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { @@ -115,7 +96,7 @@ class SecurityAndPrivacyFlowNode( NavTarget.EditRoomAddress -> { createNode(buildContext, plugins = listOf(navigator)) } - is NavTarget.ManageAuthorizedSpaces -> { + NavTarget.ManageAuthorizedSpaces -> { createNode(buildContext, plugins = listOf(navigator)) } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt index 0944ae92bd..274bf0b823 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt @@ -18,7 +18,7 @@ interface SecurityAndPrivacyNavigator : Plugin { fun onDone() fun openEditRoomAddress() fun closeEditRoomAddress() - fun openManageAuthorizedSpaces(forKnockRestricted: Boolean) + fun openManageAuthorizedSpaces() fun closeManageAuthorizedSpaces() } @@ -38,8 +38,8 @@ class BackstackSecurityAndPrivacyNavigator( backStack.pop() } - override fun openManageAuthorizedSpaces(forKnockRestricted: Boolean) { - backStack.push(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces(forKnockRestricted)) + override fun openManageAuthorizedSpaces() { + backStack.push(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces) } override fun closeManageAuthorizedSpaces() { diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt index 47abe2fbce..37d70b65f5 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt @@ -11,7 +11,7 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspac import io.element.android.libraries.matrix.api.core.RoomId sealed interface ManageAuthorizedSpacesEvent { - data class SetData(val data: AuthorizedSpacesSelection) : ManageAuthorizedSpacesEvent + data object Cancel : ManageAuthorizedSpacesEvent data object Done : ManageAuthorizedSpacesEvent data class ToggleSpace(val roomId: RoomId) : ManageAuthorizedSpacesEvent } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt index 08c757b87d..709f2189bc 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt @@ -19,12 +19,8 @@ import com.bumble.appyx.core.plugin.plugins import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode -import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.libraries.architecture.appyx.launchMolecule import io.element.android.libraries.di.RoomScope -import io.element.android.libraries.matrix.api.core.RoomId -import kotlinx.collections.immutable.ImmutableList -import kotlinx.coroutines.flow.first @ContributesNode(RoomScope::class) @AssistedInject @@ -33,20 +29,13 @@ class ManageAuthorizedSpacesNode( @Assisted plugins: List, presenter: ManageAuthorizedSpacesPresenter, ) : Node(buildContext, plugins = plugins) { - private val navigator = plugins().first() private val stateFlow = launchMolecule { presenter.present() } - suspend fun waitForCompletion(data: AuthorizedSpacesSelection): ImmutableList { - stateFlow.value.eventSink(ManageAuthorizedSpacesEvent.SetData(data)) - return stateFlow.first { it.isSelectionComplete }.selectedIds - } - @Composable override fun View(modifier: Modifier) { val state by stateFlow.collectAsState() ManageAuthorizedSpacesView( state = state, - onBackClick = { navigator.closeManageAuthorizedSpaces() }, modifier = modifier ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt index aa2251408f..5922e910a2 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt @@ -9,46 +9,43 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.matrix.api.core.RoomId -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @Inject -class ManageAuthorizedSpacesPresenter : Presenter { +class ManageAuthorizedSpacesPresenter( + private val spaceSelectionStateHolder: SpaceSelectionStateHolder, +) : Presenter { @Composable override fun present(): ManageAuthorizedSpacesState { - var selectedIds: ImmutableList by remember { mutableStateOf(persistentListOf()) } - var spacesSelection by remember { mutableStateOf(AuthorizedSpacesSelection()) } - var isSelectionComplete by remember { mutableStateOf(false) } - + val spaceSelectionState by spaceSelectionStateHolder.state.collectAsState() fun handleEvent(event: ManageAuthorizedSpacesEvent) { when (event) { - ManageAuthorizedSpacesEvent.Done -> isSelectionComplete = true is ManageAuthorizedSpacesEvent.ToggleSpace -> { - selectedIds = if (selectedIds.contains(event.roomId)) { - selectedIds.minus(event.roomId).toImmutableList() + val currentSelectedIds = spaceSelectionState.selectedSpaceIds + val newSelectedIds = if (currentSelectedIds.contains(event.roomId)) { + currentSelectedIds.minus(event.roomId).toImmutableList() } else { - selectedIds.plus(event.roomId).toImmutableList() + currentSelectedIds.plus(event.roomId).toImmutableList() } + spaceSelectionStateHolder.updateSelectedSpaceIds(newSelectedIds) } - is ManageAuthorizedSpacesEvent.SetData -> { - spacesSelection = event.data - selectedIds = event.data.initialSelectedIds + ManageAuthorizedSpacesEvent.Done -> { + spaceSelectionStateHolder.setCompletion(SpaceSelectionState.Completion.Completed) + } + ManageAuthorizedSpacesEvent.Cancel -> { + spaceSelectionStateHolder.setCompletion(SpaceSelectionState.Completion.Cancelled) } } } return ManageAuthorizedSpacesState( - selection = spacesSelection, - selectedIds = selectedIds, - isSelectionComplete = isSelectionComplete, + selectableSpaces = spaceSelectionState.selectableSpaces, + unknownSpaceIds = spaceSelectionState.unknownSpaceIds, + selectedIds = spaceSelectionState.selectedSpaceIds, eventSink = ::handleEvent, ) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt index 291cd7c760..b729fc12fa 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt @@ -11,19 +11,13 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspac import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.spaces.SpaceRoom import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.ImmutableSet data class ManageAuthorizedSpacesState( - val selection: AuthorizedSpacesSelection, + val selectableSpaces: ImmutableSet, + val unknownSpaceIds: ImmutableList, val selectedIds: ImmutableList, - val isSelectionComplete: Boolean, val eventSink: (ManageAuthorizedSpacesEvent) -> Unit ) { val isDoneButtonEnabled = selectedIds.isNotEmpty() } - -data class AuthorizedSpacesSelection( - val joinedSpaces: ImmutableList = persistentListOf(), - val unknownSpaceIds: ImmutableList = persistentListOf(), - val initialSelectedIds: ImmutableList = persistentListOf() -) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt index d818e31317..8c55af54e5 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt @@ -14,21 +14,17 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.previewutils.room.aSpaceRoom import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toImmutableSet open class ManageAuthorizedSpacesStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aManageAuthorizedSpacesState(), aManageAuthorizedSpacesState( - authorizedSpacesSelection = anAuthorizedSpaceSelection( - unknownSpaceIds = listOf(aRoomId(99)) - ) + unknownSpaceIds = listOf(aRoomId(99)) ), aManageAuthorizedSpacesState( selectedIds = listOf(aRoomId(1), aRoomId(3)), - authorizedSpacesSelection = anAuthorizedSpaceSelection( - initialSelectedIds = listOf(aRoomId(1)), - ), ), ) } @@ -49,23 +45,14 @@ private fun aSpaceRoomList(count: Int): List { } } -fun anAuthorizedSpaceSelection( - joinedSpaces: List = aSpaceRoomList(5), +fun aManageAuthorizedSpacesState( + selectableSpaces: List = aSpaceRoomList(5), unknownSpaceIds: List = emptyList(), - initialSelectedIds: List = emptyList(), -) = AuthorizedSpacesSelection( - joinedSpaces = joinedSpaces.toImmutableList(), - unknownSpaceIds = unknownSpaceIds.toImmutableList(), - initialSelectedIds = initialSelectedIds.toImmutableList(), -) - -private fun aManageAuthorizedSpacesState( - authorizedSpacesSelection: AuthorizedSpacesSelection = anAuthorizedSpaceSelection(), selectedIds: List = emptyList(), eventSink: (ManageAuthorizedSpacesEvent) -> Unit = {}, ) = ManageAuthorizedSpacesState( - selection = authorizedSpacesSelection, + selectableSpaces = selectableSpaces.toImmutableSet(), + unknownSpaceIds = unknownSpaceIds.toImmutableList(), selectedIds = selectedIds.toImmutableList(), - isSelectionComplete = false, eventSink = eventSink, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt index 022010f267..9b839b80db 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt @@ -8,6 +8,7 @@ package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces +import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope @@ -42,17 +43,24 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable fun ManageAuthorizedSpacesView( state: ManageAuthorizedSpacesState, - onBackClick: () -> Unit, modifier: Modifier = Modifier, ) { + fun onCancel() { + state.eventSink(ManageAuthorizedSpacesEvent.Cancel) + } + + fun onDone() { + state.eventSink(ManageAuthorizedSpacesEvent.Done) + } + + BackHandler(onBack = ::onCancel) + Scaffold( modifier = modifier, topBar = { ManageAuthorizedSpacesTopBar( - onBackClick = onBackClick, - onDoneClick = { - state.eventSink(ManageAuthorizedSpacesEvent.Done) - }, + onBackClick = ::onCancel, + onDoneClick = ::onDone, isDoneButtonEnabled = state.isDoneButtonEnabled ) } @@ -67,7 +75,7 @@ fun ManageAuthorizedSpacesView( hasDivider = false, ) } - items(items = state.selection.joinedSpaces) { space -> + items(items = state.selectableSpaces.toList()) { space -> CheckableSpaceListItem( headlineText = space.displayName, supportingText = space.canonicalAlias?.value, @@ -80,14 +88,14 @@ fun ManageAuthorizedSpacesView( } ) } - if (state.selection.unknownSpaceIds.isNotEmpty()) { + if (state.unknownSpaceIds.isNotEmpty()) { item { ListSectionHeader( title = stringResource(R.string.screen_manage_authorized_spaces_unknown_spaces_section_title), hasDivider = true, ) } - items(items = state.selection.unknownSpaceIds) { + items(items = state.unknownSpaceIds) { CheckableSpaceListItem( headlineText = stringResource(R.string.screen_manage_authorized_spaces_unknown_space), supportingText = it.value, @@ -185,8 +193,5 @@ private fun ManageAuthorizedSpacesTopBar( internal fun ManageAuthorizedSpacesViewPreview( @PreviewParameter(ManageAuthorizedSpacesStateProvider::class) state: ManageAuthorizedSpacesState ) = ElementPreview { - ManageAuthorizedSpacesView( - state = state, - onBackClick = {}, - ) + ManageAuthorizedSpacesView(state = state) } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/SpaceSelectionState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/SpaceSelectionState.kt new file mode 100644 index 0000000000..f24d1621b0 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/SpaceSelectionState.kt @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl.manageauthorizedspaces + +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import io.element.android.libraries.di.RoomScope +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.ImmutableSet +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.persistentSetOf +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update + +data class SpaceSelectionState( + val selectableSpaces: ImmutableSet, + val unknownSpaceIds: ImmutableList, + val selectedSpaceIds: ImmutableList, + val completion: Completion, +) { + enum class Completion { + Initial, + Completed, + Cancelled, + } + + companion object { + val INITIAL = SpaceSelectionState( + selectableSpaces = persistentSetOf(), + unknownSpaceIds = persistentListOf(), + selectedSpaceIds = persistentListOf(), + completion = Completion.Initial, + ) + } +} + +@Inject +@SingleIn(RoomScope::class) +class SpaceSelectionStateHolder { + private val _state = MutableStateFlow(SpaceSelectionState.INITIAL) + val state: StateFlow = _state.asStateFlow() + + fun update(transform: (SpaceSelectionState) -> SpaceSelectionState) { + _state.update(transform) + } + + fun updateSelectedSpaceIds(selectedSpaceIds: ImmutableList) { + update { it.copy(selectedSpaceIds = selectedSpaceIds) } + } + + fun setCompletion(completion: SpaceSelectionState.Completion) { + update { it.copy(completion = completion) } + } +} diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt index 815b7bd35e..d5fb72e72e 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt @@ -23,12 +23,9 @@ import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.compound.theme.ElementTheme import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator -import io.element.android.features.securityandprivacy.impl.manageauthorizedspaces.AuthorizedSpacesSelection import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab import io.element.android.libraries.architecture.appyx.launchMolecule import io.element.android.libraries.di.RoomScope -import io.element.android.libraries.matrix.api.core.RoomId -import kotlinx.collections.immutable.ImmutableList @ContributesNode(RoomScope::class) @AssistedInject @@ -46,19 +43,6 @@ class SecurityAndPrivacyNode( activity.openUrlInChromeCustomTab(null, darkTheme, url) } - fun getAuthorizedSpacesData(): AuthorizedSpacesSelection { - return stateFlow.value.getAuthorizedSpacesSelection() - } - - fun onAuthorizedSpacesSelected(selectedSpaces: ImmutableList, forKnock: Boolean) { - val roomAccess = if (forKnock) { - SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember(selectedSpaces) - } else { - SecurityAndPrivacyRoomAccess.SpaceMember(selectedSpaces) - } - stateFlow.value.eventSink(SecurityAndPrivacyEvent.ChangeRoomAccess(roomAccess)) - } - @Composable override fun View(modifier: Modifier) { val activity = requireNotNull(LocalActivity.current) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index f80b96ca00..09873b6b86 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -26,6 +26,8 @@ import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPerm import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissions import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.features.securityandprivacy.impl.editroomaddress.matchesServer +import io.element.android.features.securityandprivacy.impl.manageauthorizedspaces.SpaceSelectionState +import io.element.android.features.securityandprivacy.impl.manageauthorizedspaces.SpaceSelectionStateHolder import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter @@ -51,18 +53,22 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch @AssistedInject class SecurityAndPrivacyPresenter( @Assisted private val navigator: SecurityAndPrivacyNavigator, + private val spaceSelectionStateHolder: SpaceSelectionStateHolder, private val matrixClient: MatrixClient, private val room: JoinedRoom, private val featureFlagService: FeatureFlagService, ) : Presenter { @AssistedFactory interface Factory { - fun create(navigator: SecurityAndPrivacyNavigator): SecurityAndPrivacyPresenter + fun create( + navigator: SecurityAndPrivacyNavigator, + ): SecurityAndPrivacyPresenter } @Composable @@ -136,6 +142,18 @@ class SecurityAndPrivacyPresenter( } } + LaunchedEffect(selectableJoinedSpaces, savedSettings.roomAccess) { + val unknownSpaceIds = savedSettings.roomAccess.spaceIds().filter { spaceId -> + selectableJoinedSpaces.none { it.roomId == spaceId } + }.toImmutableList() + spaceSelectionStateHolder.update { state -> + state.copy( + selectableSpaces = selectableJoinedSpaces, + unknownSpaceIds = unknownSpaceIds, + ) + } + } + var showEnableEncryptionConfirmation by remember(savedSettings.isEncrypted) { mutableStateOf(false) } val permissions by room.permissionsAsState(SecurityAndPrivacyPermissions.DEFAULT) { perms -> perms.securityAndPrivacyPermissions() @@ -191,19 +209,27 @@ class SecurityAndPrivacyPresenter( SecurityAndPrivacyEvent.DismissExitConfirmation -> { saveAction.value = AsyncAction.Uninitialized } - SecurityAndPrivacyEvent.ManageAuthorizedSpaces -> { - navigator.openManageAuthorizedSpaces( + SecurityAndPrivacyEvent.ManageAuthorizedSpaces -> coroutineScope.launch { + handleMultipleSelection( + savedAccess = savedSettings.roomAccess, + editedRoomAccess = editedRoomAccess, forKnockRestricted = editedRoomAccess.value is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember ) } - SecurityAndPrivacyEvent.SelectSpaceMemberAccess -> handleSpaceMemberAccessSelection( - spaceSelectionMode = spaceSelectionMode, - editedAccess = editedRoomAccess, - ) - SecurityAndPrivacyEvent.SelectAskToJoinWithSpaceMembersAccess -> handleAskToJoinWithSpaceMembersAccessSelection( - spaceSelectionMode = spaceSelectionMode, - editedAccess = editedRoomAccess, - ) + SecurityAndPrivacyEvent.SelectSpaceMemberAccess -> coroutineScope.launch { + handleSpaceMemberAccessSelection( + spaceSelectionMode = spaceSelectionMode, + savedAccess = savedSettings.roomAccess, + editedAccess = editedRoomAccess, + ) + } + SecurityAndPrivacyEvent.SelectAskToJoinWithSpaceMembersAccess -> coroutineScope.launch { + handleAskToJoinWithSpaceMembersAccessSelection( + spaceSelectionMode = spaceSelectionMode, + savedAccess = savedSettings.roomAccess, + editedAccess = editedRoomAccess, + ) + } } } @@ -248,8 +274,9 @@ class SecurityAndPrivacyPresenter( return state } - private fun handleSpaceMemberAccessSelection( + private suspend fun handleSpaceMemberAccessSelection( spaceSelectionMode: SpaceSelectionMode, + savedAccess: SecurityAndPrivacyRoomAccess, editedAccess: MutableState, ) { if (editedAccess.value is SecurityAndPrivacyRoomAccess.SpaceMember) { @@ -257,7 +284,11 @@ class SecurityAndPrivacyPresenter( } when (spaceSelectionMode) { is SpaceSelectionMode.None -> Unit - is SpaceSelectionMode.Multiple -> navigator.openManageAuthorizedSpaces(forKnockRestricted = false) + is SpaceSelectionMode.Multiple -> handleMultipleSelection( + savedAccess = savedAccess, + editedRoomAccess = editedAccess, + forKnockRestricted = false, + ) is SpaceSelectionMode.Single -> { val newRoomAccess = SecurityAndPrivacyRoomAccess.SpaceMember( spaceIds = persistentListOf(spaceSelectionMode.spaceId) @@ -267,8 +298,9 @@ class SecurityAndPrivacyPresenter( } } - private fun handleAskToJoinWithSpaceMembersAccessSelection( + private suspend fun handleAskToJoinWithSpaceMembersAccessSelection( spaceSelectionMode: SpaceSelectionMode, + savedAccess: SecurityAndPrivacyRoomAccess, editedAccess: MutableState, ) { if (editedAccess.value is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember) { @@ -276,7 +308,11 @@ class SecurityAndPrivacyPresenter( } when (spaceSelectionMode) { is SpaceSelectionMode.None -> Unit - is SpaceSelectionMode.Multiple -> navigator.openManageAuthorizedSpaces(forKnockRestricted = true) + is SpaceSelectionMode.Multiple -> handleMultipleSelection( + savedAccess = savedAccess, + editedRoomAccess = editedAccess, + forKnockRestricted = true, + ) is SpaceSelectionMode.Single -> { val newRoomAccess = SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember( spaceIds = persistentListOf(spaceSelectionMode.spaceId) @@ -286,6 +322,38 @@ class SecurityAndPrivacyPresenter( } } + private suspend fun handleMultipleSelection( + savedAccess: SecurityAndPrivacyRoomAccess, + editedRoomAccess: MutableState, + forKnockRestricted: Boolean + ) { + val initialSelection = when (val currentRoomAccess = editedRoomAccess.value) { + is SecurityAndPrivacyRoomAccess.SpaceMember -> currentRoomAccess.spaceIds + is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember -> currentRoomAccess.spaceIds + else -> savedAccess.spaceIds() + } + spaceSelectionStateHolder.update { state -> + state.copy(selectedSpaceIds = initialSelection, completion = SpaceSelectionState.Completion.Initial) + } + navigator.openManageAuthorizedSpaces() + val newState = spaceSelectionStateHolder.state.first { it.completion != SpaceSelectionState.Completion.Initial } + when (newState.completion) { + SpaceSelectionState.Completion.Initial -> Unit + SpaceSelectionState.Completion.Cancelled -> { + navigator.closeManageAuthorizedSpaces() + } + SpaceSelectionState.Completion.Completed -> { + val selectedIds = newState.selectedSpaceIds + editedRoomAccess.value = if (forKnockRestricted) { + SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember(spaceIds = selectedIds) + } else { + SecurityAndPrivacyRoomAccess.SpaceMember(spaceIds = selectedIds) + } + navigator.closeManageAuthorizedSpaces() + } + } + } + private fun getSpaceSelectionMode( selectableJoinedSpaces: Set, savedAccess: SecurityAndPrivacyRoomAccess, diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index ff627f6a0e..6ec47ba183 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -12,7 +12,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions import io.element.android.features.securityandprivacy.impl.R -import io.element.android.features.securityandprivacy.impl.manageauthorizedspaces.AuthorizedSpacesSelection import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.matrix.api.core.RoomId @@ -121,20 +120,6 @@ data class SecurityAndPrivacyState( stringResource(R.string.screen_security_and_privacy_ask_to_join_option_description) } } - - fun getAuthorizedSpacesSelection(): AuthorizedSpacesSelection { - return AuthorizedSpacesSelection( - joinedSpaces = selectableJoinedSpaces.toImmutableList(), - unknownSpaceIds = savedSettings.roomAccess.spaceIds().filter { spaceId -> - selectableJoinedSpaces.none { it.roomId == spaceId } - }.toImmutableList(), - initialSelectedIds = when (editedSettings.roomAccess) { - is SecurityAndPrivacyRoomAccess.SpaceMember -> editedSettings.roomAccess.spaceIds - is SecurityAndPrivacyRoomAccess.AskToJoinWithSpaceMember -> editedSettings.roomAccess.spaceIds - else -> savedSettings.roomAccess.spaceIds() - } - ) - } } data class SecurityAndPrivacySettings( diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt index 5c5366caba..c0a7ca8e7f 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt @@ -14,7 +14,7 @@ class FakeSecurityAndPrivacyNavigator( private val onDoneLambda: () -> Unit = { lambdaError() }, private val openEditRoomAddressLambda: () -> Unit = { lambdaError() }, private val closeEditRoomAddressLambda: () -> Unit = { lambdaError() }, - private val openManageAuthorizedSpacesLambda: (Boolean) -> Unit = { lambdaError() }, + private val openManageAuthorizedSpacesLambda: () -> Unit = { lambdaError() }, private val closeManageAuthorizedSpacesLambda: () -> Unit = { lambdaError() }, ) : SecurityAndPrivacyNavigator { override fun onDone() { @@ -29,8 +29,8 @@ class FakeSecurityAndPrivacyNavigator( closeEditRoomAddressLambda() } - override fun openManageAuthorizedSpaces(forKnockRestricted: Boolean) { - openManageAuthorizedSpacesLambda(forKnockRestricted) + override fun openManageAuthorizedSpaces() { + openManageAuthorizedSpacesLambda() } override fun closeManageAuthorizedSpaces() { diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt index baae82a586..a6f21c0162 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNodeTest.kt @@ -49,27 +49,16 @@ class SecurityAndPrivacyFlowNodeTest { } @Test - fun `openManageAuthorizedSpaces navigates with forKnockRestricted false`() = runTest { + fun `openManageAuthorizedSpaces navigates to ManageAuthorizedSpaces`() = runTest { val flowNode = createFlowNode() - flowNode.navigator.openManageAuthorizedSpaces(forKnockRestricted = false) - assertThat(flowNode.currentNavTarget()).isEqualTo( - SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces(forKnockRestricted = false) - ) - } - - @Test - fun `openManageAuthorizedSpaces navigates with forKnockRestricted true`() = runTest { - val flowNode = createFlowNode() - flowNode.navigator.openManageAuthorizedSpaces(forKnockRestricted = true) - assertThat(flowNode.currentNavTarget()).isEqualTo( - SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces(forKnockRestricted = true) - ) + flowNode.navigator.openManageAuthorizedSpaces() + assertThat(flowNode.currentNavTarget()).isEqualTo(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces) } @Test fun `closeManageAuthorizedSpaces pops backstack`() = runTest { val flowNode = createFlowNode() - flowNode.navigator.openManageAuthorizedSpaces(forKnockRestricted = false) + flowNode.navigator.openManageAuthorizedSpaces() assertThat(flowNode.currentNavTarget()) .isInstanceOf(SecurityAndPrivacyFlowNode.NavTarget.ManageAuthorizedSpaces::class.java) flowNode.navigator.closeManageAuthorizedSpaces() diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt index 7d678b23bb..8314aca4cd 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenterTest.kt @@ -12,38 +12,33 @@ import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.tests.testutils.test import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.persistentSetOf import kotlinx.coroutines.test.runTest import org.junit.Test class ManageAuthorizedSpacesPresenterTest { @Test - fun `present - initial state has empty selection`() = runTest { - val presenter = ManageAuthorizedSpacesPresenter() + fun `present - initial state reflects shared state`() = runTest { + val sharedStateHolder = SpaceSelectionStateHolder() + val presenter = ManageAuthorizedSpacesPresenter(sharedStateHolder) presenter.test { with(awaitItem()) { assertThat(selectedIds).isEmpty() - assertThat(isSelectionComplete).isFalse() assertThat(isDoneButtonEnabled).isFalse() } } } @Test - fun `present - SetData event updates selection and initial selectedIds`() = runTest { - val presenter = ManageAuthorizedSpacesPresenter() + fun `present - state reflects shared state with pre-selected spaces`() = runTest { + val sharedStateHolder = SpaceSelectionStateHolder() + val roomId = A_ROOM_ID + sharedStateHolder.update { + it.copy(selectedSpaceIds = persistentListOf(roomId)) + } + val presenter = ManageAuthorizedSpacesPresenter(sharedStateHolder) presenter.test { - val initialState = awaitItem() - val roomId = A_ROOM_ID - val data = AuthorizedSpacesSelection( - joinedSpaces = persistentListOf(), - unknownSpaceIds = persistentListOf(), - initialSelectedIds = persistentListOf(roomId) - ) - initialState.eventSink(ManageAuthorizedSpacesEvent.SetData(data)) - // SetData updates two state variables, which may emit intermediate states - skipItems(1) with(awaitItem()) { - assertThat(selection).isEqualTo(data) assertThat(selectedIds).containsExactly(roomId) assertThat(isDoneButtonEnabled).isTrue() } @@ -51,8 +46,9 @@ class ManageAuthorizedSpacesPresenterTest { } @Test - fun `present - ToggleSpace event adds space to selectedIds`() = runTest { - val presenter = ManageAuthorizedSpacesPresenter() + fun `present - ToggleSpace event adds space to selectedIds in shared state`() = runTest { + val sharedStateHolder = SpaceSelectionStateHolder() + val presenter = ManageAuthorizedSpacesPresenter(sharedStateHolder) presenter.test { val initialState = awaitItem() val roomId = A_ROOM_ID @@ -61,34 +57,69 @@ class ManageAuthorizedSpacesPresenterTest { assertThat(selectedIds).containsExactly(roomId) assertThat(isDoneButtonEnabled).isTrue() } + // Verify the shared state is also updated + assertThat(sharedStateHolder.state.value.selectedSpaceIds).containsExactly(roomId) } } @Test fun `present - ToggleSpace event removes space when already selected`() = runTest { - val presenter = ManageAuthorizedSpacesPresenter() + val sharedStateHolder = SpaceSelectionStateHolder() + sharedStateHolder.updateSelectedSpaceIds(persistentListOf(A_ROOM_ID)) + val presenter = ManageAuthorizedSpacesPresenter(sharedStateHolder) presenter.test { val initialState = awaitItem() - val roomId = A_ROOM_ID - initialState.eventSink(ManageAuthorizedSpacesEvent.ToggleSpace(roomId)) - val stateWithSelection = awaitItem() - assertThat(stateWithSelection.selectedIds).containsExactly(roomId) - stateWithSelection.eventSink(ManageAuthorizedSpacesEvent.ToggleSpace(roomId)) + assertThat(initialState.selectedIds).containsExactly(A_ROOM_ID) + initialState.eventSink(ManageAuthorizedSpacesEvent.ToggleSpace(A_ROOM_ID)) with(awaitItem()) { assertThat(selectedIds).isEmpty() assertThat(isDoneButtonEnabled).isFalse() } + // Verify the shared state is also updated + assertThat(sharedStateHolder.state.value.selectedSpaceIds).isEmpty() } } @Test - fun `present - Done event sets isSelectionComplete to true`() = runTest { - val presenter = ManageAuthorizedSpacesPresenter() + fun `present - Done event sets completion to Completed`() = runTest { + val sharedStateHolder = SpaceSelectionStateHolder() + val presenter = ManageAuthorizedSpacesPresenter(sharedStateHolder) presenter.test { val initialState = awaitItem() initialState.eventSink(ManageAuthorizedSpacesEvent.Done) + cancelAndIgnoreRemainingEvents() + assertThat(sharedStateHolder.state.value.completion) + .isEqualTo(SpaceSelectionState.Completion.Completed) + } + } + + @Test + fun `present - Cancel event sets completion to Cancelled`() = runTest { + val sharedStateHolder = SpaceSelectionStateHolder() + val presenter = ManageAuthorizedSpacesPresenter(sharedStateHolder) + presenter.test { + val initialState = awaitItem() + initialState.eventSink(ManageAuthorizedSpacesEvent.Cancel) + cancelAndIgnoreRemainingEvents() + assertThat(sharedStateHolder.state.value.completion) + .isEqualTo(SpaceSelectionState.Completion.Cancelled) + } + } + + @Test + fun `present - displays spaces from shared state`() = runTest { + val sharedStateHolder = SpaceSelectionStateHolder() + sharedStateHolder.update { + it.copy( + selectableSpaces = persistentSetOf(), + unknownSpaceIds = persistentListOf(A_ROOM_ID), + ) + } + val presenter = ManageAuthorizedSpacesPresenter(sharedStateHolder) + presenter.test { with(awaitItem()) { - assertThat(isSelectionComplete).isTrue() + assertThat(selectableSpaces).isEmpty() + assertThat(unknownSpaceIds).containsExactly(A_ROOM_ID) } } } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesViewTest.kt index 515fe590a3..c732df6df0 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesViewTest.kt @@ -15,15 +15,15 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.test.ext.junit.runners.AndroidJUnit4 import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.previewutils.room.aSpaceRoom 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 kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toImmutableSet import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule @@ -34,11 +34,12 @@ class ManageAuthorizedSpacesViewTest { @get:Rule val rule = createAndroidComposeRule() @Test - fun `clicking back invokes callback`() { - ensureCalledOnce { callback -> - rule.setManageAuthorizedSpacesView(onBackClick = callback) - rule.pressBack() - } + fun `clicking back emits Cancel event`() { + val recorder = EventsRecorder() + val state = aManageAuthorizedSpacesState(eventSink = recorder) + rule.setManageAuthorizedSpacesView(state) + rule.pressBack() + recorder.assertSingle(ManageAuthorizedSpacesEvent.Cancel) } @Test @@ -47,9 +48,7 @@ class ManageAuthorizedSpacesViewTest { val space = aSpaceRoom(roomId = roomId, displayName = "Test Space") val recorder = EventsRecorder() val state = aManageAuthorizedSpacesState( - selection = anAuthorizedSpaceSelection( - joinedSpaces = listOf(space) - ), + selectableSpaces = listOf(space), eventSink = recorder ) rule.setManageAuthorizedSpacesView(state) @@ -86,24 +85,20 @@ private fun AndroidComposeTestRule.setManag state: ManageAuthorizedSpacesState = aManageAuthorizedSpacesState( eventSink = EventsRecorder(expectEvents = false) ), - onBackClick: () -> Unit = EnsureNeverCalled(), ) { setContent { - ManageAuthorizedSpacesView( - state = state, - onBackClick = onBackClick, - ) + ManageAuthorizedSpacesView(state = state) } } private fun aManageAuthorizedSpacesState( - selection: AuthorizedSpacesSelection = AuthorizedSpacesSelection(), + selectableSpaces: List = emptyList(), + unknownSpaceIds: List = emptyList(), selectedIds: List = emptyList(), - isSelectionComplete: Boolean = false, eventSink: (ManageAuthorizedSpacesEvent) -> Unit = {}, ) = ManageAuthorizedSpacesState( - selection = selection, + selectableSpaces = selectableSpaces.toImmutableSet(), + unknownSpaceIds = unknownSpaceIds.toImmutableList(), selectedIds = selectedIds.toImmutableList(), - isSelectionComplete = isSelectionComplete, eventSink = eventSink, ) diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenterTest.kt index 2c1611fec8..e9cd49cc94 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenterTest.kt @@ -10,6 +10,7 @@ package io.element.android.features.securityandprivacy.impl.root import com.google.common.truth.Truth.assertThat import io.element.android.features.securityandprivacy.impl.FakeSecurityAndPrivacyNavigator import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator +import io.element.android.features.securityandprivacy.impl.manageauthorizedspaces.SpaceSelectionStateHolder import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.featureflag.api.FeatureFlagService @@ -436,7 +437,7 @@ class SecurityAndPrivacyPresenterTest { @Test fun `present - SelectSpaceMemberAccess with multiple spaces opens ManageAuthorizedSpaces`() = runTest { - val openManageAuthorizedSpacesLambda = lambdaRecorder { } + val openManageAuthorizedSpacesLambda = lambdaRecorder { } val navigator = FakeSecurityAndPrivacyNavigator(openManageAuthorizedSpacesLambda = openManageAuthorizedSpacesLambda) val room = FakeJoinedRoom( @@ -471,7 +472,7 @@ class SecurityAndPrivacyPresenterTest { val state = awaitItem() assertThat(state.isSpaceMemberSelectable).isTrue() state.eventSink(SecurityAndPrivacyEvent.SelectSpaceMemberAccess) - assert(openManageAuthorizedSpacesLambda).isCalledOnce().with(value(false)) + assert(openManageAuthorizedSpacesLambda).isCalledOnce() } } @@ -605,7 +606,7 @@ class SecurityAndPrivacyPresenterTest { @Test fun `present - SelectAskToJoinWithSpaceMembersAccess with multiple spaces opens ManageAuthorizedSpaces`() = runTest { - val openManageAuthorizedSpacesLambda = lambdaRecorder { } + val openManageAuthorizedSpacesLambda = lambdaRecorder { } val navigator = FakeSecurityAndPrivacyNavigator(openManageAuthorizedSpacesLambda = openManageAuthorizedSpacesLambda) val room = FakeJoinedRoom( @@ -642,7 +643,7 @@ class SecurityAndPrivacyPresenterTest { val state = awaitItem() assertThat(state.isAskToJoinWithSpaceMembersSelectable).isTrue() state.eventSink(SecurityAndPrivacyEvent.SelectAskToJoinWithSpaceMembersAccess) - assert(openManageAuthorizedSpacesLambda).isCalledOnce().with(value(true)) + assert(openManageAuthorizedSpacesLambda).isCalledOnce() } } @@ -950,73 +951,6 @@ class SecurityAndPrivacyPresenterTest { } } - @Test - fun `present - getAuthorizedSpacesSelection returns correct data for SpaceMember`() = runTest { - val room = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - roomPermissions = roomPermissions(), - initialRoomInfo = aRoomInfo( - historyVisibility = RoomHistoryVisibility.Shared, - joinRule = JoinRule.Restricted( - rules = persistentListOf(AllowRule.RoomMembership(A_ROOM_ID)) - ) - ) - ) - ) - val spaceRoom = aSpaceRoom(roomId = A_ROOM_ID) - val client = FakeMatrixClient( - userIdServerNameLambda = { "matrix.org" }, - spaceService = FakeSpaceService( - joinedParentsResult = { _ -> Result.success(listOf(spaceRoom)) }, - getSpaceRoomResult = { null } - ) - ) - val presenter = createSecurityAndPrivacyPresenter( - room = room, - matrixClient = client, - featureFlagService = FakeFeatureFlagService( - initialState = mapOf(FeatureFlags.SpaceSettings.key to true) - ) - ) - presenter.test { - skipItems(1) - with(awaitItem()) { - val selection = getAuthorizedSpacesSelection() - assertThat(selection.joinedSpaces).containsExactly(spaceRoom) - assertThat(selection.initialSelectedIds).containsExactly(A_ROOM_ID) - assertThat(selection.unknownSpaceIds).isEmpty() - } - cancelAndIgnoreRemainingEvents() - } - } - - @Test - fun `present - getAuthorizedSpacesSelection identifies unknown space IDs`() = runTest { - val unknownSpaceId = RoomId("!unknown:matrix.org") - val room = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - roomPermissions = roomPermissions(), - initialRoomInfo = aRoomInfo( - historyVisibility = RoomHistoryVisibility.Shared, - joinRule = JoinRule.Restricted( - rules = persistentListOf(AllowRule.RoomMembership(unknownSpaceId)) - ) - ) - ) - ) - // No spaces available (the space in the join rule is unknown) - val presenter = createSecurityAndPrivacyPresenter(room = room) - presenter.test { - skipItems(1) - with(awaitItem()) { - val selection = getAuthorizedSpacesSelection() - assertThat(selection.joinedSpaces).isEmpty() - assertThat(selection.unknownSpaceIds).containsExactly(unknownSpaceId) - } - cancelAndIgnoreRemainingEvents() - } - } - @Test fun `present - SelectAskToJoinWithSpaceMembersAccess with single space auto-selects`() = runTest { val room = FakeJoinedRoom( @@ -1169,12 +1103,14 @@ class SecurityAndPrivacyPresenterTest { getSpaceRoomResult = { null } ), ), + spaceSelectionStateHolder: SpaceSelectionStateHolder = SpaceSelectionStateHolder(), ): SecurityAndPrivacyPresenter { return SecurityAndPrivacyPresenter( room = room, matrixClient = matrixClient, navigator = navigator, featureFlagService = featureFlagService, + spaceSelectionStateHolder = spaceSelectionStateHolder, ) } } From 269747437ba5cd9ca53c88ffb7c2a69c3e2b23db Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 16 Sep 2025 18:03:05 +0200 Subject: [PATCH 329/347] Add preview with a11y details. --- .../features/messages/impl/MessagesView.kt | 64 +++++++++++++++++++ .../roomdetails/impl/RoomDetailsView.kt | 9 +++ 2 files changed, 73 insertions(+) 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 5479836bb3..ea50cf0fe2 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 @@ -46,6 +46,7 @@ import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme @@ -68,6 +69,10 @@ import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBan import io.element.android.features.messages.impl.timeline.FOCUS_ON_PINNED_EVENT_DEBOUNCE_DURATION_IN_MILLIS import io.element.android.features.messages.impl.timeline.TimelineEvents import io.element.android.features.messages.impl.timeline.TimelineView +import io.element.android.features.messages.impl.timeline.aGroupedEvents +import io.element.android.features.messages.impl.timeline.aTimelineItemDaySeparator +import io.element.android.features.messages.impl.timeline.aTimelineItemEvent +import io.element.android.features.messages.impl.timeline.aTimelineState import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionBottomSheet import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents @@ -75,6 +80,9 @@ import io.element.android.features.messages.impl.timeline.components.reactionsum import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheet import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetEvents import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition +import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemStateEventContent +import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent import io.element.android.features.messages.impl.topbars.MessagesViewTopBar import io.element.android.features.messages.impl.topbars.ThreadTopBar import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessagePermissionRationaleDialog @@ -103,10 +111,12 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.timeline.Timeline +import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.textcomposer.model.TextEditorState import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.wysiwyg.link.Link +import kotlinx.collections.immutable.persistentListOf import timber.log.Timber import kotlin.time.Duration.Companion.milliseconds @@ -572,3 +582,57 @@ internal fun MessagesViewPreview(@PreviewParameter(MessagesStateProvider::class) knockRequestsBannerView = {}, ) } + +@Preview +@Composable +internal fun MessagesViewA11yPreview() = ElementPreview { + val content = aTimelineItemTextContent( + body = "A message content" + ) + MessagesView( + state = aMessagesState( + roomName = "A DM with a very looong name", + dmUserVerificationState = IdentityState.VerificationViolation, + timelineState = aTimelineState( + timelineItems = persistentListOf( + // 1 items with isMine = false + aTimelineItemEvent( + isMine = false, + content = content, + groupPosition = TimelineItemGroupPosition.None, + sendState = LocalEventSendState.Failed.Unknown("Message failed to send"), + ), + // A state event on top of it + aTimelineItemEvent( + isMine = false, + content = aTimelineItemStateEventContent(), + groupPosition = TimelineItemGroupPosition.None + ), + // 1 item with isMine = true + aTimelineItemEvent( + isMine = true, + content = content, + groupPosition = TimelineItemGroupPosition.None + ), + // A grouped event on top of it + aGroupedEvents(), + // A day separator + aTimelineItemDaySeparator(), + ), + // Render a focused event for an event with sender information displayed + focusedEventIndex = 2, + ) + ), + onBackClick = {}, + onRoomDetailsClick = {}, + onEventContentClick = { _, _ -> false }, + onUserDataClick = {}, + onLinkClick = { _, _ -> }, + onSendLocationClick = {}, + onCreatePollClick = {}, + onJoinCallClick = {}, + onViewAllPinnedMessagesClick = { }, + forceJumpToBottomVisibility = true, + knockRequestsBannerView = {}, + ) +} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 05f26daedb..86481be026 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -59,6 +59,7 @@ import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch import io.element.android.libraries.designsystem.modifiers.niceClickable +import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight @@ -768,6 +769,14 @@ internal fun RoomDetailsPreview(@PreviewParameter(RoomDetailsStateProvider::clas internal fun RoomDetailsDarkPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) = ElementPreviewDark { ContentToPreview(state) } +@PreviewWithLargeHeight +@Composable +internal fun RoomDetailsA11yPreview() = ElementPreview { + ContentToPreview( + state = aRoomDetailsState(displayAdminSettings = true) + ) +} + @ExcludeFromCoverage @Composable private fun ContentToPreview(state: RoomDetailsState) { From 5726b73282b5ed8735c132fda8b995b93adce7bc Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 9 Jan 2026 13:57:10 +0000 Subject: [PATCH 330/347] Update screenshots --- .../images/features.messages.impl_MessagesViewA11y_en.png | 3 +++ .../images/features.roomdetails.impl_RoomDetailsA11y_en.png | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesViewA11y_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsA11y_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesViewA11y_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesViewA11y_en.png new file mode 100644 index 0000000000..08972f09ac --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesViewA11y_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:769dd2d263461b4a4597ca6ca08fb5c9e93cf3b3c25121c9dc1451e4fd0ad9c6 +size 133844 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 new file mode 100644 index 0000000000..1076b7d302 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsA11y_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c057a0a0a7656f4fc77180902962aa14e0422442f139248dbdcfef0fb4216f43 +size 79689 From df76e283d03fd8f6f0ee5a8dd8f6ff46d77fd4aa Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 9 Jan 2026 15:36:10 +0100 Subject: [PATCH 331/347] Fix konsist test. --- .../io/element/android/tests/konsist/KonsistPreviewTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt index 32f2908cf7..b7ee2d5743 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt @@ -47,7 +47,7 @@ class KonsistPreviewTest { " and should be internal." ) { val testedView = it.name.removeSuffix("A11yPreview") - it.text.contains("$testedView(") && + (it.text.contains("$testedView(") || it.text.contains("ContentToPreview(")) && it.hasAllAnnotationsOf(PreviewsDayNight::class).not() && it.text.contains("ElementPreview") && it.hasInternalModifier From 4317e124cdf9e88f70f1c3ba1d62783d4c032f4d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 15:36:08 +0000 Subject: [PATCH 332/347] fix(deps): update roborazzi to v1.56.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 51e735856e..c6f7a4495a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,7 +32,7 @@ accompanist = "0.37.3" # Test test_core = "1.7.0" -roborazzi = "1.55.0" +roborazzi = "1.56.0" # Jetbrain datetime = "0.7.1" From ea35f07fa137b03791f3d1d21149dc868e1d674e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 16:01:50 +0000 Subject: [PATCH 333/347] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.1.9 (#5986) 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 51e735856e..7485da1e3f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -177,7 +177,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.1.7" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:26.1.9" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } From c75ffc6af1bb7b0198a5af3821c2ab6c628c09cf Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Fri, 9 Jan 2026 17:19:35 +0100 Subject: [PATCH 334/347] Remove previously used id filtering from `RoomSyncSubscriber` (#5985) This is done in the SDK, doing it in the client was a source of issues. --- .../matrix/impl/room/RoomSyncSubscriber.kt | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomSyncSubscriber.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomSyncSubscriber.kt index 724e3f62f0..bf31c2edf3 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomSyncSubscriber.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomSyncSubscriber.kt @@ -21,18 +21,14 @@ class RoomSyncSubscriber( private val roomListService: RoomListService, private val dispatchers: CoroutineDispatchers, ) { - private val subscribedRoomIds = mutableSetOf() private val mutex = Mutex() suspend fun subscribe(roomId: RoomId) { mutex.withLock { withContext(dispatchers.io) { try { - if (!isSubscribedTo(roomId)) { - Timber.d("Subscribing to room $roomId}") - roomListService.subscribeToRooms(listOf(roomId.value)) - } - subscribedRoomIds.add(roomId) + Timber.d("Subscribing to room $roomId}") + roomListService.subscribeToRooms(listOf(roomId.value)) } catch (exception: Exception) { Timber.e(exception, "Failed to subscribe to room $roomId") } @@ -43,12 +39,8 @@ class RoomSyncSubscriber( suspend fun batchSubscribe(roomIds: List) = mutex.withLock { withContext(dispatchers.io) { try { - val roomIdsToSubscribeTo = roomIds.filterNot { isSubscribedTo(it) } - if (roomIdsToSubscribeTo.isNotEmpty()) { - Timber.d("Subscribing to rooms: $roomIds") - roomListService.subscribeToRooms(roomIdsToSubscribeTo.map { it.value }) - subscribedRoomIds.addAll(roomIds) - } + Timber.d("Subscribing to rooms: $roomIds") + roomListService.subscribeToRooms(roomIds.map { it.value }) } catch (cancellationException: CancellationException) { throw cancellationException } catch (exception: Exception) { @@ -56,8 +48,4 @@ class RoomSyncSubscriber( } } } - - fun isSubscribedTo(roomId: RoomId): Boolean { - return subscribedRoomIds.contains(roomId) - } } From a206de5a1537df7f7030930470db53ea79fa02cf Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 9 Jan 2026 17:52:52 +0100 Subject: [PATCH 335/347] quality : fix PR remarks --- .../impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt | 1 - .../impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt | 1 - .../manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt | 1 - .../impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt | 1 - .../ManageAuthorizedSpacesStateProvider.kt | 1 - .../impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt | 2 +- .../impl/manageauthorizedspaces/SpaceSelectionState.kt | 1 - 7 files changed, 1 insertion(+), 7 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt index 37d70b65f5..3b7460721c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesEvent.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt index 709f2189bc..8414826d39 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesNode.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt index 5922e910a2..cdb0d9801f 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesPresenter.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt index b729fc12fa..bfea7d200c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesState.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt index 8c55af54e5..d2fec941ff 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesStateProvider.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt index 9b839b80db..7208ee6115 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/ManageAuthorizedSpacesView.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -40,6 +39,7 @@ 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 +// Figma design: https://www.figma.com/design/kcnHxunG1LDWXsJhaNuiHz/ER-145--Spaces-on-Element-X?node-id=6361-86274&m=dev @Composable fun ManageAuthorizedSpacesView( state: ManageAuthorizedSpacesState, diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/SpaceSelectionState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/SpaceSelectionState.kt index f24d1621b0..3df9e9bf1c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/SpaceSelectionState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/manageauthorizedspaces/SpaceSelectionState.kt @@ -1,6 +1,5 @@ /* * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. From 3fe12a59e843218a9ab351f3f93caa8899eec8cc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 08:35:19 +0100 Subject: [PATCH 336/347] fix(deps): update dependency com.posthog:posthog-android to v3.28.1 (#5988) 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 285ed84531..f96662b673 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -218,7 +218,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.28.0" +posthog = "com.posthog:posthog-android:3.28.1" sentry = "io.sentry:sentry-android:8.29.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.29.2" From 168ea3e0e4bc43dda8538e630a030a24dbee41cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 09:20:03 +0100 Subject: [PATCH 337/347] fix(deps): update metro to v0.9.4 (#5991) 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 f96662b673..aee90249fe 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -52,7 +52,7 @@ haze = "1.7.1" dependencyAnalysis = "3.5.1" # DI -metro = "0.9.3" +metro = "0.9.4" # Auto service autoservice = "1.1.1" From b4f3cd29f93b68d92be528a4de77cc9fba027da3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 12 Jan 2026 10:27:39 +0100 Subject: [PATCH 338/347] Improve code readability. --- .../libraries/textcomposer/TextComposer.kt | 275 ++++++++++-------- .../{SendButton.kt => SendButtonIcon.kt} | 23 +- ...ton.kt => VoiceMessageDeleteButtonIcon.kt} | 8 +- ...n.kt => VoiceMessageRecorderButtonIcon.kt} | 8 +- 4 files changed, 169 insertions(+), 145 deletions(-) rename libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/{SendButton.kt => SendButtonIcon.kt} (80%) rename libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/{VoiceMessageDeleteButton.kt => VoiceMessageDeleteButtonIcon.kt} (89%) rename libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/{VoiceMessageRecorderButton.kt => VoiceMessageRecorderButtonIcon.kt} (92%) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 4438715444..5f3e9ec54b 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -30,7 +30,6 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -44,7 +43,6 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.SemanticsPropertyReceiver import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.hideFromAccessibility @@ -74,11 +72,11 @@ import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetailsProvider import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag -import io.element.android.libraries.textcomposer.components.SendButton +import io.element.android.libraries.textcomposer.components.SendButtonIcon import io.element.android.libraries.textcomposer.components.TextFormatting -import io.element.android.libraries.textcomposer.components.VoiceMessageDeleteButton +import io.element.android.libraries.textcomposer.components.VoiceMessageDeleteButtonIcon import io.element.android.libraries.textcomposer.components.VoiceMessagePreview -import io.element.android.libraries.textcomposer.components.VoiceMessageRecorderButton +import io.element.android.libraries.textcomposer.components.VoiceMessageRecorderButtonIcon import io.element.android.libraries.textcomposer.components.VoiceMessageRecording import io.element.android.libraries.textcomposer.components.markdown.MarkdownTextInput import io.element.android.libraries.textcomposer.components.textInputRoundedCornerShape @@ -215,29 +213,7 @@ fun TextComposer( } } - val canSendMessage = markdown.isNotBlank() || composerMode is MessageComposerMode.Attachment - val sendButton = @Composable { - SendButton( - canSendMessage = canSendMessage, - composerMode = composerMode, - ) - } - val recordVoiceButton = @Composable { - VoiceMessageRecorderButton( - isRecording = voiceMessageState is VoiceMessageState.Recording, - ) - } - val sendVoiceButton = @Composable { - SendButton( - canSendMessage = voiceMessageState is VoiceMessageState.Preview, - composerMode = composerMode, - ) - } - val uploadVoiceProgress = @Composable { - CircularProgressIndicator( - modifier = Modifier.size(24.dp), - ) - } + val canSendTextMessage = markdown.isNotBlank() || composerMode is MessageComposerMode.Attachment val textFormattingOptions: @Composable (() -> Unit)? = (state as? TextEditorState.Rich)?.let { @Composable { TextFormatting(state = it.richTextEditorState) } @@ -249,52 +225,126 @@ fun TextComposer( hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) } - fun endButtonClickStandard() = when { - !canSendMessage -> - when (voiceMessageState) { - VoiceMessageState.Idle -> { - performHapticFeedback() - onVoiceRecorderEvent.invoke(VoiceMessageRecorderEvent.Start) - } - is VoiceMessageState.Recording -> { - performHapticFeedback() - onVoiceRecorderEvent.invoke(VoiceMessageRecorderEvent.Stop) - } - is VoiceMessageState.Preview -> when (voiceMessageState.isSending) { - true -> { - // No op + @Composable + fun rememberEndButtonParams() = remember( + composerMode.isEditing, + voiceMessageState.endButtonKey(), + canSendTextMessage, + ) { + when { + !canSendTextMessage -> + when (voiceMessageState) { + VoiceMessageState.Idle -> EndButtonParams( + endButtonContentDescriptionResId = CommonStrings.a11y_voice_message_record, + endButtonClick = { + performHapticFeedback() + onVoiceRecorderEvent.invoke(VoiceMessageRecorderEvent.Start) + }, + endButtonContent = @Composable { + VoiceMessageRecorderButtonIcon( + isRecording = false, + ) + } + ) + is VoiceMessageState.Recording -> EndButtonParams( + endButtonContentDescriptionResId = CommonStrings.a11y_voice_message_stop_recording, + endButtonClick = { + performHapticFeedback() + onVoiceRecorderEvent.invoke(VoiceMessageRecorderEvent.Stop) + }, + endButtonContent = @Composable { + VoiceMessageRecorderButtonIcon( + isRecording = true, + ) + } + ) + is VoiceMessageState.Preview -> if (voiceMessageState.isSending) { + EndButtonParams( + endButtonContentDescriptionResId = CommonStrings.common_sending, + endButtonClick = {}, + endButtonContent = @Composable { + CircularProgressIndicator( + modifier = Modifier.size(24.dp), + ) + } + ) + } else { + EndButtonParams( + endButtonContentDescriptionResId = CommonStrings.action_send_voice_message, + endButtonClick = { + onSendVoiceMessage() + }, + endButtonContent = @Composable { + SendButtonIcon( + canSendMessage = true, + isEditing = composerMode.isEditing, + ) + }, + ) } - false -> onSendVoiceMessage() } - } - else -> onSendMessage() - } - - fun endButtonClickFormatting() { - if (canSendMessage) { - onSendMessage() + composerMode.isEditing -> EndButtonParams( + endButtonContentDescriptionResId = CommonStrings.action_send_edited_message, + endButtonClick = { + onSendMessage() + }, + endButtonContent = @Composable { + SendButtonIcon( + canSendMessage = true, + isEditing = true, + ) + }, + ) + else -> EndButtonParams( + endButtonContentDescriptionResId = CommonStrings.action_send_message, + endButtonClick = { + onSendMessage() + }, + endButtonContent = @Composable { + SendButtonIcon( + canSendMessage = true, + isEditing = false, + ) + }, + ) } } - val sendOrRecordButton = when { - !canSendMessage -> - when (voiceMessageState) { - VoiceMessageState.Idle, - is VoiceMessageState.Recording -> recordVoiceButton - is VoiceMessageState.Preview -> when (voiceMessageState.isSending) { - true -> uploadVoiceProgress - false -> sendVoiceButton - } - } - else -> sendButton + @Composable + fun rememberEndButtonParamsFormatting() = remember(composerMode.isEditing, canSendTextMessage) { + if (composerMode.isEditing) { + EndButtonParams( + endButtonContentDescriptionResId = CommonStrings.action_send_edited_message, + endButtonClick = { + if (canSendTextMessage) { + onSendMessage() + } + }, + endButtonContent = @Composable { + SendButtonIcon( + canSendMessage = canSendTextMessage, + isEditing = true, + ) + }, + ) + } else { + EndButtonParams( + endButtonContentDescriptionResId = CommonStrings.action_send_message, + endButtonClick = { + if (canSendTextMessage) { + onSendMessage() + } + }, + endButtonContent = @Composable { + SendButtonIcon( + canSendMessage = canSendTextMessage, + isEditing = false, + ) + }, + ) + } } - val endButtonA11y = endButtonA11y( - composerMode = composerMode, - voiceMessageState = voiceMessageState, - canSendMessage = canSendMessage, - ) - val voiceRecording = @Composable { when (voiceMessageState) { is VoiceMessageState.Preview -> @@ -319,6 +369,7 @@ fun TextComposer( } if (showTextFormatting && textFormattingOptions != null) { + val endButtonParams = rememberEndButtonParamsFormatting() TextFormattingLayout( modifier = layoutModifier, isRoomEncrypted = state.isRoomEncrypted, @@ -331,20 +382,17 @@ fun TextComposer( ) }, textFormatting = textFormattingOptions, - sendButton = sendButton, - endButtonClick = ::endButtonClickFormatting, - endButtonA11y = endButtonA11y, + endButtonParams = endButtonParams, ) } else { + val endButtonParams = rememberEndButtonParams() StandardLayout( composerMode = composerMode, voiceMessageState = voiceMessageState, isRoomEncrypted = state.isRoomEncrypted, modifier = layoutModifier, textInput = textInput, - endButton = sendOrRecordButton, - endButtonClick = ::endButtonClickStandard, - endButtonA11y = endButtonA11y, + endButtonParams = endButtonParams, voiceRecording = voiceRecording, onAddAttachment = onAddAttachment, onDeleteVoiceMessage = onDeleteVoiceMessage, @@ -372,38 +420,11 @@ fun TextComposer( } } -@ReadOnlyComposable -@Composable -private fun endButtonA11y( - composerMode: MessageComposerMode, - voiceMessageState: VoiceMessageState, - canSendMessage: Boolean, -): (SemanticsPropertyReceiver) -> Unit { - val a11ySendButtonDescription = stringResource( - id = when { - !canSendMessage -> - when (voiceMessageState) { - VoiceMessageState.Idle, - is VoiceMessageState.Recording -> if (voiceMessageState is VoiceMessageState.Recording) { - CommonStrings.a11y_voice_message_stop_recording - } else { - CommonStrings.a11y_voice_message_record - } - is VoiceMessageState.Preview -> when (voiceMessageState.isSending) { - true -> CommonStrings.common_sending - false -> CommonStrings.action_send_voice_message - } - } - composerMode.isEditing -> CommonStrings.action_send_edited_message - else -> CommonStrings.action_send_message - } - ) - val endButtonA11y: (SemanticsPropertyReceiver.() -> Unit) = { - contentDescription = a11ySendButtonDescription - onClick(null, null) - } - return endButtonA11y -} +private data class EndButtonParams( + val endButtonContentDescriptionResId: Int, + val endButtonClick: () -> Unit, + val endButtonContent: @Composable () -> Unit, +) @Composable private fun StandardLayout( @@ -412,9 +433,7 @@ private fun StandardLayout( isRoomEncrypted: Boolean?, textInput: @Composable () -> Unit, voiceRecording: @Composable () -> Unit, - endButton: @Composable () -> Unit, - endButtonClick: () -> Unit, - endButtonA11y: (SemanticsPropertyReceiver.() -> Unit), + endButtonParams: EndButtonParams, onAddAttachment: () -> Unit, onDeleteVoiceMessage: () -> Unit, onVoiceRecorderEvent: (VoiceMessageRecorderEvent) -> Unit, @@ -469,9 +488,9 @@ private fun StandardLayout( } else { when (voiceMessageState) { is VoiceMessageState.Preview -> - VoiceMessageDeleteButton(enabled = !voiceMessageState.isSending) + VoiceMessageDeleteButtonIcon(enabled = !voiceMessageState.isSending) is VoiceMessageState.Recording -> - VoiceMessageDeleteButton(enabled = true) + VoiceMessageDeleteButtonIcon(enabled = true) } } } @@ -489,15 +508,18 @@ private fun StandardLayout( } } // To avoid loosing keyboard focus, the IconButton has to be defined here and has to be always enabled. + val endButtonContentDescription = stringResource(endButtonParams.endButtonContentDescriptionResId) IconButton( modifier = Modifier .padding(bottom = 5.dp, top = 5.dp, end = 6.dp, start = 6.dp) .size(48.dp) - .clearAndSetSemantics(endButtonA11y), - onClick = endButtonClick, - ) { - endButton() - } + .clearAndSetSemantics { + contentDescription = endButtonContentDescription + onClick(null, null) + }, + onClick = endButtonParams.endButtonClick, + content = endButtonParams.endButtonContent, + ) } } } @@ -530,9 +552,7 @@ private fun TextFormattingLayout( textInput: @Composable () -> Unit, dismissTextFormattingButton: @Composable () -> Unit, textFormatting: @Composable () -> Unit, - sendButton: @Composable () -> Unit, - endButtonClick: () -> Unit, - endButtonA11y: (SemanticsPropertyReceiver.() -> Unit), + endButtonParams: EndButtonParams, modifier: Modifier = Modifier ) { Column( @@ -564,6 +584,7 @@ private fun TextFormattingLayout( textFormatting() } // To avoid loosing keyboard focus, the IconButton has to be defined here and has to be always enabled. + val endButtonContentDescription = stringResource(endButtonParams.endButtonContentDescriptionResId) IconButton( modifier = Modifier .padding( @@ -571,11 +592,13 @@ private fun TextFormattingLayout( end = 6.dp, ) .size(48.dp) - .clearAndSetSemantics(endButtonA11y), - onClick = endButtonClick, - ) { - sendButton() - } + .clearAndSetSemantics { + contentDescription = endButtonContentDescription + onClick(null, null) + }, + onClick = endButtonParams.endButtonClick, + content = endButtonParams.endButtonContent, + ) } } } @@ -635,6 +658,12 @@ private fun TextInputBox( } } +private fun VoiceMessageState.endButtonKey() = when (this) { + is VoiceMessageState.Idle -> "Idle" + is VoiceMessageState.Preview -> "Preview_$isSending" + is VoiceMessageState.Recording -> "Recording" +} + private fun aTextEditorStateMarkdownList(isRoomEncrypted: Boolean? = null) = persistentListOf( aTextEditorStateMarkdown(initialText = "", initialFocus = true, isRoomEncrypted = isRoomEncrypted), aTextEditorStateMarkdown(initialText = "A message", initialFocus = true, isRoomEncrypted = isRoomEncrypted), diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButtonIcon.kt similarity index 80% rename from libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt rename to libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButtonIcon.kt index e3ccd383f3..d2d11c321b 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButtonIcon.kt @@ -29,9 +29,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.matrix.api.core.EventId -import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId -import io.element.android.libraries.textcomposer.model.MessageComposerMode /** * Send button for the message composer. @@ -39,17 +36,17 @@ import io.element.android.libraries.textcomposer.model.MessageComposerMode * Temporary Figma : https://www.figma.com/design/Ni6Ii8YKtmXCKYNE90cC67/Timeline-(new)?node-id=2274-39944&m=dev */ @Composable -internal fun SendButton( +internal fun SendButtonIcon( canSendMessage: Boolean, - composerMode: MessageComposerMode, + isEditing: Boolean, modifier: Modifier = Modifier, ) { val iconVector = when { - composerMode.isEditing -> CompoundIcons.Check() + isEditing -> CompoundIcons.Check() else -> CompoundIcons.SendSolid() } val iconStartPadding = when { - composerMode.isEditing -> 0.dp + isEditing -> 0.dp else -> 2.dp } Box( @@ -105,21 +102,19 @@ private fun Modifier.buttonBackgroundModifier( @PreviewsDayNight @Composable -internal fun SendButtonPreview() = ElementPreview { - val normalMode = MessageComposerMode.Normal - val editMode = MessageComposerMode.Edit(EventId("\$id").toEventOrTransactionId(), "") +internal fun SendButtonIconPreview() = ElementPreview { Row { IconButton(onClick = {}) { - SendButton(canSendMessage = true, composerMode = normalMode) + SendButtonIcon(canSendMessage = true, isEditing = false) } IconButton(onClick = {}) { - SendButton(canSendMessage = false, composerMode = normalMode) + SendButtonIcon(canSendMessage = false, isEditing = false) } IconButton(onClick = {}) { - SendButton(canSendMessage = true, composerMode = editMode) + SendButtonIcon(canSendMessage = true, isEditing = true) } IconButton(onClick = {}) { - SendButton(canSendMessage = false, composerMode = editMode) + SendButtonIcon(canSendMessage = false, isEditing = true) } } } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButton.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButtonIcon.kt similarity index 89% rename from libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButton.kt rename to libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButtonIcon.kt index 3e72b309fe..182a5d5a52 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButton.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageDeleteButtonIcon.kt @@ -23,7 +23,7 @@ import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.ui.strings.CommonStrings @Composable -fun VoiceMessageDeleteButton( +fun VoiceMessageDeleteButtonIcon( enabled: Boolean, modifier: Modifier = Modifier, ) { @@ -41,15 +41,15 @@ fun VoiceMessageDeleteButton( @PreviewsDayNight @Composable -internal fun VoiceMessageDeleteButtonPreview() = ElementPreview { +internal fun VoiceMessageDeleteButtonIconPreview() = ElementPreview { Row { IconButton(onClick = {}) { - VoiceMessageDeleteButton( + VoiceMessageDeleteButtonIcon( enabled = true, ) } IconButton(onClick = {}) { - VoiceMessageDeleteButton( + VoiceMessageDeleteButtonIcon( enabled = false, ) } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButton.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButtonIcon.kt similarity index 92% rename from libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButton.kt rename to libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButtonIcon.kt index b512154375..aeeaf839c3 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButton.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecorderButtonIcon.kt @@ -26,7 +26,7 @@ import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.utils.CommonDrawables @Composable -internal fun VoiceMessageRecorderButton( +internal fun VoiceMessageRecorderButtonIcon( isRecording: Boolean, modifier: Modifier = Modifier, ) { @@ -75,15 +75,15 @@ private fun StopButton( @PreviewsDayNight @Composable -internal fun VoiceMessageRecorderButtonPreview() = ElementPreview { +internal fun VoiceMessageRecorderButtonIconPreview() = ElementPreview { Row { IconButton(onClick = {}) { - VoiceMessageRecorderButton( + VoiceMessageRecorderButtonIcon( isRecording = false, ) } IconButton(onClick = {}) { - VoiceMessageRecorderButton( + VoiceMessageRecorderButtonIcon( isRecording = true, ) } From 1016363dd977fc6b5e78428d53412b839a1c936f Mon Sep 17 00:00:00 2001 From: ElementBot Date: Mon, 12 Jan 2026 10:36:41 +0000 Subject: [PATCH 339/347] Update screenshots --- ...libraries.textcomposer.components_SendButtonIcon_Day_0_en.png} | 0 ...braries.textcomposer.components_SendButtonIcon_Night_0_en.png} | 0 ...composer.components_VoiceMessageDeleteButtonIcon_Day_0_en.png} | 0 ...mposer.components_VoiceMessageDeleteButtonIcon_Night_0_en.png} | 0 ...mposer.components_VoiceMessageRecorderButtonIcon_Day_0_en.png} | 0 ...oser.components_VoiceMessageRecorderButtonIcon_Night_0_en.png} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename tests/uitests/src/test/snapshots/images/{libraries.textcomposer.components_SendButton_Day_0_en.png => libraries.textcomposer.components_SendButtonIcon_Day_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.textcomposer.components_SendButton_Night_0_en.png => libraries.textcomposer.components_SendButtonIcon_Night_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.textcomposer.components_VoiceMessageDeleteButton_Day_0_en.png => libraries.textcomposer.components_VoiceMessageDeleteButtonIcon_Day_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.textcomposer.components_VoiceMessageDeleteButton_Night_0_en.png => libraries.textcomposer.components_VoiceMessageDeleteButtonIcon_Night_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.textcomposer.components_VoiceMessageRecorderButton_Day_0_en.png => libraries.textcomposer.components_VoiceMessageRecorderButtonIcon_Day_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{libraries.textcomposer.components_VoiceMessageRecorderButton_Night_0_en.png => libraries.textcomposer.components_VoiceMessageRecorderButtonIcon_Night_0_en.png} (100%) diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButtonIcon_Day_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Day_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButtonIcon_Day_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButtonIcon_Night_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Night_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButtonIcon_Night_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageDeleteButton_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageDeleteButtonIcon_Day_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageDeleteButton_Day_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageDeleteButtonIcon_Day_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageDeleteButton_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageDeleteButtonIcon_Night_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageDeleteButton_Night_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageDeleteButtonIcon_Night_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageRecorderButton_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageRecorderButtonIcon_Day_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageRecorderButton_Day_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageRecorderButtonIcon_Day_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageRecorderButton_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageRecorderButtonIcon_Night_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageRecorderButton_Night_0_en.png rename to tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_VoiceMessageRecorderButtonIcon_Night_0_en.png From 536227883c26be918b2cd3f4f1aea4cbe2d3bbbb Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 12 Jan 2026 15:54:13 +0100 Subject: [PATCH 340/347] Change the title for `AnalyticsTransactions.coldStart` and `.catchUp` (#5998) --- .../services/analyticsproviders/api/AnalyticsTransactions.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransactions.kt b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransactions.kt index 5e188263fa..5c44cc9e32 100644 --- a/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransactions.kt +++ b/services/analyticsproviders/api/src/main/kotlin/io/element/android/services/analyticsproviders/api/AnalyticsTransactions.kt @@ -9,13 +9,13 @@ package io.element.android.services.analyticsproviders.api object AnalyticsTransactions { val coldStart = TransactionDefinition( - name = "Cold start", + name = "Cached room list", operation = "ux", description = "Cold start until the cached room list is displayed", ) val catchUp = TransactionDefinition( - name = "Catch-up", + name = "Up-to-date room list", operation = "ux", description = "The app syncs and the room list becomes up-to-date", ) From 552b38f2d7f5c162be3a233f5b7796a1242ca3be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:35:13 +0100 Subject: [PATCH 341/347] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.1.12 (#5999) 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 aee90249fe..14dde810a9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -177,7 +177,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.1.9" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:26.1.12" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } From a234eb3e2917291b736fb6c3f4fdc0d6f5af30d7 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 13 Jan 2026 13:39:46 +0100 Subject: [PATCH 342/347] When handling incoming share, reuse existing room screen if possible (#6001) --- .../android/appnav/LoggedInFlowNode.kt | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 92c3cfe3dd..219566d9db 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -516,9 +516,18 @@ class LoggedInFlowNode( params = ShareEntryPoint.Params(intent = navTarget.intent), callback = object : ShareEntryPoint.Callback { override fun onDone(roomIds: List) { + // Remove the incoming share screen backstack.pop() + + // Navigate to the room if the text/media was shared to a single one roomIds.singleOrNull()?.let { roomId -> - backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias())) + sessionCoroutineScope.launch { + // Wait until the incoming share screen is removed + backstack.elements.first { it.lastOrNull()?.key?.navTarget !is NavTarget.IncomingShare } + + // Then attach the room + attachRoom(roomId.toRoomIdOrAlias(), clearBackstack = false) + } } } }, @@ -644,7 +653,21 @@ private class AttachRoomOperation( operation = this ) } else { - Push(roomTarget).invoke(elements) + val existingRoomElement = elements.find { + val roomNavTarget = it.key.navTarget as? LoggedInFlowNode.NavTarget.Room + roomNavTarget?.roomIdOrAlias == roomTarget.roomIdOrAlias + } + if (existingRoomElement != null) { + elements.mapNotNull { element -> + if (element == existingRoomElement) { + null + } else { + element.transitionTo(STASHED, this) + } + } + existingRoomElement.transitionTo(ACTIVE, this) + } else { + Push(roomTarget).invoke(elements) + } } } } From 03d14087e6693a7384bb8d59d49e0a2d0778a92b Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 13 Jan 2026 14:35:49 +0100 Subject: [PATCH 343/347] Create spaces (#5982) * Allow creating a space with `CreateRoomParameters` * Add 'Create space' menu item in the spaces home screen. Also, imports new strings related to spaces. * Link the 'Create space' button with the screen to create the space * Unify room access and visibility for `ConfigureRoom`, use the updated design * Fix `EditRoomDetails` avatar size (68dp) * Replace `EditableAvatarView` and `UnsavedAvatar` copmonents with `AvatarPickerView` * `AvatarDataFetcherFactory`: Make sure we use a fallback image fetcher when the URL is not an MXC one (a local one, i.e.). This removes the previous need for a separate `UnsavedAvatarView` * Use `AvatarPickerView` in all the screens where `EditableAvatarView` was used * Improve naming and previews * Update strings, remove unused ones for `RoomAccessItem` * Make `isSpace` part of the `CreateRoomConfig` * Ensure the content fits in the screenshots for `AvatarPickerSizesPreview` * Add `AvatarDataFetcherFactoryTest` * Add new feature flag for creating spaces * Fix ripple being too large for the `Pick` state * Tweak margins and section titles a bit * Add preview for `HomeTopBar` with the spaces case * Update screenshots --------- Co-authored-by: ElementBot --- .../android/appnav/LoggedInFlowNode.kt | 17 + .../createroom/api/CreateRoomEntryPoint.kt | 1 + .../createroom/impl/CreateRoomFlowNode.kt | 15 +- .../impl/DefaultCreateRoomEntryPoint.kt | 4 +- .../impl/configureroom/ConfigureRoomNode.kt | 15 +- .../configureroom/ConfigureRoomPresenter.kt | 22 +- .../ConfigureRoomStateProvider.kt | 12 + .../impl/configureroom/ConfigureRoomView.kt | 177 +++---- .../impl/configureroom/CreateRoomConfig.kt | 1 + .../configureroom/CreateRoomConfigStore.kt | 10 +- .../impl/configureroom/RoomAccessItem.kt | 18 +- .../impl/configureroom/RoomVisibilityItem.kt | 24 +- .../src/main/res/values-be/translations.xml | 4 - .../src/main/res/values-bg/translations.xml | 4 - .../src/main/res/values-cs/translations.xml | 5 - .../src/main/res/values-cy/translations.xml | 5 - .../src/main/res/values-da/translations.xml | 5 - .../src/main/res/values-de/translations.xml | 5 - .../src/main/res/values-el/translations.xml | 5 - .../src/main/res/values-es/translations.xml | 5 - .../src/main/res/values-et/translations.xml | 5 - .../src/main/res/values-eu/translations.xml | 5 - .../src/main/res/values-fa/translations.xml | 5 - .../src/main/res/values-fi/translations.xml | 5 - .../src/main/res/values-fr/translations.xml | 5 - .../src/main/res/values-hr/translations.xml | 5 - .../src/main/res/values-hu/translations.xml | 5 - .../src/main/res/values-in/translations.xml | 5 - .../src/main/res/values-it/translations.xml | 5 - .../src/main/res/values-ka/translations.xml | 2 - .../src/main/res/values-ko/translations.xml | 5 - .../src/main/res/values-lt/translations.xml | 2 - .../src/main/res/values-nb/translations.xml | 5 - .../src/main/res/values-nl/translations.xml | 5 - .../src/main/res/values-pl/translations.xml | 5 - .../main/res/values-pt-rBR/translations.xml | 5 - .../src/main/res/values-pt/translations.xml | 5 - .../src/main/res/values-ro/translations.xml | 5 - .../src/main/res/values-ru/translations.xml | 5 - .../src/main/res/values-sk/translations.xml | 5 - .../src/main/res/values-sv/translations.xml | 5 - .../src/main/res/values-tr/translations.xml | 5 - .../src/main/res/values-uk/translations.xml | 5 - .../src/main/res/values-ur/translations.xml | 2 - .../src/main/res/values-uz/translations.xml | 5 - .../main/res/values-zh-rTW/translations.xml | 5 - .../src/main/res/values-zh/translations.xml | 5 - .../impl/src/main/res/values/localazy.xml | 30 +- .../impl/DefaultCreateRoomEntryPointTest.kt | 1 + .../ConfigureRoomPresenterTest.kt | 2 + .../api/FakeCreateRoomEntryPoint.kt | 1 + .../features/home/api/HomeEntryPoint.kt | 1 + .../features/home/impl/HomeFlowNode.kt | 1 + .../android/features/home/impl/HomeView.kt | 9 +- .../home/impl/components/HomeTopBar.kt | 186 +++++--- .../home/impl/spaces/HomeSpacesPresenter.kt | 5 + .../home/impl/spaces/HomeSpacesState.kt | 1 + .../impl/spaces/HomeSpacesStateProvider.kt | 9 + .../home/impl/DefaultHomeEntryPointTest.kt | 1 + .../home/impl/roomlist/RoomListViewTest.kt | 2 + .../impl/spaces/HomeSpacesPresenterTest.kt | 10 + .../user/editprofile/EditUserProfileView.kt | 22 +- .../impl/src/main/res/values/localazy.xml | 4 +- .../impl/RoomDetailsEditView.kt | 32 +- .../impl/src/main/res/values/localazy.xml | 2 +- .../startchat/impl/StartChatFlowNode.kt | 1 + .../components/avatar/AvatarSize.kt | 2 +- .../libraries/featureflag/api/FeatureFlags.kt | 7 + .../api/createroom/CreateRoomParameters.kt | 1 + .../libraries/matrix/impl/RustMatrixClient.kt | 1 + .../ui/media/AvatarDataFetcherFactory.kt | 20 +- .../ui/media/AvatarDataFetcherFactoryTest.kt | 78 ++++ .../matrix/ui/components/AvatarPickerView.kt | 436 ++++++++++++++++++ .../ui/components/EditableAvatarView.kt | 157 ------- .../matrix/ui/components/UnsavedAvatar.kt | 93 ---- .../ui/room/address/RoomAddressField.kt | 2 +- .../src/main/res/values/localazy.xml | 6 + .../tests/konsist/KonsistPreviewTest.kt | 4 + ...nfigureroom_ConfigureRoomViewDark_0_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_1_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_2_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_3_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_4_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_5_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_6_en.png | 3 + ...figureroom_ConfigureRoomViewLight_0_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_1_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_2_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_3_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_4_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_5_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_6_en.png | 3 + ...l.components_HomeTopBarSpaces_Day_0_en.png | 3 + ...components_HomeTopBarSpaces_Night_0_en.png | 3 + ...me.impl.spaces_HomeSpacesView_Day_2_en.png | 3 + ....impl.spaces_HomeSpacesView_Night_2_en.png | 3 + .../features.home.impl_HomeView_Day_4_en.png | 4 +- ...features.home.impl_HomeView_Night_4_en.png | 4 +- ...itprofile_EditUserProfileView_Day_0_en.png | 4 +- ...itprofile_EditUserProfileView_Day_1_en.png | 4 +- ...itprofile_EditUserProfileView_Day_2_en.png | 4 +- ...profile_EditUserProfileView_Night_0_en.png | 4 +- ...profile_EditUserProfileView_Night_1_en.png | 4 +- ...profile_EditUserProfileView_Night_2_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_0_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_1_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_2_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_3_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_4_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_5_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_6_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_7_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_8_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_9_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_0_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_1_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_2_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_3_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_4_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_5_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_6_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_7_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_8_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_9_en.png | 4 +- ....root_SecurityAndPrivacyViewDark_14_en.png | 4 +- ....root_SecurityAndPrivacyViewDark_15_en.png | 4 +- ....root_SecurityAndPrivacyViewDark_16_en.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_4_en.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_5_en.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_6_en.png | 4 +- ...root_SecurityAndPrivacyViewLight_14_en.png | 4 +- ...root_SecurityAndPrivacyViewLight_15_en.png | 4 +- ...root_SecurityAndPrivacyViewLight_16_en.png | 4 +- ....root_SecurityAndPrivacyViewLight_4_en.png | 4 +- ....root_SecurityAndPrivacyViewLight_5_en.png | 4 +- ....root_SecurityAndPrivacyViewLight_6_en.png | 4 +- ....components_AvatarPickerSizes_Day_0_en.png | 3 + ...omponents_AvatarPickerSizes_Night_0_en.png | 3 + ...omponents_AvatarPickerViewRtl_Day_0_en.png | 3 + ...ponents_AvatarPickerViewRtl_Night_0_en.png | 3 + ...i.components_AvatarPickerView_Day_0_en.png | 3 + ...components_AvatarPickerView_Night_0_en.png | 3 + ...components_EditableAvatarView_Day_0_en.png | 3 - ...components_EditableAvatarView_Day_1_en.png | 3 - ...components_EditableAvatarView_Day_2_en.png | 3 - ...mponents_EditableAvatarView_Night_0_en.png | 3 - ...mponents_EditableAvatarView_Night_1_en.png | 3 - ...mponents_EditableAvatarView_Night_2_en.png | 3 - ...x.ui.components_UnsavedAvatar_Day_0_en.png | 3 - ...ui.components_UnsavedAvatar_Night_0_en.png | 3 - 150 files changed, 1097 insertions(+), 778 deletions(-) create mode 100644 libraries/matrixmedia/impl/src/test/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactoryTest.kt create mode 100644 libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt delete mode 100644 libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt delete mode 100644 libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 219566d9db..21bdd99a47 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -47,6 +47,7 @@ import io.element.android.appnav.room.RoomFlowNode import io.element.android.appnav.room.RoomNavigationTarget import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode import io.element.android.compound.colors.SemanticColorsLightDark +import io.element.android.features.createroom.api.CreateRoomEntryPoint import io.element.android.features.enterprise.api.EnterpriseService import io.element.android.features.enterprise.api.SessionEnterpriseService import io.element.android.features.ftue.api.FtueEntryPoint @@ -144,6 +145,7 @@ class LoggedInFlowNode( snackbarDispatcher: SnackbarDispatcher, private val analyticsService: AnalyticsService, private val analyticsRoomListStateWatcher: AnalyticsRoomListStateWatcher, + private val createRoomEntryPoint: CreateRoomEntryPoint, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.Placeholder, @@ -287,6 +289,9 @@ class LoggedInFlowNode( @Parcelize data object CreateRoom : NavTarget + @Parcelize + data object CreateSpace : NavTarget + @Parcelize data class SecureBackup( val initialElement: SecureBackupEntryPoint.InitialTarget = SecureBackupEntryPoint.InitialTarget.Root @@ -338,6 +343,10 @@ class LoggedInFlowNode( backstack.push(NavTarget.CreateRoom) } + override fun navigateToCreateSpace() { + backstack.push(NavTarget.CreateSpace) + } + override fun navigateToSetUpRecovery() { backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.Root)) } @@ -469,6 +478,14 @@ class LoggedInFlowNode( callback = callback, ) } + is NavTarget.CreateSpace -> { + val callback = object : CreateRoomEntryPoint.Callback { + override fun onRoomCreated(roomId: RoomId) { + backstack.replace(NavTarget.Room(roomIdOrAlias = RoomIdOrAlias.Id(roomId), serverNames = emptyList())) + } + } + createRoomEntryPoint.createNode(isSpace = true, parentNode = this, buildContext = buildContext, callback = callback) + } is NavTarget.SecureBackup -> { secureBackupEntryPoint.createNode( parentNode = this, diff --git a/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/CreateRoomEntryPoint.kt b/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/CreateRoomEntryPoint.kt index 1c6a9f04db..22757aba06 100644 --- a/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/CreateRoomEntryPoint.kt +++ b/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/CreateRoomEntryPoint.kt @@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.api.core.RoomId interface CreateRoomEntryPoint : FeatureEntryPoint { fun createNode( + isSpace: Boolean, parentNode: Node, buildContext: BuildContext, callback: Callback, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt index 7fea6fc0e5..89dbddd186 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt @@ -24,6 +24,7 @@ import io.element.android.features.createroom.impl.addpeople.AddPeopleNode import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode +import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.SessionScope @@ -37,23 +38,29 @@ class CreateRoomFlowNode( @Assisted plugins: List, ) : BaseFlowNode( backstack = BackStack( - initialElement = NavTarget.ConfigureRoom, + initialElement = NavTarget.ConfigureRoom(isSpace = plugins.filterIsInstance().first().isSpace), savedStateMap = buildContext.savedStateMap, ), buildContext = buildContext, plugins = plugins ) { + @Parcelize + data class Inputs( + val isSpace: Boolean + ) : NodeInputs, Parcelable + private val callback: CreateRoomEntryPoint.Callback = callback() override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { return when (navTarget) { - NavTarget.ConfigureRoom -> { + is NavTarget.ConfigureRoom -> { + val inputs = ConfigureRoomNode.Inputs(isSpace = navTarget.isSpace) val callback = object : ConfigureRoomNode.Callback { override fun onCreateRoomSuccess(roomId: RoomId) { backstack.replace(NavTarget.AddPeople(roomId)) } } - createNode(buildContext, plugins = listOf(callback)) + createNode(buildContext, plugins = listOf(inputs, callback)) } is NavTarget.AddPeople -> { val inputs = AddPeopleNode.Inputs(navTarget.roomId) @@ -74,7 +81,7 @@ class CreateRoomFlowNode( sealed interface NavTarget : Parcelable { @Parcelize - data object ConfigureRoom : NavTarget + data class ConfigureRoom(val isSpace: Boolean) : NavTarget @Parcelize data class AddPeople(val roomId: RoomId) : NavTarget diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPoint.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPoint.kt index 2261d294cf..63163e7a28 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPoint.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPoint.kt @@ -18,10 +18,12 @@ import io.element.android.libraries.di.SessionScope @ContributesBinding(SessionScope::class) class DefaultCreateRoomEntryPoint : CreateRoomEntryPoint { override fun createNode( + isSpace: Boolean, parentNode: Node, buildContext: BuildContext, callback: CreateRoomEntryPoint.Callback, ): Node { - return parentNode.createNode(buildContext, listOf(callback)) + val inputs = CreateRoomFlowNode.Inputs(isSpace) + return parentNode.createNode(buildContext, listOf(inputs, callback)) } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt index 43ceee3594..e021a7a0f9 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt @@ -8,6 +8,7 @@ package io.element.android.features.createroom.impl.configureroom +import android.os.Parcelable import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.bumble.appyx.core.lifecycle.subscribe @@ -18,23 +19,35 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.MobileScreen import io.element.android.annotations.ContributesNode +import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.callback +import io.element.android.libraries.architecture.inputs import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.services.analytics.api.AnalyticsService +import kotlinx.parcelize.Parcelize @ContributesNode(SessionScope::class) @AssistedInject class ConfigureRoomNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, - private val presenter: ConfigureRoomPresenter, + presenterFactory: ConfigureRoomPresenter.Factory, private val analyticsService: AnalyticsService, ) : Node(buildContext, plugins = plugins) { interface Callback : Plugin { fun onCreateRoomSuccess(roomId: RoomId) } + @Parcelize + data class Inputs( + val isSpace: Boolean, + ) : NodeInputs, Parcelable + + private val inputs = inputs() + + private val presenter = presenterFactory.create(inputs.isSpace) + init { lifecycle.subscribe( onResume = { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index dbec30c0c5..aef55c77df 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -19,7 +19,9 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.core.net.toUri -import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedFactory +import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.CreatedRoom import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter @@ -49,8 +51,9 @@ import kotlinx.coroutines.launch import timber.log.Timber import kotlin.jvm.optionals.getOrDefault -@Inject +@AssistedInject class ConfigureRoomPresenter( + @Assisted private val isSpace: Boolean, private val dataStore: CreateRoomConfigStore, private val matrixClient: MatrixClient, private val mediaPickerProvider: PickerProvider, @@ -61,13 +64,22 @@ class ConfigureRoomPresenter( private val roomAliasHelper: RoomAliasHelper, private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider, ) : Presenter { + @AssistedFactory + interface Factory { + fun create(isSpace: Boolean): ConfigureRoomPresenter + } + private val cameraPermissionPresenter: PermissionsPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA) private var pendingPermissionRequest = false + init { + dataStore.setIsSpace(isSpace) + } + @Composable override fun present(): ConfigureRoomState { val cameraPermissionState = cameraPermissionPresenter.present() - val createRoomConfig by dataStore.getCreateRoomConfigFlow().collectAsState(CreateRoomConfig()) + val createRoomConfig by dataStore.getCreateRoomConfigFlow().collectAsState() val homeserverName = remember { matrixClient.userIdServerName() } val isKnockFeatureEnabled by remember { featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock) @@ -171,7 +183,8 @@ class ConfigureRoomPresenter( preset = RoomPreset.PUBLIC_CHAT, invite = config.invites.map { it.userId }, avatar = avatarUrl, - roomAliasName = config.roomVisibility.roomAddress() + roomAliasName = config.roomVisibility.roomAddress(), + isSpace = isSpace, ) } else { CreateRoomParameters( @@ -184,6 +197,7 @@ class ConfigureRoomPresenter( preset = RoomPreset.PRIVATE_CHAT, invite = config.invites.map { it.userId }, avatar = avatarUrl, + isSpace = isSpace, ) } matrixClient.createRoom(params) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index 7f760b46fb..dc78ed7aab 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -78,6 +78,18 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider Unit, modifier: Modifier = Modifier, ) { + val isSpace = state.config.isSpace val focusManager = LocalFocusManager.current val isAvatarActionsSheetVisible = remember { mutableStateOf(false) } @@ -81,6 +87,7 @@ fun ConfigureRoomView( modifier = modifier.clearFocusOnTap(focusManager), topBar = { ConfigureRoomToolbar( + isSpace = isSpace, isNextActionEnabled = state.isValid, onBackClick = onBackClick, onNextClick = { @@ -96,9 +103,10 @@ fun ConfigureRoomView( .imePadding() .verticalScroll(rememberScrollState()) .consumeWindowInsets(padding), - verticalArrangement = Arrangement.spacedBy(24.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), ) { RoomNameWithAvatar( + isSpace = isSpace, modifier = Modifier.padding(horizontal = 16.dp), avatarUri = state.config.avatarUri, roomName = state.config.roomName.orEmpty(), @@ -110,37 +118,35 @@ fun ConfigureRoomView( topic = state.config.topic.orEmpty(), onTopicChange = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) }, ) - RoomVisibilityOptions( + + RoomVisibilityAndAccessOptions( selected = when (state.config.roomVisibility) { is RoomVisibilityState.Private -> RoomVisibilityItem.Private - is RoomVisibilityState.Public -> RoomVisibilityItem.Public + is RoomVisibilityState.Public -> when (state.config.roomVisibility.roomAccess) { + RoomAccess.Knocking -> RoomVisibilityItem.AskToJoin + RoomAccess.Anyone -> RoomVisibilityItem.Public + } }, + isKnockingEnabled = state.isKnockFeatureEnabled, onOptionClick = { focusManager.clearFocus() state.eventSink(ConfigureRoomEvents.RoomVisibilityChanged(it)) }, ) - if (state.config.roomVisibility is RoomVisibilityState.Public && state.isKnockFeatureEnabled) { - RoomAccessOptions( - selected = when (state.config.roomVisibility.roomAccess) { - RoomAccess.Anyone -> RoomAccessItem.Anyone - RoomAccess.Knocking -> RoomAccessItem.AskToJoin - }, - onOptionClick = { - focusManager.clearFocus() - state.eventSink(ConfigureRoomEvents.RoomAccessChanged(it)) - }, - ) - RoomAddressField( - modifier = Modifier.padding(horizontal = 16.dp), - address = state.config.roomVisibility.roomAddress.value, - homeserverName = state.homeserverName, - addressValidity = state.roomAddressValidity, - onAddressChange = { state.eventSink(ConfigureRoomEvents.RoomAddressChanged(it)) }, - label = stringResource(R.string.screen_create_room_room_address_section_title), - supportingText = stringResource(R.string.screen_create_room_room_address_section_footer), - ) - Spacer(Modifier) + + if (state.config.roomVisibility !is RoomVisibilityState.Private) { + Column { + ListSectionHeader(title = stringResource(R.string.screen_create_room_room_address_section_title)) + RoomAddressField( + modifier = Modifier.padding(horizontal = 16.dp), + address = state.config.roomVisibility.roomAddress().getOrNull().orEmpty(), + homeserverName = state.homeserverName, + addressValidity = state.roomAddressValidity, + onAddressChange = { state.eventSink(ConfigureRoomEvents.RoomAddressChanged(it)) }, + label = null, + supportingText = stringResource(R.string.screen_create_room_room_address_section_footer), + ) + } } } } @@ -156,11 +162,11 @@ fun ConfigureRoomView( async = state.createRoomAction, progressDialog = { AsyncActionViewDefaults.ProgressDialog( - progressText = stringResource(CommonStrings.common_creating_room), + progressText = stringResource(if (isSpace) CommonStrings.common_creating_space else CommonStrings.common_creating_room), ) }, onSuccess = { onCreateRoomSuccess(it) }, - errorMessage = { stringResource(R.string.screen_create_room_error_creating_room) }, + errorMessage = { stringResource(if (isSpace) R.string.screen_create_room_error_creating_space else R.string.screen_create_room_error_creating_room) }, onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom) }, onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) }, ) @@ -173,12 +179,13 @@ fun ConfigureRoomView( @OptIn(ExperimentalMaterial3Api::class) @Composable private fun ConfigureRoomToolbar( + isSpace: Boolean, isNextActionEnabled: Boolean, onBackClick: () -> Unit, onNextClick: () -> Unit, ) { TopAppBar( - titleStr = stringResource(R.string.screen_create_room_title), + titleStr = stringResource(if (isSpace) R.string.screen_create_room_new_space_title else R.string.screen_create_room_new_room_title), navigationIcon = { BackButton(onClick = onBackClick) }, actions = { TextButton( @@ -192,6 +199,7 @@ private fun ConfigureRoomToolbar( @Composable private fun RoomNameWithAvatar( + isSpace: Boolean, avatarUri: String?, roomName: String, onAvatarClick: () -> Unit, @@ -203,25 +211,33 @@ private fun RoomNameWithAvatar( horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.CenterVertically, ) { - val a11yAvatar = stringResource(CommonStrings.a11y_room_avatar) - UnsavedAvatar( - avatarUri = avatarUri, - avatarSize = AvatarSize.EditRoomDetails, - avatarType = AvatarType.Room(), - modifier = Modifier - .clickable( - onClick = onAvatarClick, - onClickLabel = stringResource(CommonStrings.action_open_context_menu), - ) - .clearAndSetSemantics { - contentDescription = a11yAvatar - }, - ) + Box( + modifier = Modifier.padding(end = 8.dp).size(AvatarSize.EditRoomDetails.dp), + contentAlignment = Alignment.Center, + ) { + val avatarState = remember(avatarUri) { + if (avatarUri != null) { + AvatarPickerState.Selected( + avatarData = AvatarData(id = "#", name = null, url = avatarUri, size = AvatarSize.EditRoomDetails), + type = if (isSpace) AvatarType.Space() else AvatarType.Room(), + ) + } else { + val containerSize = 48.dp + val padding = PaddingValues((AvatarSize.EditRoomDetails.dp - containerSize) / 2) + AvatarPickerState.Pick(buttonSize = 48.dp, iconSize = 24.dp, externalPadding = padding) + } + } + AvatarPickerView( + state = avatarState, + onClick = onAvatarClick, + ) + } TextField( - label = stringResource(R.string.screen_create_room_room_name_label), + modifier = Modifier.padding(bottom = 18.dp), + label = stringResource(CommonStrings.common_name), value = roomName, - placeholder = stringResource(CommonStrings.common_room_name_placeholder), + placeholder = stringResource(R.string.screen_create_room_name_placeholder), singleLine = true, onValueChange = onChangeRoomName, ) @@ -240,7 +256,7 @@ private fun RoomTopic( value = topic, onValueChange = onTopicChange, maxLines = 3, - supportingText = stringResource(CommonStrings.common_topic_placeholder), + placeholder = stringResource(R.string.screen_create_room_topic_placeholder), keyboardOptions = KeyboardOptions( capitalization = KeyboardCapitalization.Sentences, ), @@ -256,38 +272,58 @@ private fun ConfigureRoomOptions( Column( modifier = modifier.selectableGroup() ) { - Text( - text = title, - style = ElementTheme.typography.fontBodyLgMedium, - color = ElementTheme.colors.textPrimary, - modifier = Modifier.padding(horizontal = 16.dp), - ) + ListSectionHeader(title = title) content() } } @Composable -private fun RoomVisibilityOptions( +private fun RoomVisibilityAndAccessOptions( selected: RoomVisibilityItem, + isKnockingEnabled: Boolean, onOptionClick: (RoomVisibilityItem) -> Unit, modifier: Modifier = Modifier, ) { ConfigureRoomOptions( - title = stringResource(R.string.screen_create_room_room_visibility_section_title), + title = stringResource(R.string.screen_create_room_room_access_section_title), modifier = modifier, ) { RoomVisibilityItem.entries.forEach { item -> + if (item == RoomVisibilityItem.AskToJoin && !isKnockingEnabled) { + return@forEach + } + val isSelected = item == selected ListItem( leadingContent = ListItemContent.Custom { RoundedIconAtom( size = RoundedIconAtomSize.Big, - resourceId = item.icon, + resourceId = when (item) { + RoomVisibilityItem.Public -> CompoundDrawables.ic_compound_public + RoomVisibilityItem.AskToJoin -> CompoundDrawables.ic_compound_user_add + RoomVisibilityItem.Private -> CompoundDrawables.ic_compound_lock + }, tint = if (isSelected) ElementTheme.colors.iconPrimary else ElementTheme.colors.iconSecondary, + backgroundTint = Color.Transparent, ) }, - headlineContent = { Text(text = stringResource(item.title)) }, - supportingContent = { Text(text = stringResource(item.description)) }, + headlineContent = { + val title = when (item) { + RoomVisibilityItem.Public -> stringResource(R.string.screen_create_room_public_option_title) + RoomVisibilityItem.AskToJoin -> stringResource(R.string.screen_create_room_room_access_section_knocking_option_title) + RoomVisibilityItem.Private -> stringResource(R.string.screen_create_room_private_option_title) + } + Text(text = title) + }, + supportingContent = { + // TODO handle description of items in a certain space/org + val description = when (item) { + RoomVisibilityItem.Public -> stringResource(R.string.screen_create_room_public_option_short_description) + RoomVisibilityItem.AskToJoin -> stringResource(R.string.screen_create_room_room_access_section_knocking_option_description) + RoomVisibilityItem.Private -> stringResource(R.string.screen_create_room_private_option_description) + } + Text(text = description) + }, trailingContent = ListItemContent.RadioButton(selected = isSelected), onClick = { onOptionClick(item) }, ) @@ -295,27 +331,6 @@ private fun RoomVisibilityOptions( } } -@Composable -private fun RoomAccessOptions( - selected: RoomAccessItem, - onOptionClick: (RoomAccessItem) -> Unit, - modifier: Modifier = Modifier, -) { - ConfigureRoomOptions( - title = stringResource(R.string.screen_create_room_room_access_section_header), - modifier = modifier, - ) { - RoomAccessItem.entries.forEach { item -> - ListItem( - headlineContent = { Text(text = stringResource(item.title)) }, - supportingContent = { Text(text = stringResource(item.description)) }, - trailingContent = ListItemContent.RadioButton(selected = item == selected), - onClick = { onOptionClick(item) }, - ) - } - } -} - @PreviewWithLargeHeight @Composable internal fun ConfigureRoomViewLightPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) = diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfig.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfig.kt index b9d05a144f..8355047ddf 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfig.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfig.kt @@ -13,6 +13,7 @@ import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf data class CreateRoomConfig( + val isSpace: Boolean = false, val roomName: String? = null, val topic: String? = null, val avatarUri: String? = null, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfigStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfigStore.kt index 5e8637ddd6..81c9638f0c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfigStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfigStore.kt @@ -72,11 +72,11 @@ class CreateRoomConfigStore( config.copy( roomVisibility = when (visibility) { RoomVisibilityItem.Private -> RoomVisibilityState.Private - RoomVisibilityItem.Public -> { + RoomVisibilityItem.Public, RoomVisibilityItem.AskToJoin -> { val roomAliasName = roomAliasHelper.roomAliasNameFromRoomDisplayName(config.roomName.orEmpty()) RoomVisibilityState.Public( roomAddress = RoomAddress.AutoFilled(roomAliasName), - roomAccess = RoomAccess.Anyone, + roomAccess = if (visibility == RoomVisibilityItem.AskToJoin) RoomAccess.Knocking else RoomAccess.Anyone, ) } } @@ -114,6 +114,12 @@ class CreateRoomConfigStore( } } + fun setIsSpace(isSpace: Boolean) { + createRoomConfigFlow.getAndUpdate { config -> + config.copy(isSpace = isSpace) + } + } + fun clearCachedData() { cachedAvatarUri = null } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccessItem.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccessItem.kt index 2d37be9103..9d140b952c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccessItem.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccessItem.kt @@ -8,19 +8,7 @@ package io.element.android.features.createroom.impl.configureroom -import androidx.annotation.StringRes -import io.element.android.features.createroom.impl.R - -enum class RoomAccessItem( - @StringRes val title: Int, - @StringRes val description: Int -) { - Anyone( - title = R.string.screen_create_room_room_access_section_anyone_option_title, - description = R.string.screen_create_room_room_access_section_anyone_option_description, - ), - AskToJoin( - title = R.string.screen_create_room_room_access_section_knocking_option_title, - description = R.string.screen_create_room_room_access_section_knocking_option_description, - ), +enum class RoomAccessItem { + Anyone, + AskToJoin, } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityItem.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityItem.kt index b92dee4d6e..feff1ee90f 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityItem.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityItem.kt @@ -8,24 +8,8 @@ package io.element.android.features.createroom.impl.configureroom -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import io.element.android.features.createroom.impl.R -import io.element.android.libraries.designsystem.icons.CompoundDrawables - -enum class RoomVisibilityItem( - @DrawableRes val icon: Int, - @StringRes val title: Int, - @StringRes val description: Int -) { - Private( - icon = CompoundDrawables.ic_compound_lock, - title = R.string.screen_create_room_private_option_title, - description = R.string.screen_create_room_private_option_description, - ), - Public( - icon = CompoundDrawables.ic_compound_public, - title = R.string.screen_create_room_public_option_title, - description = R.string.screen_create_room_public_option_description, - ) +enum class RoomVisibilityItem { + Public, + AskToJoin, + Private } diff --git a/features/createroom/impl/src/main/res/values-be/translations.xml b/features/createroom/impl/src/main/res/values-be/translations.xml index f5d6a234e2..23d70a3b3d 100644 --- a/features/createroom/impl/src/main/res/values-be/translations.xml +++ b/features/createroom/impl/src/main/res/values-be/translations.xml @@ -8,10 +8,6 @@ "Любы можа знайсці гэты пакой. Вы можаце змяніць гэта ў любы час у наладах пакоя." "Публічны пакой" - "Хто заўгодна" - "Доступ у пакой" "Папрасіце далучыцца" - "Назва пакоя" - "Стварыце пакой" "Тэма (неабавязкова)" diff --git a/features/createroom/impl/src/main/res/values-bg/translations.xml b/features/createroom/impl/src/main/res/values-bg/translations.xml index 249058b7af..83fb24e691 100644 --- a/features/createroom/impl/src/main/res/values-bg/translations.xml +++ b/features/createroom/impl/src/main/res/values-bg/translations.xml @@ -8,11 +8,7 @@ "Всеки може да намери тази стая. Можете да промените това по всяко време в настройките на стаята." "Общодостъпна стая" - "Всеки може да се присъедини към тази стая" - "Всеки" "За да бъде тази стая видима в директорията на общодостъпните стаи, ще ви е необходим адрес на стаята." - "Име на стаята" "Видимост на стаята" - "Създаване на стая" "Тема за разговор (незадължително)" diff --git a/features/createroom/impl/src/main/res/values-cs/translations.xml b/features/createroom/impl/src/main/res/values-cs/translations.xml index e19cfbcf91..af95081f1d 100644 --- a/features/createroom/impl/src/main/res/values-cs/translations.xml +++ b/features/createroom/impl/src/main/res/values-cs/translations.xml @@ -8,15 +8,10 @@ "Tuto místnost může najít kdokoli. To můžete kdykoli změnit v nastavení místnosti." "Veřejná místnost" - "Do této místnosti může vstoupit kdokoli" - "Kdokoliv" - "Přístup do místnosti" "Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout" "Požádat o připojení" "Aby byla tato místnost viditelná v adresáři veřejných místností, budete potřebovat adresu místnosti." "Adresa místnosti" - "Název místnosti" "Viditelnost místnosti" - "Vytvořit místnost" "Téma (nepovinné)" diff --git a/features/createroom/impl/src/main/res/values-cy/translations.xml b/features/createroom/impl/src/main/res/values-cy/translations.xml index 52168014bf..741022659c 100644 --- a/features/createroom/impl/src/main/res/values-cy/translations.xml +++ b/features/createroom/impl/src/main/res/values-cy/translations.xml @@ -8,15 +8,10 @@ "Gall unrhyw un ddod o hyd i\'r ystafell hon. Gallwch newid hyn unrhyw bryd yng ngosodiadau ystafell." "Ystafell gyhoeddus" - "Gall unrhyw un ymuno â\'r ystafell hon" - "Unrhyw un" - "Mynediad i\'r Ystafell" "Gall unrhyw un ofyn am gael ymuno â\'r ystafell ond bydd rhaid i weinyddwr neu gymedrolwr dderbyn y cais" "Gofyn i gael ymuno" "Er mwyn i\'r ystafell hon fod yn weladwy yn y cyfeiriadur ystafelloedd cyhoeddus, bydd angen cyfeiriad ystafell arnoch." "Cyfeiriad yr ystafell" - "Enw\'r ystafell" "Gwelededd yr ystafell" - "Creu ystafell" "Pwnc (dewisol)" diff --git a/features/createroom/impl/src/main/res/values-da/translations.xml b/features/createroom/impl/src/main/res/values-da/translations.xml index 1a69f150fb..45261f2a29 100644 --- a/features/createroom/impl/src/main/res/values-da/translations.xml +++ b/features/createroom/impl/src/main/res/values-da/translations.xml @@ -8,15 +8,10 @@ "Alle kan finde dette rum. Du kan ændre dette når som helst i rummets indstillinger." "Offentligt rum" - "Alle kan deltage i dette rum" - "Enhver" - "Adgang til rummet" "Alle kan bede om at deltage i rummet, men en administrator eller en moderator skal acceptere anmodningen" "Spørg om at deltage" "Hvis dette rum skal være synligt i det offentlige register, skal du bruge en rum-adresse." "Rummets adresse" - "Navn på rum" "Rummets synlighed" - "Opret et rum" "Emne (valgfrit)" diff --git a/features/createroom/impl/src/main/res/values-de/translations.xml b/features/createroom/impl/src/main/res/values-de/translations.xml index 9c48001c92..692a2c921e 100644 --- a/features/createroom/impl/src/main/res/values-de/translations.xml +++ b/features/createroom/impl/src/main/res/values-de/translations.xml @@ -8,15 +8,10 @@ "Jeder kann diesen Chat finden. Du kannst dies jederzeit in den Einstellungen des Chats ändern." "Öffentlicher Chat" - "Jeder darf diesem Chat beitreten" - "Jeder" - "Chat Zugang" "Jeder kann den Beitritt zum Chat erbitten, aber ein Admin oder Moderator muss die Anfrage akzeptieren." "Beitritt beantragen" "Du benötigst eine Chat-Adresse, damit dieser Chat im öffentlichen Verzeichnis sichtbar ist." "Chatroom Adresse" - "Chat-Name" " Sichtbarkeit des Chats" - "Chat erstellen" "Thema (optional)" diff --git a/features/createroom/impl/src/main/res/values-el/translations.xml b/features/createroom/impl/src/main/res/values-el/translations.xml index 37ccd49d0e..a8c500df94 100644 --- a/features/createroom/impl/src/main/res/values-el/translations.xml +++ b/features/createroom/impl/src/main/res/values-el/translations.xml @@ -8,15 +8,10 @@ "Ο καθένας μπορεί να βρει αυτή την αίθουσα. Αυτό μπορείτε να το αλλάξετε ανά πάσα στιγμή στις ρυθμίσεις της αίθουσας." "Δημόσια αίθουσα" - "Οποιοσδήποτε μπορεί να συμμετάσχει σε αυτή την αίθουσα" - "Οποιοσδήποτε" - "Πρόσβαση στην Αίθουσα" "Οποιοσδήποτε μπορεί να ζητήσει να συμμετάσχει στην αίθουσα, αλλά ένας διαχειριστής ή ένας συντονιστής θα πρέπει να αποδεχτεί το αίτημα" "Αίτημα συμμετοχής" "Για να είναι ορατή αυτή η αίθουσα στον δημόσιο κατάλογο αιθουσών, θα χρειαστείτε μια διεύθυνση αίθουσας." "Διεύθυνση δωματίου" - "Όνομα αίθουσας" "Ορατότητα αίθουσας" - "Δημιουργία αίθουσας" "Θέμα (προαιρετικό)" diff --git a/features/createroom/impl/src/main/res/values-es/translations.xml b/features/createroom/impl/src/main/res/values-es/translations.xml index 64806977c0..fcf2996398 100644 --- a/features/createroom/impl/src/main/res/values-es/translations.xml +++ b/features/createroom/impl/src/main/res/values-es/translations.xml @@ -8,14 +8,9 @@ "Cualquiera puede encontrar esta sala. Puedes cambiar esto en cualquier momento en los ajustes de la sala." "Sala pública" - "Cualquiera puede unirse a esta sala" - "Cualquiera" - "Acceso a la sala" "Cualquiera puede solicitar unirse a la sala, pero un administrador o un moderador tendrá que aceptar la solicitud" "Solicitud para unirse" "Para que esta sala sea visible en el directorio de salas públicas, necesitarás una dirección de sala." - "Nombre de la sala" "Visibilidad de la sala" - "Crear una sala" "Tema (opcional)" diff --git a/features/createroom/impl/src/main/res/values-et/translations.xml b/features/createroom/impl/src/main/res/values-et/translations.xml index 98449f4817..c81caebede 100644 --- a/features/createroom/impl/src/main/res/values-et/translations.xml +++ b/features/createroom/impl/src/main/res/values-et/translations.xml @@ -8,15 +8,10 @@ "Kõik saavad seda jututuba leida. Sa võid seda jututoa seadistustest alati muuta." "Avalik jututuba" - "Kõik võivad selle jututoaga liituda" - "Kõik kasutajad" - "Ligipääs jututoale" "Kõik võivad paluda selle jututoaga liitumist, kuid peakasutaja või moderaator peavad selle kinnitama" "Küsi võimalust liitumiseks" "Selleks, et see jututuba oleks nähtav jututubade avalikus kataloogis, sa vajad jututoa aadressi." "Jututoa aadress" - "Jututoa nimi" "Jututoa nähtavus" - "Loo jututuba" "Teema (kui soovid lisada)" diff --git a/features/createroom/impl/src/main/res/values-eu/translations.xml b/features/createroom/impl/src/main/res/values-eu/translations.xml index 537aa495a5..f4b6d405b7 100644 --- a/features/createroom/impl/src/main/res/values-eu/translations.xml +++ b/features/createroom/impl/src/main/res/values-eu/translations.xml @@ -8,12 +8,7 @@ "Edonork aurki dezake gela hau. Gelaren ezarpenetan aldatu dezakezu hobespena." "Gela publikoa" - "Edonor sar daiteke gela honetara" - "Edonork" - "Gelarako sarbidea" "Gelaren helbidea" - "Gelaren izena" "Gelaren ikusgarritasuna" - "Sortu gela" "Mintzagaia (aukerakoa)" diff --git a/features/createroom/impl/src/main/res/values-fa/translations.xml b/features/createroom/impl/src/main/res/values-fa/translations.xml index 09869c76f6..dad5298a0f 100644 --- a/features/createroom/impl/src/main/res/values-fa/translations.xml +++ b/features/createroom/impl/src/main/res/values-fa/translations.xml @@ -8,13 +8,8 @@ "هرکسی می‌تواند اتاق را بیابد. می‌توانید بعداً در تظیمات اتاق عوضش کنید." "اتاق عمومی" - "هرکسی می‌تواند به این اتاق بپیوندد" - "هرکسی" - "دسترسی اتاق" "درخواست دعوت" "نشانی اتاق" - "نام اتاق" "نمایانی اتاق" - "ایجاد اتاق" "موضوع (اختیاری)" diff --git a/features/createroom/impl/src/main/res/values-fi/translations.xml b/features/createroom/impl/src/main/res/values-fi/translations.xml index df541d3dee..3b120947cc 100644 --- a/features/createroom/impl/src/main/res/values-fi/translations.xml +++ b/features/createroom/impl/src/main/res/values-fi/translations.xml @@ -8,15 +8,10 @@ "Kuka tahansa voi löytää tämän huoneen. Voit muuttaa tämän milloin tahansa huoneen asetuksista." "Julkinen huone" - "Kuka tahansa voi liittyä tähän huoneeseen" - "Kuka tahansa" - "Huoneeseen Pääsy" "Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö" "Pyydä liittymistä" "Jotta tämä huone näkyisi julkisessa huonehakemistossa, tarvitset huoneen osoitteen." "Huoneen osoite" - "Huoneen nimi" "Huoneen näkyvyys" - "Luo huone" "Aihe (valinnainen)" diff --git a/features/createroom/impl/src/main/res/values-fr/translations.xml b/features/createroom/impl/src/main/res/values-fr/translations.xml index afbdc919ba..d500902949 100644 --- a/features/createroom/impl/src/main/res/values-fr/translations.xml +++ b/features/createroom/impl/src/main/res/values-fr/translations.xml @@ -8,15 +8,10 @@ "N’importe qui peut trouver ce salon. Vous pouvez modifier cela à tout moment dans les paramètres du salon." "Salon public" - "Tout le monde peut rejoindre ce salon" - "Tout le monde" - "Accès au salon" "Tout le monde peut demander à rejoindre le salon, mais un administrateur ou un modérateur devra accepter la demande" "Demander à rejoindre" "Pour que ce salon soit visible dans le répertoire des salons publics, vous aurez besoin d’une adresse de salon." "Adresse du salon" - "Nom du salon" "Visibilité du salon" - "Créer un salon" "Sujet (facultatif)" diff --git a/features/createroom/impl/src/main/res/values-hr/translations.xml b/features/createroom/impl/src/main/res/values-hr/translations.xml index 1d6d7e5af7..510bd68659 100644 --- a/features/createroom/impl/src/main/res/values-hr/translations.xml +++ b/features/createroom/impl/src/main/res/values-hr/translations.xml @@ -8,15 +8,10 @@ "Svatko može pronaći ovu sobu. To možete u svakom trenutku promijeniti u postavkama sobe." "Javna soba" - "Svatko se može pridružiti ovoj sobi" - "Svatko" - "Pristup sobi" "Svatko može zatražiti pridruživanje sobi, ali administrator ili moderator morat će prihvatiti zahtjev." "Zatraži pridruživanje" "Da bi ova soba bila vidljiva u javnom direktoriju soba, trebat će vam adresa sobe." "Adresa sobe" - "Naziv sobe" "Vidljivost sobe" - "Stvori sobu" "Tema (neobavezno)" diff --git a/features/createroom/impl/src/main/res/values-hu/translations.xml b/features/createroom/impl/src/main/res/values-hu/translations.xml index 24f71983ce..bfa1205b05 100644 --- a/features/createroom/impl/src/main/res/values-hu/translations.xml +++ b/features/createroom/impl/src/main/res/values-hu/translations.xml @@ -8,15 +8,10 @@ "Bárki megtalálhatja ezt a szobát. Ezt bármikor módosíthatja a szobabeállításokban." "Nyilvános szoba" - "Bárki csatlakozhat ehhez a szobához" - "Bárki" - "Szobahozzáférés" "Bárki kérheti, hogy csatlakozzon a szobához, de egy adminisztrátornak vagy moderátornak el kell fogadnia a kérést" "Csatlakozás kérése" "Ahhoz, hogy ez a szoba látható legyen a nyilvános szobák címtárában, meg kell adnia a szoba címét." "Szoba címe" - "Szoba neve" "Szoba láthatósága" - "Szoba létrehozása" "Téma (nem kötelező)" diff --git a/features/createroom/impl/src/main/res/values-in/translations.xml b/features/createroom/impl/src/main/res/values-in/translations.xml index 219f621068..014fc8a628 100644 --- a/features/createroom/impl/src/main/res/values-in/translations.xml +++ b/features/createroom/impl/src/main/res/values-in/translations.xml @@ -8,15 +8,10 @@ "Siapa pun dapat mencari ruangan ini. Anda dapat mengubah ini kapan pun dalam pengaturan ruangan." "Ruangan publik" - "Siapa pun dapat bergabung dengan ruangan ini" - "Siapa pun" - "Akses Ruangan" "Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut" "Minta untuk bergabung" "Supaya ruangan ini terlihat di direktori ruangan publik, Anda memerlukan alamat ruangan." "Alamat ruangan" - "Nama ruangan" "Keterlihatan ruangan" - "Buat ruangan" "Topik (opsional)" diff --git a/features/createroom/impl/src/main/res/values-it/translations.xml b/features/createroom/impl/src/main/res/values-it/translations.xml index 741b88b763..980fb5c660 100644 --- a/features/createroom/impl/src/main/res/values-it/translations.xml +++ b/features/createroom/impl/src/main/res/values-it/translations.xml @@ -8,15 +8,10 @@ "Chiunque può trovare questa stanza. Puoi modificarlo in qualsiasi momento nelle impostazioni della stanza." "Stanza pubblica" - "Chiunque può entrare in questa stanza" - "Chiunque" - "Accesso alla stanza" "Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta" "Chiedi di entrare" "Affinché questa stanza sia visibile nell\'elenco delle stanze pubbliche, è necessario un indirizzo della stanza." "Indirizzo della stanza" - "Nome stanza" "Visibilità della stanza" - "Crea una stanza" "Argomento (facoltativo)" diff --git a/features/createroom/impl/src/main/res/values-ka/translations.xml b/features/createroom/impl/src/main/res/values-ka/translations.xml index 20c7af40de..de1e33bd68 100644 --- a/features/createroom/impl/src/main/res/values-ka/translations.xml +++ b/features/createroom/impl/src/main/res/values-ka/translations.xml @@ -7,7 +7,5 @@ "კერძო ოთახი" "ყველას ამ ოთახის მოძებნა შეუძლია. თქვენ ნებისმიერ დროს შეგიძლიათ ამის შეცვლა ოთახის პარამეტრებში." - "ოთახის სახელი" - "ოთახის შექმნა" "თემა (სურვილისამებრ)" diff --git a/features/createroom/impl/src/main/res/values-ko/translations.xml b/features/createroom/impl/src/main/res/values-ko/translations.xml index 3dfdc46e7c..e861333e9b 100644 --- a/features/createroom/impl/src/main/res/values-ko/translations.xml +++ b/features/createroom/impl/src/main/res/values-ko/translations.xml @@ -8,14 +8,9 @@ "누구나 이 방을 찾을 수 있습니다. 방 설정에서 언제든지 변경할 수 있습니다." "공개 방" - "누구나 이 방에 참여할 수 있습니다." - "누구나" - "방 액세스" "누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다." "참가 요청" "이 방이 공개 방 디렉토리에 표시되려면 방 주소가 필요합니다." - "방 이름" "방 표시 여부" - "방 만들기" "주제 (선택)" diff --git a/features/createroom/impl/src/main/res/values-lt/translations.xml b/features/createroom/impl/src/main/res/values-lt/translations.xml index 2fb7b3eb5c..e392f57717 100644 --- a/features/createroom/impl/src/main/res/values-lt/translations.xml +++ b/features/createroom/impl/src/main/res/values-lt/translations.xml @@ -7,7 +7,5 @@ "Privatus kambarys" "Bet kas gali rasti šį kambarį. Tai galite bet kada pakeisti kambario nustatymuose." - "Kambario pavadinimas" - "Kurti kambarį" "Tema (nebūtina)" diff --git a/features/createroom/impl/src/main/res/values-nb/translations.xml b/features/createroom/impl/src/main/res/values-nb/translations.xml index e6021cf5ac..14a8c53e52 100644 --- a/features/createroom/impl/src/main/res/values-nb/translations.xml +++ b/features/createroom/impl/src/main/res/values-nb/translations.xml @@ -8,15 +8,10 @@ "Alle kan finne dette rommet. Du kan endre dette når som helst i rominnstillingene." "Offentlig rom" - "Alle kan bli med i dette rommet" - "Alle" - "Tilgang til rom" "Alle kan be om å få bli med i rommet, men en administrator eller moderator må godta forespørselen" "Be om å bli med" "For at dette rommet skal være synlig i den offentlige romkatalogen, trenger du en romadresse." "Romadresse" - "Romnavn" "Romsynlighet" - "Opprett et rom" "Emne (valgfritt)" diff --git a/features/createroom/impl/src/main/res/values-nl/translations.xml b/features/createroom/impl/src/main/res/values-nl/translations.xml index 5142148171..8af8b11621 100644 --- a/features/createroom/impl/src/main/res/values-nl/translations.xml +++ b/features/createroom/impl/src/main/res/values-nl/translations.xml @@ -8,12 +8,7 @@ "Iedereen kan deze kamer vinden. Je kunt dit op elk gewenst moment wijzigen in de kamerinstellingen." "Openbare kamer" - "Iedereen kan toetreden tot deze kamer" - "Iedereen" - "Toegang tot de kamer" "Iedereen kan vragen om toe te treden tot de kamer, maar een beheerder of moderator moet het verzoek accepteren" "Vraag om toe te treden" - "Naam van de kamer" - "Creëer een kamer" "Onderwerp (optioneel)" diff --git a/features/createroom/impl/src/main/res/values-pl/translations.xml b/features/createroom/impl/src/main/res/values-pl/translations.xml index 446644b622..f79c2cbb32 100644 --- a/features/createroom/impl/src/main/res/values-pl/translations.xml +++ b/features/createroom/impl/src/main/res/values-pl/translations.xml @@ -8,15 +8,10 @@ "Każdy może znaleźć ten pokój. Możesz to zmienić w ustawieniach pokoju." "Pokój publiczny" - "Każdy może dołączyć do tego pokoju" - "Wszyscy" - "Dostęp do pokoju" "Każdy może poprosić o dołączenie do pokoju, ale administrator lub moderator będzie musiał zatwierdzić prośbę" "Poproś o dołączenie" "Aby ten pokój był widoczny w katalogu pomieszczeń publicznych, będziesz potrzebował adres pokoju." "Adres pokoju" - "Nazwa pokoju" "Widoczność pomieszczenia" - "Utwórz pokój" "Temat (opcjonalnie)" diff --git a/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml b/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml index 399c9fec17..becc333d0d 100644 --- a/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml @@ -8,15 +8,10 @@ "Qualquer um pode encontrar esta sala. Você pode mudar isso a qualquer momento nas configurações da sala." "Sala pública" - "Qualquer pessoa pode entrar nesta sala" - "Qualquer pessoa" - "Acesso à sala" "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá de aceitar a solicitação" "Pedir para entrar" "Para que esta sala fique visível no diretório público de salas, você precisará de um endereço de sala." "Endereço da sala" - "Nome da sala" "Visibilidade da sala" - "Criar uma sala" "Tópico (opcional)" diff --git a/features/createroom/impl/src/main/res/values-pt/translations.xml b/features/createroom/impl/src/main/res/values-pt/translations.xml index 1524914bb2..942c39edf3 100644 --- a/features/createroom/impl/src/main/res/values-pt/translations.xml +++ b/features/createroom/impl/src/main/res/values-pt/translations.xml @@ -8,15 +8,10 @@ "Qualquer um pode encontrar esta sala. Pode alterar esta opção nas definições da sala." "Sala pública" - "Qualquer pessoa pode entrar nesta sala" - "Qualquer pessoa" - "Acesso à sala" "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou um moderador terá de aceitar o pedido" "Pedir para participar" "Para que esta sala seja visível no diretório público de salas, precisas de um endereço de sala." "Endereço da sala" - "Nome da sala" "Visibilidade da sala" - "Criar uma sala" "Descrição (opcional)" diff --git a/features/createroom/impl/src/main/res/values-ro/translations.xml b/features/createroom/impl/src/main/res/values-ro/translations.xml index b9fe78bb19..e4a3e0dba1 100644 --- a/features/createroom/impl/src/main/res/values-ro/translations.xml +++ b/features/createroom/impl/src/main/res/values-ro/translations.xml @@ -8,15 +8,10 @@ "Oricine poate găsi această cameră. Puteți modifica acest lucru oricând în setări." "Cameră publică" - "Oricine se poate alătura acestei camere" - "Oricine" - "Acces la cameră" "Oricine poate cere să se alăture camerei, dar un administrator sau un moderator va trebui să accepte cererea" "Cereți să vă alăturați" "Pentru ca această cameră să fie vizibilă în directorul de camere publice, veți avea nevoie de o adresă de cameră." "Adresa camerei" - "Numele camerei" "Vizibilitatea camerei" - "Creați o cameră" "Subiect (opțional)" diff --git a/features/createroom/impl/src/main/res/values-ru/translations.xml b/features/createroom/impl/src/main/res/values-ru/translations.xml index e871673114..68cdad1ad4 100644 --- a/features/createroom/impl/src/main/res/values-ru/translations.xml +++ b/features/createroom/impl/src/main/res/values-ru/translations.xml @@ -8,15 +8,10 @@ "Любой желающий может найти эту комнату. Вы можете изменить это в любое время в настройках комнаты." "Общедоступная комната" - "Любой желающий может присоединиться к этой комнате" - "Любой" - "Доступ в комнату" "Любой желающий может подать заявку на присоединение к комнате, но администратор или модератор должен будет принять запрос." "Попросить присоединиться" "Чтобы эта комната была видна в каталоге общедоступных, вам необходим ее адрес" "Адрес комнаты" - "Название комнаты" "Видимость комнаты" - "Создать комнату" "Тема (необязательно)" diff --git a/features/createroom/impl/src/main/res/values-sk/translations.xml b/features/createroom/impl/src/main/res/values-sk/translations.xml index 7b6d89b2e1..dacec52b33 100644 --- a/features/createroom/impl/src/main/res/values-sk/translations.xml +++ b/features/createroom/impl/src/main/res/values-sk/translations.xml @@ -8,15 +8,10 @@ "Túto miestnosť môže nájsť ktokoľvek. Môžete to kedykoľvek zmeniť v nastaveniach miestnosti." "Verejná miestnosť" - "Do tejto miestnosti sa môže pripojiť ktokoľvek" - "Ktokoľvek" - "Prístup do miestnosti" "Ktokoľvek môže požiadať o pripojenie sa k miestnosti, ale administrátor alebo moderátor bude musieť žiadosť schváliť" "Požiadať o pripojenie" "Aby bola táto miestnosť viditeľná v adresári verejných miestností, budete potrebovať adresu miestnosti." "Adresa miestnosti" - "Názov miestnosti" "Viditeľnosť miestnosti" - "Vytvoriť miestnosť" "Téma (voliteľné)" diff --git a/features/createroom/impl/src/main/res/values-sv/translations.xml b/features/createroom/impl/src/main/res/values-sv/translations.xml index 8cd01ebd0e..3c0de1aa65 100644 --- a/features/createroom/impl/src/main/res/values-sv/translations.xml +++ b/features/createroom/impl/src/main/res/values-sv/translations.xml @@ -8,15 +8,10 @@ "Vem som helst kan hitta det här rummet. Du kan ändra detta när som helst i rumsinställningarna." "Offentligt rum" - "Vem som helst kan gå med i det här rummet" - "Vem som helst" - "Rumsåtkomst" "Vem som helst kan be om att gå med i rummet men en administratör eller en moderator måste acceptera begäran" "Be om att gå med" "För att detta rum ska vara synligt i den allmänna rumskatalogen behöver du en rumsadress." "Rumsadress" - "Rumsnamn" "Rumssynlighet" - "Skapa ett rum" "Ämne (valfritt)" diff --git a/features/createroom/impl/src/main/res/values-tr/translations.xml b/features/createroom/impl/src/main/res/values-tr/translations.xml index d97139c973..b5a8f131a0 100644 --- a/features/createroom/impl/src/main/res/values-tr/translations.xml +++ b/features/createroom/impl/src/main/res/values-tr/translations.xml @@ -8,15 +8,10 @@ "Bu odayı herkes bulabilir. Bunu istediğiniz zaman oda ayarlarından değiştirebilirsiniz." "Herkese açık oda" - "Bu odaya herkes katılabilir" - "Herkes" - "Oda Erişimi" "Herkes odaya katılmayı isteyebilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekecektir" "Katılmak için sor" "Bu odanın genel oda dizininde görünür olması için bir oda adresine ihtiyacınız olacaktır." "Oda adresi" - "Oda adı" "Oda görünürlüğü" - "Bir oda oluştur" "Konu (isteğe bağlı)" diff --git a/features/createroom/impl/src/main/res/values-uk/translations.xml b/features/createroom/impl/src/main/res/values-uk/translations.xml index 047b4dd9d2..e83359b89c 100644 --- a/features/createroom/impl/src/main/res/values-uk/translations.xml +++ b/features/createroom/impl/src/main/res/values-uk/translations.xml @@ -8,15 +8,10 @@ "Будь-хто може знайти цю кімнату. Ви можете змінити це в будь-який час у налаштуваннях кімнати." "Загальнодоступна кімната" - "Будь-хто може приєднатися до цієї кімнати" - "Кожний" - "Доступ до кімнати" "Будь-хто може попросити приєднатися до кімнати, але адміністратор або модератор повинен буде прийняти запит" "Запросити приєднатися" "Щоб цю кімнату було видно в каталозі загальнодоступних кімнат, вам знадобиться її адреса." "Адреса кімнати" - "Назва кімнати" "Видимість кімнати" - "Створити кімнату" "Тема (необов\'язково)" diff --git a/features/createroom/impl/src/main/res/values-ur/translations.xml b/features/createroom/impl/src/main/res/values-ur/translations.xml index b68992085f..1783963c67 100644 --- a/features/createroom/impl/src/main/res/values-ur/translations.xml +++ b/features/createroom/impl/src/main/res/values-ur/translations.xml @@ -8,7 +8,5 @@ "کوئی بھی یہ کمرہ ڈھونڈ سکتا ہے۔ آپ اسے کمرے کی ترتیبات میں کسی بھی وقت تبدیل کرسکتے ہیں۔" "عوامی کمرہ" - "کمرے کا نام" - "ایک کمرہ بنائیں" "موضوع (اختیاری)" diff --git a/features/createroom/impl/src/main/res/values-uz/translations.xml b/features/createroom/impl/src/main/res/values-uz/translations.xml index 34062f9669..665851ce02 100644 --- a/features/createroom/impl/src/main/res/values-uz/translations.xml +++ b/features/createroom/impl/src/main/res/values-uz/translations.xml @@ -8,14 +8,9 @@ "Bu xonani har kim topishi mumkin. Buni xona sozlamalaridan istalgan vaqtda oʻzgartirishingiz mumkin." "Jamoat xonasi" - "Bu xonaga istalgan kishi qo‘shilishi mumkin" - "Har kim" - "Xonaga kirish" "Xonaga qo‘shilishni istalgan kishi so‘rashi mumkin, lekin administrator yoki moderator so‘rovni qabul qilishi kerak" "Qo‘shilishni so‘rang" "Ushbu xona ommaviy xonalar ro‘yxatida ko‘rinishi uchun sizga xona manzili kerak bo‘ladi." - "Xona nomi" "Xonaning ko‘rinishi" - "Xonani yaratish" "Mavzu (ixtiyoriy)" diff --git a/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml b/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml index 476f9cff7e..065e05f321 100644 --- a/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml @@ -8,15 +8,10 @@ "任何人都可以找到此聊天室。 您隨時都可以在聊天室設定中變更此設定。" "公開的聊天室" - "任何人都可以加入此聊天室" - "任何人" - "聊天室存取權" "任何人都可以要求加入聊天室,但管理員或版主必須接受該請求" "要求加入" "為了讓此聊天室在公開聊天室目錄中可見,您需要聊天室地址。" "聊天室地址" - "聊天室名稱" "聊天室能見度" - "建立聊天室" "主題(非必填)" diff --git a/features/createroom/impl/src/main/res/values-zh/translations.xml b/features/createroom/impl/src/main/res/values-zh/translations.xml index d20e34801d..f17accb9fd 100644 --- a/features/createroom/impl/src/main/res/values-zh/translations.xml +++ b/features/createroom/impl/src/main/res/values-zh/translations.xml @@ -8,15 +8,10 @@ "任何人都能找到此聊天室。 你可以随时在聊天室设置中更改。" "公共聊天室" - "任何人都可以加入此房间" - "任何人" - "房间访问权限" "任何人都可以请求加入房间,但必须由管理员或审核人接受" "请求加入" "要使该房间在公开房间目录中可见,您需要一个房间地址。" "房间地址" - "聊天室名称" "房间可见性" - "创建聊天室" "主题(可选)" diff --git a/features/createroom/impl/src/main/res/values/localazy.xml b/features/createroom/impl/src/main/res/values/localazy.xml index fa9a1cb276..3ec2d9d6f3 100644 --- a/features/createroom/impl/src/main/res/values/localazy.xml +++ b/features/createroom/impl/src/main/res/values/localazy.xml @@ -3,20 +3,26 @@ "New room" "Invite people" "An error occurred when creating the room" - "Only people invited can access this room. All messages are end-to-end encrypted." - "Private room" + "The space could not be created because of an unknown error. Try again later." + "Add name…" + "New room" + "New space" + "Only people invited can join." + "Private" "Anyone can find this room. You can change this anytime in room settings." - "Public room" - "Anyone can join this room" - "Anyone" - "Room Access" - "Anyone can ask to join the room but an administrator or a moderator will have to accept the request" - "Ask to join" - "In order for this room to be visible in the public room directory, you will need a room address." - "Room address" - "Room name" + "Anyone can join." + "Public" + "Anyone can ask to join but an administrator or a moderator must accept the request." + "Allow ask to join" + "Only people invited can join." + "Private" + "Anyone can join." + "Public" + "Who has access" + "You’ll need an address in order to make it visible in the public directory." + "Address" "Room visibility" - "Create a room" "Topic (optional)" + "Add description…" diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPointTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPointTest.kt index 35b6637bbf..5b7a6c1142 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPointTest.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPointTest.kt @@ -40,6 +40,7 @@ class DefaultCreateRoomEntryPointTest { override fun onRoomCreated(roomId: RoomId) = lambdaError() } val result = entryPoint.createNode( + isSpace = false, parentNode = parentNode, buildContext = BuildContext.root(null), callback = callback, diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt index 6de15904d7..e82d8c3912 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt @@ -380,6 +380,7 @@ class ConfigureRoomPresenterTest { ) private fun createConfigureRoomPresenter( + isSpace: Boolean = false, roomAliasHelper: RoomAliasHelper = FakeRoomAliasHelper(), dataStore: CreateRoomConfigStore = CreateRoomConfigStore(roomAliasHelper), matrixClient: MatrixClient = createMatrixClient(), @@ -390,6 +391,7 @@ class ConfigureRoomPresenterTest { isKnockFeatureEnabled: Boolean = true, mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(), ) = ConfigureRoomPresenter( + isSpace = isSpace, dataStore = dataStore, matrixClient = matrixClient, mediaPickerProvider = pickerProvider, diff --git a/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/api/FakeCreateRoomEntryPoint.kt b/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/api/FakeCreateRoomEntryPoint.kt index 2beaecf013..bbeb69c26b 100644 --- a/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/api/FakeCreateRoomEntryPoint.kt +++ b/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/api/FakeCreateRoomEntryPoint.kt @@ -14,6 +14,7 @@ import io.element.android.tests.testutils.lambda.lambdaError class FakeCreateRoomEntryPoint : CreateRoomEntryPoint { override fun createNode( + isSpace: Boolean, parentNode: Node, buildContext: BuildContext, callback: CreateRoomEntryPoint.Callback, diff --git a/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt b/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt index 71ee093985..1a90245611 100644 --- a/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt +++ b/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt @@ -25,6 +25,7 @@ interface HomeEntryPoint : FeatureEntryPoint { interface Callback : Plugin { fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) fun navigateToCreateRoom() + fun navigateToCreateSpace() fun navigateToSettings() fun navigateToSetUpRecovery() fun navigateToEnterRecoveryKey() diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt index d9f87e2edd..0e92761bd5 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt @@ -220,6 +220,7 @@ class HomeFlowNode( onRoomClick = ::navigateToRoom, onSettingsClick = callback::navigateToSettings, onStartChatClick = callback::navigateToCreateRoom, + onCreateSpaceClick = callback::navigateToCreateSpace, onSetUpRecoveryClick = callback::navigateToSetUpRecovery, onConfirmRecoveryKeyClick = callback::navigateToEnterRecoveryKey, onRoomSettingsClick = callback::navigateToRoomSettings, diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt index 1b05fc99ec..f55183feb0 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt @@ -74,6 +74,7 @@ fun HomeView( onSetUpRecoveryClick: () -> Unit, onConfirmRecoveryKeyClick: () -> Unit, onStartChatClick: () -> Unit, + onCreateSpaceClick: () -> Unit, onRoomSettingsClick: (roomId: RoomId) -> Unit, onMenuActionClick: (RoomListMenuAction) -> Unit, onReportRoomClick: (roomId: RoomId) -> Unit, @@ -113,6 +114,7 @@ fun HomeView( onRoomClick = { if (firstThrottler.canHandle()) onRoomClick(it) }, onOpenSettings = { if (firstThrottler.canHandle()) onSettingsClick() }, onStartChatClick = { if (firstThrottler.canHandle()) onStartChatClick() }, + onCreateSpaceClick = { if (firstThrottler.canHandle()) onCreateSpaceClick() }, onMenuActionClick = onMenuActionClick, ) // This overlaid view will only be visible when state.displaySearchResults is true @@ -138,6 +140,7 @@ private fun HomeScaffold( onRoomClick: (RoomId) -> Unit, onOpenSettings: () -> Unit, onStartChatClick: () -> Unit, + onCreateSpaceClick: () -> Unit, onMenuActionClick: (RoomListMenuAction) -> Unit, modifier: Modifier = Modifier, ) { @@ -164,6 +167,7 @@ private fun HomeScaffold( modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { HomeTopBar( + selectedNavigationItem = state.currentHomeNavigationBarItem, title = stringResource(state.currentHomeNavigationBarItem.labelRes), currentUserAndNeighbors = state.currentUserAndNeighbors, showAvatarIndicator = state.showAvatarIndicator, @@ -174,10 +178,11 @@ private fun HomeScaffold( onAccountSwitch = { state.eventSink(HomeEvents.SwitchToAccount(it)) }, + onCreateSpace = onCreateSpaceClick, scrollBehavior = scrollBehavior, - displayMenuItems = state.displayActions, displayFilters = state.displayRoomListFilters, filtersState = roomListState.filtersState, + canCreateSpaces = state.homeSpacesState.canCreateSpaces, canReportBug = state.canReportBug, modifier = Modifier.hazeEffect( state = hazeState, @@ -328,6 +333,7 @@ internal fun HomeViewPreview(@PreviewParameter(HomeStateProvider::class) state: onSetUpRecoveryClick = {}, onConfirmRecoveryKeyClick = {}, onStartChatClick = {}, + onCreateSpaceClick = {}, onRoomSettingsClick = {}, onReportRoomClick = {}, onMenuActionClick = {}, @@ -347,6 +353,7 @@ internal fun HomeViewA11yPreview() = ElementPreview { onSetUpRecoveryClick = {}, onConfirmRecoveryKeyClick = {}, onStartChatClick = {}, + onCreateSpaceClick = {}, onRoomSettingsClick = {}, onReportRoomClick = {}, onMenuActionClick = {}, diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt index 093b91fb66..c92a5b9fb8 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.unit.dp import io.element.android.appconfig.RoomListConfig import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.home.impl.HomeNavigationBarItem import io.element.android.features.home.impl.R import io.element.android.features.home.impl.filters.RoomListFiltersState import io.element.android.features.home.impl.filters.RoomListFiltersView @@ -73,6 +74,7 @@ import kotlinx.collections.immutable.toImmutableList @OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeTopBar( + selectedNavigationItem: HomeNavigationBarItem, title: String, currentUserAndNeighbors: ImmutableList, showAvatarIndicator: Boolean, @@ -81,8 +83,9 @@ fun HomeTopBar( onMenuActionClick: (RoomListMenuAction) -> Unit, onOpenSettings: () -> Unit, onAccountSwitch: (SessionId) -> Unit, + onCreateSpace: () -> Unit, scrollBehavior: TopAppBarScrollBehavior, - displayMenuItems: Boolean, + canCreateSpaces: Boolean, canReportBug: Boolean, displayFilters: Boolean, filtersState: RoomListFiltersState, @@ -117,63 +120,16 @@ fun HomeTopBar( ) }, actions = { - if (displayMenuItems) { - IconButton( - onClick = onToggleSearch, - ) { - Icon( - imageVector = CompoundIcons.Search(), - contentDescription = stringResource(CommonStrings.action_search), - ) - } - if (RoomListConfig.HAS_DROP_DOWN_MENU) { - var showMenu by remember { mutableStateOf(false) } - IconButton( - onClick = { showMenu = !showMenu } - ) { - Icon( - imageVector = CompoundIcons.OverflowVertical(), - contentDescription = null, - ) - } - DropdownMenu( - expanded = showMenu, - onDismissRequest = { showMenu = false } - ) { - if (RoomListConfig.SHOW_INVITE_MENU_ITEM) { - DropdownMenuItem( - onClick = { - showMenu = false - onMenuActionClick(RoomListMenuAction.InviteFriends) - }, - text = { Text(stringResource(id = CommonStrings.action_invite)) }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.ShareAndroid(), - tint = ElementTheme.colors.iconSecondary, - contentDescription = null, - ) - } - ) - } - if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM && canReportBug) { - DropdownMenuItem( - onClick = { - showMenu = false - onMenuActionClick(RoomListMenuAction.ReportBug) - }, - text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.ChatProblem(), - tint = ElementTheme.colors.iconSecondary, - contentDescription = null, - ) - } - ) - } - } - } + when (selectedNavigationItem) { + HomeNavigationBarItem.Chats -> RoomListMenuItems( + onToggleSearch = onToggleSearch, + onMenuActionClick = onMenuActionClick, + canReportBug = canReportBug + ) + HomeNavigationBarItem.Spaces -> SpacesMenuItems( + canCreateSpaces = canCreateSpaces, + onCreateSpace = onCreateSpace + ) } }, // We want a 16dp left padding for the navigationIcon : @@ -193,6 +149,85 @@ fun HomeTopBar( } } +@Composable +private fun RoomListMenuItems( + onToggleSearch: () -> Unit, + onMenuActionClick: (RoomListMenuAction) -> Unit, + canReportBug: Boolean, +) { + IconButton( + onClick = onToggleSearch, + ) { + Icon( + imageVector = CompoundIcons.Search(), + contentDescription = stringResource(CommonStrings.action_search), + ) + } + if (RoomListConfig.HAS_DROP_DOWN_MENU) { + var showMenu by remember { mutableStateOf(false) } + IconButton( + onClick = { showMenu = !showMenu } + ) { + Icon( + imageVector = CompoundIcons.OverflowVertical(), + contentDescription = null, + ) + } + DropdownMenu( + expanded = showMenu, + onDismissRequest = { showMenu = false } + ) { + if (RoomListConfig.SHOW_INVITE_MENU_ITEM) { + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClick(RoomListMenuAction.InviteFriends) + }, + text = { Text(stringResource(id = CommonStrings.action_invite)) }, + leadingIcon = { + Icon( + imageVector = CompoundIcons.ShareAndroid(), + tint = ElementTheme.colors.iconSecondary, + contentDescription = null, + ) + } + ) + } + if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM && canReportBug) { + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClick(RoomListMenuAction.ReportBug) + }, + text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) }, + leadingIcon = { + Icon( + imageVector = CompoundIcons.ChatProblem(), + tint = ElementTheme.colors.iconSecondary, + contentDescription = null, + ) + } + ) + } + } + } +} + +@Composable +private fun SpacesMenuItems( + canCreateSpaces: Boolean, + onCreateSpace: () -> Unit +) { + if (canCreateSpaces) { + IconButton(onClick = onCreateSpace) { + Icon( + imageVector = CompoundIcons.Plus(), + contentDescription = stringResource(CommonStrings.action_create_space) + ) + } + } +} + @Composable private fun NavigationIcon( currentUserAndNeighbors: ImmutableList, @@ -273,6 +308,7 @@ private fun AccountIcon( @Composable internal fun HomeTopBarPreview() = ElementPreview { HomeTopBar( + selectedNavigationItem = HomeNavigationBarItem.Chats, title = stringResource(R.string.screen_roomlist_main_space_title), currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")), showAvatarIndicator = false, @@ -281,7 +317,8 @@ internal fun HomeTopBarPreview() = ElementPreview { onOpenSettings = {}, onAccountSwitch = {}, onToggleSearch = {}, - displayMenuItems = true, + onCreateSpace = {}, + canCreateSpaces = true, canReportBug = true, displayFilters = true, filtersState = aRoomListFiltersState(), @@ -289,11 +326,35 @@ internal fun HomeTopBarPreview() = ElementPreview { ) } +@OptIn(ExperimentalMaterial3Api::class) +@PreviewsDayNight +@Composable +internal fun HomeTopBarSpacesPreview() = ElementPreview { + HomeTopBar( + selectedNavigationItem = HomeNavigationBarItem.Spaces, + title = stringResource(R.string.screen_home_tab_spaces), + currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")), + showAvatarIndicator = false, + areSearchResultsDisplayed = false, + scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()), + onOpenSettings = {}, + onAccountSwitch = {}, + onToggleSearch = {}, + onCreateSpace = {}, + canCreateSpaces = true, + canReportBug = true, + displayFilters = false, + filtersState = aRoomListFiltersState(), + onMenuActionClick = {}, + ) +} + @OptIn(ExperimentalMaterial3Api::class) @PreviewsDayNight @Composable internal fun HomeTopBarWithIndicatorPreview() = ElementPreview { HomeTopBar( + selectedNavigationItem = HomeNavigationBarItem.Chats, title = stringResource(R.string.screen_roomlist_main_space_title), currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")), showAvatarIndicator = true, @@ -302,7 +363,8 @@ internal fun HomeTopBarWithIndicatorPreview() = ElementPreview { onOpenSettings = {}, onAccountSwitch = {}, onToggleSearch = {}, - displayMenuItems = true, + onCreateSpace = {}, + canCreateSpaces = true, canReportBug = true, displayFilters = true, filtersState = aRoomListFiltersState(), @@ -315,6 +377,7 @@ internal fun HomeTopBarWithIndicatorPreview() = ElementPreview { @Composable internal fun HomeTopBarMultiAccountPreview() = ElementPreview { HomeTopBar( + selectedNavigationItem = HomeNavigationBarItem.Chats, title = stringResource(R.string.screen_roomlist_main_space_title), currentUserAndNeighbors = aMatrixUserList().take(3).toImmutableList(), showAvatarIndicator = false, @@ -323,7 +386,8 @@ internal fun HomeTopBarMultiAccountPreview() = ElementPreview { onOpenSettings = {}, onAccountSwitch = {}, onToggleSearch = {}, - displayMenuItems = true, + onCreateSpace = {}, + canCreateSpaces = true, canReportBug = true, displayFilters = true, filtersState = aRoomListFiltersState(), diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt index a890a61ac3..00129235fe 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt @@ -15,6 +15,8 @@ import androidx.compose.runtime.remember import dev.zacsweers.metro.Inject import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.libraries.architecture.Presenter +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.ui.safety.rememberHideInvitesAvatar import kotlinx.collections.immutable.persistentListOf @@ -27,9 +29,11 @@ import kotlinx.coroutines.flow.map class HomeSpacesPresenter( private val client: MatrixClient, private val seenInvitesStore: SeenInvitesStore, + private val featureFlagsService: FeatureFlagService, ) : Presenter { @Composable override fun present(): HomeSpacesState { + val canCreateSpaces by featureFlagsService.isFeatureEnabledFlow(FeatureFlags.CreateSpaces).collectAsState(false) val hideInvitesAvatar by client.rememberHideInvitesAvatar() val spaceRooms by remember { client.spaceService.spaceRoomsFlow.map { it.toImmutableList() } @@ -48,6 +52,7 @@ class HomeSpacesPresenter( spaceRooms = spaceRooms, seenSpaceInvites = seenSpaceInvites, hideInvitesAvatar = hideInvitesAvatar, + canCreateSpaces = canCreateSpaces, eventSink = ::handleEvent, ) } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt index 7dcb370219..9bcf7131c8 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt @@ -18,6 +18,7 @@ data class HomeSpacesState( val spaceRooms: ImmutableList, val seenSpaceInvites: ImmutableSet, val hideInvitesAvatar: Boolean, + val canCreateSpaces: Boolean, val eventSink: (HomeSpacesEvents) -> Unit, ) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStateProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStateProvider.kt index 8c03cff7ee..c1a32a1f34 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStateProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStateProvider.kt @@ -30,6 +30,13 @@ open class HomeSpacesStateProvider : PreviewParameterProvider { ), spaceRooms = aListOfSpaceRooms(), ), + aHomeSpacesState( + space = CurrentSpace.Space( + spaceRoom = aSpaceRoom(roomId = RoomId("!mySpace:example.com")) + ), + spaceRooms = aListOfSpaceRooms(), + canCreateSpaces = false, + ), ) } @@ -38,12 +45,14 @@ internal fun aHomeSpacesState( spaceRooms: List = aListOfSpaceRooms(), seenSpaceInvites: Set = emptySet(), hideInvitesAvatar: Boolean = false, + canCreateSpaces: Boolean = true, eventSink: (HomeSpacesEvents) -> Unit = {}, ) = HomeSpacesState( space = space, spaceRooms = spaceRooms.toImmutableList(), seenSpaceInvites = seenSpaceInvites.toImmutableSet(), hideInvitesAvatar = hideInvitesAvatar, + canCreateSpaces = canCreateSpaces, eventSink = eventSink, ) diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt index 9778556dd2..582de66414 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt @@ -47,6 +47,7 @@ class DefaultHomeEntryPointTest { val callback = object : HomeEntryPoint.Callback { override fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) = lambdaError() override fun navigateToCreateRoom() = lambdaError() + override fun navigateToCreateSpace() = lambdaError() override fun navigateToSettings() = lambdaError() override fun navigateToSetUpRecovery() = lambdaError() override fun navigateToEnterRecoveryKey() = lambdaError() diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt index bb82d51a79..a07093aa9f 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt @@ -273,6 +273,7 @@ private fun AndroidComposeTestRule.setRoomL onSetUpRecoveryClick: () -> Unit = EnsureNeverCalled(), onConfirmRecoveryKeyClick: () -> Unit = EnsureNeverCalled(), onCreateRoomClick: () -> Unit = EnsureNeverCalled(), + onCreateSpaceClick: () -> Unit = EnsureNeverCalled(), onRoomSettingsClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(), onMenuActionClick: (RoomListMenuAction) -> Unit = EnsureNeverCalledWithParam(), onReportRoomClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(), @@ -286,6 +287,7 @@ private fun AndroidComposeTestRule.setRoomL onSetUpRecoveryClick = onSetUpRecoveryClick, onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick, onStartChatClick = onCreateRoomClick, + onCreateSpaceClick = onCreateSpaceClick, onRoomSettingsClick = onRoomSettingsClick, onMenuActionClick = onMenuActionClick, onDeclineInviteAndBlockUser = onDeclineInviteAndBlockUser, diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenterTest.kt index c7608833ac..43d3a8896d 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenterTest.kt @@ -11,6 +11,9 @@ package io.element.android.features.home.impl.spaces import com.google.common.truth.Truth.assertThat import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.features.invite.test.InMemorySeenInvitesStore +import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.tests.testutils.test @@ -23,18 +26,25 @@ class HomeSpacesPresenterTest { val presenter = createPresenter() presenter.test { val state = awaitItem() + // canCreateSpaces is initially false + assertThat(state.canCreateSpaces).isFalse() assertThat(state.space).isEqualTo(CurrentSpace.Root) assertThat(state.spaceRooms).isEmpty() assertThat(state.hideInvitesAvatar).isFalse() assertThat(state.seenSpaceInvites).isEmpty() + + // It'll eventually be true + assertThat(awaitItem().canCreateSpaces).isTrue() } } private fun createPresenter( client: MatrixClient = FakeMatrixClient(), seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore(), + featureFlagsService: FeatureFlagService = FakeFeatureFlagService(initialState = mapOf(FeatureFlags.CreateSpaces.key to true)), ) = HomeSpacesPresenter( client = client, seenInvitesStore = seenInvitesStore, + featureFlagsService = featureFlagsService, ) } 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 5b42440101..e997f08d65 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 @@ -34,6 +34,7 @@ import io.element.android.features.preferences.impl.R import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults +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.button.BackButton @@ -47,7 +48,8 @@ import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TextField import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet -import io.element.android.libraries.matrix.ui.components.EditableAvatarView +import io.element.android.libraries.matrix.ui.components.AvatarPickerState +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 @@ -103,13 +105,17 @@ fun EditUserProfileView( .verticalScroll(rememberScrollState()) ) { Spacer(modifier = Modifier.height(24.dp)) - EditableAvatarView( - matrixId = state.userId.value, - displayName = state.displayName, - avatarUrl = state.userAvatarUrl, - avatarSize = AvatarSize.EditProfileDetails, - avatarType = AvatarType.User, - onAvatarClick = { onAvatarClick() }, + val avatarPickerState = remember(state.userAvatarUrl) { + val size = AvatarSize.EditProfileDetails + val type = AvatarType.User + AvatarPickerState.Selected( + avatarData = AvatarData(id = state.userId.value, name = state.displayName, size = size, url = state.userAvatarUrl), + type = type + ) + } + AvatarPickerView( + state = avatarPickerState, + onClick = ::onAvatarClick, modifier = Modifier.align(Alignment.CenterHorizontally), ) Spacer(modifier = Modifier.height(16.dp)) diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index cd90edf709..ca00571dd1 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -63,7 +63,7 @@ "Profile" "Requests to join" "Roles & permissions" - "Room name" + "Name" "Security & privacy" "Security" "Share room" @@ -143,7 +143,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Enable end-to-end encryption" "Anyone can join." "Anyone" - "Choose which spaces’ members can join this room without an invitation. %1$s" + "Choose which spaces’ members can join this room without an invitation. %1$s" "Manage spaces" "Only invited people can join." "Invite only" 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 aedb9bd16b..d2de2ba260 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 @@ -13,7 +13,6 @@ package io.element.android.features.roomdetailsedit.impl import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding @@ -24,6 +23,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource @@ -33,6 +33,7 @@ import androidx.compose.ui.unit.dp import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults +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.button.BackButton @@ -45,7 +46,8 @@ import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TextField import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet -import io.element.android.libraries.matrix.ui.components.EditableAvatarView +import io.element.android.libraries.matrix.ui.components.AvatarPickerState +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 @@ -99,20 +101,18 @@ fun RoomDetailsEditView( .verticalScroll(rememberScrollState()) ) { Spacer(modifier = Modifier.height(24.dp)) - EditableAvatarView( - matrixId = state.roomId.value, - // As per Element Web, we use the raw name for the avatar as well - displayName = state.roomRawName, - avatarUrl = state.roomAvatarUrl, - avatarSize = AvatarSize.EditRoomDetails, - avatarType = if (state.isSpace) { - AvatarType.Space() - } else { - AvatarType.Room() - }, - enabled = state.canChangeAvatar, - onAvatarClick = ::onAvatarClick, - modifier = Modifier.fillMaxWidth(), + val avatarPickerState = remember(state.roomAvatarUrl) { + val size = AvatarSize.EditRoomDetails + val type = AvatarType.Room() + AvatarPickerState.Selected( + avatarData = AvatarData(id = state.roomId.value, name = state.roomRawName, size = size, url = state.roomAvatarUrl), + type = type + ) + } + AvatarPickerView( + state = avatarPickerState, + onClick = ::onAvatarClick, + modifier = Modifier.align(Alignment.CenterHorizontally), ) Spacer(modifier = Modifier.height(32.dp)) diff --git a/features/securityandprivacy/impl/src/main/res/values/localazy.xml b/features/securityandprivacy/impl/src/main/res/values/localazy.xml index 902a89d7bd..5cb5cdf5ec 100644 --- a/features/securityandprivacy/impl/src/main/res/values/localazy.xml +++ b/features/securityandprivacy/impl/src/main/res/values/localazy.xml @@ -22,7 +22,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Enable end-to-end encryption" "Anyone can join." "Anyone" - "Choose which spaces’ members can join this room without an invitation. %1$s" + "Choose which spaces’ members can join this room without an invitation. %1$s" "Manage spaces" "Only invited people can join." "Invite only" diff --git a/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/StartChatFlowNode.kt b/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/StartChatFlowNode.kt index 236d92fd4a..c7d9aa4fd0 100644 --- a/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/StartChatFlowNode.kt +++ b/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/StartChatFlowNode.kt @@ -81,6 +81,7 @@ class StartChatFlowNode( } } createRoomEntryPoint.createNode( + isSpace = false, parentNode = this, buildContext = buildContext, callback = callback, 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 0f99349494..4124d7a967 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(70.dp), + EditRoomDetails(68.dp), RoomListManageUser(96.dp), NotificationsOptIn(32.dp), 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 08bdaf942f..a77e09711f 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 @@ -70,6 +70,13 @@ enum class FeatureFlags( defaultValue = { false }, isFinished = false, ), + CreateSpaces( + key = "feature.createSpaces", + title = "Create spaces", + description = "Allow creating spaces.", + defaultValue = { false }, + isFinished = false, + ), SpaceSettings( key = "feature.spaceSettings", title = "Space settings", diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt index a0a0bde1ed..1f23d32df6 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt @@ -26,4 +26,5 @@ data class CreateRoomParameters( val joinRuleOverride: JoinRule? = null, val historyVisibilityOverride: RoomHistoryVisibility? = null, val roomAliasName: Optional = Optional.empty(), + val isSpace: Boolean = false, ) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 4cb84abc03..b4f39d2693 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -393,6 +393,7 @@ class RustMatrixClient( joinRuleOverride = createRoomParams.joinRuleOverride?.map(), historyVisibilityOverride = createRoomParams.historyVisibilityOverride?.map(), canonicalAlias = createRoomParams.roomAliasName.getOrNull(), + isSpace = createRoomParams.isSpace, ) val roomId = RoomId(innerClient.createRoom(rustParams)) // Wait to receive the room back from the sync but do not returns failure if it fails. diff --git a/libraries/matrixmedia/impl/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt b/libraries/matrixmedia/impl/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt index b6093cd327..9d7767e42d 100644 --- a/libraries/matrixmedia/impl/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt +++ b/libraries/matrixmedia/impl/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt @@ -11,6 +11,7 @@ package io.element.android.libraries.matrix.ui.media import coil3.ImageLoader import coil3.fetch.Fetcher import coil3.request.Options +import coil3.toUri import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.api.media.MatrixMediaLoader @@ -21,10 +22,19 @@ internal class AvatarDataFetcherFactory( data: AvatarData, options: Options, imageLoader: ImageLoader - ): Fetcher { - return CoilMediaFetcher( - mediaLoader = matrixMediaLoader, - mediaData = data.toMediaRequestData(), - ) + ): Fetcher? { + return when { + data.url == null -> null + data.url?.startsWith("mxc") == true -> CoilMediaFetcher( + mediaLoader = matrixMediaLoader, + mediaData = data.toMediaRequestData(), + ) + else -> { + // If the URL does not use the mxc scheme, it might be a local one using `content://`, try using a fallback fetcher + data.url?.toUri()?.let { uri -> + imageLoader.components.newFetcher(uri, options, imageLoader) + }?.first + } + } } } diff --git a/libraries/matrixmedia/impl/src/test/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactoryTest.kt b/libraries/matrixmedia/impl/src/test/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactoryTest.kt new file mode 100644 index 0000000000..eefacb3065 --- /dev/null +++ b/libraries/matrixmedia/impl/src/test/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactoryTest.kt @@ -0,0 +1,78 @@ +/* + * 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.ui.media + +import android.graphics.Bitmap +import coil3.ComponentRegistry +import coil3.ImageLoader +import coil3.asImage +import coil3.disk.DiskCache +import coil3.memory.MemoryCache +import coil3.request.Disposable +import coil3.request.ImageRequest +import coil3.request.ImageResult +import coil3.request.Options +import coil3.request.SuccessResult +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.designsystem.components.avatar.anAvatarData +import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader +import io.mockk.mockk +import org.junit.Test + +class AvatarDataFetcherFactoryTest { + @Test + fun `create - with mxc returns CoilMediaFetcher`() { + val factory = AvatarDataFetcherFactory(matrixMediaLoader = FakeMatrixMediaLoader()) + + val fetcher = factory.create(anAvatarData(url = "mxc://test"), Options(mockk()), imageLoader = FakeImageLoader()) + assertThat(fetcher).isInstanceOf(CoilMediaFetcher::class.java) + } + + @Test + fun `create - with http or https returns null, which means fallback default fetcher will be used`() { + val factory = AvatarDataFetcherFactory(matrixMediaLoader = FakeMatrixMediaLoader()) + + val fetcherHttp = factory.create(anAvatarData(url = "http://test"), Options(mockk()), imageLoader = FakeImageLoader()) + assertThat(fetcherHttp).isNull() + + val fetcherHttps = factory.create(anAvatarData(url = "https://test"), Options(mockk()), imageLoader = FakeImageLoader()) + assertThat(fetcherHttps).isNull() + } + + @Test + fun `create - with content scheme returns null, which means fallback default fetcher will be used`() { + val factory = AvatarDataFetcherFactory(matrixMediaLoader = FakeMatrixMediaLoader()) + + val fetcher = factory.create(anAvatarData(url = "content://test"), Options(mockk()), imageLoader = FakeImageLoader()) + assertThat(fetcher).isNull() + } +} + +private class FakeImageLoader : ImageLoader { + override val defaults: ImageRequest.Defaults = ImageRequest.Defaults.DEFAULT + override val components: ComponentRegistry = ComponentRegistry.Builder().build() + override val memoryCache: MemoryCache? = null + override val diskCache: DiskCache? = null + + override fun enqueue(request: ImageRequest): Disposable { + return mockk() + } + + override suspend fun execute(request: ImageRequest): ImageResult { + return SuccessResult( + image = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8).asImage(), + request = request, + ) + } + + override fun shutdown() {} + + override fun newBuilder(): ImageLoader.Builder { + return ImageLoader.Builder(mockk()) + } +} 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 new file mode 100644 index 0000000000..1c904e891b --- /dev/null +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt @@ -0,0 +1,436 @@ +/* + * 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.ui.components + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.BorderStroke +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 +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.ripple +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.CompositingStrategy +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import 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.icons.CompoundDrawables +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.HorizontalDivider +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.testtags.TestTags +import io.element.android.libraries.testtags.testTag +import io.element.android.libraries.ui.strings.CommonStrings + +/** + * Avatar picker view, based on https://www.figma.com/design/kcnHxunG1LDWXsJhaNuiHz/ER-145--Spaces-on-Element-X?node-id=5918-97417&t=JYDQysgjS33AZb74-4 + * + * 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. + * + * Note: this function contains lots of 'magic numbers', but those are just the fractions used to scale the different dimensions based on the Figma design. + */ +@Composable +fun AvatarPickerView( + state: AvatarPickerState, + modifier: Modifier = Modifier, + onClick: (() -> Unit) = {}, + onClickLabel: String? = stringResource(CommonStrings.a11y_edit_avatar), + enabled: Boolean = true, +) { + val a11yAvatar = stringResource(CommonStrings.a11y_avatar) + + val clickableModifier = Modifier.clickable( + enabled = enabled, + interactionSource = remember { MutableInteractionSource() }, + onClickLabel = onClickLabel, + onClick = onClick, + indication = ripple(bounded = false), + ) + .testTag(TestTags.editAvatar) + .clearAndSetSemantics { + contentDescription = a11yAvatar + } + + val layoutDirection = LocalLayoutDirection.current + + fun eraseBackgroundModifier( + parentWidth: Dp, + editIconRadius: Dp, + ) = Modifier + .graphicsLayer { + compositingStrategy = CompositingStrategy.Offscreen + } + .drawWithContent { + drawContent() + drawCircle( + color = Color.Black, + center = Offset( + x = if (layoutDirection == LayoutDirection.Ltr) { + parentWidth.toPx() - editIconRadius.toPx() * 0.48f + } else { + editIconRadius.toPx() * 0.48f + }, + y = size.height - editIconRadius.toPx(), + ), + radius = editIconRadius.toPx() * 1.2f, + blendMode = BlendMode.Clear, + ) + } + + when (state) { + is AvatarPickerState.Pick -> { + PickButton( + buttonSize = state.buttonSize, + iconSize = state.iconSize, + iconId = state.iconId, + modifier = modifier.padding(state.externalPadding).then(clickableModifier), + ) + } + is AvatarPickerState.Selected -> { + Box(modifier = modifier) { + Avatar( + avatarData = state.avatarData, + avatarType = state.type, + modifier = clickableModifier.then(eraseBackgroundModifier(state.avatarData.size.dp, state.avatarData.size.dp * 0.225f)), + ) + + OverlayEditButton(editButtonSize = state.avatarData.size.dp * 0.44f) + } + } + } +} + +@Composable +private fun PickButton( + buttonSize: Dp, + iconSize: Dp, + @DrawableRes iconId: Int, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .size(buttonSize) + .clip(CircleShape) + .border(BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary), shape = CircleShape) + ) { + Icon( + resourceId = iconId, + contentDescription = null, + modifier = Modifier + .align(Alignment.Center) + .size(iconSize), + tint = ElementTheme.colors.iconPrimary, + ) + } +} + +@Composable +private fun BoxScope.OverlayEditButton(editButtonSize: Dp) { + Box( + modifier = Modifier.align(Alignment.BottomEnd) + .size(editButtonSize) + .offset(x = editButtonSize * 0.266f) + .clip(CircleShape) + .background(ElementTheme.colors.bgCanvasDefault) + .border(BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary), shape = CircleShape), + contentAlignment = Alignment.Center, + ) { + Icon( + modifier = Modifier.size(editButtonSize * 0.66f), + imageVector = CompoundIcons.Edit(), + contentDescription = null, + ) + } +} + +@Immutable +sealed interface AvatarPickerState { + data class Pick( + val buttonSize: Dp, + val iconSize: Dp = buttonSize / 2, + val externalPadding: PaddingValues = PaddingValues.Zero, + @DrawableRes val iconId: Int = CompoundDrawables.ic_compound_take_photo, + ) : AvatarPickerState + + data class Selected( + val avatarData: AvatarData, + val type: AvatarType, + ) : AvatarPickerState +} + +@PreviewsDayNight +@Composable +internal fun AvatarPickerViewPreview() = ElementPreview { + PreviewContent() +} + +@PreviewsDayNight +@Composable +internal fun AvatarPickerViewRtlPreview() = CompositionLocalProvider( + LocalLayoutDirection provides LayoutDirection.Rtl, +) { + ElementPreview { PreviewContent() } +} + +@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 = {}) + } + 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 { + 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) + ) + } + } +} + +@Composable +private fun PreviewContent() { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text("Pick image") + AvatarPickerView(AvatarPickerState.Pick(buttonSize = 48.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) + HorizontalDivider() + + Text("User avatar") + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("No url") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", null, size = AvatarSize.EditRoomDetails), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Local") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("MXC") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "mxc://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + } + HorizontalDivider() + + Text("Room avatar") + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("No url") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Room", null, size = AvatarSize.EditRoomDetails), + type = AvatarType.Room() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Local") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Room", "content://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.Room() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("MXC") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Room", "mxc://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.Room() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + } + HorizontalDivider() + + Text("Space avatar") + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("No url") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Space", null, size = AvatarSize.EditRoomDetails), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Local") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Space", "content://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("MXC") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Space", "mxc://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + } + } +} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt deleted file mode 100644 index 284ffcbab1..0000000000 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt +++ /dev/null @@ -1,157 +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.matrix.ui.components - -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.ripple -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.BlendMode -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.CompositingStrategy -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.clearAndSetSemantics -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -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.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.utils.CommonDrawables -import io.element.android.libraries.testtags.TestTags -import io.element.android.libraries.testtags.testTag -import io.element.android.libraries.ui.strings.CommonStrings - -@Composable -fun EditableAvatarView( - matrixId: String, - displayName: String?, - avatarUrl: String?, - avatarSize: AvatarSize, - avatarType: AvatarType, - onAvatarClick: () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, -) { - val a11yAvatar = stringResource(CommonStrings.a11y_avatar) - val editIconRadius = 15.dp - val parentHeight = avatarSize.dp - val parentWidth = avatarSize.dp + editIconRadius / 2f - Box( - modifier = modifier - .wrapContentSize() - .size(height = parentHeight, width = parentWidth) - .clickable( - enabled = enabled, - interactionSource = remember { MutableInteractionSource() }, - onClickLabel = stringResource(CommonStrings.a11y_edit_avatar), - onClick = onAvatarClick, - indication = ripple(bounded = false), - ) - .testTag(TestTags.editAvatar) - .clearAndSetSemantics { - contentDescription = a11yAvatar - }, - ) { - Box( - modifier = Modifier - .graphicsLayer { - compositingStrategy = CompositingStrategy.Offscreen - } - .drawWithContent { - drawContent() - drawCircle( - color = Color.Black, - center = Offset( - x = parentWidth.toPx() - editIconRadius.toPx(), - y = size.height - editIconRadius.toPx(), - ), - radius = (editIconRadius + 4.dp).toPx(), - blendMode = BlendMode.Clear, - ) - } - ) { - when { - avatarUrl == null || avatarUrl.startsWith("mxc://") -> { - Avatar( - avatarData = AvatarData( - id = matrixId, - name = displayName, - url = avatarUrl, - size = avatarSize, - ), - avatarType = avatarType, - ) - } - else -> { - UnsavedAvatar( - avatarUri = avatarUrl, - avatarSize = avatarSize, - avatarType = avatarType, - ) - } - } - } - Icon( - modifier = Modifier - .align(Alignment.BottomEnd) - .size(editIconRadius * 2) - .border(1.dp, ElementTheme.colors.borderInteractiveSecondary, CircleShape) - .padding(6.dp), - imageVector = CompoundIcons.Edit(), - contentDescription = null, - tint = ElementTheme.colors.iconPrimary, - ) - } -} - -@PreviewsDayNight -@Composable -internal fun EditableAvatarViewPreview( - @PreviewParameter(EditableAvatarViewUriProvider::class) uri: String? -) = ElementPreview( - drawableFallbackForImages = CommonDrawables.sample_avatar, -) { - EditableAvatarView( - matrixId = "id", - displayName = "Room", - avatarUrl = uri, - avatarSize = AvatarSize.RoomDetailsHeader, - avatarType = AvatarType.User, - onAvatarClick = {}, - ) -} - -open class EditableAvatarViewUriProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - null, - "mxc://matrix.org/123456", - "https://example.com/avatar.jpg", - ) -} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt deleted file mode 100644 index 104a418360..0000000000 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt +++ /dev/null @@ -1,93 +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.matrix.ui.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.AddAPhoto -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.painter.ColorPainter -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import io.element.android.compound.theme.ElementTheme -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 io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.temporaryColorBgSpecial - -/** - * An avatar that the user has selected, but which has not yet been uploaded to Matrix. - * - * The image is loaded from a local resource instead of from a MXC URI. - */ -@Composable -fun UnsavedAvatar( - avatarUri: String?, - avatarSize: AvatarSize, - avatarType: AvatarType, - modifier: Modifier = Modifier, -) { - val commonModifier = modifier - .size(avatarSize.dp) - .clip(avatarType.avatarShape(avatarSize.dp)) - - if (avatarUri != null) { - val context = LocalContext.current - val model = ImageRequest.Builder(context) - .data(avatarUri) - .build() - AsyncImage( - modifier = commonModifier, - model = model, - placeholder = ColorPainter(MaterialTheme.colorScheme.surfaceVariant), - contentScale = ContentScale.Crop, - contentDescription = null, - ) - } else { - Box(modifier = commonModifier.background(ElementTheme.colors.temporaryColorBgSpecial)) { - Icon( - imageVector = Icons.Outlined.AddAPhoto, - contentDescription = null, - modifier = Modifier - .align(Alignment.Center) - .size(avatarSize.dp * 4 / 7), - tint = ElementTheme.colors.iconSecondary, - ) - } - } -} - -@PreviewsDayNight -@Composable -internal fun UnsavedAvatarPreview() = ElementPreview { - Row( - modifier = Modifier.padding(8.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.User) - UnsavedAvatar("", AvatarSize.EditRoomDetails, AvatarType.User) - UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.Space()) - UnsavedAvatar("", AvatarSize.EditRoomDetails, AvatarType.Space()) - } -} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressField.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressField.kt index 4166f37cd7..ec494c2888 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressField.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressField.kt @@ -27,7 +27,7 @@ fun RoomAddressField( homeserverName: String, addressValidity: RoomAddressValidity, onAddressChange: (String) -> Unit, - label: String, + label: String?, supportingText: String, modifier: Modifier = Modifier, ) { diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 3a108277ba..5d65ecdbe3 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -56,6 +56,7 @@ "Your avatar" "Accept" "Add caption" + "Add existing rooms" "Add to timeline" "Back" "Call" @@ -75,6 +76,7 @@ "Copy text" "Create" "Create a room" + "Create space" "Deactivate" "Deactivate account" "Decline" @@ -112,6 +114,7 @@ "Load more" "Manage account" "Manage devices" + "Manage rooms" "Message" "Minimise" "Next" @@ -191,6 +194,7 @@ "Copied to clipboard" "Copyright" "Creating room…" + "Creating space…" "Request canceled" "Left room" "Left space" @@ -337,6 +341,7 @@ Reason: %1$s." "Starting chat…" "Sticker" "Success" + "Suggested" "Suggestions" "Syncing" "System" @@ -473,6 +478,7 @@ Are you sure you want to continue?" "Share this location" "Spaces you have created or joined." "%1$s • %2$s" + "Create spaces to organize rooms" "%1$s space" "Spaces" "View members" diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt index b7ee2d5743..e4a9d60679 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt @@ -79,6 +79,9 @@ class KonsistPreviewTest { private val previewNameExceptions = listOf( "AsyncIndicatorFailurePreview", "AsyncIndicatorLoadingPreview", + "AvatarPickerSizesPreview", + "AvatarPickerViewPreview", + "AvatarPickerViewRtlPreview", "BackgroundVerticalGradientDisabledPreview", "BackgroundVerticalGradientPreview", "ColorAliasesPreview", @@ -86,6 +89,7 @@ class KonsistPreviewTest { "GradientFloatingActionButtonCircleShapePreview", "HeaderFooterPageScrollablePreview", "HomeTopBarMultiAccountPreview", + "HomeTopBarSpacesPreview", "HomeTopBarWithIndicatorPreview", "IconsOtherPreview", "MarkdownTextComposerEditPreview", 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 01986a9c5f..ae1511ef58 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:61d96e2f91d217a1112421633426692fc5a2c35e9756d4980bd75fb3088a4b8f -size 29568 +oid sha256:9719e20a56fa6bcbd6afd5fd4cef5877af0d0664dfb9559e84dd332d1a161b7f +size 29538 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 2f8038140b..d2e5ed4ff2 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:4cf57997e6ca0c7244811154564f27c2af135f0a85dc4598e16df51251096b65 -size 35844 +oid sha256:20c185481e6a13fbccae6e4d8c02752222f8cfcc5c03398c255666beb5df5cc4 +size 34243 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 07a00b2546..de71057a78 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:6f8f4593373a4229d852a8b4e2e3b937796e45135a032afbbd0563a4fa5e651c -size 56375 +oid sha256:2d0fb8d4c5acde1b03908f15eb959d3e544917a53c529f5971804eb674f989fa +size 41893 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 4a562be62c..ff8f88d0fd 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:5c80c8f9ee81b35b6054a10872e14d4fc4d8654b7747a620ea4b9a79d3595265 -size 56756 +oid sha256:a601ab64bac5f2c11480892e4b81dcaf3b9fe72afd222f6f42d1e5f577220a8c +size 42786 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 d2d4c19999..3e2a94d2ba 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:27c31889281d6ba95448b033a07f1e41bc1c55bed26840cc796283a0f9368bf0 -size 58454 +oid sha256:f8a2dd4b01f32b9325e9adf8340f18b6776ff20c06f4e27590bde207d802b3c8 +size 44542 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 07a00b2546..de71057a78 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:6f8f4593373a4229d852a8b4e2e3b937796e45135a032afbbd0563a4fa5e651c -size 56375 +oid sha256:2d0fb8d4c5acde1b03908f15eb959d3e544917a53c529f5971804eb674f989fa +size 41893 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 new file mode 100644 index 0000000000..ff18c21fbf --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0f2a05605785d5a9484e6e34b03c6074125927f6b8130f5e60f54e3922d7bc4 +size 42863 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 e6a51b3035..c9e3ba2b8b 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:f3e9fb42af90f7db14c02d572366ce59808ebd551cac7cc8552ee308d65f7c83 -size 30607 +oid sha256:9c955974f899511eb023e0b25f067cff55edd6d360ebbba5081df5662445d0e4 +size 30753 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 0bbe373b9d..8f1e0520e9 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:3b9bb30aec0b92dd5d352dd9dec4d26177ecb38a10c2984bab5c4bd4584b9b2d -size 36992 +oid sha256:fd25259e89b4a8833c884727d23fb503b53099b698ff2eafd812bf70422b5cbe +size 35631 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 dd9a8c8bf5..7e6d2bf350 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:0c7b44d045dbea3f47c774465be245046e972ade8ad6b9240df956c685dcbd59 -size 58228 +oid sha256:30a4f34c42cb57b3cbd08114fef8531175890d46d0033f0dc5d1337189e33d1c +size 43653 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 7067367b4d..68a1d1bfd0 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:3ee8385caada3a2739834bbabe1411d2f6da4d645d5b99cf07a6da96fe5eabb9 -size 58584 +oid sha256:ab5d721149a96e53f850d7792653b0b71d41124c0db82d653ad79c66c72dabee +size 44600 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 152991f1ef..87c118d7f0 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:fb1bff539ab70b3d8bb8ae5f5490374e855c9b7807d1868b0aa1cffacc10e1f5 -size 60382 +oid sha256:b7a8c9c3cb8f877d3dc2deb1b918666143c73aed34fdd3d3961bc2530f32d0f5 +size 46369 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 dd9a8c8bf5..7e6d2bf350 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:0c7b44d045dbea3f47c774465be245046e972ade8ad6b9240df956c685dcbd59 -size 58228 +oid sha256:30a4f34c42cb57b3cbd08114fef8531175890d46d0033f0dc5d1337189e33d1c +size 43653 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 new file mode 100644 index 0000000000..b4d8ddbeb2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3cb687ded32d38164cb67657b495958f1632457d1e49ede0d8c9f1b1f5a287b +size 44675 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Day_0_en.png new file mode 100644 index 0000000000..a436e9b1e4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08e7f4dad9666652eea98b7ecf807f2d0050024a59e8b25113b00d7584ff7fa7 +size 12382 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Night_0_en.png new file mode 100644 index 0000000000..1be8da04e4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8d8783952c0fd66f6ca762b79061d26abdf6aedbf601266292a6507da674792 +size 11419 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 new file mode 100644 index 0000000000..834f73ab9f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:542d8ba6a6031fe2789cf111f333eef22acf95281f57421ace2c7b5b0a599cc2 +size 41140 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 new file mode 100644 index 0000000000..7dc28605d2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c31cd78bc054610be05012cdba7eb0cbc770435b0e12bc065f6eae4a773ca39e +size 40121 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 5cd1c50997..2e8c314c9d 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:27c5418d421ca6cf0069e34ca3e22ca807203d252b9c1424eca447f070fbbbdf -size 54177 +oid sha256:d398e399f468705b9f78283535c2b0e3f44f8be0456cf99bb9b3611746cd0af2 +size 54380 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 d6b722a3f3..f23d07d437 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:fc4c11b4d2c83b179409083ca36fcb95e44b7d8c51abd23e9c07f4d3be8a339c -size 52626 +oid sha256:7fce6676e186e13f14ea8cc8436fdbcadcf41bf84a1999104794bd2245814337 +size 52805 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 b509b7fff7..cd447a2df1 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:5896d5e6fd21697d6270aedb4389eee0d57a9796536b847ae657f57e6c2dab3d -size 20974 +oid sha256:4f3dff815d0233a7a3716ec2298e06f78bf3b52806412c4f628a81ed53e841c3 +size 21818 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 c7aa6f6105..417ebf2b1f 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:95100c25fb085329f8968a765a4f4359678be67309d5e086ead311c48cfda29f -size 67826 +oid sha256:bbadbe374c9a0235af368e9ceedd9aadd4cd736ca7f68592a656b2bd854fe3de +size 63364 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 17eb214c80..a92c5f5c0a 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:9b6869e6026df038d739cc14a0a585563d595b1430ba23a985ec57680506ead2 -size 29857 +oid sha256:f78f81d996c9124b2c06406fc0b86f242c0a05b9e85fe19ea550769682e9ba11 +size 30493 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 3920f3fe0c..e52e8f373d 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:7f103f89c71cc97a837cf0edc1035c580bfdf2d682857897241a6dec23c91436 -size 21163 +oid sha256:1ff355d7046ae53a00a0a0c6432823f31f73cd3206268c72414f5e6172d588a0 +size 21994 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 1a31286fd6..8543f0f600 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:9989d429a1ed9f3190a19c0678168de77aca597ed8fda5208e19bbe109ab9ada -size 66391 +oid sha256:14dfa82a7762b5a787ba5b663878854adce1db268f5764f2deb695284d077412 +size 62305 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 8ee822b18b..df3d2a522f 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:2b3eb9e8908deb84153b19d3735dd2338fac2a7998793915eeec32d7607a0b94 -size 28671 +oid sha256:856b6175eb5331d079ceb4b9037045738aaf42ffe55e3fe8fe32bcb948c2225c +size 29235 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 98fffb180d..d046fd1e4c 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:c200761849da1ba650f38adfeed65fcc35f4fda94a4b1302447faf55d4196c16 -size 28211 +oid sha256:9f22ca53d5ab8897718c6628efc436566d648bff8736f592f456b56502eb18f7 +size 28189 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 146d245888..219c962a9c 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:282680791aed814f49e25134742e55270ffa155004d48a4f4645ef160450c529 -size 21933 +oid sha256:32773f03c02c65758cf122566c28b633474dc31e1f4e84a36bf8a89bda6791c0 +size 21904 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 f9fb3f287d..b89f6150b1 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:fc04e9e69f8111c2837d998f6503e2ea146d91284d1839ac8619d5d9325645d7 -size 29613 +oid sha256:4f2f2548c1fd553657e1b8b13613a691371f053d12dc3a8e08016deb8cd671f2 +size 29532 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 169e16037f..15ac502c6b 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:c7579d7b70e81228d997f8390285210a6e6a7c764523a82b59cd68b2e1969656 -size 52193 +oid sha256:44363d7d7ed3abd614fe9cc6f4fce750c280335ae34177a9a147c1c9b5a18f9a +size 50999 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 fc9cf97e30..596057c7fe 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:eaad1ca1ef992a03aae784836139963e5ac8867d5fc70871eb63d273acf05948 -size 49266 +oid sha256:e8c00c06c9da1432f196aafa11e529e393f6b03310fa4d9984bf66d4f7faa058 +size 44922 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 817b7943b8..637db7b7c9 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:44331b9967290ab96c55cce7a5f8a3531564ad0c074ea6b25adf9299a6ec0239 -size 28165 +oid sha256:7b6ee74993d1fa47bba94df064612aa80a5d0be3333d9986a5caf0e1aa7d0089 +size 28328 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 74c01ba304..b4a57f090f 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:d037d7c70b304980c4c0a2c292fdcf800eafff15aee8c3c3adbf180e7e47a557 -size 28293 +oid sha256:13d339ed6e27f32f7820048acf35008f406f7ad2597cf1487a05b0a7e6b1ab5b +size 28289 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 a01340b169..fc613213a8 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:f4467db8409103caf24b97dab28e5280da60ca420d951d689d353ebaf63841bf -size 24737 +oid sha256:1858184e176bdf7dce86d39da44b1732f31ff5d516c154d42de063def0b13fb7 +size 24897 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 e3e8f0a8c0..12a3e650ed 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:109a1451e031bcc46e55c2c111a4ce65eb5635a3b66b1ba6a5e6a0980184ec0d -size 26087 +oid sha256:674a37e0ff50291151afcef77e81f449e234112ebc1c103bcfdfd9c7c223a0f3 +size 26152 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 a1da37b1de..d996f53828 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:e3d196d9b4946165718d8a4ad37869d1d81c6134e94e05dcc1b23b71338482cb -size 28941 +oid sha256:dd0a5f6164167b707a3765f3aef44da02c5a74e24a6ee4d5f8fe2e8f15b88f85 +size 29012 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 de17d9174f..226e57c2cf 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:d797584eca407120de11bdac2792a4501dd414274e5acf786fab74b7df668209 -size 27518 +oid sha256:95dc827f3f94a9c6b9b8e71f0057271e47cddbe18a60833d633f80b9a9a55e0f +size 27485 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 df8188c586..b57822d36b 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:0ba88593c26798de646f331f68c48b4675f33090e7533b88f6a31e0c5cfbd081 -size 21538 +oid sha256:599e7d7c23b137a8f234481b130724aba799ccde53601e600f623e0b130181db +size 21564 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 da0a0553d5..8c7ae4e616 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:16c5f05bb20e9a1f5b3480827fe7c7c4384daa60496da0ee0dc9bcdd77ccdddd -size 29004 +oid sha256:b6fac75a22e067ec468e1c0dc80ba039f886ce622c5696c89e8ba88f78057d2e +size 28970 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 9cd03d2914..fbf8c6a0ba 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:7616b1926b6b6f1c6aa19d797866a74cb7db487fa72e59b291e715f22d961607 -size 50787 +oid sha256:8f0f25c356fce23df0dd5b07352a52c4510a559c81733c424027ab1966fe30d3 +size 49577 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 ae64071349..eab0932ee8 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:f2c9d431942b442b2620268cec8f06166db18b5df732b7a77cd71a11228106c6 -size 48325 +oid sha256:9f9eb9966b578538160a181719f3ea1a22caa0541ccc579f363f9e0f00f5851c +size 43811 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 051a142e26..bdc56406d7 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:bd244116c434d143950d0bb7c291d3a4faf4540f34112286b9069c41eb7de576 -size 27509 +oid sha256:8910fdb134040309196009b90d499d89acc085ca5d20dbefaf4781f0f8d02a6c +size 27596 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 c0fadc78e5..a42d10c37b 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:3e98e5bdd03bdd7c2da11595416987398ec4af4ba88010a0eab25f11da149ea7 -size 27520 +oid sha256:0c3abff638ea74e7d2913ce45de920f896b546d705424ea09e10eda4b1ff6072 +size 27467 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 e7c94c7669..4936178a29 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:fd96a05649a403454636d07168398476b25aae4aaad76cac4e41265478ec4791 -size 23768 +oid sha256:5d060c0fe749dca414d99f6820c174e9423248e08f2a1724f6bc13cc04c3abe1 +size 24046 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 4e8cabc23c..f64b7f30fe 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:7c95f90eba87b390c09894087d4c55dfe8e7797af712315ccbee3f927be4e5d5 -size 24314 +oid sha256:74bd3527bc14031b326008ec61743f71a26008ee11f7ed6d34b3776d0e792cbf +size 24500 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 1643569702..a916008e8f 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:b9187a1e5fc63707a2c1a9804411e15439469f8562eac2c9766a4e033e214166 -size 27289 +oid sha256:5a6d90e7299cb60f6d2ee1b083134daab398ac93394dc8aa6b03dc5b74f10dfe +size 27497 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png index 04d7a13388..36132424ed 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da260572a274c3fedcc81b055e1c52b8cf7467692287aa176b0dd9171be76937 -size 25139 +oid sha256:48a00c3111761d2f8d058bb1b782c066222edd7963f2154b7b59e5d2907972ac +size 25100 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png index 8eb93a77e0..92622922a6 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da888123f37a0dcc7d80849216044b82a442052c900d636d006020ad42469a71 -size 51849 +oid sha256:120a6bf52ad4144f423eb80d86defa794ef2ae2c05ee36d7e3b2930ae18466e5 +size 51811 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png index 8eb93a77e0..92622922a6 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da888123f37a0dcc7d80849216044b82a442052c900d636d006020ad42469a71 -size 51849 +oid sha256:120a6bf52ad4144f423eb80d86defa794ef2ae2c05ee36d7e3b2930ae18466e5 +size 51811 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png index d320c0dc11..70947dd13f 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64134bc23ef38b73a087ec5679784516bfd66f23dd675a3771e1aa8cf6159836 -size 44729 +oid sha256:e93b37a435d6465e5b4285b705d0e6b7f2702fc53d2763c0d4779931c2380195 +size 44681 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png index 9de784287c..06ef3ad65a 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56d1614ce5e0da0bc29f8184f045339e263087676e9d7908a94007f410924b5d -size 59154 +oid sha256:262bfe062d02b42c061603ee697a1bba55f68de10ff87da9c1afcbeb2418efec +size 59105 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png index 9de784287c..06ef3ad65a 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56d1614ce5e0da0bc29f8184f045339e263087676e9d7908a94007f410924b5d -size 59154 +oid sha256:262bfe062d02b42c061603ee697a1bba55f68de10ff87da9c1afcbeb2418efec +size 59105 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png index c200e6a21c..5d780a3a05 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20a302e03d4f10c912c249f7c26f8ecc06472dd2a2ad4abe91607bb7527de732 -size 25577 +oid sha256:0c4363353050180ba9bf64cf571d846b1c4fa15dbae96a6a2a81502f1363957d +size 25535 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png index e0f67fd111..1f065f09d6 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9939e7a38e0e280d42a996576a3cfbeb773625cf43ddf8afd04aad6ab35fd955 -size 53555 +oid sha256:fea1457bf9f172e9a635ca83529c5c79d0886c8c492d0454306d6899bbd85591 +size 53482 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png index e0f67fd111..1f065f09d6 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9939e7a38e0e280d42a996576a3cfbeb773625cf43ddf8afd04aad6ab35fd955 -size 53555 +oid sha256:fea1457bf9f172e9a635ca83529c5c79d0886c8c492d0454306d6899bbd85591 +size 53482 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png index 264166a069..e097ccb8c5 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:093bb9672ecd80432c7e6102bd5ed2d1184cd384c91e479d99d13c0ba773bf78 -size 46448 +oid sha256:bda2d33e58d4dc1b2c1fd19a5fe0b2e574315b5b1a4f6a6367360dd31c602c51 +size 46390 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png index 920c64d380..4669fb8074 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee80f7a765a453c3704af6d1f38f90637528bcf1e5966dc1bd016f4d34f21fa4 -size 61069 +oid sha256:890064df86090c0003ae6fc4f461e392a3cbfa95b6d8a1f937bc1058580697d1 +size 61001 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png index 920c64d380..4669fb8074 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee80f7a765a453c3704af6d1f38f90637528bcf1e5966dc1bd016f4d34f21fa4 -size 61069 +oid sha256:890064df86090c0003ae6fc4f461e392a3cbfa95b6d8a1f937bc1058580697d1 +size 61001 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 new file mode 100644 index 0000000000..e4ae3155a6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:193626470640c2d6499d8155a4a18836bf5564678b5f78b6a187f0d7505a61a7 +size 217630 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 new file mode 100644 index 0000000000..07599ae211 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3eab1e9017e55668ded1c01a7051aded0b99932986afc22d477e5ad0d500cd33 +size 212898 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 new file mode 100644 index 0000000000..945a52bcbc --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ac5166b6bf6c040c726321be6130f7d557b33e9ac6e111ddcd5c95be1d5d389 +size 183882 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 new file mode 100644 index 0000000000..f7fb461a63 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d07761ac69d93cd40592ff78566079be0c9c0e566b8606be1939f96440262f9 +size 180551 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 new file mode 100644 index 0000000000..30cee8ca0b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ed5ce625e3cd20ad173b96ef67ca3c274e4310d55794502a5e23235d580f775 +size 180934 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 new file mode 100644 index 0000000000..9f6fec05f0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d3d87bd05c47e9e150d92287499503af0c148ba015d46b080ad6dd3e575554f +size 179035 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png deleted file mode 100644 index 0e5502a30c..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a0635fa0f0ca2b150f598279fee291f25203c6313f8d5fe449e4c1629c96637a -size 8528 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png deleted file mode 100644 index 11f2b08dc7..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1f8fe5034ae0b5bb611df443e7c1054f3f5e61e608894b14b79aba287eb6fa47 -size 11643 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png deleted file mode 100644 index 11f2b08dc7..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1f8fe5034ae0b5bb611df443e7c1054f3f5e61e608894b14b79aba287eb6fa47 -size 11643 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png deleted file mode 100644 index bb5b9d07ee..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:66242e5546b6f853a2d78493ece0bca7065c036246cd88d83301887b9edc362e -size 8628 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png deleted file mode 100644 index 27f54811e1..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f3d1e3d3d5212df16af61a9ec5a8904fe71bfff4bbfe5086f08e6a2dbc9e58b -size 11823 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png deleted file mode 100644 index 27f54811e1..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f3d1e3d3d5212df16af61a9ec5a8904fe71bfff4bbfe5086f08e6a2dbc9e58b -size 11823 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png deleted file mode 100644 index c0eccb5941..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0a22271c3970f9ddf514b271d1ac012c07dadef134470c95eea58c645e02f173 -size 68699 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png deleted file mode 100644 index fa1880b64b..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1da0dcdb96fe88591d97b6f38b2f4b11b095af981340c1d87a805b866182574c -size 68171 From 28b63745f4796a40d93c24a94510a2d3c2976528 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 14 Jan 2026 11:56:45 +0100 Subject: [PATCH 344/347] When a duplicate room list entry is found, report it and remove it (#6006) * When a duplicate room list entry is found, report it and remove it * Fix tests and fixtures * Simplify how the updates are described in the Sentry reports --- .../impl/datasource/RoomListDataSource.kt | 18 +++++++-- .../impl/roomlist/RoomListStateProvider.kt | 2 +- .../impl/datasource/RoomListDataSourceTest.kt | 2 + .../impl/roomlist/RoomListPresenterTest.kt | 1 + .../libraries/matrix/impl/RustMatrixClient.kt | 1 + .../matrix/impl/roomlist/RoomListFactory.kt | 2 +- .../impl/roomlist/RoomSummaryListProcessor.kt | 37 ++++++++++++++----- .../matrix/impl/spaces/RustSpaceRoomList.kt | 5 ++- .../matrix/impl/spaces/RustSpaceService.kt | 6 ++- .../impl/spaces/SpaceListUpdateProcessor.kt | 34 +++++++++++++++-- .../roomlist/RoomSummaryListProcessorTest.kt | 8 ++-- .../spaces/RoomSummaryListProcessorTest.kt | 12 ++++-- .../impl/spaces/RustSpaceRoomListTest.kt | 2 + .../android/libraries/matrix/test/TestData.kt | 1 + .../sentry/SentryAnalyticsProvider.kt | 1 + 15 files changed, 105 insertions(+), 27 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListDataSource.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListDataSource.kt index ef5d1ffcc6..c17923fb04 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListDataSource.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListDataSource.kt @@ -19,6 +19,7 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomSummary +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope @@ -31,7 +32,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext -import timber.log.Timber +import java.lang.IllegalStateException import kotlin.time.Duration.Companion.seconds @Inject @@ -43,6 +44,7 @@ class RoomListDataSource( @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, private val dateTimeObserver: DateTimeObserver, + private val analyticsService: AnalyticsService, ) { init { observeNotificationSettings() @@ -139,10 +141,18 @@ class RoomListDataSource( // TODO remove once https://github.com/element-hq/element-x-android/issues/5031 has been confirmed as fixed val duplicates = cachingResults.filter { (_, operations) -> operations.size > 1 } if (duplicates.isNotEmpty()) { - Timber.e("Found duplicates in room summaries after an UI update: $duplicates. This could be a race condition/caching issue of some kind") - } + analyticsService.trackError( + IllegalStateException( + "Found duplicates in room summaries after a local UI update: $duplicates. " + + "This could be a race condition/caching issue of some kind" + ) + ) - _allRooms.emit(roomListRoomSummaries.toImmutableList()) + // Remove duplicates before emitting the new values + _allRooms.emit(roomListRoomSummaries.distinctBy { it.roomId }.toImmutableList()) + } else { + _allRooms.emit(roomListRoomSummaries.toImmutableList()) + } } private fun buildAndCacheItem(roomSummaries: List, index: Int): RoomListRoomSummary? { diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListStateProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListStateProvider.kt index 188f4468de..7f58e05c7e 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListStateProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListStateProvider.kt @@ -91,7 +91,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList { timestamp = "14:18", latestEvent = LatestEvent.Synced("A very very very very long message which suites on two lines"), avatarData = AvatarData("!id", "R", size = AvatarSize.RoomListItem), - id = "!roomId:domain", + id = "!roomId5:domain", ), aRoomListRoomSummary( name = "Room#2", diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListDataSourceTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListDataSourceTest.kt index 35c30af86e..aaecd90c56 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListDataSourceTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListDataSourceTest.kt @@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService import io.element.android.libraries.matrix.test.room.aRoomSummary import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService +import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest @@ -103,5 +104,6 @@ class RoomListDataSourceTest { notificationSettingsService = notificationSettingsService, sessionCoroutineScope = backgroundScope, dateTimeObserver = dateTimeObserver, + analyticsService = FakeAnalyticsService(), ) } diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt index acc68db018..a97c189947 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt @@ -662,6 +662,7 @@ class RoomListPresenterTest { notificationSettingsService = client.notificationSettingsService, sessionCoroutineScope = backgroundScope, dateTimeObserver = FakeDateTimeObserver(), + analyticsService = FakeAnalyticsService(), ), searchPresenter = searchPresenter, sessionPreferencesStore = sessionPreferencesStore, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index b4f39d2693..f17f92517a 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -203,6 +203,7 @@ class RustMatrixClient( roomMembershipObserver = roomMembershipObserver, sessionCoroutineScope = sessionCoroutineScope, sessionDispatcher = sessionDispatcher, + analyticsService = analyticsService, ) override val sessionVerificationService = RustSessionVerificationService( diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt index b15411c382..fa3f4a8acf 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt @@ -56,7 +56,7 @@ internal class RoomListFactory( val loadingStateFlow: MutableStateFlow = MutableStateFlow(RoomList.LoadingState.NotLoaded) val filteredSummariesFlow = MutableSharedFlow>(replay = 1, extraBufferCapacity = 1) val summariesFlow = MutableSharedFlow>(replay = 1, extraBufferCapacity = 1) - val processor = RoomSummaryListProcessor(summariesFlow, innerRoomListService, coroutineContext, roomSummaryFactory) + val processor = RoomSummaryListProcessor(summariesFlow, innerRoomListService, coroutineContext, roomSummaryFactory, analyticsService) // Makes sure we don't miss any events val dynamicEvents = MutableSharedFlow(replay = 100) val currentFilter = MutableStateFlow(initialFilter) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt index 3f5a919139..968a768fa2 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.matrix.impl.roomlist import io.element.android.libraries.matrix.api.roomlist.RoomSummary +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock @@ -18,6 +19,7 @@ import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate import org.matrix.rustcomponents.sdk.RoomListServiceInterface import org.matrix.rustcomponents.sdk.use import timber.log.Timber +import kotlin.collections.groupingBy import kotlin.coroutines.CoroutineContext class RoomSummaryListProcessor( @@ -25,26 +27,21 @@ class RoomSummaryListProcessor( private val roomListService: RoomListServiceInterface, private val coroutineContext: CoroutineContext, private val roomSummaryFactory: RoomSummaryFactory, + private val analyticsService: AnalyticsService, ) { private val mutex = Mutex() suspend fun postUpdate(updates: List) { - updateRoomSummaries { + updateRoomSummaries(updates) { Timber.v("Update rooms from postUpdates (with ${updates.size} items) on ${Thread.currentThread()}") updates.forEach { update -> applyUpdate(update) } - - // TODO remove once https://github.com/element-hq/element-x-android/issues/5031 has been confirmed as fixed - val duplicates = groupingBy { it.roomId }.eachCount().filter { it.value > 1 } - if (duplicates.isNotEmpty()) { - Timber.e("Found duplicates in room summaries after a list update from the SDK: $duplicates. Updates: $updates") - } } } suspend fun rebuildRoomSummaries() { - updateRoomSummaries { + updateRoomSummaries(emptyList()) { forEachIndexed { i, summary -> val result = buildRoomSummaryForIdentifier(summary.roomId.value) if (result != null) { @@ -112,12 +109,32 @@ class RoomSummaryListProcessor( } } - private suspend fun updateRoomSummaries(block: suspend MutableList.() -> Unit) = withContext(coroutineContext) { + private suspend fun updateRoomSummaries(updates: List, block: suspend MutableList.() -> Unit) = withContext( + coroutineContext + ) { mutex.withLock { val current = roomSummaries.replayCache.lastOrNull() val mutableRoomSummaries = current.orEmpty().toMutableList() block(mutableRoomSummaries) - roomSummaries.emit(mutableRoomSummaries) + + // TODO remove once https://github.com/element-hq/element-x-android/issues/5031 has been confirmed as fixed + val uniqueRooms = mutableRoomSummaries.distinctBy { it.roomId } + + if (uniqueRooms.size != mutableRoomSummaries.size) { + val duplicates = mutableRoomSummaries.groupingBy { it.roomId }.eachCount().filter { it.value > 1 } + if (duplicates.isNotEmpty()) { + analyticsService.trackError( + IllegalStateException( + "Found duplicates in room summaries after a list update from the SDK: $duplicates. " + + "Updates: ${updates.description()}" + ) + ) + } + } + + roomSummaries.emit(uniqueRooms) } } } + +private fun List.description(): String = joinToString { it.describe() } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomList.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomList.kt index c6fe86700e..80652bee71 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomList.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomList.kt @@ -12,6 +12,7 @@ import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoomList +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -32,6 +33,7 @@ class RustSpaceRoomList( private val innerProvider: suspend () -> InnerSpaceRoomList, private val coroutineScope: CoroutineScope, spaceRoomMapper: SpaceRoomMapper, + private val analyticsService: AnalyticsService, ) : SpaceRoomList { private val innerCompletable = CompletableDeferred() @@ -43,7 +45,8 @@ class RustSpaceRoomList( MutableStateFlow(SpaceRoomList.PaginationStatus.Idle(hasMoreToLoad = false)) private val spaceListUpdateProcessor = SpaceListUpdateProcessor( spaceRoomsFlow = spaceRoomsFlow, - mapper = spaceRoomMapper + mapper = spaceRoomMapper, + analyticsService = analyticsService, ) init { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt index fad698c731..95eaefb671 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceService.kt @@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.spaces.SpaceRoom import io.element.android.libraries.matrix.api.spaces.SpaceRoomList import io.element.android.libraries.matrix.api.spaces.SpaceService import io.element.android.libraries.matrix.impl.util.cancelAndDestroy +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.Channel @@ -41,12 +42,14 @@ class RustSpaceService( private val sessionCoroutineScope: CoroutineScope, private val sessionDispatcher: CoroutineDispatcher, private val roomMembershipObserver: RoomMembershipObserver, + private val analyticsService: AnalyticsService, ) : SpaceService { private val spaceRoomMapper = SpaceRoomMapper() override val spaceRoomsFlow = MutableSharedFlow>(replay = 1, extraBufferCapacity = 1) private val spaceListUpdateProcessor = SpaceListUpdateProcessor( spaceRoomsFlow = spaceRoomsFlow, - mapper = spaceRoomMapper + mapper = spaceRoomMapper, + analyticsService = analyticsService, ) override suspend fun joinedSpaces(): Result> = withContext(sessionDispatcher) { @@ -80,6 +83,7 @@ class RustSpaceService( innerProvider = { innerSpaceService.spaceRoomList(id.value) }, coroutineScope = childCoroutineScope, spaceRoomMapper = spaceRoomMapper, + analyticsService = analyticsService, ) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/SpaceListUpdateProcessor.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/SpaceListUpdateProcessor.kt index 41f2cc1266..c9763dffa8 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/SpaceListUpdateProcessor.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/spaces/SpaceListUpdateProcessor.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.matrix.impl.spaces import io.element.android.libraries.matrix.api.spaces.SpaceRoom +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.sync.Mutex @@ -19,17 +20,18 @@ import timber.log.Timber internal class SpaceListUpdateProcessor( private val spaceRoomsFlow: MutableSharedFlow>, private val mapper: SpaceRoomMapper, + private val analyticsService: AnalyticsService, ) { private val mutex = Mutex() suspend fun postUpdates(updates: List) { Timber.v("Update space rooms from postUpdates (with ${updates.size} items) on ${Thread.currentThread()}") - updateSpaceRooms { + updateSpaceRooms(updates) { updates.forEach { update -> applyUpdate(update) } } } - private suspend fun updateSpaceRooms(block: MutableList.() -> Unit) = + private suspend fun updateSpaceRooms(updates: List, block: MutableList.() -> Unit) = mutex.withLock { val spaceRooms = if (spaceRoomsFlow.replayCache.isNotEmpty()) { spaceRoomsFlow.first().toMutableList() @@ -37,7 +39,17 @@ internal class SpaceListUpdateProcessor( mutableListOf() } block(spaceRooms) - spaceRoomsFlow.emit(spaceRooms) + val uniqueRooms = spaceRooms.distinctBy { it.roomId } + + // TODO remove once https://github.com/element-hq/element-x-android/issues/5031 has been confirmed as fixed + if (spaceRooms.size != uniqueRooms.size) { + val duplicateKeys = spaceRooms.groupBy { it.roomId }.filter { it.value.size > 1 }.keys + analyticsService.trackError( + IllegalStateException("Found duplicate keys in space rooms list ($duplicateKeys) after SDK updates: ${updates.description()}") + ) + } + + spaceRoomsFlow.emit(uniqueRooms) } private fun MutableList.applyUpdate(update: SpaceListUpdate) { @@ -83,3 +95,19 @@ internal class SpaceListUpdateProcessor( } } } + +private fun List.description(): String = joinToString { it.description() } + +private fun SpaceListUpdate.description(): String = when (this) { + is SpaceListUpdate.Append -> "Append(${values.map { it.roomId }})" + SpaceListUpdate.Clear -> "Clear" + is SpaceListUpdate.Insert -> "Insert($index, ${value.roomId})" + SpaceListUpdate.PopBack -> "PopBack" + SpaceListUpdate.PopFront -> "PopFront" + is SpaceListUpdate.PushBack -> "PushBack(${value.roomId})" + is SpaceListUpdate.PushFront -> "PushFront(${value.roomId})" + is SpaceListUpdate.Remove -> "Remove($index)" + is SpaceListUpdate.Reset -> "Reset(${values.map { it.roomId }})" + is SpaceListUpdate.Set -> "Set($index, ${value.roomId})" + is SpaceListUpdate.Truncate -> "Truncate($length)" +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt index 022aa19ee7..6fac54b904 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt @@ -16,7 +16,9 @@ import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiRoomListSe import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_ID_2 import io.element.android.libraries.matrix.test.A_ROOM_ID_3 +import io.element.android.libraries.matrix.test.A_ROOM_ID_4 import io.element.android.libraries.matrix.test.room.aRoomSummary +import io.element.android.services.analytics.test.FakeAnalyticsService import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope @@ -33,11 +35,10 @@ class RoomSummaryListProcessorTest { summaries.value = listOf(aRoomSummary()) val processor = createProcessor() - val newEntry = aRustRoom(A_ROOM_ID_2) - processor.postUpdate(listOf(RoomListEntriesUpdate.Append(listOf(newEntry, newEntry, newEntry)))) + processor.postUpdate(listOf(RoomListEntriesUpdate.Append(listOf(aRustRoom(A_ROOM_ID_2), aRustRoom(A_ROOM_ID_3), aRustRoom(A_ROOM_ID_4))))) assertThat(summaries.value.count()).isEqualTo(4) - assertThat(summaries.value.subList(1, 4).all { it.roomId == A_ROOM_ID_2 }).isTrue() + assertThat(summaries.value.subList(1, 4).map { it.roomId }).isEqualTo(listOf(A_ROOM_ID_2, A_ROOM_ID_3, A_ROOM_ID_4)) } @Test @@ -182,5 +183,6 @@ class RoomSummaryListProcessorTest { FakeFfiRoomListService(), coroutineContext = StandardTestDispatcher(testScheduler), roomSummaryFactory = RoomSummaryFactory(), + analyticsService = FakeAnalyticsService(), ) } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt index d21e259d42..f23f0886d4 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RoomSummaryListProcessorTest.kt @@ -14,7 +14,9 @@ import io.element.android.libraries.matrix.impl.fixtures.factories.aRustSpaceRoo import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_ID_2 import io.element.android.libraries.matrix.test.A_ROOM_ID_3 +import io.element.android.libraries.matrix.test.A_ROOM_ID_4 import io.element.android.libraries.previewutils.room.aSpaceRoom +import io.element.android.services.analytics.test.FakeAnalyticsService import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest @@ -29,11 +31,14 @@ class RoomSummaryListProcessorTest { spaceRoomsFlow.value = listOf(aSpaceRoom()) val processor = createProcessor() - val newEntry = aRustSpaceRoom(roomId = A_ROOM_ID_2) - processor.postUpdates(listOf(SpaceListUpdate.Append(listOf(newEntry, newEntry, newEntry)))) + processor.postUpdates( + listOf( + SpaceListUpdate.Append(listOf(aRustSpaceRoom(roomId = A_ROOM_ID_2), aRustSpaceRoom(roomId = A_ROOM_ID_3), aRustSpaceRoom(roomId = A_ROOM_ID_4))) + ) + ) assertThat(spaceRoomsFlow.value.count()).isEqualTo(4) - assertThat(spaceRoomsFlow.value.subList(1, 4).all { it.roomId == A_ROOM_ID_2 }).isTrue() + assertThat(spaceRoomsFlow.value.subList(1, 4).map { it.roomId }).isEqualTo(listOf(A_ROOM_ID_2, A_ROOM_ID_3, A_ROOM_ID_4)) } @Test @@ -186,5 +191,6 @@ class RoomSummaryListProcessorTest { ) = SpaceListUpdateProcessor( spaceRoomsFlow = spaceRoomsFlow, mapper = SpaceRoomMapper(), + analyticsService = FakeAnalyticsService(), ) } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt index e966309c87..08f9407b93 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/spaces/RustSpaceRoomListTest.kt @@ -18,6 +18,7 @@ import io.element.android.libraries.matrix.impl.fixtures.factories.aRustSpaceRoo import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiSpaceRoomList import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_ID_2 +import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.lambda.lambdaRecorder import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope @@ -97,6 +98,7 @@ class RustSpaceRoomListTest { innerProvider = innerProvider, coroutineScope = backgroundScope, spaceRoomMapper = spaceRoomMapper, + analyticsService = FakeAnalyticsService(), ) } } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt index dcacadd975..c41ce0fe3e 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/TestData.kt @@ -46,6 +46,7 @@ val A_SPACE_ID_2 = SpaceId("!aSpaceId2:domain") val A_ROOM_ID = RoomId("!aRoomId:domain") val A_ROOM_ID_2 = RoomId("!aRoomId2:domain") val A_ROOM_ID_3 = RoomId("!aRoomId3:domain") +val A_ROOM_ID_4 = RoomId("!aRoomId4:domain") val A_THREAD_ID = ThreadId("\$aThreadId") val A_THREAD_ID_2 = ThreadId("\$aThreadId2") val AN_EVENT_ID = EventId("\$anEventId") diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index f3e3f0c9e1..ef2d4e21d9 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -109,6 +109,7 @@ class SentryAnalyticsProvider( } override fun trackError(throwable: Throwable) { + Timber.e(throwable, "Sending error to Sentry") Sentry.captureException(throwable) } From d01a511903f6be78a8e7ea13b6bbbcf3080ed6a7 Mon Sep 17 00:00:00 2001 From: ElementBot <110224175+ElementBot@users.noreply.github.com> Date: Wed, 14 Jan 2026 12:43:57 +0100 Subject: [PATCH 345/347] Sync Strings from Localazy (#5994) Co-authored-by: jmartinesp <480955+jmartinesp@users.noreply.github.com> --- .../src/main/res/values-be/translations.xml | 4 +- .../src/main/res/values-bg/translations.xml | 5 +- .../src/main/res/values-cs/translations.xml | 3 +- .../src/main/res/values-cy/translations.xml | 3 +- .../src/main/res/values-da/translations.xml | 4 +- .../src/main/res/values-de/translations.xml | 23 +- .../src/main/res/values-el/translations.xml | 5 +- .../src/main/res/values-es/translations.xml | 5 +- .../src/main/res/values-et/translations.xml | 3 +- .../src/main/res/values-eu/translations.xml | 3 +- .../src/main/res/values-fa/translations.xml | 4 +- .../src/main/res/values-fi/translations.xml | 3 +- .../src/main/res/values-fr/translations.xml | 23 +- .../src/main/res/values-hr/translations.xml | 4 +- .../src/main/res/values-hu/translations.xml | 3 +- .../src/main/res/values-in/translations.xml | 3 +- .../src/main/res/values-it/translations.xml | 3 +- .../src/main/res/values-ka/translations.xml | 2 +- .../src/main/res/values-ko/translations.xml | 5 +- .../src/main/res/values-lt/translations.xml | 1 - .../src/main/res/values-nb/translations.xml | 3 +- .../src/main/res/values-nl/translations.xml | 3 +- .../src/main/res/values-pl/translations.xml | 3 +- .../main/res/values-pt-rBR/translations.xml | 14 +- .../src/main/res/values-pt/translations.xml | 3 +- .../src/main/res/values-ro/translations.xml | 3 +- .../src/main/res/values-ru/translations.xml | 3 +- .../src/main/res/values-sk/translations.xml | 3 +- .../src/main/res/values-sv/translations.xml | 3 +- .../src/main/res/values-tr/translations.xml | 3 +- .../src/main/res/values-uk/translations.xml | 5 +- .../src/main/res/values-ur/translations.xml | 2 - .../src/main/res/values-uz/translations.xml | 5 +- .../main/res/values-zh-rTW/translations.xml | 5 +- .../src/main/res/values-zh/translations.xml | 5 +- .../src/main/res/values-cs/translations.xml | 19 + .../src/main/res/values-de/translations.xml | 19 + .../src/main/res/values-fr/translations.xml | 18 +- .../main/res/values-pt-rBR/translations.xml | 3 + .../src/main/res/values-cs/translations.xml | 2 + .../src/main/res/values-de/translations.xml | 2 + .../src/main/res/values-fr/translations.xml | 20 +- .../main/res/values-pt-rBR/translations.xml | 2 + .../src/main/res/values-de/translations.xml | 33 +- .../src/main/res/values-be/translations.xml | 3 - .../src/main/res/values-bg/translations.xml | 2 - .../src/main/res/values-cs/translations.xml | 16 +- .../src/main/res/values-cy/translations.xml | 1 - .../src/main/res/values-da/translations.xml | 3 - .../src/main/res/values-de/translations.xml | 63 +- .../src/main/res/values-el/translations.xml | 1 - .../src/main/res/values-es/translations.xml | 3 - .../src/main/res/values-et/translations.xml | 6 +- .../src/main/res/values-eu/translations.xml | 2 - .../src/main/res/values-fa/translations.xml | 1 - .../src/main/res/values-fi/translations.xml | 3 +- .../src/main/res/values-fr/translations.xml | 2 +- .../src/main/res/values-hr/translations.xml | 4 +- .../src/main/res/values-hu/translations.xml | 3 +- .../src/main/res/values-in/translations.xml | 3 - .../src/main/res/values-it/translations.xml | 1 - .../src/main/res/values-ka/translations.xml | 1 - .../src/main/res/values-ko/translations.xml | 3 - .../src/main/res/values-lt/translations.xml | 1 - .../src/main/res/values-nb/translations.xml | 3 - .../src/main/res/values-nl/translations.xml | 3 - .../src/main/res/values-pl/translations.xml | 3 +- .../main/res/values-pt-rBR/translations.xml | 8 +- .../src/main/res/values-pt/translations.xml | 3 +- .../src/main/res/values-ro/translations.xml | 4 +- .../src/main/res/values-ru/translations.xml | 5 +- .../src/main/res/values-sk/translations.xml | 1 - .../src/main/res/values-sv/translations.xml | 1 - .../src/main/res/values-tr/translations.xml | 3 +- .../src/main/res/values-uk/translations.xml | 5 +- .../src/main/res/values-ur/translations.xml | 1 - .../src/main/res/values-uz/translations.xml | 3 - .../main/res/values-zh-rTW/translations.xml | 1 - .../src/main/res/values-zh/translations.xml | 1 - .../src/main/res/values-de/translations.xml | 2 + .../src/main/res/values-be/translations.xml | 5 - .../src/main/res/values-bg/translations.xml | 1 - .../src/main/res/values-cs/translations.xml | 19 +- .../src/main/res/values-da/translations.xml | 2 - .../src/main/res/values-de/translations.xml | 38 +- .../src/main/res/values-es/translations.xml | 2 - .../src/main/res/values-et/translations.xml | 4 +- .../src/main/res/values-eu/translations.xml | 1 - .../src/main/res/values-fi/translations.xml | 2 +- .../src/main/res/values-hr/translations.xml | 2 - .../src/main/res/values-hu/translations.xml | 2 +- .../src/main/res/values-in/translations.xml | 2 - .../src/main/res/values-ko/translations.xml | 2 - .../src/main/res/values-nb/translations.xml | 2 - .../src/main/res/values-nl/translations.xml | 5 - .../src/main/res/values-pl/translations.xml | 2 +- .../main/res/values-pt-rBR/translations.xml | 6 +- .../src/main/res/values-pt/translations.xml | 2 +- .../src/main/res/values-ro/translations.xml | 2 - .../src/main/res/values-ru/translations.xml | 4 +- .../src/main/res/values-tr/translations.xml | 2 +- .../src/main/res/values-uk/translations.xml | 4 +- .../src/main/res/values-uz/translations.xml | 2 - .../src/main/res/values-cs/translations.xml | 4 +- .../src/main/res/values-de/translations.xml | 3 + .../src/main/res/values-cs/translations.xml | 7 + .../src/main/res/values-da/translations.xml | 1 + .../src/main/res/values-de/translations.xml | 24 +- .../src/main/res/values-et/translations.xml | 1 + .../src/main/res/values-fi/translations.xml | 1 + .../src/main/res/values-fr/translations.xml | 8 + .../src/main/res/values-hr/translations.xml | 1 + .../src/main/res/values-hu/translations.xml | 1 + .../src/main/res/values-it/translations.xml | 1 + .../main/res/values-pt-rBR/translations.xml | 5 + .../src/main/res/values-ro/translations.xml | 1 + .../src/main/res/values-ru/translations.xml | 1 + .../src/main/res/values-sk/translations.xml | 1 + .../main/res/values-zh-rTW/translations.xml | 1 + .../src/main/res/values/localazy.xml | 8 + ...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 | 3 + ...figureroom_ConfigureRoomViewLight_0_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_1_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_2_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_3_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_4_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_5_de.png | 4 +- ...figureroom_ConfigureRoomViewLight_6_de.png | 3 + ...pl.components_RoomSummaryRow_Day_37_de.png | 3 + ...me.impl.spaces_HomeSpacesView_Day_2_de.png | 3 + .../features.home.impl_HomeView_Day_0_de.png | 4 +- .../features.home.impl_HomeView_Day_10_de.png | 4 +- .../features.home.impl_HomeView_Day_13_de.png | 4 +- .../features.home.impl_HomeView_Day_14_de.png | 4 +- .../features.home.impl_HomeView_Day_15_de.png | 4 +- .../features.home.impl_HomeView_Day_1_de.png | 4 +- .../features.home.impl_HomeView_Day_2_de.png | 4 +- .../features.home.impl_HomeView_Day_4_de.png | 4 +- .../features.home.impl_HomeView_Day_5_de.png | 4 +- .../features.home.impl_HomeView_Day_9_de.png | 4 +- ...ens.desktop_DesktopNoticeView_Day_0_de.png | 4 +- ....impl.screens.error_ErrorView_Day_4_de.png | 4 +- ...creens.number_EnterNumberView_Day_0_de.png | 4 +- ...creens.number_EnterNumberView_Day_1_de.png | 4 +- ...creens.number_EnterNumberView_Day_2_de.png | 4 +- ...creens.number_EnterNumberView_Day_3_de.png | 4 +- ...creens.number_EnterNumberView_Day_4_de.png | 4 +- ...creens.number_EnterNumberView_Day_5_de.png | 4 +- ...screens.qrcode_ShowQrCodeView_Day_0_de.png | 4 +- ...ns.root_LinkNewDeviceRootView_Day_0_de.png | 4 +- ...ns.root_LinkNewDeviceRootView_Day_1_de.png | 3 + ...ns.root_LinkNewDeviceRootView_Day_2_de.png | 4 +- ...ns.root_LinkNewDeviceRootView_Day_3_de.png | 4 +- ...ns.root_LinkNewDeviceRootView_Day_4_de.png | 3 + ...ns.root_LinkNewDeviceRootView_Day_5_de.png | 4 +- ...sible_HistoryVisibleStateView_Day_0_de.png | 4 +- ...essagesViewWithHistoryVisible_Day_0_de.png | 4 +- ...es.impl.timeline_TimelineView_Day_8_de.png | 3 - ...s.messages.impl_MessagesView_Day_11_de.png | 4 +- ...impl.root_PreferencesRootViewDark_0_de.png | 4 +- ...impl.root_PreferencesRootViewDark_1_de.png | 4 +- ...mpl.root_PreferencesRootViewLight_0_de.png | 4 +- ...mpl.root_PreferencesRootViewLight_1_de.png | 4 +- ...itprofile_EditUserProfileView_Day_0_de.png | 4 +- ...itprofile_EditUserProfileView_Day_1_de.png | 4 +- ...itprofile_EditUserProfileView_Day_2_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_0_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_1_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_2_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_3_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_4_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_5_de.png | 4 +- ...ons_ChangeRoomPermissionsView_Day_6_de.png | 4 +- ...s.impl.roles_ChangeRolesView_Day_10_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_1_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_2_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_3_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_4_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_6_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_7_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_8_de.png | 4 +- ...ns.impl.roles_ChangeRolesView_Day_9_de.png | 4 +- ..._PendingMemberRowWithLongName_Day_0_de.png | 3 + ....root_RolesAndPermissionsView_Day_0_de.png | 4 +- ....root_RolesAndPermissionsView_Day_1_de.png | 4 +- ....root_RolesAndPermissionsView_Day_3_de.png | 4 +- ....root_RolesAndPermissionsView_Day_6_de.png | 4 +- ....root_RolesAndPermissionsView_Day_7_de.png | 4 +- ....root_RolesAndPermissionsView_Day_8_de.png | 4 +- ...pl.members_RoomMemberListView_Day_2_de.png | 4 +- ...pl.members_RoomMemberListView_Day_3_de.png | 4 +- ...pl.members_RoomMemberListView_Day_4_de.png | 4 +- ...pl.members_RoomMemberListView_Day_5_de.png | 4 +- ...pl.members_RoomMemberListView_Day_6_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 +- ...omaddress_EditRoomAddressView_Day_0_de.png | 4 +- ...omaddress_EditRoomAddressView_Day_1_de.png | 4 +- ...omaddress_EditRoomAddressView_Day_2_de.png | 4 +- ...omaddress_EditRoomAddressView_Day_3_de.png | 4 +- ...omaddress_EditRoomAddressView_Day_4_de.png | 4 +- ...es_ManageAuthorizedSpacesView_Day_0_de.png | 3 + ...es_ManageAuthorizedSpacesView_Day_1_de.png | 3 + ...es_ManageAuthorizedSpacesView_Day_2_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_0_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_10_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_11_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_12_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_13_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_14_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_15_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_16_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_17_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_18_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_19_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_1_de.png | 4 +- ....root_SecurityAndPrivacyViewDark_20_de.png | 3 + ....root_SecurityAndPrivacyViewDark_21_de.png | 3 + ....root_SecurityAndPrivacyViewDark_22_de.png | 3 + ....root_SecurityAndPrivacyViewDark_23_de.png | 3 + ...l.root_SecurityAndPrivacyViewDark_2_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_3_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_4_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_5_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_6_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_7_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_8_de.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_9_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_0_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_10_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_11_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_12_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_13_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_14_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_15_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_16_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_17_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_18_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_19_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_1_de.png | 4 +- ...root_SecurityAndPrivacyViewLight_20_de.png | 3 + ...root_SecurityAndPrivacyViewLight_21_de.png | 3 + ...root_SecurityAndPrivacyViewLight_22_de.png | 3 + ...root_SecurityAndPrivacyViewLight_23_de.png | 3 + ....root_SecurityAndPrivacyViewLight_2_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_3_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_4_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_5_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_6_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_7_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_8_de.png | 4 +- ....root_SecurityAndPrivacyViewLight_9_de.png | 4 +- ...ace.impl.leave_LeaveSpaceView_Day_9_de.png | 4 +- ...ming_IncomingVerificationView_Day_0_de.png | 4 +- ...ing_IncomingVerificationView_Day_10_de.png | 4 +- ...ing_IncomingVerificationView_Day_11_de.png | 4 +- ...ming_IncomingVerificationView_Day_1_de.png | 4 +- ...ming_IncomingVerificationView_Day_2_de.png | 4 +- ...ming_IncomingVerificationView_Day_3_de.png | 4 +- ...ming_IncomingVerificationView_Day_4_de.png | 4 +- ...ming_IncomingVerificationView_Day_7_de.png | 4 +- ...ming_IncomingVerificationView_Day_8_de.png | 4 +- ...ing_OutgoingVerificationView_Day_10_de.png | 4 +- ...ing_OutgoingVerificationView_Day_11_de.png | 4 +- ...oing_OutgoingVerificationView_Day_1_de.png | 4 +- ...oing_OutgoingVerificationView_Day_2_de.png | 4 +- ...oing_OutgoingVerificationView_Day_3_de.png | 4 +- ...oing_OutgoingVerificationView_Day_6_de.png | 4 +- ...impl.gallery_MediaGalleryView_Day_7_de.png | 4 +- ...TextComposerVoiceNotEncrypted_Day_0_de.png | 4 +- screenshots/html/data.js | 1989 +++++++++-------- 285 files changed, 1745 insertions(+), 1522 deletions(-) delete mode 100644 features/securityandprivacy/impl/src/main/res/values-be/translations.xml delete mode 100644 features/securityandprivacy/impl/src/main/res/values-nl/translations.xml create mode 100644 screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_de.png create mode 100644 screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_de.png create mode 100644 screenshots/de/features.home.impl.components_RoomSummaryRow_Day_37_de.png create mode 100644 screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_2_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_de.png create mode 100644 screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_de.png delete mode 100644 screenshots/de/features.messages.impl.timeline_TimelineView_Day_8_de.png create mode 100644 screenshots/de/features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_de.png create mode 100644 screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_de.png diff --git a/features/createroom/impl/src/main/res/values-be/translations.xml b/features/createroom/impl/src/main/res/values-be/translations.xml index 23d70a3b3d..4cc6aee822 100644 --- a/features/createroom/impl/src/main/res/values-be/translations.xml +++ b/features/createroom/impl/src/main/res/values-be/translations.xml @@ -4,10 +4,10 @@ "Запрасіць карыстальнікаў" "Пры стварэнні пакоя адбылася памылка" "Толькі запрошаныя людзі могуць атрымаць доступ да гэтага пакоя. Усе паведамленні абаронены end-to-end шыфраваннем." - "Прыватны пакой" "Любы можа знайсці гэты пакой. Вы можаце змяніць гэта ў любы час у наладах пакоя." - "Публічны пакой" + "Публічны пакой (для ўсіх)" "Папрасіце далучыцца" + "Хто заўгодна" "Тэма (неабавязкова)" diff --git a/features/createroom/impl/src/main/res/values-bg/translations.xml b/features/createroom/impl/src/main/res/values-bg/translations.xml index 83fb24e691..4c6bfed0e4 100644 --- a/features/createroom/impl/src/main/res/values-bg/translations.xml +++ b/features/createroom/impl/src/main/res/values-bg/translations.xml @@ -4,10 +4,11 @@ "Поканване на хора" "Възникна грешка при създаването на стаята" "Само поканени хора имат достъп до тази стая. Всички съобщения са шифровани от край до край." - "Частна стая" "Всеки може да намери тази стая. Можете да промените това по всяко време в настройките на стаята." - "Общодостъпна стая" + "Публична стая (всеки)" + "Всеки може да се присъедини към тази стая" + "Всеки" "За да бъде тази стая видима в директорията на общодостъпните стаи, ще ви е необходим адрес на стаята." "Видимост на стаята" "Тема за разговор (незадължително)" diff --git a/features/createroom/impl/src/main/res/values-cs/translations.xml b/features/createroom/impl/src/main/res/values-cs/translations.xml index af95081f1d..39f9d573e0 100644 --- a/features/createroom/impl/src/main/res/values-cs/translations.xml +++ b/features/createroom/impl/src/main/res/values-cs/translations.xml @@ -4,12 +4,13 @@ "Pozvat přátele" "Při vytváření místnosti došlo k chybě" "Do této místnosti mají přístup pouze pozvaní lidé. Všechny zprávy jsou koncově šifrovány." - "Soukromá místnost" "Tuto místnost může najít kdokoli. To můžete kdykoli změnit v nastavení místnosti." "Veřejná místnost" "Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout" "Požádat o připojení" + "Do této místnosti může vstoupit kdokoli" + "Kdokoliv" "Aby byla tato místnost viditelná v adresáři veřejných místností, budete potřebovat adresu místnosti." "Adresa místnosti" "Viditelnost místnosti" diff --git a/features/createroom/impl/src/main/res/values-cy/translations.xml b/features/createroom/impl/src/main/res/values-cy/translations.xml index 741022659c..9ac9e5e3bc 100644 --- a/features/createroom/impl/src/main/res/values-cy/translations.xml +++ b/features/createroom/impl/src/main/res/values-cy/translations.xml @@ -4,12 +4,13 @@ "Gwahodd pobl" "Bu gwall wrth greu\'r ystafell" "Dim ond pobl wahoddwyd all gael mynediad i\'r ystafell hon. Mae pob neges wedi\'i hamgryptio o\'r dechrau i\'r diwedd." - "Ystafell breifat" "Gall unrhyw un ddod o hyd i\'r ystafell hon. Gallwch newid hyn unrhyw bryd yng ngosodiadau ystafell." "Ystafell gyhoeddus" "Gall unrhyw un ofyn am gael ymuno â\'r ystafell ond bydd rhaid i weinyddwr neu gymedrolwr dderbyn y cais" "Gofyn i gael ymuno" + "Gall unrhyw un ymuno â\'r ystafell hon" + "Unrhyw un" "Er mwyn i\'r ystafell hon fod yn weladwy yn y cyfeiriadur ystafelloedd cyhoeddus, bydd angen cyfeiriad ystafell arnoch." "Cyfeiriad yr ystafell" "Gwelededd yr ystafell" diff --git a/features/createroom/impl/src/main/res/values-da/translations.xml b/features/createroom/impl/src/main/res/values-da/translations.xml index 45261f2a29..13d8b01b62 100644 --- a/features/createroom/impl/src/main/res/values-da/translations.xml +++ b/features/createroom/impl/src/main/res/values-da/translations.xml @@ -4,12 +4,12 @@ "Invitér andre" "Der opstod en fejl ved oprettelsen af rummet" "Kun inviterede personer kan få adgang til dette rum. Alle meddelelser er ende-til-ende krypteret." - "Privat rum" "Alle kan finde dette rum. Du kan ændre dette når som helst i rummets indstillinger." - "Offentligt rum" "Alle kan bede om at deltage i rummet, men en administrator eller en moderator skal acceptere anmodningen" "Spørg om at deltage" + "Alle kan deltage i dette rum" + "Enhver" "Hvis dette rum skal være synligt i det offentlige register, skal du bruge en rum-adresse." "Rummets adresse" "Rummets synlighed" diff --git a/features/createroom/impl/src/main/res/values-de/translations.xml b/features/createroom/impl/src/main/res/values-de/translations.xml index 692a2c921e..55d7a0b66e 100644 --- a/features/createroom/impl/src/main/res/values-de/translations.xml +++ b/features/createroom/impl/src/main/res/values-de/translations.xml @@ -3,15 +3,26 @@ "Neuer Chat" "Nutzer einladen" "Beim Erstellen des Chats ist ein Fehler aufgetreten" - "Nur eingeladene Personen haben Zutritt zu diesem Chat. Alle Nachrichten sind Ende-zu-Ende verschlüsselt." - "Privater Chat" + "Der Space konnte wegen eines unbekannten Fehlers nicht erstellt werden. Versuch\' es später nochmal." + "Name hinzufügen…" + "Neuer Chat" + "Neuer Space" + "Nur eingeladene Personen haben Zutritt zu diesem Chat." + "Privat" "Jeder kann diesen Chat finden. Du kannst dies jederzeit in den Einstellungen des Chats ändern." - "Öffentlicher Chat" + "Jeder kann beitreten." + "Öffentlicher Chatroom" "Jeder kann den Beitritt zum Chat erbitten, aber ein Admin oder Moderator muss die Anfrage akzeptieren." - "Beitritt beantragen" - "Du benötigst eine Chat-Adresse, damit dieser Chat im öffentlichen Verzeichnis sichtbar ist." - "Chatroom Adresse" + "Anfrage zum Beitritt zulassen" + "Nur eingeladene Personen können beitreten." + "Privat" + "Jeder darf diesem Chat beitreten." + "Jeder" + "Wer hat Zugang" + "Du benötigst eine Adresse, um diesen Chat im öffentlichen Verzeichnis sichtbar zu machen." + "Adresse" " Sichtbarkeit des Chats" "Thema (optional)" + "Beschreibung hinzufügen…" diff --git a/features/createroom/impl/src/main/res/values-el/translations.xml b/features/createroom/impl/src/main/res/values-el/translations.xml index a8c500df94..3b1c94c443 100644 --- a/features/createroom/impl/src/main/res/values-el/translations.xml +++ b/features/createroom/impl/src/main/res/values-el/translations.xml @@ -4,12 +4,13 @@ "Πρόσκληση ατόμων" "Προέκυψε σφάλμα κατά τη δημιουργία της αίθουσας" "Μόνο τα άτομα που έχουν προσκληθεί μπορούν να έχουν πρόσβαση σε αυτή την αίθουσα. Όλα τα μηνύματα είναι κρυπτογραφημένα από άκρο σε άκρο." - "Ιδιωτική αίθουσα" "Ο καθένας μπορεί να βρει αυτή την αίθουσα. Αυτό μπορείτε να το αλλάξετε ανά πάσα στιγμή στις ρυθμίσεις της αίθουσας." - "Δημόσια αίθουσα" + "Δημόσιο δωμάτιο" "Οποιοσδήποτε μπορεί να ζητήσει να συμμετάσχει στην αίθουσα, αλλά ένας διαχειριστής ή ένας συντονιστής θα πρέπει να αποδεχτεί το αίτημα" "Αίτημα συμμετοχής" + "Οποιοσδήποτε μπορεί να συμμετάσχει σε αυτή την αίθουσα" + "Οποιοσδήποτε" "Για να είναι ορατή αυτή η αίθουσα στον δημόσιο κατάλογο αιθουσών, θα χρειαστείτε μια διεύθυνση αίθουσας." "Διεύθυνση δωματίου" "Ορατότητα αίθουσας" diff --git a/features/createroom/impl/src/main/res/values-es/translations.xml b/features/createroom/impl/src/main/res/values-es/translations.xml index fcf2996398..34362f537d 100644 --- a/features/createroom/impl/src/main/res/values-es/translations.xml +++ b/features/createroom/impl/src/main/res/values-es/translations.xml @@ -4,12 +4,13 @@ "Invitar personas" "Se ha producido un error al crear la sala" "Solo las personas invitadas pueden acceder a esta sala. Todos los mensajes están cifrados de extremo a extremo." - "Sala privada" "Cualquiera puede encontrar esta sala. Puedes cambiar esto en cualquier momento en los ajustes de la sala." - "Sala pública" + "Sala pública (cualquiera)" "Cualquiera puede solicitar unirse a la sala, pero un administrador o un moderador tendrá que aceptar la solicitud" "Solicitud para unirse" + "Cualquiera puede unirse a esta sala" + "Cualquiera" "Para que esta sala sea visible en el directorio de salas públicas, necesitarás una dirección de sala." "Visibilidad de la sala" "Tema (opcional)" diff --git a/features/createroom/impl/src/main/res/values-et/translations.xml b/features/createroom/impl/src/main/res/values-et/translations.xml index c81caebede..0527302e0e 100644 --- a/features/createroom/impl/src/main/res/values-et/translations.xml +++ b/features/createroom/impl/src/main/res/values-et/translations.xml @@ -4,12 +4,13 @@ "Kutsu osalejaid" "Jututoa loomisel tekkis viga" "Ligipääs siia jututuppa on vaid kutse alusel. Kõik sõnumid siin jututoas on läbivalt krüptitud." - "Privaatne jututuba" "Kõik saavad seda jututuba leida. Sa võid seda jututoa seadistustest alati muuta." "Avalik jututuba" "Kõik võivad paluda selle jututoaga liitumist, kuid peakasutaja või moderaator peavad selle kinnitama" "Küsi võimalust liitumiseks" + "Kõik võivad selle jututoaga liituda" + "Kõik kasutajad" "Selleks, et see jututuba oleks nähtav jututubade avalikus kataloogis, sa vajad jututoa aadressi." "Jututoa aadress" "Jututoa nähtavus" diff --git a/features/createroom/impl/src/main/res/values-eu/translations.xml b/features/createroom/impl/src/main/res/values-eu/translations.xml index f4b6d405b7..7e4fefe08f 100644 --- a/features/createroom/impl/src/main/res/values-eu/translations.xml +++ b/features/createroom/impl/src/main/res/values-eu/translations.xml @@ -4,10 +4,11 @@ "Gonbidatu jendea" "Errorea gertatu da gela sortzean" "Gonbidatutako jendea soilik sar daiteke gelara. Mezu guztiak daude ertzetik ertzera zifratuta." - "Gela pribatua" "Edonork aurki dezake gela hau. Gelaren ezarpenetan aldatu dezakezu hobespena." "Gela publikoa" + "Edonor sar daiteke gela honetara" + "Edonork" "Gelaren helbidea" "Gelaren ikusgarritasuna" "Mintzagaia (aukerakoa)" diff --git a/features/createroom/impl/src/main/res/values-fa/translations.xml b/features/createroom/impl/src/main/res/values-fa/translations.xml index dad5298a0f..499b0a24ad 100644 --- a/features/createroom/impl/src/main/res/values-fa/translations.xml +++ b/features/createroom/impl/src/main/res/values-fa/translations.xml @@ -7,8 +7,10 @@ "اتاق خصوصی" "هرکسی می‌تواند اتاق را بیابد. می‌توانید بعداً در تظیمات اتاق عوضش کنید." - "اتاق عمومی" + "اتاق عمومی (هرکسی)" "درخواست دعوت" + "هرکسی می‌تواند به این اتاق بپیوندد" + "هرکسی" "نشانی اتاق" "نمایانی اتاق" "موضوع (اختیاری)" diff --git a/features/createroom/impl/src/main/res/values-fi/translations.xml b/features/createroom/impl/src/main/res/values-fi/translations.xml index 3b120947cc..e436983989 100644 --- a/features/createroom/impl/src/main/res/values-fi/translations.xml +++ b/features/createroom/impl/src/main/res/values-fi/translations.xml @@ -4,12 +4,13 @@ "Kutsu henkilöitä" "Huoneen luomisessa tapahtui virhe" "Vain kutsutut henkilöt pääsevät tähän huoneeseen. Kaikki viestit ovat päästä päähän salattuja." - "Yksityinen huone" "Kuka tahansa voi löytää tämän huoneen. Voit muuttaa tämän milloin tahansa huoneen asetuksista." "Julkinen huone" "Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö" "Pyydä liittymistä" + "Kuka tahansa voi liittyä tähän huoneeseen" + "Kuka tahansa" "Jotta tämä huone näkyisi julkisessa huonehakemistossa, tarvitset huoneen osoitteen." "Huoneen osoite" "Huoneen näkyvyys" diff --git a/features/createroom/impl/src/main/res/values-fr/translations.xml b/features/createroom/impl/src/main/res/values-fr/translations.xml index d500902949..72b5314893 100644 --- a/features/createroom/impl/src/main/res/values-fr/translations.xml +++ b/features/createroom/impl/src/main/res/values-fr/translations.xml @@ -3,15 +3,26 @@ "Nouveau salon" "Inviter des amis" "Une erreur s’est produite lors de la création du salon" - "Seules les personnes invitées peuvent accéder à ce salon. Tous les messages sont chiffrés de bout en bout." - "Salon privé" + "L’espace n’a pas pu être créé à cause d’une erreur inconnue. Réessayez plus tard." + "Ajouter un nom…" + "Nouveau salon" + "Nouvel espace" + "Seules les personnes invitées peuvent joindre." + "Privé" "N’importe qui peut trouver ce salon. Vous pouvez modifier cela à tout moment dans les paramètres du salon." + "Tout le monde peut joindre" "Salon public" - "Tout le monde peut demander à rejoindre le salon, mais un administrateur ou un modérateur devra accepter la demande" - "Demander à rejoindre" - "Pour que ce salon soit visible dans le répertoire des salons publics, vous aurez besoin d’une adresse de salon." - "Adresse du salon" + "Tout le monde peut demander à joindre, mais un administrateur ou un modérateur devra accepter la demande" + "Autoriser la demande à joindre" + "Seules les personnes invitées peuvent joindre." + "Privé" + "Tout le monde peut joindre" + "Tout le monde" + "Qui a accès" + "Vous aurez besoin d’une adresse pour qu’il soit visible dans le répertoire public." + "Adresse" "Visibilité du salon" "Sujet (facultatif)" + "Ajouter une description…" diff --git a/features/createroom/impl/src/main/res/values-hr/translations.xml b/features/createroom/impl/src/main/res/values-hr/translations.xml index 510bd68659..1a23597ff4 100644 --- a/features/createroom/impl/src/main/res/values-hr/translations.xml +++ b/features/createroom/impl/src/main/res/values-hr/translations.xml @@ -4,12 +4,12 @@ "Pozovi osobe" "Došlo je do pogreške prilikom stvaranja sobe" "Samo pozvane osobe mogu pristupiti ovoj sobi. Sve su poruke sveobuhvatno šifrirane." - "Privatna soba" "Svatko može pronaći ovu sobu. To možete u svakom trenutku promijeniti u postavkama sobe." - "Javna soba" "Svatko može zatražiti pridruživanje sobi, ali administrator ili moderator morat će prihvatiti zahtjev." "Zatraži pridruživanje" + "Svatko se može pridružiti ovoj sobi" + "Svatko" "Da bi ova soba bila vidljiva u javnom direktoriju soba, trebat će vam adresa sobe." "Adresa sobe" "Vidljivost sobe" diff --git a/features/createroom/impl/src/main/res/values-hu/translations.xml b/features/createroom/impl/src/main/res/values-hu/translations.xml index bfa1205b05..2e80833b2e 100644 --- a/features/createroom/impl/src/main/res/values-hu/translations.xml +++ b/features/createroom/impl/src/main/res/values-hu/translations.xml @@ -4,12 +4,13 @@ "Ismerősök meghívása" "Hiba történt a szoba létrehozásakor" "Csak a meghívottak léphetnek be ebbe a szobába. Az összes üzenet végpontok közti titkosítással van védve." - "Privát szoba" "Bárki megtalálhatja ezt a szobát. Ezt bármikor módosíthatja a szobabeállításokban." "Nyilvános szoba" "Bárki kérheti, hogy csatlakozzon a szobához, de egy adminisztrátornak vagy moderátornak el kell fogadnia a kérést" "Csatlakozás kérése" + "Bárki csatlakozhat ehhez a szobához" + "Bárki" "Ahhoz, hogy ez a szoba látható legyen a nyilvános szobák címtárában, meg kell adnia a szoba címét." "Szoba címe" "Szoba láthatósága" diff --git a/features/createroom/impl/src/main/res/values-in/translations.xml b/features/createroom/impl/src/main/res/values-in/translations.xml index 014fc8a628..20f23fd5c9 100644 --- a/features/createroom/impl/src/main/res/values-in/translations.xml +++ b/features/createroom/impl/src/main/res/values-in/translations.xml @@ -4,12 +4,13 @@ "Undang orang-orang" "Terjadi kesalahan saat membuat ruangan" "Hanya orang-orang yang diundang dapat mengakses ruangan ini. Semua pesan terenkripsi secara ujung ke ujung." - "Ruangan pribadi" "Siapa pun dapat mencari ruangan ini. Anda dapat mengubah ini kapan pun dalam pengaturan ruangan." "Ruangan publik" "Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut" "Minta untuk bergabung" + "Siapa pun dapat bergabung dengan ruangan ini" + "Siapa pun" "Supaya ruangan ini terlihat di direktori ruangan publik, Anda memerlukan alamat ruangan." "Alamat ruangan" "Keterlihatan ruangan" diff --git a/features/createroom/impl/src/main/res/values-it/translations.xml b/features/createroom/impl/src/main/res/values-it/translations.xml index 980fb5c660..03d4c140fc 100644 --- a/features/createroom/impl/src/main/res/values-it/translations.xml +++ b/features/createroom/impl/src/main/res/values-it/translations.xml @@ -4,12 +4,13 @@ "Invita persone" "Si è verificato un errore durante la creazione della stanza" "Solo le persone invitate possono accedere a questa stanza. Tutti i messaggi sono cifrati end-to-end." - "Stanza privata" "Chiunque può trovare questa stanza. Puoi modificarlo in qualsiasi momento nelle impostazioni della stanza." "Stanza pubblica" "Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta" "Chiedi di entrare" + "Chiunque può entrare in questa stanza" + "Chiunque" "Affinché questa stanza sia visibile nell\'elenco delle stanze pubbliche, è necessario un indirizzo della stanza." "Indirizzo della stanza" "Visibilità della stanza" diff --git a/features/createroom/impl/src/main/res/values-ka/translations.xml b/features/createroom/impl/src/main/res/values-ka/translations.xml index de1e33bd68..22fc67afce 100644 --- a/features/createroom/impl/src/main/res/values-ka/translations.xml +++ b/features/createroom/impl/src/main/res/values-ka/translations.xml @@ -4,8 +4,8 @@ "ხალხის მოწვევა" "ოთახის შექმნისას შეცდომა მოხდა" "ამ ოთახში შეტყობინებები დაშიფრულია. შემდგომ დაშიფვრის გამორთვა შეუძლებელია." - "კერძო ოთახი" "ყველას ამ ოთახის მოძებნა შეუძლია. თქვენ ნებისმიერ დროს შეგიძლიათ ამის შეცვლა ოთახის პარამეტრებში." + "საჯარო ოთახი" "თემა (სურვილისამებრ)" diff --git a/features/createroom/impl/src/main/res/values-ko/translations.xml b/features/createroom/impl/src/main/res/values-ko/translations.xml index e861333e9b..b1cd90bbf1 100644 --- a/features/createroom/impl/src/main/res/values-ko/translations.xml +++ b/features/createroom/impl/src/main/res/values-ko/translations.xml @@ -4,12 +4,13 @@ "사람 초대하기" "방을 생성하던 중 오류가 발생했어요" "초대받은 사람만 이 방에 액세스할 수 있습니다. 모든 메시지는 종단 간 암호화됩니다." - "비공개 방" "누구나 이 방을 찾을 수 있습니다. 방 설정에서 언제든지 변경할 수 있습니다." - "공개 방" + "공개 방 (모두)" "누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다." "참가 요청" + "누구나 이 방에 참여할 수 있습니다." + "누구나" "이 방이 공개 방 디렉토리에 표시되려면 방 주소가 필요합니다." "방 표시 여부" "주제 (선택)" diff --git a/features/createroom/impl/src/main/res/values-lt/translations.xml b/features/createroom/impl/src/main/res/values-lt/translations.xml index e392f57717..3d5566cb15 100644 --- a/features/createroom/impl/src/main/res/values-lt/translations.xml +++ b/features/createroom/impl/src/main/res/values-lt/translations.xml @@ -4,7 +4,6 @@ "Pakviesti žmonių" "Kuriant kambarį įvyko klaida" "Į šį kambarį gali patekti tik pakviesti žmonės. Visi pranešimai yra užšifruoti nuo pradžios iki galo." - "Privatus kambarys" "Bet kas gali rasti šį kambarį. Tai galite bet kada pakeisti kambario nustatymuose." "Tema (nebūtina)" diff --git a/features/createroom/impl/src/main/res/values-nb/translations.xml b/features/createroom/impl/src/main/res/values-nb/translations.xml index 14a8c53e52..e5ad63c84b 100644 --- a/features/createroom/impl/src/main/res/values-nb/translations.xml +++ b/features/createroom/impl/src/main/res/values-nb/translations.xml @@ -4,12 +4,13 @@ "Inviter folk" "Det oppsto en feil under opprettelsen av rommet" "Bare inviterte personer har tilgang til dette rommet. Alle meldinger er ende-til-ende-kryptert." - "Privat rom" "Alle kan finne dette rommet. Du kan endre dette når som helst i rominnstillingene." "Offentlig rom" "Alle kan be om å få bli med i rommet, men en administrator eller moderator må godta forespørselen" "Be om å bli med" + "Alle kan bli med i dette rommet" + "Alle" "For at dette rommet skal være synlig i den offentlige romkatalogen, trenger du en romadresse." "Romadresse" "Romsynlighet" diff --git a/features/createroom/impl/src/main/res/values-nl/translations.xml b/features/createroom/impl/src/main/res/values-nl/translations.xml index 8af8b11621..4691cb1f19 100644 --- a/features/createroom/impl/src/main/res/values-nl/translations.xml +++ b/features/createroom/impl/src/main/res/values-nl/translations.xml @@ -4,11 +4,12 @@ "Mensen uitnodigen" "Er is een fout opgetreden bij het aanmaken van de kamer" "Alleen uitgenodigde personen hebben toegang tot deze kamer. Alle berichten zijn end-to-end versleuteld." - "Privé kamer" "Iedereen kan deze kamer vinden. Je kunt dit op elk gewenst moment wijzigen in de kamerinstellingen." "Openbare kamer" "Iedereen kan vragen om toe te treden tot de kamer, maar een beheerder of moderator moet het verzoek accepteren" "Vraag om toe te treden" + "Iedereen kan toetreden tot deze kamer" + "Iedereen" "Onderwerp (optioneel)" diff --git a/features/createroom/impl/src/main/res/values-pl/translations.xml b/features/createroom/impl/src/main/res/values-pl/translations.xml index f79c2cbb32..325d40cf5b 100644 --- a/features/createroom/impl/src/main/res/values-pl/translations.xml +++ b/features/createroom/impl/src/main/res/values-pl/translations.xml @@ -4,12 +4,13 @@ "Zaproś znajomych" "Wystąpił błąd w trakcie tworzenia pokoju" "Tylko zaproszone osoby mogą dołączyć do tego pokoju. Wszystkie wiadomości są szyfrowane end-to-end." - "Pokój prywatny" "Każdy może znaleźć ten pokój. Możesz to zmienić w ustawieniach pokoju." "Pokój publiczny" "Każdy może poprosić o dołączenie do pokoju, ale administrator lub moderator będzie musiał zatwierdzić prośbę" "Poproś o dołączenie" + "Każdy może dołączyć do tego pokoju" + "Wszyscy" "Aby ten pokój był widoczny w katalogu pomieszczeń publicznych, będziesz potrzebował adres pokoju." "Adres pokoju" "Widoczność pomieszczenia" diff --git a/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml b/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml index becc333d0d..174f42db06 100644 --- a/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml @@ -3,13 +3,19 @@ "Nova sala" "Convidar pessoas" "Ocorreu um erro ao criar a sala" - "Apenas as pessoas convidadas podem entrar nesta sala. Todas as mensagens são criptografadas de ponta a ponta." - "Sala privada" + "O espaço não pôde ser criado por conta de um erro desconhecido. Tente novamente mais tarde." + "Novo espaço" + "Apenas pessoas convidadas podem entrar." + "Privada" "Qualquer um pode encontrar esta sala. Você pode mudar isso a qualquer momento nas configurações da sala." - "Sala pública" - "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá de aceitar a solicitação" + "Qualquer um pode entrar." + "Publica" + "Qualquer um pode pedir para entrar, mas um administrador ou moderador deve aceitar a solicitação" "Pedir para entrar" + "Qualquer um pode entrar." + "Qualquer pessoa" + "Quem tem acesso" "Para que esta sala fique visível no diretório público de salas, você precisará de um endereço de sala." "Endereço da sala" "Visibilidade da sala" diff --git a/features/createroom/impl/src/main/res/values-pt/translations.xml b/features/createroom/impl/src/main/res/values-pt/translations.xml index 942c39edf3..6225f531a5 100644 --- a/features/createroom/impl/src/main/res/values-pt/translations.xml +++ b/features/createroom/impl/src/main/res/values-pt/translations.xml @@ -4,12 +4,13 @@ "Convidar pessoas" "Ocorreu um erro ao criar a sala" "Apenas as pessoas convidadas podem aceder a esta sala. Todas as mensagens são cifradas ponta-a-ponta." - "Sala privada" "Qualquer um pode encontrar esta sala. Pode alterar esta opção nas definições da sala." "Sala pública" "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou um moderador terá de aceitar o pedido" "Pedir para participar" + "Qualquer pessoa pode entrar nesta sala" + "Qualquer pessoa" "Para que esta sala seja visível no diretório público de salas, precisas de um endereço de sala." "Endereço da sala" "Visibilidade da sala" diff --git a/features/createroom/impl/src/main/res/values-ro/translations.xml b/features/createroom/impl/src/main/res/values-ro/translations.xml index e4a3e0dba1..01ce6bfa38 100644 --- a/features/createroom/impl/src/main/res/values-ro/translations.xml +++ b/features/createroom/impl/src/main/res/values-ro/translations.xml @@ -4,12 +4,13 @@ "Invitați prieteni" "A apărut o eroare la crearea camerei" "Doar persoanele invitate pot accesa această cameră. Toate mesajele sunt criptate end-to-end." - "Cameră privată" "Oricine poate găsi această cameră. Puteți modifica acest lucru oricând în setări." "Cameră publică" "Oricine poate cere să se alăture camerei, dar un administrator sau un moderator va trebui să accepte cererea" "Cereți să vă alăturați" + "Oricine se poate alătura acestei camere" + "Oricine" "Pentru ca această cameră să fie vizibilă în directorul de camere publice, veți avea nevoie de o adresă de cameră." "Adresa camerei" "Vizibilitatea camerei" diff --git a/features/createroom/impl/src/main/res/values-ru/translations.xml b/features/createroom/impl/src/main/res/values-ru/translations.xml index 68cdad1ad4..4a009eaa10 100644 --- a/features/createroom/impl/src/main/res/values-ru/translations.xml +++ b/features/createroom/impl/src/main/res/values-ru/translations.xml @@ -4,12 +4,13 @@ "Пригласить в комнату" "Произошла ошибка при создании комнаты" "Доступ в эту комнату имеют только приглашенные пользователи. Все сообщения защищены сквозным шифрованием." - "Частная комната" "Любой желающий может найти эту комнату. Вы можете изменить это в любое время в настройках комнаты." "Общедоступная комната" "Любой желающий может подать заявку на присоединение к комнате, но администратор или модератор должен будет принять запрос." "Попросить присоединиться" + "Любой желающий может присоединиться к этой комнате" + "Любой" "Чтобы эта комната была видна в каталоге общедоступных, вам необходим ее адрес" "Адрес комнаты" "Видимость комнаты" diff --git a/features/createroom/impl/src/main/res/values-sk/translations.xml b/features/createroom/impl/src/main/res/values-sk/translations.xml index dacec52b33..555571fba9 100644 --- a/features/createroom/impl/src/main/res/values-sk/translations.xml +++ b/features/createroom/impl/src/main/res/values-sk/translations.xml @@ -4,12 +4,13 @@ "Pozvať ľudí" "Pri vytváraní miestnosti došlo k chybe" "Do tejto miestnosti majú prístup iba pozvaní ľudia. Všetky správy sú end-to-end šifrované." - "Súkromná miestnosť" "Túto miestnosť môže nájsť ktokoľvek. Môžete to kedykoľvek zmeniť v nastaveniach miestnosti." "Verejná miestnosť" "Ktokoľvek môže požiadať o pripojenie sa k miestnosti, ale administrátor alebo moderátor bude musieť žiadosť schváliť" "Požiadať o pripojenie" + "Do tejto miestnosti sa môže pripojiť ktokoľvek" + "Ktokoľvek" "Aby bola táto miestnosť viditeľná v adresári verejných miestností, budete potrebovať adresu miestnosti." "Adresa miestnosti" "Viditeľnosť miestnosti" diff --git a/features/createroom/impl/src/main/res/values-sv/translations.xml b/features/createroom/impl/src/main/res/values-sv/translations.xml index 3c0de1aa65..779bd893ea 100644 --- a/features/createroom/impl/src/main/res/values-sv/translations.xml +++ b/features/createroom/impl/src/main/res/values-sv/translations.xml @@ -4,12 +4,13 @@ "Bjud in personer" "Ett fel uppstod när rummet skapades" "Endast inbjudna personer har tillgång till detta rum. Alla meddelanden är totalsträckskrypterade." - "Privat rum" "Vem som helst kan hitta det här rummet. Du kan ändra detta när som helst i rumsinställningarna." "Offentligt rum" "Vem som helst kan be om att gå med i rummet men en administratör eller en moderator måste acceptera begäran" "Be om att gå med" + "Vem som helst kan gå med i det här rummet" + "Vem som helst" "För att detta rum ska vara synligt i den allmänna rumskatalogen behöver du en rumsadress." "Rumsadress" "Rumssynlighet" diff --git a/features/createroom/impl/src/main/res/values-tr/translations.xml b/features/createroom/impl/src/main/res/values-tr/translations.xml index b5a8f131a0..34406bb0fd 100644 --- a/features/createroom/impl/src/main/res/values-tr/translations.xml +++ b/features/createroom/impl/src/main/res/values-tr/translations.xml @@ -4,12 +4,13 @@ "İnsanları davet et" "Oda oluşturulurken bir hata oluştu" "Bu odaya yalnızca davet edilen kişiler erişebilir. Tüm mesajlar uçtan uca şifrelenir." - "Özel oda" "Bu odayı herkes bulabilir. Bunu istediğiniz zaman oda ayarlarından değiştirebilirsiniz." "Herkese açık oda" "Herkes odaya katılmayı isteyebilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekecektir" "Katılmak için sor" + "Bu odaya herkes katılabilir" + "Herkes" "Bu odanın genel oda dizininde görünür olması için bir oda adresine ihtiyacınız olacaktır." "Oda adresi" "Oda görünürlüğü" diff --git a/features/createroom/impl/src/main/res/values-uk/translations.xml b/features/createroom/impl/src/main/res/values-uk/translations.xml index e83359b89c..e665d5c2f3 100644 --- a/features/createroom/impl/src/main/res/values-uk/translations.xml +++ b/features/createroom/impl/src/main/res/values-uk/translations.xml @@ -4,12 +4,13 @@ "Запросити людей" "Під час створення кімнати сталася помилка" "Лише запрошені люди мають доступ до цієї кімнати. Усі повідомлення захищені наскрізним шифруванням." - "Приватна кімната (тільки за запрошенням)" "Будь-хто може знайти цю кімнату. Ви можете змінити це в будь-який час у налаштуваннях кімнати." - "Загальнодоступна кімната" + "Публічна кімната" "Будь-хто може попросити приєднатися до кімнати, але адміністратор або модератор повинен буде прийняти запит" "Запросити приєднатися" + "Будь-хто може приєднатися до цієї кімнати" + "Кожний" "Щоб цю кімнату було видно в каталозі загальнодоступних кімнат, вам знадобиться її адреса." "Адреса кімнати" "Видимість кімнати" diff --git a/features/createroom/impl/src/main/res/values-ur/translations.xml b/features/createroom/impl/src/main/res/values-ur/translations.xml index 1783963c67..ce1e23ffc9 100644 --- a/features/createroom/impl/src/main/res/values-ur/translations.xml +++ b/features/createroom/impl/src/main/res/values-ur/translations.xml @@ -4,9 +4,7 @@ "لوگوں کو مدعو کریں" "کمرہ تخلیق کرتے ہوئے ایک نقص واقع ہوا" "صرف مدعو لوگ ہی اس کمرے تک رسائی حاصل کر سکتے ہیں۔ تمام پیغامات آخر تا آخر مرموز کردہ ہیں۔" - "نجی کمرہ" "کوئی بھی یہ کمرہ ڈھونڈ سکتا ہے۔ آپ اسے کمرے کی ترتیبات میں کسی بھی وقت تبدیل کرسکتے ہیں۔" - "عوامی کمرہ" "موضوع (اختیاری)" diff --git a/features/createroom/impl/src/main/res/values-uz/translations.xml b/features/createroom/impl/src/main/res/values-uz/translations.xml index 665851ce02..46905b5f1d 100644 --- a/features/createroom/impl/src/main/res/values-uz/translations.xml +++ b/features/createroom/impl/src/main/res/values-uz/translations.xml @@ -4,12 +4,13 @@ "Odamlarni taklif qiling" "Xonani yaratishda xatolik yuz berdi" "Faqat taklif etilgan shaxslargina bu xonaga kira oladi. Barcha xabarlar boshdan-oxirigacha shifrlanadi." - "Shaxsiy xona" "Bu xonani har kim topishi mumkin. Buni xona sozlamalaridan istalgan vaqtda oʻzgartirishingiz mumkin." - "Jamoat xonasi" + "Jamoat xonasi (har kim)" "Xonaga qo‘shilishni istalgan kishi so‘rashi mumkin, lekin administrator yoki moderator so‘rovni qabul qilishi kerak" "Qo‘shilishni so‘rang" + "Bu xonaga istalgan kishi qo‘shilishi mumkin" + "Har kim" "Ushbu xona ommaviy xonalar ro‘yxatida ko‘rinishi uchun sizga xona manzili kerak bo‘ladi." "Xonaning ko‘rinishi" "Mavzu (ixtiyoriy)" diff --git a/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml b/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml index 065e05f321..595b06d55e 100644 --- a/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml @@ -4,12 +4,13 @@ "邀請夥伴" "建立聊天室時發生錯誤" "僅被邀請的人才能存取此聊天室。所有訊息均會端到端加密。" - "私密聊天室" "任何人都可以找到此聊天室。 您隨時都可以在聊天室設定中變更此設定。" - "公開的聊天室" + "公開聊天室" "任何人都可以要求加入聊天室,但管理員或版主必須接受該請求" "要求加入" + "任何人都可以加入此聊天室" + "任何人" "為了讓此聊天室在公開聊天室目錄中可見,您需要聊天室地址。" "聊天室地址" "聊天室能見度" diff --git a/features/createroom/impl/src/main/res/values-zh/translations.xml b/features/createroom/impl/src/main/res/values-zh/translations.xml index f17accb9fd..1a189884cf 100644 --- a/features/createroom/impl/src/main/res/values-zh/translations.xml +++ b/features/createroom/impl/src/main/res/values-zh/translations.xml @@ -4,12 +4,13 @@ "邀请朋友" "创建聊天室时出错" "只有受邀用户才能访问此聊天室。所有消息均经过端到端加密。" - "私有聊天室" "任何人都能找到此聊天室。 你可以随时在聊天室设置中更改。" - "公共聊天室" + "公开聊天室" "任何人都可以请求加入房间,但必须由管理员或审核人接受" "请求加入" + "任何人都可以加入此房间" + "任何人" "要使该房间在公开房间目录中可见,您需要一个房间地址。" "房间地址" "房间可见性" diff --git a/features/linknewdevice/impl/src/main/res/values-cs/translations.xml b/features/linknewdevice/impl/src/main/res/values-cs/translations.xml index de08f790e3..4b8f230d55 100644 --- a/features/linknewdevice/impl/src/main/res/values-cs/translations.xml +++ b/features/linknewdevice/impl/src/main/res/values-cs/translations.xml @@ -1,16 +1,33 @@ "Naskenujte QR kód" + "Otevřete %1$s na notebooku nebo stolním počítači" "Naskenujte QR kód pomocí tohoto zařízení" "Připraveno ke skenování" + "Otevřete %1$s na stolním počítači a získejte QR kód" + "Čísla se neshodují" + "Zadejte dvoumístný kód" + "Tím ověříte, zda je připojení k druhému zařízení bezpečné." + "Zadejte číslo zobrazené na druhém zařízení" "Váš poskytovatel účtu nepodporuje %1$s." "%1$s není podporováno" + "Poskytovatel vašeho účtu nepodporuje přihlašování do nového zařízení pomocí QR kódu." "QR kód není podporován" "Přihlášení bylo na druhém zařízení zrušeno." "Žádost o přihlášení zrušena" "Platnost přihlášení vypršela. Zkuste to prosím znovu." "Přihlášení nebylo dokončeno včas" + "Otevřete %1$s na druhém zařízení" "Vybrat %1$s" + "„Přihlásit se pomocí QR kódu“" + "Naskenujte zde zobrazený QR kód pomocí jiného zařízení" + "Otevřete %1$s na druhém zařízení" + "Stolní počítač" + "Načítání QR kódu…" + "Mobilní zařízení" + "Jaký typ zařízení chcete propojit?" + "Zkuste to prosím znovu a ujistěte se, že jste zadali dvoumístný kód správně. Pokud se čísla stále neshodují, kontaktujte poskytovatele účtu." + "Čísla se neshodují" "K novému zařízení se nepodařilo navázat bezpečné připojení. Vaše stávající zařízení jsou stále v bezpečí a nemusíte se o ně obávat." "Co teď?" "Zkuste se znovu přihlásit pomocí QR kódu v případě, že se jednalo o problém se sítí" @@ -21,6 +38,8 @@ "Žádost o přihlášení zrušena" "Přihlášení bylo na druhém zařízení odmítnuto." "Přihlášení odmítnuto" + "Nemusíte dělat nic jiného." + "Vaše další zařízení je již přihlášeno" "Platnost přihlášení vypršela. Zkuste to prosím znovu." "Přihlášení nebylo dokončeno včas" "Vaše druhé zařízení nepodporuje přihlášení k %su pomocí QR kódu. diff --git a/features/linknewdevice/impl/src/main/res/values-de/translations.xml b/features/linknewdevice/impl/src/main/res/values-de/translations.xml index 25343c93c2..b8ad8b80ef 100644 --- a/features/linknewdevice/impl/src/main/res/values-de/translations.xml +++ b/features/linknewdevice/impl/src/main/res/values-de/translations.xml @@ -1,16 +1,33 @@ "QR-Code scannen" + "Öffne %1$s auf einem Laptop oder Desktop-Computer" "Scanne den QR-Code mit diesem Gerät" "Bereit zum Scannen" + "Öffne %1$s auf einem Desktop-Computer, um den QR-Code zu erhalten" + "Die Zahlen stimmen nicht überein" + "Gib den 2-stelligen Code ein" + "Dadurch wird überprüft, ob die Verbindung zu deinem anderen Gerät sicher ist." + "Gib die Nummer ein, die auf deinem anderen Gerät angezeigt wird" "Dein Kontoanbieter unterstützt %1$s nicht." "%1$s wird nicht unterstützt" + "Dein Kontoanbieter unterstützt die Anmeldung auf einem neuen Gerät mit einem QR-Code nicht." "QR-Code wird nicht unterstützt" "Die Anmeldung wurde auf dem anderen Gerät abgebrochen." "Anmeldeanfrage abgebrochen" "Die Anmeldung ist abgelaufen. Bitte versuche es erneut." "Die Anmeldung wurde nicht rechtzeitig abgeschlossen" + "Öffne %1$s auf dem anderen Gerät" "Wähle %1$s" + "„Mit QR-Code anmelden”" + "Scanne den hier gezeigten QR-Code mit dem anderen Gerät." + "Öffne %1$s auf dem anderen Gerät" + "Desktop-Computer" + "QR-Code wird geladen…" + "Mobilgerät" + "Welchen Gerätetyp möchtest du verknüpfen?" + "Versuch\' es bitte noch mal und stell sicher, dass du den zweistelligen Code richtig eingegeben hast. Wenn die Zahlen immer noch nicht übereinstimmen, wende dich an deinen Kontoanbieter." + "Die Zahlen stimmen nicht überein" "Es konnte keine sichere Verbindung zu dem neuen Gerät hergestellt werden." "Und jetzt?" "Versuche, dich erneut mit einem QR-Code anzumelden, falls dies ein Netzwerkproblem war." @@ -21,6 +38,8 @@ "Anmeldeanfrage abgebrochen" "Die Anmeldung auf dem anderen Gerät wurde abgelehnt." "Anmelden abgelehnt" + "Du musst nichts weiter tun." + "Dein anderes Gerät ist schon angemeldet." "Die Anmeldung ist abgelaufen. Bitte versuche es erneut." "Die Anmeldung wurde nicht rechtzeitig abgeschlossen" "Dein anderes Gerät unterstützt die Anmeldung bei %s mit einem QR-Code nicht. diff --git a/features/linknewdevice/impl/src/main/res/values-fr/translations.xml b/features/linknewdevice/impl/src/main/res/values-fr/translations.xml index 2b6774dfd4..0c91dca7a1 100644 --- a/features/linknewdevice/impl/src/main/res/values-fr/translations.xml +++ b/features/linknewdevice/impl/src/main/res/values-fr/translations.xml @@ -1,8 +1,8 @@ - "Scannez le QR code" + "Scannez le code QR" "Ouvrir %1$s sur un ordinateur" - "Scanner le QR code avec cet appareil" + "Scanner le code QR avec cet appareil" "Prêt à scanner" "Ouvrir %1$s sur un ordinateur pour obtenir le code QR" "Les nombres ne correspondent pas" @@ -12,7 +12,7 @@ "Votre fournisseur de compte ne supporte pas %1$s." "%1$s n’est pas supporté" "Votre fournisseur de compte ne prend pas en charge la connexion à un nouvel appareil à l’aide d’un code QR." - "QR code non supporté" + "Code QR non supporté" "La connexion a été annulée sur l’autre appareil." "Demande de connexion annulée" "Connexion expirée. Veuillez essayer à nouveau." @@ -30,7 +30,7 @@ "Les nombres ne correspondent pas" "Aucune connexion sécurisée n’a pu être établie avec la nouvelle session. Vos sessions existantes sont toujours en sécurité et vous n’avez pas à vous en soucier." "Et maintenant ?" - "Essayez de vous connecter à nouveau à l’aide du QR code au cas où il s’agirait d’un problème réseau" + "Essayez de vous connecter à nouveau à l’aide du code QR au cas où il s’agirait d’un problème réseau" "Si vous rencontrez le même problème, essayez un autre réseau wifi ou utilisez vos données mobiles au lieu du wifi" "Si cela ne fonctionne pas, connectez-vous manuellement" "La connexion n’est pas sécurisée" @@ -42,14 +42,14 @@ "Votre autre appareil est déjà connecté" "Connexion expirée. Veuillez essayer à nouveau." "La connexion a pris trop de temps." - "Votre autre appareil ne supporte pas la connexion à %s avec un QR code. Essayer de vous connecter manuellement, ou scanner le QR code avec un autre appareil." - "QR code non supporté" + "Votre autre appareil ne supporte pas la connexion à %s avec un code QR. Essayer de vous connecter manuellement, ou scanner le code QR avec un autre appareil." + "Code QR non supporté" "Votre fournisseur de compte ne supporte pas %1$s." "%1$s n’est pas supporté" - "Scannez le QR code affiché sur l’autre appareil." + "Scannez le code QR affiché sur l’autre appareil." "Essayer à nouveau" - "QR code erroné" + "Code QR erroné" "Vous devez autoriser %1$s à utiliser la camera de votre appareil pour continuer." - "Autoriser l’usage de la caméra pour scanner le QR code" + "Autoriser l’usage de la caméra pour scanner le code QR" "Une erreur inattendue s’est produite. Veuillez réessayer." diff --git a/features/linknewdevice/impl/src/main/res/values-pt-rBR/translations.xml b/features/linknewdevice/impl/src/main/res/values-pt-rBR/translations.xml index 8fb178f3e5..f11bdc6e6d 100644 --- a/features/linknewdevice/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/linknewdevice/impl/src/main/res/values-pt-rBR/translations.xml @@ -26,6 +26,7 @@ "Carregando código QR…" "Dispositivo móvel" "Que tipo de dispositivo você deseja vincular?" + "Tente novamente e certifique-se que digitou o código de 2 dígitos corretamente. Se os números ainda não conferirem, entre em contato com o provedor da sua conta." "Os números não conferem" "Não foi possível estabelecer uma conexão segura com o novo dispositivo. Seus dispositivos existentes ainda estão seguros e você não precisa se preocupar com eles." "E agora?" @@ -37,6 +38,8 @@ "Solicitação de entrada foi cancelada" "A entrada foi recusada no outro dispositivo." "Entrada recusada" + "Você não precisa fazer mais nada." + "O seu outro dispositivo já está conectado" "O processo de entrada expirou. Tente novamente." "A entrada não foi concluída a tempo" "Seu outro dispositivo não tem suporte a entrar no %s com um código QR. diff --git a/features/login/impl/src/main/res/values-cs/translations.xml b/features/login/impl/src/main/res/values-cs/translations.xml index 6ffd9a84d4..73f0dd51cc 100644 --- a/features/login/impl/src/main/res/values-cs/translations.xml +++ b/features/login/impl/src/main/res/values-cs/translations.xml @@ -60,6 +60,8 @@ "Žádost o přihlášení zrušena" "Přihlášení bylo na druhém zařízení odmítnuto." "Přihlášení odmítnuto" + "Nemusíte dělat nic jiného." + "Vaše další zařízení je již přihlášeno" "Platnost přihlášení vypršela. Zkuste to prosím znovu." "Přihlášení nebylo dokončeno včas" "Vaše druhé zařízení nepodporuje přihlášení k %su pomocí QR kódu. diff --git a/features/login/impl/src/main/res/values-de/translations.xml b/features/login/impl/src/main/res/values-de/translations.xml index cb3459f62b..f1d426e134 100644 --- a/features/login/impl/src/main/res/values-de/translations.xml +++ b/features/login/impl/src/main/res/values-de/translations.xml @@ -60,6 +60,8 @@ "Anmeldeanfrage abgebrochen" "Die Anmeldung auf dem anderen Gerät wurde abgelehnt." "Anmelden abgelehnt" + "Du musst nichts weiter tun." + "Dein anderes Gerät ist schon angemeldet." "Die Anmeldung ist abgelaufen. Bitte versuche es erneut." "Die Anmeldung wurde nicht rechtzeitig abgeschlossen" "Dein anderes Gerät unterstützt die Anmeldung bei %s mit einem QR-Code nicht. diff --git a/features/login/impl/src/main/res/values-fr/translations.xml b/features/login/impl/src/main/res/values-fr/translations.xml index c58e00b521..9846feec38 100644 --- a/features/login/impl/src/main/res/values-fr/translations.xml +++ b/features/login/impl/src/main/res/values-fr/translations.xml @@ -40,7 +40,7 @@ "Version %1$s" "Se connecter manuellement" "Connectez-vous à %1$s" - "Se connecter avec un QR code" + "Se connecter avec un code QR" "Créer un compte" "Bienvenue dans l’application %1$s la plus rapide de tous les temps. Boosté pour plus de rapidité et de simplicité." "Bienvenue sur %1$s. Boosté, pour plus de rapidité et de simplicité." @@ -48,7 +48,7 @@ "Établissement d’une connexion sécurisée" "Aucune connexion sécurisée n’a pu être établie avec la nouvelle session. Vos sessions existantes sont toujours en sécurité et vous n’avez pas à vous en soucier." "Et maintenant ?" - "Essayez de vous connecter à nouveau à l’aide du QR code au cas où il s’agirait d’un problème réseau" + "Essayez de vous connecter à nouveau à l’aide du code QR au cas où il s’agirait d’un problème réseau" "Si vous rencontrez le même problème, essayez un autre réseau wifi ou utilisez vos données mobiles au lieu du wifi" "Si cela ne fonctionne pas, connectez-vous manuellement" "La connexion n’est pas sécurisée" @@ -64,8 +64,8 @@ "Votre autre appareil est déjà connecté" "Connexion expirée. Veuillez essayer à nouveau." "La connexion a pris trop de temps." - "Votre autre appareil ne supporte pas la connexion à %s avec un QR code. Essayer de vous connecter manuellement, ou scanner le QR code avec un autre appareil." - "QR code non supporté" + "Votre autre appareil ne supporte pas la connexion à %s avec un code QR. Essayer de vous connecter manuellement, ou scanner le code QR avec un autre appareil." + "Code QR non supporté" "Votre fournisseur de compte ne supporte pas %1$s." "%1$s n’est pas supporté" "Prêt à scanner" @@ -73,16 +73,16 @@ "Cliquez sur votre image de profil" "Choisissez %1$s" "“Associer une nouvelle session”" - "Scanner le QR code avec cet appareil" + "Scanner le code QR avec cet appareil" "Disponible uniquement si votre fournisseur de compte le supporte." - "Ouvrez %1$s sur un autre appareil pour obtenir le QR code" - "Scannez le QR code affiché sur l’autre appareil." + "Ouvrez %1$s sur un autre appareil pour obtenir le code QR" + "Scannez le code QR affiché sur l’autre appareil." "Essayer à nouveau" - "QR code erroné" + "Code QR erroné" "Accéder aux paramètres de l’appareil photo" "Vous devez autoriser %1$s à utiliser la camera de votre appareil pour continuer." - "Autoriser l’usage de la caméra pour scanner le QR code" - "Scannez le QR code" + "Autoriser l’usage de la caméra pour scanner le code QR" + "Scannez le code QR" "Recommencer" "Une erreur inattendue s’est produite. Veuillez réessayer." "En attente de votre autre session" diff --git a/features/login/impl/src/main/res/values-pt-rBR/translations.xml b/features/login/impl/src/main/res/values-pt-rBR/translations.xml index ce67264ae8..afca14d201 100644 --- a/features/login/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/login/impl/src/main/res/values-pt-rBR/translations.xml @@ -60,6 +60,8 @@ "Solicitação de entrada foi cancelada" "A entrada foi recusada no outro dispositivo." "Entrada recusada" + "Você não precisa fazer mais nada." + "O seu outro dispositivo já está conectado" "O processo de entrada expirou. Tente novamente." "A entrada não foi concluída a tempo" "Seu outro dispositivo não tem suporte a entrar no %s com um código QR. diff --git a/features/rolesandpermissions/impl/src/main/res/values-de/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-de/translations.xml index 2767781d2b..f51f96672b 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-de/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-de/translations.xml @@ -1,17 +1,23 @@ - "Nur Admins" + "Admin" "Mitglieder sperren" + "Einstellungen ändern" "Nachrichten entfernen" - "Personen einladen und Beitrittsanfragen annehmen" + "Mitglied" + "Mitglieder hinzufügen" + "Space konfigurieren" + "Chats und Gruppen konfigurieren" + "Mitglieder verwalten" "Nachrichten senden & löschen" - "Admins und Moderatoren" - "Personen entfernen und Beitrittsanfragen ablehnen" + "Moderator" + "Mitglieder entfernen" "Avatar ändern" "Chat bearbeiten" "Chat-Namen ändern" "Chat Thema ändern" "Nachrichten senden" + "Berechtigungen" "Admins bearbeiten" "Du kannst diese Aktion nicht mehr rückgängig machen. Du vergibst dieselbe Rolle, die du auch hast." "Als Admin hinzufügen?" @@ -32,6 +38,12 @@ "Du hast nicht gespeicherte Änderungen." "Änderungen speichern?" "Es gibt keine gesperrten Nutzer." + + "%1$d gesperrt" + "%1$d gesperrt" + + "Überprüfe die Schreibweise oder versuch\'s mit einer neuen Suche" + "Keine Ergebnisse für „%1$s“" "%1$d Person" "%1$d Personen" @@ -43,8 +55,13 @@ "Sperre für diesen Chat aufheben" "Gesperrt" "Mitglieder" - "Nur Admins" - "Admins und Moderatoren" + + "%1$d eingeladen" + "%1$d eingeladen" + + "Ausstehend" + "Admin" + "Moderator" "Eigentümer" "Mitglieder" "%1$s wird entsperrt." @@ -57,10 +74,12 @@ "Nachrichten senden & löschen" "Moderatoren" "Eigentümer" - "Rollen und Berechtigungen zurücksetzen" + "Berechtigungen" + "Berechtigungen zurücksetzen" "Sobald du die Berechtigungen zurücksetzt, verlierst du die aktuellen Einstellungen." "Berechtigungen zurücksetzen?" "Rollen" "Chat-Details anpassen" + "Details zum Space" "Rollen und Berechtigungen" diff --git a/features/roomdetails/impl/src/main/res/values-be/translations.xml b/features/roomdetails/impl/src/main/res/values-be/translations.xml index a986cd9789..9b89f2cef0 100644 --- a/features/roomdetails/impl/src/main/res/values-be/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-be/translations.xml @@ -51,7 +51,6 @@ "Замацаваныя паведамленні" "Профіль" "Ролі і дазволы" - "Назва пакоя" "Бяспека" "Падзяліцца пакоем" "Інфармацыя аб пакоі" @@ -100,6 +99,4 @@ "Ролі" "Дэталі пакоя" "Ролі і дазволы" - "Папрасіце далучыцца" - "Хто заўгодна" diff --git a/features/roomdetails/impl/src/main/res/values-bg/translations.xml b/features/roomdetails/impl/src/main/res/values-bg/translations.xml index 340f14a8f1..9273f7c38a 100644 --- a/features/roomdetails/impl/src/main/res/values-bg/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-bg/translations.xml @@ -42,7 +42,6 @@ "Закачени съобщения" "Профил" "Роли и разрешения" - "Име на стаята" "Защита и поверителност" "Защита" "Споделяне на стаята" @@ -86,7 +85,6 @@ "Шифроване" "Включване на шифроване от край до край" "Всеки може да намери и да се присъедини" - "Всеки" "Хората могат да се присъединят само ако са поканени" "Само с покана" "Достъп до стаята" diff --git a/features/roomdetails/impl/src/main/res/values-cs/translations.xml b/features/roomdetails/impl/src/main/res/values-cs/translations.xml index fc19bf400e..78a8a9f703 100644 --- a/features/roomdetails/impl/src/main/res/values-cs/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-cs/translations.xml @@ -63,7 +63,7 @@ "Profil" "Žádosti o vstup" "Role a oprávnění" - "Název místnosti" + "Název" "Zabezpečení a soukromí" "Zabezpečení" "Sdílet místnost" @@ -132,8 +132,10 @@ "Podrobnosti místnosti" "Role a oprávnění" "Přidat adresu" + "Připojit se může kdokoli v autorizovaných prostorách, ale všichni ostatní musí o přístup požádat." "Všichni musí požádat o přístup." - "Požádat o připojení" + "Požádat o vstup" + "Kdokoli v %1$s se může připojit, ale všichni ostatní musí o přístup požádat." "Ano, povolit šifrování" "Po aktivaci nelze šifrování místnosti deaktivovat. Historie zpráv bude viditelná pouze pro členy místnosti od doby, kdy byli pozváni nebo od té doby, co do místnosti vstoupili. Nikdo kromě členů místnosti nebude moci číst zprávy. To může bránit správnému fungování robotů a propojení. @@ -144,7 +146,8 @@ Nedoporučujeme povolovat šifrování pro místnosti, které může kdokoli naj "Povolit koncové šifrování" "Vstoupit může kdokoli." "Kdokoliv" - "Vyberte, kteří členové prostorů se k této místnosti mohou připojit bez pozvánky. %1$s" + "Vyberte, kteří členové prostorů mohou vstoupit do této místnosti bez pozvánky. %1$s" + "Spravovat prostory" "Vstoupit mohou pouze pozvaní lidé." "Pouze pro zvané" "Přístup" @@ -157,10 +160,11 @@ Nedoporučujeme povolovat šifrování pro místnosti, které může kdokoli naj "Umožněte nalezení této místnosti prohledáním adresáře veřejných místností na %1$s" "Umožnit nalezení vyhledáváním ve veřejném adresáři." "Viditelné ve veřejném adresáři" - "Kdokoliv" + "Kdokoli (historie je veřejná)" + "Změny neovlivní starší zprávy, pouze nové. %1$s" "Kdo může číst historii" - "Pouze členové od té doby, co byli pozváni" - "Pouze členové od výběru této možnosti" + "Členové od pozvání" + "Členové (úplná historie)" "Adresy místností představují způsoby, jak najít místnosti a získat k nim přístup. Díky tomu můžete svoji místnost snadno sdílet s ostatními. Můžete se rozhodnout publikovat svou místnost ve veřejném adresáři místnosti vašeho domovského serveru." "Publikování místnosti" diff --git a/features/roomdetails/impl/src/main/res/values-cy/translations.xml b/features/roomdetails/impl/src/main/res/values-cy/translations.xml index 97d39509fa..79de35224e 100644 --- a/features/roomdetails/impl/src/main/res/values-cy/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-cy/translations.xml @@ -63,7 +63,6 @@ "Proffil" "Ceisiadau i ymuno" "Rolau a chaniatâd" - "Enw\'r ystafell" "Diogelwch a phreifatrwydd" "Diogelwch" "Rhannu ystafell" diff --git a/features/roomdetails/impl/src/main/res/values-da/translations.xml b/features/roomdetails/impl/src/main/res/values-da/translations.xml index 9da1c66904..d646b03acb 100644 --- a/features/roomdetails/impl/src/main/res/values-da/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-da/translations.xml @@ -63,7 +63,6 @@ "Profil" "Anmodninger om at deltage" "Roller og tilladelser" - "Navn på rum" "Sikkerhed og privatliv" "Sikkerhed" "Del rum" @@ -130,7 +129,6 @@ "Roller og tilladelser" "Tilføj adresse" "Alle skal anmode om adgang." - "Spørg om at deltage" "Ja, aktivér kryptering" "Når det først er aktiveret, kan kryptering for et rum ikke deaktiveres igen. Beskedhistorik vil kun være synlig for rummedlemmer, siden de blev inviteret, eller siden de blev medlem af rummet. Ingen udover medlemmer af rummet vil være i stand til at læse beskeder. Dette kan forhindre bots og broer i at fungere korrekt. @@ -140,7 +138,6 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Kryptering" "Aktivér end-to-end-kryptering" "Alle kan være med." - "Enhver" "Kun inviterede personer kan deltage i dette rum." "Kun inviterede" "Adgang" diff --git a/features/roomdetails/impl/src/main/res/values-de/translations.xml b/features/roomdetails/impl/src/main/res/values-de/translations.xml index 89ef69c173..0cd1d187a3 100644 --- a/features/roomdetails/impl/src/main/res/values-de/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-de/translations.xml @@ -1,17 +1,19 @@ - "Du benötigst eine Chat-Adresse, um den Chat im Verzeichnis sichtbar zu machen." - "Chat-Adresse" + "Du benötigst eine Chat-Adresse, um den Chat im öffentlichen Verzeichnis sichtbar zu machen." + "Chat-Adresse bearbeiten" "Beim Aktualisieren der Benachrichtigungseinstellungen ist ein Fehler aufgetreten." "Dein Homeserver unterstützt diese Option in verschlüsselten Chats nicht. In einigen Chats erhältst du möglicherweise keine Benachrichtigungen." "Umfragen" - "Nur Admins" + "Admin" "Mitglieder sperren" "Nachrichten entfernen" - "Personen einladen und Beitrittsanfragen annehmen" + "Mitglied" + "Mitglieder hinzufügen" + "Mitglieder verwalten" "Nachrichten senden & löschen" - "Admins und Moderatoren" - "Personen entfernen und Beitrittsanfragen ablehnen" + "Moderator" + "Mitglieder entfernen" "Avatar ändern" "Chat bearbeiten" "Chat-Namen ändern" @@ -61,7 +63,7 @@ "Profil" "Beitrittsanfragen" "Rollen und Berechtigungen" - "Chat-Name" + "Name" "Sicherheit & Datenschutz" "Sicherheit" "Teilen" @@ -69,6 +71,12 @@ "Thema" "Chat wird aktualisiert…" "Es gibt keine gesperrten Nutzer." + + "%1$d gesperrt" + "%1$d gesperrt" + + "Überprüfe die Schreibweise oder versuch\'s mit einer neuen Suche" + "Keine Ergebnisse für „%1$s“" "%1$d Person" "%1$d Personen" @@ -80,8 +88,13 @@ "Sperre für diesen Chat aufheben" "Gesperrt" "Mitglieder" - "Nur Admins" - "Admins und Moderatoren" + + "%1$d eingeladen" + "%1$d eingeladen" + + "Ausstehend" + "Admin" + "Moderator" "Eigentümer" "Mitglieder" "%1$s wird entsperrt." @@ -108,15 +121,18 @@ "Nachrichten senden & löschen" "Moderatoren" "Eigentümer" - "Rollen und Berechtigungen zurücksetzen" + "Berechtigungen" + "Berechtigungen zurücksetzen" "Sobald du die Berechtigungen zurücksetzt, verlierst du die aktuellen Einstellungen." "Berechtigungen zurücksetzen?" "Rollen" "Chat-Details anpassen" "Rollen und Berechtigungen" "Chat-Adresse hinzufügen" - "Jeder kann den Beitritt zum Chat anfragen, aber ein Admin oder Moderator müssen die Anfrage akzeptieren." - "Beitritt beantragen" + "Jedes Mitglied eines autorisierten Space kann beitreten, aber alle anderen müssen einen Beitritt anfragen." + "Zugang nur auf Anfrage." + "Bitte um Beitritt" + "Jeder in %1$s kann beitreten, aber alle anderen müssen den Beitritt anfragen." "Ja, Verschlüsselung aktivieren" "Einmal angeschaltet kann die Verschlüsselung für einen Chat nicht mehr deaktiviert werden. Der Nachrichtenverlauf ist für Mitglieder nur sichtbar, seit sie eingeladen wurden oder dem Chat beigetreten sind. Niemand außer den Chat Mitgliedern kann Nachrichten lesen. Dies kann verhindern, dass Bots und Bridges richtig funktionieren. @@ -125,24 +141,31 @@ Wir empfehlen keine Verschlüsselung für Chats zu aktivieren, die jeder finden "Einmal angeschaltet kann die Verschlüsselung nicht mehr deaktiviert werden." "Verschlüsselung" "Ende-zu-Ende-Verschlüsselung aktivieren" - "Jeder kann diesen Chat finden und ihm beitreten" + "Jeder kann beitreten." "Jeder" - "Personen können nur beitreten, wenn sie eingeladen werden." + "Wähle aus, welche Spaces ihren Mitgliedern ermöglichen sollen, dieser Gruppe ohne Einladung beitreten zu können. %1$s" + "Spaces verwalten" + "Nur eingeladene Personen können beitreten" "Nur auf Einladung" - "Chat Zugang" + "Zugang" + "Jeder in autorisierten Spaces kann beitreten." + "Jeder in %1$s kann beitreten." "Spacemitglieder" "Spaces werden zur Zeit nicht unterstützt." - "Du benötigst eine Chat-Adresse, um den Chat im Verzeichnis sichtbar zu machen." - "Chatroomadresse" + "Du benötigst eine Chat-Adresse, um den Chat im öffentlichen Verzeichnis sichtbar zu machen." + "Adresse" "Erlaube das Auffinden dieses Chats durch Suche im öffentlichen Verzeichnis von %1$s" + "Lass dich über die Suche im öffentlichen Verzeichnis finden." "Sichtbar im öffentlichen Verzeichnis" - "Jeder" + "Jeder (Nachrichtenverlauf ist öffentlich)" + "Änderungen wirken sich nicht auf alte Nachrichten aus, sondern nur auf neue. %1$s" "Wer hat Zugriff auf den Nachrichtenverlauf" "Nur Mitglieder, aber erst seit deren Einladung" - "Nur Mitglieder seit Auswahl dieser Option" + "Mitglieder (voller Nachrichtenverlauf)" "Chat-Adressen machen es möglich, Chats zu finden und ihnen beizutreten. Dies erleichtert es, Chats mit anderen zu teilen. Auf Wunsch kannst du deinen Chat im öffentlichen Verzeichnis deines Homeservers veröffentlichen." "Veröffentlichung von Chats" - "Chatroomsichtbarkeit." + "Adressen ermöglichen es, Gruppen und Spaces zu finden und zu betreten. Dadurch wird auch sichergestellt, dass diese problemlos mit anderen geteilt werden können." + "Sichtbarkeit" "Sicherheit & Datenschutz" diff --git a/features/roomdetails/impl/src/main/res/values-el/translations.xml b/features/roomdetails/impl/src/main/res/values-el/translations.xml index 9f481e8d46..eeba5d5bf7 100644 --- a/features/roomdetails/impl/src/main/res/values-el/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-el/translations.xml @@ -55,7 +55,6 @@ "Προφίλ" "Αιτήματα συμμετοχής" "Ρόλοι και δικαιώματα" - "Όνομα αίθουσας" "Ασφάλεια & απόρρητο" "Ασφάλεια" "Κοινή χρήση αίθουσας" diff --git a/features/roomdetails/impl/src/main/res/values-es/translations.xml b/features/roomdetails/impl/src/main/res/values-es/translations.xml index 43a42bb274..bd3bfabc79 100644 --- a/features/roomdetails/impl/src/main/res/values-es/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-es/translations.xml @@ -55,7 +55,6 @@ "Perfil" "Solicitudes de unión" "Roles y permisos" - "Nombre de la sala" "Seguridad y privacidad" "Seguridad" "Compartir sala" @@ -107,7 +106,6 @@ "Roles y permisos" "Agregar dirección de sala" "Cualquiera puede solicitar unirse a la sala, pero un administrador o moderador tendrá que aceptar la solicitud." - "Solicitud para unirse" "Sí, activar cifrado" "Una vez activado, el cifrado de una sala no se puede desactivar. El historial de mensajes solo será visible para los miembros de la sala desde que fueron invitados o desde que se unieron a la sala. Nadie más que los miembros de la sala podrán leer los mensajes. Esto puede impedir que los bots y los puentes funcionen correctamente. @@ -117,7 +115,6 @@ No recomendamos habilitar el cifrado para las salas que cualquiera pueda encontr "Cifrado" "Activar el cifrado de extremo a extremo" "Cualquiera puede encontrarla y unirse" - "Cualquiera" "Las personas solo pueden unirse si están invitadas" "Solo por invitación" "Acceso a la sala" diff --git a/features/roomdetails/impl/src/main/res/values-et/translations.xml b/features/roomdetails/impl/src/main/res/values-et/translations.xml index 1c45e12cef..65e39cf045 100644 --- a/features/roomdetails/impl/src/main/res/values-et/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-et/translations.xml @@ -63,7 +63,7 @@ "Profiil" "Liitumispalved" "Rollid ja õigused" - "Jututoa nimi" + "Nimi" "Turvalisus ja privaatsus" "Turvalisus" "Jaga jututuba" @@ -131,7 +131,7 @@ "Lisa aadress" "Liituda saavad kõik volitatud kogukondade liikmed, kuid kõik teised peavad küsima võimalust ligipääsuks." "Kõik võivad paluda jututoaga liitumist." - "Küsi võimalust liitumiseks" + "Palu võimalust liituda" "Liituda saavad kõik „%1$s“ kogukonna liikmed, kuid kõik teised peavad küsima võimalust ligipääsuks." "Jah, lülita krüptimine sisse" "Kui jututoa krüptimine on kord sisse lülitatud, siis seda välja lülitada ei saa. Sõnumite ajalugu on nähtav vaid jututoa liikmetele alates kutse saamise või liitumise hetkest. @@ -142,7 +142,7 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Krüptimine" "Võta läbiv krüptimine kasutusele" "Kõik võivad jututoaga liituda" - "Kõik kasutajad" + "Avalik" "Vali kogukonnad, mille liikmed saavad selle jututoaga liituda ilma kutseta. %1$s" "Halda kogukondi" "Liituda saab vaid kutse olemasolul" diff --git a/features/roomdetails/impl/src/main/res/values-eu/translations.xml b/features/roomdetails/impl/src/main/res/values-eu/translations.xml index 95d6b17daf..8f90f44a8a 100644 --- a/features/roomdetails/impl/src/main/res/values-eu/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-eu/translations.xml @@ -53,7 +53,6 @@ "Profila" "Sartzeko eskaerak" "Rolak eta baimenak" - "Gelaren izena" "Segurtasuna eta pribatutasuna" "Segurtasuna" "Partekatu gela" @@ -104,7 +103,6 @@ "Bai, gaitu zifratzea" "Zifratzea" "Edonork aurkitu eta bat egin dezake" - "Edonork" "Gonbidatutako pertsonak bakarrik sartu ahal izango dira" "Gonbidapen bidez" "Gelarako sarbidea" diff --git a/features/roomdetails/impl/src/main/res/values-fa/translations.xml b/features/roomdetails/impl/src/main/res/values-fa/translations.xml index c04650417c..7ae439b983 100644 --- a/features/roomdetails/impl/src/main/res/values-fa/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fa/translations.xml @@ -61,7 +61,6 @@ "نمایه" "درخواست‌های پیوستن" "نقش‌ها و اجازه‌ها" - "نام اتاق" "امنیت و محرمانگی" "امنیت" "هم‌رسانی اتاق" diff --git a/features/roomdetails/impl/src/main/res/values-fi/translations.xml b/features/roomdetails/impl/src/main/res/values-fi/translations.xml index b696660b62..e6a7105027 100644 --- a/features/roomdetails/impl/src/main/res/values-fi/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fi/translations.xml @@ -63,7 +63,6 @@ "Profiili" "Liittymispyynnöt" "Roolit ja oikeudet" - "Huoneen nimi" "Turvallisuus ja yksityisyys" "Turvallisuus" "Jaa huone" @@ -143,7 +142,7 @@ Emme suosittele salauksen ottamista käyttöön huoneissa, jotka kuka tahansa vo "Kuka tahansa" "Kuka voi lukea viestihistoriaa" "Jäsenet vasta kutsusta lähtien" - "Jäsenet tämän vaihtoehdon valinnan jälkeen" + "Jäsenet (koko historia)" "Huoneosoitteet ovat tapoja löytää ja käyttää huoneita. Näin voit myös helposti jakaa huoneesi muiden kanssa. Voit halutessasi julkaista huoneesi kotipalvelimesi julkisessa huonehakemistossa." "Huoneen julkaiseminen" diff --git a/features/roomdetails/impl/src/main/res/values-fr/translations.xml b/features/roomdetails/impl/src/main/res/values-fr/translations.xml index 2feda357a1..3445cf4802 100644 --- a/features/roomdetails/impl/src/main/res/values-fr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fr/translations.xml @@ -63,7 +63,7 @@ "Profil" "Demandes en attente" "Rôles & autorisations" - "Nom du salon" + "Nom" "Sécurité & confidentialité" "Sécurité" "Partager le salon" diff --git a/features/roomdetails/impl/src/main/res/values-hr/translations.xml b/features/roomdetails/impl/src/main/res/values-hr/translations.xml index 0edf4dadbb..037b43be8a 100644 --- a/features/roomdetails/impl/src/main/res/values-hr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-hr/translations.xml @@ -63,7 +63,7 @@ "Profil" "Zahtjevi za pridruživanje" "Uloge i dopuštenja" - "Naziv sobe" + "Naziv" "Sigurnost i privatnost" "Sigurnost" "Podijeli sobu" @@ -134,7 +134,6 @@ "Dodaj adresu" "Svatko tko se nalazi u ovlaštenim prostorima može se pridružiti, ali svi ostali moraju zatražiti pristup." "Svi moraju zatražiti pristup." - "Zatraži pridruživanje" "Svatko u %1$s može se pridružiti, ali svi ostali moraju zatražiti pristup." "Da, omogući šifriranje" "Nakon što se šifriranje za sobu omogući, više se neće moći onemogućiti. Povijest poruka bit će vidljiva samo članovima sobe otkad su pozvani ili otkad su joj se pridružili. @@ -145,7 +144,6 @@ Ne preporučujemo omogućavanje šifriranja za sobe koje svatko može pronaći i "Šifriranje" "Omogući sveobuhvatno šifriranje" "Svatko se može pridružiti." - "Svatko" "Odaberite iz kojih se prostora članovi mogu pridružiti ovoj sobi bez pozivnice. %1$s" "Upravljaj prostorima" "Samo pozvane osobe mogu se pridružiti." diff --git a/features/roomdetails/impl/src/main/res/values-hu/translations.xml b/features/roomdetails/impl/src/main/res/values-hu/translations.xml index 440ae23d09..a549ef437c 100644 --- a/features/roomdetails/impl/src/main/res/values-hu/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-hu/translations.xml @@ -63,7 +63,6 @@ "Profil" "Csatlakozási kérelem" "Szerepkörök és jogosultságok" - "Szoba neve" "Biztonság és adatvédelem" "Biztonság" "Szoba megosztása" @@ -132,7 +131,7 @@ Nem javasoljuk a titkosítás engedélyezését az olyan szobákban, amelyeket b "Titkosítás" "Végpontok közötti titkosítás engedélyezése" "Bárki csatlakozhat." - "Bárki" + "Nyilvános" "Csak a meghívott emberek léphetnek be." "Csak meghívásos" "Hozzáférés" diff --git a/features/roomdetails/impl/src/main/res/values-in/translations.xml b/features/roomdetails/impl/src/main/res/values-in/translations.xml index 34703d6c01..27a1a5745e 100644 --- a/features/roomdetails/impl/src/main/res/values-in/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-in/translations.xml @@ -55,7 +55,6 @@ "Profil" "Permintaan untuk bergabung" "Peran dan perizinan" - "Nama ruangan" "Keamanan & privasi" "Keamanan" "Bagikan ruangan" @@ -106,7 +105,6 @@ "Peran dan perizinan" "Tambahkan alamat ruangan" "Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut." - "Minta untuk bergabung" "Ya, aktifkan enkripsi" "Setelah diaktifkan, encryption untuk sebuah ruangan tidak dapat dinonaktifkan, Riwayat pesan hanya akan terlihat oleh anggota ruangan sejak mereka diundang atau sejak mereka bergabung dengan ruangan tersebut. Tidak ada orang lain selain anggota ruangan yang dapat membaca pesan. Hal ini dapat mencegah bot dan jembatan bekerja dengan benar. @@ -116,7 +114,6 @@ Kami tidak menyarankan untuk mengaktifkan enkripsi untuk ruangan yang dapat dite "Enkripsi" "Aktifkan enkripsi ujung ke ujung" "Siapa pun dapat menemukan dan bergabung" - "Siapa pun" "Orang hanya dapat bergabung jika mereka diundang" "Hanya undangan" "Akses ruangan" diff --git a/features/roomdetails/impl/src/main/res/values-it/translations.xml b/features/roomdetails/impl/src/main/res/values-it/translations.xml index 3d83dba3cb..6d73fc83c9 100644 --- a/features/roomdetails/impl/src/main/res/values-it/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-it/translations.xml @@ -63,7 +63,6 @@ "Profilo" "Richieste di accesso" "Ruoli e autorizzazioni" - "Nome stanza" "Sicurezza e privacy" "Sicurezza" "Condividi stanza" diff --git a/features/roomdetails/impl/src/main/res/values-ka/translations.xml b/features/roomdetails/impl/src/main/res/values-ka/translations.xml index d9c56aa89c..3ffc962603 100644 --- a/features/roomdetails/impl/src/main/res/values-ka/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ka/translations.xml @@ -46,7 +46,6 @@ "შეტყობინებები" "პროფილი" "როლები და ნებართვები" - "ოთახის სახელი" "უსაფრთხოება" "ოთახის გაზიარება" "ოთახის ინფორმაცია" diff --git a/features/roomdetails/impl/src/main/res/values-ko/translations.xml b/features/roomdetails/impl/src/main/res/values-ko/translations.xml index 196656408c..7c53921655 100644 --- a/features/roomdetails/impl/src/main/res/values-ko/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ko/translations.xml @@ -59,7 +59,6 @@ "프로필" "참여 요청" "역할 및 권한" - "방 이름" "보안 및 개인정보 보호" "보안" "방 공유하기" @@ -113,7 +112,6 @@ "역할 및 권한" "방 주소 추가" "누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다." - "참가 요청" "예, 암호화 활성화" "일단 활성화되면, 방의 암호화는 비활성화할 수 없습니다. 메시지 기록은 방에 초대된 후 또는 방에 참여한 이후부터 방 구성원만 볼 수 있습니다. 방 구성원 외에는 아무도 메시지를 읽을 수 없습니다. 이로 인해 봇과 브리지가 제대로 작동하지 않을 수 있습니다. @@ -123,7 +121,6 @@ "암호화" "종단간 암호화 활성화" "누구나 찾을 수 있고 참여할 수 있습니다." - "누구나" "초대받은 사용자만 가입할 수 있습니다." "초대 전용" "방 액세스" diff --git a/features/roomdetails/impl/src/main/res/values-lt/translations.xml b/features/roomdetails/impl/src/main/res/values-lt/translations.xml index 727875d696..fc0e84f6cc 100644 --- a/features/roomdetails/impl/src/main/res/values-lt/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-lt/translations.xml @@ -10,7 +10,6 @@ "Pakviesti žmonių" "Palikti pokalbį" "Palikti kambarį" - "Kambario pavadinimas" "Saugumas" "Bendrinti kambarį" "Tema" diff --git a/features/roomdetails/impl/src/main/res/values-nb/translations.xml b/features/roomdetails/impl/src/main/res/values-nb/translations.xml index 45499ee3c9..d28c16f0ca 100644 --- a/features/roomdetails/impl/src/main/res/values-nb/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-nb/translations.xml @@ -63,7 +63,6 @@ "Profil" "Forespørsler om å bli med" "Roller og tillatelser" - "Romnavn" "Sikkerhet og personvern" "Sikkerhet" "Del rom" @@ -118,7 +117,6 @@ "Roller og tillatelser" "Legg til adresse" "Alle må be om tilgang." - "Be om å bli med" "Ja, aktiver kryptering" "Når kryptering for et rom er aktivert, kan den ikke deaktiveres. Meldingshistorikken vil bare være synlig for rommedlemmer siden de ble invitert eller siden de ble med i rommet. Ingen andre enn rommedlemmene vil kunne lese meldingene. Dette kan føre til at bots og broer ikke fungerer som de skal. @@ -128,7 +126,6 @@ Vi anbefaler ikke å aktivere kryptering for rom som hvem som helst kan finne og "Kryptering" "Aktiver ende-til-ende-kryptering" "Alle kan bli med." - "Alle" "Bare inviterte personer kan bli med." "Kun for inviterte" "Tilgang" diff --git a/features/roomdetails/impl/src/main/res/values-nl/translations.xml b/features/roomdetails/impl/src/main/res/values-nl/translations.xml index f780437cd5..f6655f690d 100644 --- a/features/roomdetails/impl/src/main/res/values-nl/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-nl/translations.xml @@ -51,7 +51,6 @@ "Vastgezette berichten" "Profiel" "Rollen en rechten" - "Naam van de kamer" "Beveiliging" "Kamer delen" "Kamer info" @@ -99,6 +98,4 @@ "Rollen" "Kamergegevens" "Rollen en rechten" - "Vraag om toe te treden" - "Iedereen" diff --git a/features/roomdetails/impl/src/main/res/values-pl/translations.xml b/features/roomdetails/impl/src/main/res/values-pl/translations.xml index 620bd0d674..551e4cf5c8 100644 --- a/features/roomdetails/impl/src/main/res/values-pl/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pl/translations.xml @@ -61,7 +61,6 @@ "Profil" "Prośby o dołączenie" "Role i uprawnienia" - "Nazwa pokoju" "Bezpieczeństwo i prywatność" "Bezpieczeństwo" "Udostępnij pokój" @@ -127,7 +126,7 @@ Odradzamy włączanie szyfrowania dla pokoi, które każdy może znaleźć i do "Szyfrowanie" "Włącz szyfrowanie end-to-end" "Każdy może znaleźć i dołączyć" - "Wszyscy" + "Każdy" "Tylko osoby z zaproszeniem mogą dołączyć" "Tylko zaproszenie" "Dostęp do pokoju" diff --git a/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml b/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml index 0b65ee0f63..b24f4e5716 100644 --- a/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml @@ -63,7 +63,7 @@ "Perfil" "Pedidos de entrada" "Cargos e permissões" - "Nome da sala" + "Nome" "Segurança e privacidade" "Segurança" "Compartilhar sala" @@ -131,7 +131,6 @@ "Adicionar endereço" "Qualquer um nos espaços autorizados podem entrar, mas todos os outros devem pedir acesso." "Qualquer um pode pedir acesso, mas um administrador terá que aceitar o pedido." - "Pedir para entrar" "Qualquer um em %1$s pode entrar, mas todos os outros devem pedir acesso." "Sim, ativar a criptografia" "Uma vez ativada, a criptografia de uma sala não pode ser desativada. O histórico de mensagens só será visível para os membros da sala desde que foram convidados ou desde que entraram na sala. @@ -142,14 +141,13 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Criptografia" "Ativar a criptografia de ponta a ponta" "Qualquer um pode entrar" - "Qualquer pessoa" "Escolha os espaços dos quais os membros podem entrar nesta sala sem um convite. %1$s" "Gerenciar espaços" "Apenas pessoas convidadas podem entrar." "Privado" "Acesso" "Qualquer um em espaços autorizados podem entrar." - "Qualquer um em %1$s pode entrar." + "Qualquer pessoa em %1$s pode participar." "Membros do espaço" "No momento, não há suporte aos espaços" "Você precisará de um endereço para torná-la visível no diretório." @@ -157,6 +155,8 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Permitir que esta sala seja encontrada pesquisando diretório de salas públicas de %1$s" "Permite que seja encontrada ao buscar no diretório público." "Visível no diretório público" + "Qualquer um (histórico público)" + "As alterações não afetarão mensagens anteriores, somente as novas. %1$s" "Quem pode ler o histórico" "Membros desde o convite" "Membros (histórico completo)" diff --git a/features/roomdetails/impl/src/main/res/values-pt/translations.xml b/features/roomdetails/impl/src/main/res/values-pt/translations.xml index b682c0597d..6e75c110ee 100644 --- a/features/roomdetails/impl/src/main/res/values-pt/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pt/translations.xml @@ -61,7 +61,6 @@ "Perfil" "Pedidos de entrada" "Cargos e permissões" - "Nome da sala" "Segurança e privacidade" "Segurança" "Partilhar sala" @@ -116,7 +115,7 @@ "Cargos e permissões" "Adicionar endereço de sala" "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador tem que aceitar o pedido." - "Pedir para participar" + "Pedir para entrar" "Sim, ativar cifragem" "Uma vez ativada, a cifragem não pode ser desativada. O histórico de mensagens só será visível a membros a partir do momento em que foram convidados ou que entraram na sala. Ninguém além dos membros poderão ler quaisquer mensagens. Isto pode impedir que robôs (\"bots\") e pontes (\"bridges\") funcionem devidamente. diff --git a/features/roomdetails/impl/src/main/res/values-ro/translations.xml b/features/roomdetails/impl/src/main/res/values-ro/translations.xml index 854d3643ce..3ac69c59a5 100644 --- a/features/roomdetails/impl/src/main/res/values-ro/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ro/translations.xml @@ -63,7 +63,7 @@ "Profil" "Cereri de alăturare" "Roluri și permisiuni" - "Numele camerei" + "Nume" "Securitate & confidențialitate" "Securitate" "Partajați camera" @@ -134,7 +134,6 @@ "Adăugați o adresă" "Oricine se află în spațiile autorizate se poate alătura, dar toți ceilalți trebuie să solicite accesul." "Toată lumea trebuie să solicite acces." - "Cereți să vă alăturați" "Oricine în %1$s se poate alătura, dar toți ceilalți trebuie să solicite acces." "Da, activați criptarea" "Odată activată, criptarea pentru o cameră nu poate fi dezactivată. Mesajele anterioare vor fi vizibile numai pentru membrii camerei de la momentul la care au fost invitați sau de la momentul la care s-au alăturat camerei. @@ -145,7 +144,6 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Criptare" "Activați criptarea end-to-end" "Oricine se poate alătura." - "Oricine" "Alegeți membrii căror spații se pot alătura acestei camere fără invitație. %1$s" "Gestionați spațiile" "Doar persoanele invitate se pot alătura." diff --git a/features/roomdetails/impl/src/main/res/values-ru/translations.xml b/features/roomdetails/impl/src/main/res/values-ru/translations.xml index 47de4c388c..e618bd8dc1 100644 --- a/features/roomdetails/impl/src/main/res/values-ru/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ru/translations.xml @@ -63,7 +63,6 @@ "Профиль" "Запросы на вступление" "Роли и разрешения" - "Название комнаты" "Безопасность и конфиденциальность" "Безопасность" "Поделиться комнатой" @@ -123,7 +122,7 @@ "Роли и разрешения" "Добавить адрес" "Каждый должен запросить доступ." - "Попросить присоединиться" + "Присоединиться" "Да, включить шифрование" "Шифрование комнаты нельзя будет отключить, история сообщений будет видна только участникам комнаты с момента их приглашения или с момента присоединения к комнате. Никто, кроме членов комнаты, не сможет читать сообщения. Это может помешать ботам и мостам работать корректно. @@ -133,7 +132,7 @@ "Шифрование" "Включить сквозное шифрование" "Любой желающий может найти и присоединиться" - "Любой" + "Публичный" "Присоединиться могут только приглашенные люди." "Только по приглашению" "Доступ" diff --git a/features/roomdetails/impl/src/main/res/values-sk/translations.xml b/features/roomdetails/impl/src/main/res/values-sk/translations.xml index f61e3341bf..7cd14bc7a5 100644 --- a/features/roomdetails/impl/src/main/res/values-sk/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-sk/translations.xml @@ -63,7 +63,6 @@ "Profil" "Žiadosti o vstup" "Roly a povolenia" - "Názov miestnosti" "Bezpečnosť a súkromie" "Bezpečnosť" "Zdieľať miestnosť" diff --git a/features/roomdetails/impl/src/main/res/values-sv/translations.xml b/features/roomdetails/impl/src/main/res/values-sv/translations.xml index 1cc0d81715..0d7ade3f39 100644 --- a/features/roomdetails/impl/src/main/res/values-sv/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-sv/translations.xml @@ -59,7 +59,6 @@ "Profil" "Begäran om att gå med" "Roller och behörigheter" - "Rumsnamn" "Säkerhet och sekretess" "Säkerhet" "Dela rum" diff --git a/features/roomdetails/impl/src/main/res/values-tr/translations.xml b/features/roomdetails/impl/src/main/res/values-tr/translations.xml index 01cac3a6cb..ab6c02fdf9 100644 --- a/features/roomdetails/impl/src/main/res/values-tr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-tr/translations.xml @@ -55,7 +55,6 @@ "Profil" "Katılma istekleri" "Roller ve izinler" - "Oda adı" "Güvenlik ve gizlilik" "Güvenlik" "Oda paylaş" @@ -106,7 +105,7 @@ "Roller ve izinler" "Oda adresi ekle" "Herkes odaya katılma isteğinde bulunabilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekir." - "Katılmak için sor" + "Katılma isteği gönder" "Evet, şifrelemeyi etkinleştir" "Etkinleştirildikten sonra, bir oda için şifreleme devre dışı bırakılamaz, Mesaj geçmişi yalnızca davet edildiklerinden veya odaya katıldıklarından beri oda üyeleri için görünür olacaktır. Oda üyeleri dışında hiç kimse mesajları okuyamayacaktır. Bu, botların ve köprülerin düzgün çalışmasını engelleyebilir. diff --git a/features/roomdetails/impl/src/main/res/values-uk/translations.xml b/features/roomdetails/impl/src/main/res/values-uk/translations.xml index fddcca05d0..65e424398d 100644 --- a/features/roomdetails/impl/src/main/res/values-uk/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-uk/translations.xml @@ -59,7 +59,6 @@ "Профіль" "Запити на приєднання" "Ролі та дозволи" - "Назва кімнати" "Безпека й приватність" "Безпека" "Поділитися кімнатою" @@ -115,7 +114,7 @@ "Ролі та дозволи" "Додати адресу кімнати" "Будь-хто може надіслати запит приєднатися до кімнати, але адміністратор або модератор повинні прийняти запит." - "Запросити приєднатися" + "Запит на приєднання" "Так, увімкнути шифрування" "Після ввімкнення шифрування кімнати, його неможливо вимкнути, історію повідомлень бачитимуть лише учасники кімнати, яких було запрошено або які приєдналися до кімнати. Ніхто, крім учасників кімнати, не зможе прочитати повідомлення. Це може перешкоджати коректній роботі ботів і мостів. @@ -125,7 +124,7 @@ "Шифрування" "Увімкнути наскрізне шифрування" "Будь-хто може знайти та приєднатися." - "Кожний" + "Будь-хто" "Люди можуть приєднатися, лише якщо їх запросили" "Лише запрошені" "Доступ до кімнати" diff --git a/features/roomdetails/impl/src/main/res/values-ur/translations.xml b/features/roomdetails/impl/src/main/res/values-ur/translations.xml index 524afe515d..3715bb91ff 100644 --- a/features/roomdetails/impl/src/main/res/values-ur/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ur/translations.xml @@ -51,7 +51,6 @@ "مثبوتہ پیغامات" "نمایہ" "کردارہا اور اجازتیں" - "کمرے کا نام" "حفاظت" "کمرے کا اشتراک کریں" "کمرے کی معلومات" diff --git a/features/roomdetails/impl/src/main/res/values-uz/translations.xml b/features/roomdetails/impl/src/main/res/values-uz/translations.xml index 466bf18b8b..d401c7e371 100644 --- a/features/roomdetails/impl/src/main/res/values-uz/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-uz/translations.xml @@ -60,7 +60,6 @@ "Profil" "Qo‘shilish uchun so‘rovlar" "Rollar va ruxsatlar" - "Xona nomi" "Xavfsizlik va maxfiylik" "Xavfsizlik" "Xonani baham ko\'ring" @@ -115,7 +114,6 @@ "Rollar va ruxsatlar" "Xona manzilini kiritish" "Xonaga qo‘shilishni istalgan kishi so‘rashi mumkin, lekin administrator yoki moderator so‘rovni qabul qilishi kerak" - "Qo‘shilishni so‘rang" "Ha, shifrlashni yoqish" "Yoqilgandan so‘ng, xona uchun shifrlashni o‘chirib bo‘lmaydi. Xabarlar tarixi faqat xona a’zolari taklif qilinganidan yoki xonaga qo‘shilganidan keyingi davrdan boshlab ko‘rinadi. Xona a’zolaridan tashqari hech kim xabarlarni o‘qiy olmaydi. Bu botlar va ko‘priklarning to‘g‘ri ishlashiga to‘sqinlik qilishi mumkin. Shu sababli, har kim topishi va qo‘shilishi mumkin bo‘lgan xonalar uchun shifrlashni yoqishni tavsiya etmaymiz." @@ -124,7 +122,6 @@ Shu sababli, har kim topishi va qo‘shilishi mumkin bo‘lgan xonalar uchun shi "Shifrlash" "End-to-end shifrlashni yoqish" "Istalgan kishi topishi va qo‘shilishi mumkin" - "Har kim" "Odamlar faqat taklif qilingan taqdirdagina qo‘shilishi mumkin" "Faqat taklif qilish" "Xonaga kirish huquqi" diff --git a/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml b/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml index 0332c0ffd5..8649a29ba6 100644 --- a/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml @@ -63,7 +63,6 @@ "個人檔案" "請求加入" "角色與權限" - "聊天室名稱" "安全與隱私" "安全性" "分享聊天室" diff --git a/features/roomdetails/impl/src/main/res/values-zh/translations.xml b/features/roomdetails/impl/src/main/res/values-zh/translations.xml index f925bdca2a..2568b550a3 100644 --- a/features/roomdetails/impl/src/main/res/values-zh/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-zh/translations.xml @@ -61,7 +61,6 @@ "个人资料" "申请加入" "角色与权限" - "聊天室名称" "安全与隐私" "安全" "分享聊天室" diff --git a/features/roommembermoderation/impl/src/main/res/values-de/translations.xml b/features/roommembermoderation/impl/src/main/res/values-de/translations.xml index 6c6f9dc827..89af01f0b7 100644 --- a/features/roommembermoderation/impl/src/main/res/values-de/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-de/translations.xml @@ -4,10 +4,12 @@ "Sperren" "Sie können diesem Chat auch auf Einladung nicht erneut beitreten." "Möchtest du diesen Nutzer wirklich sperren?" + "Mitglieder können diesem Space auch mit Einladung nicht mehr beitreten, aber sie bleiben weiterhin Mitglied in allen Chats und untergeordneten Spaces." "%1$s wird gesperrt." "Entfernen" "Die Nutzer können dem Chat wieder beitreten, wenn sie eingeladen werden." "Möchtest du dieses Mitglied wirklich entfernen?" + "Sie können diesem Space wieder beitreten, wenn sie eingeladen werden. Außerdem behalten sie ihre Mitgliedschaft in allen Chats und untergeordneten Spaces." "Nutzerprofil anzeigen" "Mitglied entfernen" "Mitglied entfernen und für die Zukunft sperren?" diff --git a/features/securityandprivacy/impl/src/main/res/values-be/translations.xml b/features/securityandprivacy/impl/src/main/res/values-be/translations.xml deleted file mode 100644 index 4587ac191c..0000000000 --- a/features/securityandprivacy/impl/src/main/res/values-be/translations.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - "Папрасіце далучыцца" - "Хто заўгодна" - diff --git a/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml b/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml index 348c9d491f..7258696260 100644 --- a/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml @@ -7,7 +7,6 @@ "Шифроване" "Включване на шифроване от край до край" "Всеки може да намери и да се присъедини" - "Всеки" "Хората могат да се присъединят само ако са поканени" "Само с покана" "Достъп до стаята" diff --git a/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml b/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml index a70ccdbf72..71480958c6 100644 --- a/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml @@ -2,9 +2,16 @@ "Budete potřebovat adresu místnosti, aby byla viditelná v adresáři místností." "Upravit adresu" + "Prostory, kam se členové mohou připojit bez pozvánky." + "Spravovat prostory" + "(Neznámý prostor)" + "Další prostory, jejichž nejste členem" + "Vaše prostory" "Přidat adresu" + "Připojit se může kdokoli v autorizovaných prostorách, ale všichni ostatní musí o přístup požádat." "Všichni musí požádat o přístup." - "Požádat o připojení" + "Požádat o vstup" + "Kdokoli v %1$s se může připojit, ale všichni ostatní musí o přístup požádat." "Ano, povolit šifrování" "Po aktivaci nelze šifrování místnosti deaktivovat. Historie zpráv bude viditelná pouze pro členy místnosti od doby, kdy byli pozváni nebo od té doby, co do místnosti vstoupili. Nikdo kromě členů místnosti nebude moci číst zprávy. To může bránit správnému fungování robotů a propojení. @@ -15,7 +22,8 @@ Nedoporučujeme povolovat šifrování pro místnosti, které může kdokoli naj "Povolit koncové šifrování" "Vstoupit může kdokoli." "Kdokoliv" - "Vyberte, kteří členové prostorů se k této místnosti mohou připojit bez pozvánky. %1$s" + "Vyberte, kteří členové prostorů mohou vstoupit do této místnosti bez pozvánky. %1$s" + "Spravovat prostory" "Vstoupit mohou pouze pozvaní lidé." "Pouze pro zvané" "Přístup" @@ -28,10 +36,11 @@ Nedoporučujeme povolovat šifrování pro místnosti, které může kdokoli naj "Umožněte nalezení této místnosti prohledáním adresáře veřejných místností na %1$s" "Umožnit nalezení vyhledáváním ve veřejném adresáři." "Viditelné ve veřejném adresáři" - "Kdokoliv" + "Kdokoli (historie je veřejná)" + "Změny neovlivní starší zprávy, pouze nové. %1$s" "Kdo může číst historii" - "Pouze členové od té doby, co byli pozváni" - "Pouze členové od výběru této možnosti" + "Členové od pozvání" + "Členové (úplná historie)" "Adresy místností představují způsoby, jak najít místnosti a získat k nim přístup. Díky tomu můžete svoji místnost snadno sdílet s ostatními. Můžete se rozhodnout publikovat svou místnost ve veřejném adresáři místnosti vašeho domovského serveru." "Publikování místnosti" diff --git a/features/securityandprivacy/impl/src/main/res/values-da/translations.xml b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml index 12ab70d44e..2758e944b6 100644 --- a/features/securityandprivacy/impl/src/main/res/values-da/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml @@ -4,7 +4,6 @@ "Redigér adresse" "Tilføj adresse" "Alle skal anmode om adgang." - "Spørg om at deltage" "Ja, aktivér kryptering" "Når det først er aktiveret, kan kryptering for et rum ikke deaktiveres igen. Beskedhistorik vil kun være synlig for rummedlemmer, siden de blev inviteret, eller siden de blev medlem af rummet. Ingen udover medlemmer af rummet vil være i stand til at læse beskeder. Dette kan forhindre bots og broer i at fungere korrekt. @@ -14,7 +13,6 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Kryptering" "Aktivér end-to-end-kryptering" "Alle kan være med." - "Enhver" "Kun inviterede personer kan deltage i dette rum." "Kun inviterede" "Adgang" diff --git a/features/securityandprivacy/impl/src/main/res/values-de/translations.xml b/features/securityandprivacy/impl/src/main/res/values-de/translations.xml index c37481560d..82322e12fc 100644 --- a/features/securityandprivacy/impl/src/main/res/values-de/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-de/translations.xml @@ -1,10 +1,17 @@ - "Du benötigst eine Chat-Adresse, um den Chat im Verzeichnis sichtbar zu machen." - "Chat-Adresse" + "Du benötigst eine Chat-Adresse, um den Chat im öffentlichen Verzeichnis sichtbar zu machen." + "Chat-Adresse bearbeiten" + "Spaces, deren Mitglieder der Gruppe ohne Einladung beitreten können." + "Spaces verwalten" + "(Unbekannter Space)" + "Andere Spaces, in denen du kein Mitglied bist" + "Deine Spaces" "Chat-Adresse hinzufügen" - "Jeder kann den Beitritt zum Chat anfragen, aber ein Admin oder Moderator müssen die Anfrage akzeptieren." - "Beitritt beantragen" + "Jedes Mitglied eines autorisierten Space kann beitreten, aber alle anderen müssen einen Beitritt anfragen." + "Zugang nur auf Anfrage." + "Bitte um Beitritt" + "Jeder in %1$s kann beitreten, aber alle anderen müssen den Beitritt anfragen." "Ja, Verschlüsselung aktivieren" "Einmal angeschaltet kann die Verschlüsselung für einen Chat nicht mehr deaktiviert werden. Der Nachrichtenverlauf ist für Mitglieder nur sichtbar, seit sie eingeladen wurden oder dem Chat beigetreten sind. Niemand außer den Chat Mitgliedern kann Nachrichten lesen. Dies kann verhindern, dass Bots und Bridges richtig funktionieren. @@ -13,24 +20,31 @@ Wir empfehlen keine Verschlüsselung für Chats zu aktivieren, die jeder finden "Einmal angeschaltet kann die Verschlüsselung nicht mehr deaktiviert werden." "Verschlüsselung" "Ende-zu-Ende-Verschlüsselung aktivieren" - "Jeder kann diesen Chat finden und ihm beitreten" + "Jeder kann beitreten." "Jeder" - "Personen können nur beitreten, wenn sie eingeladen werden." + "Wähle aus, welche Spaces ihren Mitgliedern ermöglichen sollen, dieser Gruppe ohne Einladung beitreten zu können. %1$s" + "Spaces verwalten" + "Nur eingeladene Personen können beitreten" "Nur auf Einladung" - "Chat Zugang" + "Zugang" + "Jeder in autorisierten Spaces kann beitreten." + "Jeder in %1$s kann beitreten." "Spacemitglieder" "Spaces werden zur Zeit nicht unterstützt." - "Du benötigst eine Chat-Adresse, um den Chat im Verzeichnis sichtbar zu machen." - "Chatroomadresse" + "Du benötigst eine Chat-Adresse, um den Chat im öffentlichen Verzeichnis sichtbar zu machen." + "Adresse" "Erlaube das Auffinden dieses Chats durch Suche im öffentlichen Verzeichnis von %1$s" + "Lass dich über die Suche im öffentlichen Verzeichnis finden." "Sichtbar im öffentlichen Verzeichnis" - "Jeder" + "Jeder (Nachrichtenverlauf ist öffentlich)" + "Änderungen wirken sich nicht auf alte Nachrichten aus, sondern nur auf neue. %1$s" "Wer hat Zugriff auf den Nachrichtenverlauf" "Nur Mitglieder, aber erst seit deren Einladung" - "Nur Mitglieder seit Auswahl dieser Option" + "Mitglieder (voller Nachrichtenverlauf)" "Chat-Adressen machen es möglich, Chats zu finden und ihnen beizutreten. Dies erleichtert es, Chats mit anderen zu teilen. Auf Wunsch kannst du deinen Chat im öffentlichen Verzeichnis deines Homeservers veröffentlichen." "Veröffentlichung von Chats" - "Chatroomsichtbarkeit." + "Adressen ermöglichen es, Gruppen und Spaces zu finden und zu betreten. Dadurch wird auch sichergestellt, dass diese problemlos mit anderen geteilt werden können." + "Sichtbarkeit" "Sicherheit & Datenschutz" diff --git a/features/securityandprivacy/impl/src/main/res/values-es/translations.xml b/features/securityandprivacy/impl/src/main/res/values-es/translations.xml index c63bee50ef..97b138c75f 100644 --- a/features/securityandprivacy/impl/src/main/res/values-es/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-es/translations.xml @@ -4,7 +4,6 @@ "Dirección de la sala" "Agregar dirección de sala" "Cualquiera puede solicitar unirse a la sala, pero un administrador o moderador tendrá que aceptar la solicitud." - "Solicitud para unirse" "Sí, activar cifrado" "Una vez activado, el cifrado de una sala no se puede desactivar. El historial de mensajes solo será visible para los miembros de la sala desde que fueron invitados o desde que se unieron a la sala. Nadie más que los miembros de la sala podrán leer los mensajes. Esto puede impedir que los bots y los puentes funcionen correctamente. @@ -14,7 +13,6 @@ No recomendamos habilitar el cifrado para las salas que cualquiera pueda encontr "Cifrado" "Activar el cifrado de extremo a extremo" "Cualquiera puede encontrarla y unirse" - "Cualquiera" "Las personas solo pueden unirse si están invitadas" "Solo por invitación" "Acceso a la sala" diff --git a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml index 06d095cf4f..a907f0bb16 100644 --- a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml @@ -10,7 +10,7 @@ "Lisa aadress" "Liituda saavad kõik volitatud kogukondade liikmed, kuid kõik teised peavad küsima võimalust ligipääsuks." "Kõik võivad paluda jututoaga liitumist." - "Küsi võimalust liitumiseks" + "Palu võimalust liituda" "Liituda saavad kõik „%1$s“ kogukonna liikmed, kuid kõik teised peavad küsima võimalust ligipääsuks." "Jah, lülita krüptimine sisse" "Kui jututoa krüptimine on kord sisse lülitatud, siis seda välja lülitada ei saa. Sõnumite ajalugu on nähtav vaid jututoa liikmetele alates kutse saamise või liitumise hetkest. @@ -21,7 +21,7 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Krüptimine" "Võta läbiv krüptimine kasutusele" "Kõik võivad jututoaga liituda" - "Kõik kasutajad" + "Avalik" "Vali kogukonnad, mille liikmed saavad selle jututoaga liituda ilma kutseta. %1$s" "Halda kogukondi" "Liituda saab vaid kutse olemasolul" diff --git a/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml b/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml index 7024f1c40b..f9f3514dbd 100644 --- a/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml @@ -5,7 +5,6 @@ "Bai, gaitu zifratzea" "Zifratzea" "Edonork aurkitu eta bat egin dezake" - "Edonork" "Gonbidatutako pertsonak bakarrik sartu ahal izango dira" "Gonbidapen bidez" "Gelarako sarbidea" diff --git a/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml index 0f42d87675..3a7d5503ac 100644 --- a/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml @@ -28,7 +28,7 @@ Emme suosittele salauksen ottamista käyttöön huoneissa, jotka kuka tahansa vo "Kuka tahansa" "Kuka voi lukea viestihistoriaa" "Jäsenet vasta kutsusta lähtien" - "Jäsenet tämän vaihtoehdon valinnan jälkeen" + "Jäsenet (koko historia)" "Huoneosoitteet ovat tapoja löytää ja käyttää huoneita. Näin voit myös helposti jakaa huoneesi muiden kanssa. Voit halutessasi julkaista huoneesi kotipalvelimesi julkisessa huonehakemistossa." "Huoneen julkaiseminen" diff --git a/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml index b8905bef30..8d237c32d2 100644 --- a/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-hr/translations.xml @@ -10,7 +10,6 @@ "Dodaj adresu" "Svatko tko se nalazi u ovlaštenim prostorima može se pridružiti, ali svi ostali moraju zatražiti pristup." "Svi moraju zatražiti pristup." - "Zatraži pridruživanje" "Svatko u %1$s može se pridružiti, ali svi ostali moraju zatražiti pristup." "Da, omogući šifriranje" "Nakon što se šifriranje za sobu omogući, više se neće moći onemogućiti. Povijest poruka bit će vidljiva samo članovima sobe otkad su pozvani ili otkad su joj se pridružili. @@ -21,7 +20,6 @@ Ne preporučujemo omogućavanje šifriranja za sobe koje svatko može pronaći i "Šifriranje" "Omogući sveobuhvatno šifriranje" "Svatko se može pridružiti." - "Svatko" "Odaberite iz kojih se prostora članovi mogu pridružiti ovoj sobi bez pozivnice. %1$s" "Upravljaj prostorima" "Samo pozvane osobe mogu se pridružiti." diff --git a/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml b/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml index 503fdc8efe..980b55d52f 100644 --- a/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml @@ -14,7 +14,7 @@ Nem javasoljuk a titkosítás engedélyezését az olyan szobákban, amelyeket b "Titkosítás" "Végpontok közötti titkosítás engedélyezése" "Bárki csatlakozhat." - "Bárki" + "Nyilvános" "Csak a meghívott emberek léphetnek be." "Csak meghívásos" "Hozzáférés" diff --git a/features/securityandprivacy/impl/src/main/res/values-in/translations.xml b/features/securityandprivacy/impl/src/main/res/values-in/translations.xml index ea7668dac5..5b475a41f6 100644 --- a/features/securityandprivacy/impl/src/main/res/values-in/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-in/translations.xml @@ -4,7 +4,6 @@ "Alamat ruangan" "Tambahkan alamat ruangan" "Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut." - "Minta untuk bergabung" "Ya, aktifkan enkripsi" "Setelah diaktifkan, encryption untuk sebuah ruangan tidak dapat dinonaktifkan, Riwayat pesan hanya akan terlihat oleh anggota ruangan sejak mereka diundang atau sejak mereka bergabung dengan ruangan tersebut. Tidak ada orang lain selain anggota ruangan yang dapat membaca pesan. Hal ini dapat mencegah bot dan jembatan bekerja dengan benar. @@ -14,7 +13,6 @@ Kami tidak menyarankan untuk mengaktifkan enkripsi untuk ruangan yang dapat dite "Enkripsi" "Aktifkan enkripsi ujung ke ujung" "Siapa pun dapat menemukan dan bergabung" - "Siapa pun" "Orang hanya dapat bergabung jika mereka diundang" "Hanya undangan" "Akses ruangan" diff --git a/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml index e18ba05140..98e9f002ac 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml @@ -4,7 +4,6 @@ "방 주소" "방 주소 추가" "누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다." - "참가 요청" "예, 암호화 활성화" "일단 활성화되면, 방의 암호화는 비활성화할 수 없습니다. 메시지 기록은 방에 초대된 후 또는 방에 참여한 이후부터 방 구성원만 볼 수 있습니다. 방 구성원 외에는 아무도 메시지를 읽을 수 없습니다. 이로 인해 봇과 브리지가 제대로 작동하지 않을 수 있습니다. @@ -14,7 +13,6 @@ "암호화" "종단간 암호화 활성화" "누구나 찾을 수 있고 참여할 수 있습니다." - "누구나" "초대받은 사용자만 가입할 수 있습니다." "초대 전용" "방 액세스" diff --git a/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml b/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml index 3a9d90345d..8dd3220565 100644 --- a/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml @@ -4,7 +4,6 @@ "Rediger adresse" "Legg til adresse" "Alle må be om tilgang." - "Be om å bli med" "Ja, aktiver kryptering" "Når kryptering for et rom er aktivert, kan den ikke deaktiveres. Meldingshistorikken vil bare være synlig for rommedlemmer siden de ble invitert eller siden de ble med i rommet. Ingen andre enn rommedlemmene vil kunne lese meldingene. Dette kan føre til at bots og broer ikke fungerer som de skal. @@ -14,7 +13,6 @@ Vi anbefaler ikke å aktivere kryptering for rom som hvem som helst kan finne og "Kryptering" "Aktiver ende-til-ende-kryptering" "Alle kan bli med." - "Alle" "Bare inviterte personer kan bli med." "Kun for inviterte" "Tilgang" diff --git a/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml b/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml deleted file mode 100644 index 6925a40289..0000000000 --- a/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - "Vraag om toe te treden" - "Iedereen" - diff --git a/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml index f49f944872..c85ec8eae4 100644 --- a/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml @@ -14,7 +14,7 @@ Odradzamy włączanie szyfrowania dla pokoi, które każdy może znaleźć i do "Szyfrowanie" "Włącz szyfrowanie end-to-end" "Każdy może znaleźć i dołączyć" - "Wszyscy" + "Każdy" "Tylko osoby z zaproszeniem mogą dołączyć" "Tylko zaproszenie" "Dostęp do pokoju" diff --git a/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml index dfe1aee558..26d8660180 100644 --- a/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml @@ -10,7 +10,6 @@ "Adicionar endereço" "Qualquer um nos espaços autorizados podem entrar, mas todos os outros devem pedir acesso." "Qualquer um pode pedir acesso, mas um administrador terá que aceitar o pedido." - "Pedir para entrar" "Qualquer um em %1$s pode entrar, mas todos os outros devem pedir acesso." "Sim, ativar a criptografia" "Uma vez ativada, a criptografia de uma sala não pode ser desativada. O histórico de mensagens só será visível para os membros da sala desde que foram convidados ou desde que entraram na sala. @@ -21,14 +20,13 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Criptografia" "Ativar a criptografia de ponta a ponta" "Qualquer um pode entrar" - "Qualquer pessoa" "Escolha os espaços dos quais os membros podem entrar nesta sala sem um convite. %1$s" "Gerenciar espaços" "Apenas pessoas convidadas podem entrar." "Privado" "Acesso" "Qualquer um em espaços autorizados podem entrar." - "Qualquer um em %1$s pode entrar." + "Qualquer pessoa em %1$s pode participar." "Membros do espaço" "No momento, não há suporte aos espaços" "Você precisará de um endereço para torná-la visível no diretório." @@ -36,6 +34,8 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Permitir que esta sala seja encontrada pesquisando diretório de salas públicas de %1$s" "Permite que seja encontrada ao buscar no diretório público." "Visível no diretório público" + "Qualquer um (histórico público)" + "As alterações não afetarão mensagens anteriores, somente as novas. %1$s" "Quem pode ler o histórico" "Membros desde o convite" "Membros (histórico completo)" diff --git a/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml index 26585dc4f9..f06e7d8945 100644 --- a/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml @@ -4,7 +4,7 @@ "Endereço da sala" "Adicionar endereço de sala" "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador tem que aceitar o pedido." - "Pedir para participar" + "Pedir para entrar" "Sim, ativar cifragem" "Uma vez ativada, a cifragem não pode ser desativada. O histórico de mensagens só será visível a membros a partir do momento em que foram convidados ou que entraram na sala. Ninguém além dos membros poderão ler quaisquer mensagens. Isto pode impedir que robôs (\"bots\") e pontes (\"bridges\") funcionem devidamente. diff --git a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml index f3c62f2497..a6c17d7619 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml @@ -10,7 +10,6 @@ "Adăugați o adresă" "Oricine se află în spațiile autorizate se poate alătura, dar toți ceilalți trebuie să solicite accesul." "Toată lumea trebuie să solicite acces." - "Cereți să vă alăturați" "Oricine în %1$s se poate alătura, dar toți ceilalți trebuie să solicite acces." "Da, activați criptarea" "Odată activată, criptarea pentru o cameră nu poate fi dezactivată. Mesajele anterioare vor fi vizibile numai pentru membrii camerei de la momentul la care au fost invitați sau de la momentul la care s-au alăturat camerei. @@ -21,7 +20,6 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Criptare" "Activați criptarea end-to-end" "Oricine se poate alătura." - "Oricine" "Alegeți membrii căror spații se pot alătura acestei camere fără invitație. %1$s" "Gestionați spațiile" "Doar persoanele invitate se pot alătura." diff --git a/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml index 1a138fbb94..2fc0101a0c 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml @@ -4,7 +4,7 @@ "Редактировать адрес комнаты" "Добавить адрес" "Каждый должен запросить доступ." - "Попросить присоединиться" + "Присоединиться" "Да, включить шифрование" "Шифрование комнаты нельзя будет отключить, история сообщений будет видна только участникам комнаты с момента их приглашения или с момента присоединения к комнате. Никто, кроме членов комнаты, не сможет читать сообщения. Это может помешать ботам и мостам работать корректно. @@ -14,7 +14,7 @@ "Шифрование" "Включить сквозное шифрование" "Любой желающий может найти и присоединиться" - "Любой" + "Публичный" "Присоединиться могут только приглашенные люди." "Только по приглашению" "Доступ" diff --git a/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml index 940fdc9a91..8dec5001e0 100644 --- a/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml @@ -4,7 +4,7 @@ "Oda adresi" "Oda adresi ekle" "Herkes odaya katılma isteğinde bulunabilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekir." - "Katılmak için sor" + "Katılma isteği gönder" "Evet, şifrelemeyi etkinleştir" "Etkinleştirildikten sonra, bir oda için şifreleme devre dışı bırakılamaz, Mesaj geçmişi yalnızca davet edildiklerinden veya odaya katıldıklarından beri oda üyeleri için görünür olacaktır. Oda üyeleri dışında hiç kimse mesajları okuyamayacaktır. Bu, botların ve köprülerin düzgün çalışmasını engelleyebilir. diff --git a/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml b/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml index 511ebbd980..7d48ca3acd 100644 --- a/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml @@ -4,7 +4,7 @@ "Адреса кімнати" "Додати адресу кімнати" "Будь-хто може надіслати запит приєднатися до кімнати, але адміністратор або модератор повинні прийняти запит." - "Запросити приєднатися" + "Запит на приєднання" "Так, увімкнути шифрування" "Після ввімкнення шифрування кімнати, його неможливо вимкнути, історію повідомлень бачитимуть лише учасники кімнати, яких було запрошено або які приєдналися до кімнати. Ніхто, крім учасників кімнати, не зможе прочитати повідомлення. Це може перешкоджати коректній роботі ботів і мостів. @@ -14,7 +14,7 @@ "Шифрування" "Увімкнути наскрізне шифрування" "Будь-хто може знайти та приєднатися." - "Кожний" + "Будь-хто" "Люди можуть приєднатися, лише якщо їх запросили" "Лише запрошені" "Доступ до кімнати" diff --git a/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml b/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml index 671308c8a1..6709080b03 100644 --- a/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml @@ -4,7 +4,6 @@ "Xona manzili" "Xona manzilini kiritish" "Xonaga qo‘shilishni istalgan kishi so‘rashi mumkin, lekin administrator yoki moderator so‘rovni qabul qilishi kerak" - "Qo‘shilishni so‘rang" "Ha, shifrlashni yoqish" "Yoqilgandan so‘ng, xona uchun shifrlashni o‘chirib bo‘lmaydi. Xabarlar tarixi faqat xona a’zolari taklif qilinganidan yoki xonaga qo‘shilganidan keyingi davrdan boshlab ko‘rinadi. Xona a’zolaridan tashqari hech kim xabarlarni o‘qiy olmaydi. Bu botlar va ko‘priklarning to‘g‘ri ishlashiga to‘sqinlik qilishi mumkin. Shu sababli, har kim topishi va qo‘shilishi mumkin bo‘lgan xonalar uchun shifrlashni yoqishni tavsiya etmaymiz." @@ -13,7 +12,6 @@ Shu sababli, har kim topishi va qo‘shilishi mumkin bo‘lgan xonalar uchun shi "Shifrlash" "End-to-end shifrlashni yoqish" "Istalgan kishi topishi va qo‘shilishi mumkin" - "Har kim" "Odamlar faqat taklif qilingan taqdirdagina qo‘shilishi mumkin" "Faqat taklif qilish" "Xonaga kirish huquqi" diff --git a/libraries/push/impl/src/main/res/values-cs/translations.xml b/libraries/push/impl/src/main/res/values-cs/translations.xml index 667f181536..0231af68d9 100644 --- a/libraries/push/impl/src/main/res/values-cs/translations.xml +++ b/libraries/push/impl/src/main/res/values-cs/translations.xml @@ -42,6 +42,8 @@ "%1$s vás pozval(a) do místnosti" "Já" "%1$s zmínil(a) nebo odpověděl(a)" + "Pozvali vás do prostoru" + "%1$s vás pozvali do prostoru" "Prohlížíte si oznámení! Klikněte na mě!" "Vlákno v %1$s" "%1$s: %2$s" @@ -99,5 +101,5 @@ "Chyba, nelze otestovat push." "Chyba, časový limit čekání na push." "Push zpětná smyčka trvala %1$d ms." - "Otestovat push zpětnou smyčku" + "Otestovat push pomocí zpětného volání" diff --git a/libraries/push/impl/src/main/res/values-de/translations.xml b/libraries/push/impl/src/main/res/values-de/translations.xml index 6997c9f160..6c0e51564a 100644 --- a/libraries/push/impl/src/main/res/values-de/translations.xml +++ b/libraries/push/impl/src/main/res/values-de/translations.xml @@ -13,6 +13,7 @@ "%d Mitteilung" "%d Mitteilungen" + "Der Dienst für UnifiedPush Benachrichtigungen konnte nicht registriert werden. Daher können aktuell keine Push-Benachrichtigungen erhalten werden. Bitte überprüfe die Einstellungen der Benachrichtigungen in der App und den Status des Push-Dienstes." "Du hast neue Nachrichten." "Eingehender Anruf" "** Fehler beim Senden - bitte Chat öffnen" @@ -37,6 +38,8 @@ "%1$s hat dich eingeladen, dem Chat beizutreten" "Ich" "%1$s hat Dich erwähnt oder geantwortet" + "Einladung zum Space" + "%1$s hat dich eingeladen, dem Space beizutreten" "Du siehst dir die Benachrichtigung an! Klicke hier!" "Thread in %1$s" "%1$s: %2$s" diff --git a/libraries/ui-strings/src/main/res/values-cs/translations.xml b/libraries/ui-strings/src/main/res/values-cs/translations.xml index 196ec6f175..45823e3a0d 100644 --- a/libraries/ui-strings/src/main/res/values-cs/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cs/translations.xml @@ -114,6 +114,7 @@ "Načíst více" "Spravovat účet" "Spravovat zařízení" + "Spravovat místnosti" "Zpráva" "Minimalizovat" "Další" @@ -163,6 +164,7 @@ "Klepnutím načtete mapu" "Vyfotit" "Klepnutím zobrazíte možnosti" + "Přeložit" "Zkusit znovu" "Odepnout" "Zobrazit" @@ -237,6 +239,7 @@ Důvod: %1$s." "Světlý" "Řádek zkopírován do schránky" "Odkaz zkopírován do schránky" + "Připojit nové zařízení" "Načítání…" "Načítání dalších…" @@ -251,10 +254,12 @@ Důvod: %1$s." "Zpráva" "Akce zprávy" + "Zprávu se nepodařilo odeslat" "Zobrazení zpráv" "Zpráva byla odstraněna" "Moderní" "Ztlumit" + "Název" "%1$s (%2$s)" "Žádné výsledky" "Žádný název místnosti" @@ -330,6 +335,7 @@ Důvod: %1$s." "Něco se nepovedlo" "Narazili jsme na problém. Zkuste to prosím znovu." "Prostor" + "O čem je tento prostor?" "%1$d prostor" "%1$d prostory" @@ -375,6 +381,7 @@ Důvod: %1$s." "Čekání…" "Čekání na dešifrovací klíč" "Vy" + "Tato místnost byla nastavena tak, aby noví členové mohli číst historii. %1$s" "Identita uživatele %1$s se změnila. %2$s" "Identita uživatele %1$s %2$s se změnila. %3$s" "(%1$s)" 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 73b70cf4f1..6a230d4dfe 100644 --- a/libraries/ui-strings/src/main/res/values-da/translations.xml +++ b/libraries/ui-strings/src/main/res/values-da/translations.xml @@ -112,6 +112,7 @@ "Indlæs mere" "Administrer konto" "Administrer enheder" + "Administrer rum" "Besked" "Minimér" "Næste" diff --git a/libraries/ui-strings/src/main/res/values-de/translations.xml b/libraries/ui-strings/src/main/res/values-de/translations.xml index 65803db3aa..05650799ec 100644 --- a/libraries/ui-strings/src/main/res/values-de/translations.xml +++ b/libraries/ui-strings/src/main/res/values-de/translations.xml @@ -56,6 +56,7 @@ "Dein Avatar" "Akzeptieren" "Bildunterschrift hinzufügen" + "Bestehende Chats hinzufügen" "Zum Nachrichtenverlauf hinzufügen" "Zurück" "Anruf" @@ -75,6 +76,7 @@ "Text kopieren" "Erstellen" "Chat erstellen" + "Space erstellen" "Deaktivieren" "Nutzerkonto deaktivieren" "Ablehnen" @@ -95,6 +97,7 @@ "Passwort vergessen?" "Weiterleiten" "Zurück" + "Gehe zu Rollen & Berechtigungen" "Zu den Einstellungen" "Ignorieren" "Einladen" @@ -111,6 +114,7 @@ "Mehr laden…" "Konto verwalten" "Geräte verwalten" + "Chats und Gruppen konfigurieren" "Nachricht" "Minimieren" "Weiter" @@ -160,6 +164,7 @@ "Tippe, um die Karte zu laden" "Foto aufnehmen" "Für Optionen tippen" + "Übersetzen" "Erneut versuchen" "Lösen" "Ansicht" @@ -189,6 +194,7 @@ "In die Zwischenablage kopiert" "Copyright" "Chat wird erstellt…" + "Space wird angelegt…" "Anfrage abgebrochen" "Hat den Chat verlassen" "Space verlassen" @@ -234,6 +240,7 @@ Grund: %1$s." "Hell" "Zeile in die Zwischenablage kopiert" "Link in die Zwischenablage kopiert" + "Neues Gerät verknüpfen" "Laden…" "Mehr wird geladen…" @@ -246,10 +253,12 @@ Grund: %1$s." "Nachricht" "Nachrichtenaktionen" + "Nachricht konnte nicht gesendet werden" "Nachrichtenlayout" "Nachricht entfernt" "Modern" "Stumm" + "Name" "%1$s(%2$s)" "Keine Ergebnisse" "Kein Chat-Name" @@ -295,7 +304,7 @@ Grund: %1$s." "Rich-Text-Editor" "Chat" "Chat-Name" - "z.B. dein Projektname" + "z.B. Projektname" "%1$d Chat" "%1$d Chats" @@ -324,6 +333,7 @@ Grund: %1$s." "Es ist ein Fehler aufgetreten." "Wir haben ein Problem festgestellt. Bitte versuch es erneut." "Space" + "Worum geht es hier?" "%1$d Space" "%1$d Spaces" @@ -331,6 +341,7 @@ Grund: %1$s." "Chat wird gestartet…" "Sticker" "Erfolg" + "Empfohlen" "Vorschläge" "Synchronisieren" "System" @@ -338,7 +349,7 @@ Grund: %1$s." "Hinweise von Drittanbietern" "Thread" "Thema" - "Worum geht es in diesem Chat?" + "Worum geht is in diesem Chat?" "Entschlüsselung nicht möglich" "Von einem ungesicherten Gerät gesendet" "Du hast keinen Zugriff auf diese Nachricht." @@ -368,6 +379,8 @@ Grund: %1$s." "Warten…" "Warte auf diese Nachricht" "Du" + "%1$s (%2$s) hat diese Nachricht geteilt, weil du nicht im Chat warst, als sie verschickt wurde." + "Diese Gruppe wurde so konfiguriert, dass neue Mitglieder den vergangenen Nachrichtenverlauf lesen können. %1$s" "%1$s\'s Identität has sich geändert. %2$s" "%1$s\'s %2$s Identität hat sich geändert. %3$s" "(%1$s)" @@ -464,11 +477,18 @@ Möchtest du wirklich fortfahren?" "In Google Maps öffnen" "In OpenStreetMap öffnen" "Diesen Standort teilen" + "Das Hinzufügen eines Chats hat keinen Einfluss auf die Beitrittsregeln. Um die Regeln zu ändern, gehe zu \"Raum Info\" und dann zu \"Datenschutz und Sicherheit\"" "Von dir erstellte oder beigetretene Spaces." "%1$s • %2$s" + "Erstelle einen Space, um Chats zu organisieren" "%1$s Space" "Spaces" "Mitglieder anzeigen" + "Das Entfernen eines Chats hat keinen Einfluss auf die Beitrittsregeln. Um die Regeln zu ändern, gehe zu \"Raum Info\" und dann zu \"Datenschutz und Sicherheit\"" + + "Chat aus %1$s entfernen" + "%1$d chats aus %2$s entfernen" + "Nachricht nicht gesendet, weil sich die verifizierte Identität von %1$s geändert hat." "Die Nachricht wurde nicht gesendet, weil %1$s nicht alle Geräte verifiziert hat." "Die Nachricht wurde nicht gesendet, weil du eines oder mehrere deiner Geräte nicht verifiziert hast." diff --git a/libraries/ui-strings/src/main/res/values-et/translations.xml b/libraries/ui-strings/src/main/res/values-et/translations.xml index b2f08ecb65..6e344cd6b2 100644 --- a/libraries/ui-strings/src/main/res/values-et/translations.xml +++ b/libraries/ui-strings/src/main/res/values-et/translations.xml @@ -112,6 +112,7 @@ "Näita veel" "Halda kasutajakontot" "Halda seadmeid" + "Halda jututuba" "Saada sõnum" "Minimeeri" "Edasi" 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 f6a7678358..4aa4797e3c 100644 --- a/libraries/ui-strings/src/main/res/values-fi/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fi/translations.xml @@ -112,6 +112,7 @@ "Lataa lisää" "Hallitse tiliä" "Hallitse laitteita" + "Huoneiden hallitseminen" "Lähetä viesti" "Pienennä" "Seuraava" 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 1a6ffc8271..46e0b3dfb1 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -56,6 +56,7 @@ "Votre avatar" "Accepter" "Ajouter une légende" + "Ajouter des salons existants" "Ajouter à la discussion" "Retour" "Appel" @@ -75,6 +76,7 @@ "Copier le texte" "Créer" "Créer un salon" + "Créer un espace" "Désactiver" "Désactiver le compte" "Refuser" @@ -112,6 +114,7 @@ "Voir plus" "Gérer le compte" "Gérez les sessions" + "Gérer les salons" "Message" "Minimiser" "Suivant" @@ -191,6 +194,7 @@ "Copié dans le presse-papiers" "Droits d’auteur" "Création du salon…" + "Création de l’espace…" "Demande annulée" "Vous avez quitté le salon" "Vous avez quitté l’espace" @@ -337,6 +341,7 @@ Raison : %1$s." "Création de la discussion…" "Autocollant" "Succès" + "Recommandé" "Suggestions" "Synchronisation" "Système" @@ -374,6 +379,8 @@ Raison : %1$s." "En attente…" "En attente de la clé de déchiffrement" "Vous" + "%1$s (%2$s) a partagé ce message avec vous car vous n’étiez pas dans le salon lors de son envoi." + "%1$s a partagé ce message avec vous car vous n’étiez pas dans le salon lors de son envoi." "Ce salon a été configuré pour que les nouveaux membres puissent lire l’historique. %1$s" "L’identité de %1$s a été réinitialisée. %2$s" "L’identité de %1$s %2$s a été réinitialisée. %3$s" @@ -473,6 +480,7 @@ Raison : %1$s." "Partager cette position" "Espaces que vous avez créés ou rejoints." "%1$s • %2$s" + "Créer des espaces pour organiser les salons" "Espace %1$s" "Espaces" "Voir les membres" diff --git a/libraries/ui-strings/src/main/res/values-hr/translations.xml b/libraries/ui-strings/src/main/res/values-hr/translations.xml index 0ea527dca8..20aa4a2f66 100644 --- a/libraries/ui-strings/src/main/res/values-hr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hr/translations.xml @@ -114,6 +114,7 @@ "Učitaj više" "Upravljanje računom" "Upravljanje uređajima" + "Upravljaj sobama" "Poruka" "Minimiziraj" "Dalje" diff --git a/libraries/ui-strings/src/main/res/values-hu/translations.xml b/libraries/ui-strings/src/main/res/values-hu/translations.xml index 0174bd79b1..be1cc82207 100644 --- a/libraries/ui-strings/src/main/res/values-hu/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hu/translations.xml @@ -112,6 +112,7 @@ "Továbbiak betöltése" "Fiók kezelése" "Eszközök kezelése" + "Szobák kezelése" "Üzenet" "Minimalizálás" "Következő" diff --git a/libraries/ui-strings/src/main/res/values-it/translations.xml b/libraries/ui-strings/src/main/res/values-it/translations.xml index abde675f0f..01eb441661 100644 --- a/libraries/ui-strings/src/main/res/values-it/translations.xml +++ b/libraries/ui-strings/src/main/res/values-it/translations.xml @@ -112,6 +112,7 @@ "Carica altro" "Gestisci account" "Gestisci dispositivi" + "Gestisci le stanze" "Invia messaggio" "Riduci" "Avanti" diff --git a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml index f588e6bdca..74acd35b3e 100644 --- a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml @@ -75,6 +75,7 @@ "Copiar texto" "Criar" "Criar uma sala" + "Criar espaço" "Desativar" "Desativar conta" "Recusar" @@ -112,6 +113,7 @@ "Carregar mais" "Gerenciar conta" "Gerenciar dispositivos" + "Gerenciar salas" "Mensagem" "Minimizar" "Avançar" @@ -161,6 +163,7 @@ "Toque para carregar o mapa" "Tirar foto" "Toque para opções" + "Traduzir" "Tente novamente" "Desafixar" "Visualizar" @@ -190,6 +193,7 @@ "Copiado para a área de transferência" "Direitos autorais" "Criando sala…" + "Criando espaço…" "Solicitação cancelada" "Saiu da sala" "Saiu do espaço" @@ -336,6 +340,7 @@ Motivo:​ %1$s." "Iniciando a conversa…" "Figurinha" "Sucesso" + "Sugerido" "Sugestões" "Sincronizando" "Sistema" diff --git a/libraries/ui-strings/src/main/res/values-ro/translations.xml b/libraries/ui-strings/src/main/res/values-ro/translations.xml index 69f2aba019..e8727a98ae 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -114,6 +114,7 @@ "Încărcați mai mult" "Administrare cont" "Gestionare dispozitive" + "Gestionați camerele" "Mesaj" "Minimizați" "Următorul" 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 1ccde058c3..77dde7078d 100644 --- a/libraries/ui-strings/src/main/res/values-ru/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ru/translations.xml @@ -114,6 +114,7 @@ "Загрузить еще" "Настройки учетной записи" "Управление устройствами" + "Управление комнатами" "Сообщение" "Свернуть" "Далее" diff --git a/libraries/ui-strings/src/main/res/values-sk/translations.xml b/libraries/ui-strings/src/main/res/values-sk/translations.xml index 3c8f4f16ef..747ac45132 100644 --- a/libraries/ui-strings/src/main/res/values-sk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sk/translations.xml @@ -114,6 +114,7 @@ "Načítať viac" "Spravovať účet" "Spravovať zariadenia" + "Spravovať miestnosti" "Poslať správu" "Minimalizovať" "Ďalej" diff --git a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml index 046d7f36ba..67815cfbc6 100644 --- a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml @@ -110,6 +110,7 @@ "載入更多" "管理帳號" "管理裝置" + "管理聊天室" "聊天" "最小化" "下一步" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 5d65ecdbe3..9a86b9c203 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -379,6 +379,8 @@ Reason: %1$s." "Waiting…" "Waiting for this message" "You" + "%1$s (%2$s) shared this message since you were not in the room when it was sent." + "%1$s shared this message since you were not in the room when it was sent." "This room has been configured so that new members can read history. %1$s" "%1$s\'s identity was reset. %2$s" "%1$s’s %2$s identity was reset. %3$s" @@ -476,12 +478,18 @@ Are you sure you want to continue?" "Open in Google Maps" "Open in OpenStreetMap" "Share this location" + "Adding a room will not affect the room access. To change the access go to Room info > Privacy & security." "Spaces you have created or joined." "%1$s • %2$s" "Create spaces to organize rooms" "%1$s space" "Spaces" "View members" + "Removing a room will not affect the room access. To change the access go to Room info > Privacy & security." + + "Remove room from %1$s" + "Remove %1$d rooms from %2$s" + "Message not sent because %1$s’s verified identity was reset." "Message not sent because %1$s has not verified all devices." "Message not sent because you have not verified one or more of your devices." 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 bd0e8752b4..7ca177c146 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:bba0a8575b618446b61d69372af6b8c9a87aec8dd925066bea543c9bda4de758 -size 34195 +oid sha256:153b2806d0c7d5365655f251574dc4d8efdabb2ed7df730d6868ef26c4220aeb +size 35747 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 d996235ee9..0193a9231d 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:0a95826d38ba306dad54a21fea3f0c3b348bb388ce3f734d084fb36bb689678b -size 40246 +oid sha256:6a4eec28988e82c97fb8214f34551195c8603f6256116c927db8ab1295213e17 +size 37733 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 dec36c9974..18c3031dc1 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:caab417458e9798b4c338de667afc8e8fac9ee8a45168ee60e7e31ddf035f8cd -size 61831 +oid sha256:1821e3f108b027a68f7ace7b1f6d21fb0b23bbf75f89f7d27062e1ea7f1333dc +size 47279 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 411a3ed5b8..db5a190e48 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:83e83f59efcff4f7a1d9b01eee242d3384c512f5a1d0623fa9dbfcfdc73a61e0 -size 62570 +oid sha256:d352f8a17349e87fbe4208bbd59a857a829bb6a642f1b784f4e45be8de9121c8 +size 48100 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 d666f4e02a..c101ef8fe7 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:8f1ced6eb71c9009b54c408e7617d2b945071e64c88caf6eff10a4c8c482aa9a -size 63985 +oid sha256:a1fb60c0aa28717fb826f26829479583d4d5c4e259f051141b6c3f9bc0612737 +size 49652 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 dec36c9974..18c3031dc1 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:caab417458e9798b4c338de667afc8e8fac9ee8a45168ee60e7e31ddf035f8cd -size 61831 +oid sha256:1821e3f108b027a68f7ace7b1f6d21fb0b23bbf75f89f7d27062e1ea7f1333dc +size 47279 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_de.png new file mode 100644 index 0000000000..a4c473986c --- /dev/null +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f875911124d060cf6dda0b5c20c66a6da7e398e5d3a4682dbd1919d0113403d +size 48260 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 74ba252140..27abd5e7aa 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:bf37caa5c17b00d268041c4897b9b148f7d7d4e16dd4c0938c05b6e1b9fd0e84 -size 35289 +oid sha256:a13e8b7def20d642afabca21352c1794375540f750eadd5fc72d936058fda1f1 +size 37054 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 32acfffcc8..14a0e6206b 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:43586d8414cb23ab363491c57b7c4bb22a95d2bb55b8dc1d1507054a67a69f7f -size 41598 +oid sha256:ae79dbebfa8c9ba79adb7090c685a20c11ff61e3d975a4d70441a4f975f04960 +size 39147 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 726a329f48..b2cdc0fea7 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:27f2ddc3924cea4dfc4f7ee4b077dc2e9a3fb33122a4f0fb1fade3322f305815 -size 63881 +oid sha256:78a0a71076d0a1dc741e7e32e93d75df12b89e4f278ea4dfa8aa28e780f530d2 +size 49129 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 cdbed88a65..7b03f8e40f 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:d2fd3ba9c6bfa6de0cb78195fdda1677408281f5c408996ef8d6ae3e1567f83b -size 64670 +oid sha256:cc2375bed58e7104fadb739c4d49eebd793e35e8a72c113782515b3cedbd31ea +size 49983 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 99b5863d77..8ce919a69a 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:07e66f22455d1c79851b28807bab15ee114f45bca794c6405358c47d8a313bcc -size 66193 +oid sha256:484f21f65a0a74bae1aa96ea71f6649e1560204c8ac5c4e14af6efd1c719a75b +size 51672 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 726a329f48..b2cdc0fea7 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:27f2ddc3924cea4dfc4f7ee4b077dc2e9a3fb33122a4f0fb1fade3322f305815 -size 63881 +oid sha256:78a0a71076d0a1dc741e7e32e93d75df12b89e4f278ea4dfa8aa28e780f530d2 +size 49129 diff --git a/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_de.png b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_de.png new file mode 100644 index 0000000000..9de401ad7a --- /dev/null +++ b/screenshots/de/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93eb08d49cd64cfb211cbf515d751f16d75a4c6bcb9daf94e12c8edf2cb91d0f +size 49964 diff --git a/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_37_de.png b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_37_de.png new file mode 100644 index 0000000000..f919d8a3de --- /dev/null +++ b/screenshots/de/features.home.impl.components_RoomSummaryRow_Day_37_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c59f0552149c52947cc5d2ffac8879921d7db853cb16ded5bba0559efe26f8fd +size 16055 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 new file mode 100644 index 0000000000..11761bef37 --- /dev/null +++ b/screenshots/de/features.home.impl.spaces_HomeSpacesView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a93222cebbc0bc6ba382b10bef1118edf67fdf520b37038d0c47725e3c9e831 +size 42115 diff --git a/screenshots/de/features.home.impl_HomeView_Day_0_de.png b/screenshots/de/features.home.impl_HomeView_Day_0_de.png index d6e6402fea..a1dc5a763e 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_0_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb38da7cb17bf60d3f65657d66a59cae1c282dea3a5855694eeb65486a0b89a9 -size 63760 +oid sha256:ede89923763221905dbae3033521df9f1cbc8963d3e79a6e1a560bfc034687e5 +size 67281 diff --git a/screenshots/de/features.home.impl_HomeView_Day_10_de.png b/screenshots/de/features.home.impl_HomeView_Day_10_de.png index 069dd23b63..a380abb631 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_10_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62d1ad64d8d096a34458c7845fb800fa0cd605461f3ef4fe0699d30ca03c7925 -size 33284 +oid sha256:4acc7d49f09091fe4d675c13c2cd6ecfd1cd9b471e3fa12f04657f91c2c4a6a8 +size 37021 diff --git a/screenshots/de/features.home.impl_HomeView_Day_13_de.png b/screenshots/de/features.home.impl_HomeView_Day_13_de.png index 5b21661b2a..99c54fe8a2 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_13_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_13_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66dc64fb12b3cc6e2e3953eef03b1615473fd58c9476bd2beec5f72753011076 -size 95190 +oid sha256:e13c5a998a4903daa9fddfb7ca8583e710674403afdf801f7a37a315775414b5 +size 89311 diff --git a/screenshots/de/features.home.impl_HomeView_Day_14_de.png b/screenshots/de/features.home.impl_HomeView_Day_14_de.png index 8a5d19579b..db81606d72 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_14_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_14_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07b0d56ddeacc0c5d28ae7cfabb5ebe69fa96cc33207945a57c5f146d0d5879a -size 89944 +oid sha256:26bb5998203b72484f9428c785e8553b252667fa3adeec0474ffb090b6f98e2b +size 86242 diff --git a/screenshots/de/features.home.impl_HomeView_Day_15_de.png b/screenshots/de/features.home.impl_HomeView_Day_15_de.png index 6ac7326cdf..eb6efe5158 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_15_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_15_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7ab0fb505552504a2b069118818f82738f1c364e54f4a7298fecbfcee067f53 -size 55052 +oid sha256:1c42e7a3a004be541769274234393ca31680c871dd2cbb5e48442926b6a49421 +size 55036 diff --git a/screenshots/de/features.home.impl_HomeView_Day_1_de.png b/screenshots/de/features.home.impl_HomeView_Day_1_de.png index d6e6402fea..a1dc5a763e 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_1_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb38da7cb17bf60d3f65657d66a59cae1c282dea3a5855694eeb65486a0b89a9 -size 63760 +oid sha256:ede89923763221905dbae3033521df9f1cbc8963d3e79a6e1a560bfc034687e5 +size 67281 diff --git a/screenshots/de/features.home.impl_HomeView_Day_2_de.png b/screenshots/de/features.home.impl_HomeView_Day_2_de.png index d6e6402fea..a1dc5a763e 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_2_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb38da7cb17bf60d3f65657d66a59cae1c282dea3a5855694eeb65486a0b89a9 -size 63760 +oid sha256:ede89923763221905dbae3033521df9f1cbc8963d3e79a6e1a560bfc034687e5 +size 67281 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 ffba89ca4f..4fa57e9cf6 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:8902154fddfa359e605cf95c715e080a5b027a79bac4ff0026464c20dd29311a -size 55725 +oid sha256:238c0cc5521bf1a151226a73282a8bf1e0b53cb06e8ce10f7326a9a51aab8e1b +size 55937 diff --git a/screenshots/de/features.home.impl_HomeView_Day_5_de.png b/screenshots/de/features.home.impl_HomeView_Day_5_de.png index d6e6402fea..a1dc5a763e 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_5_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb38da7cb17bf60d3f65657d66a59cae1c282dea3a5855694eeb65486a0b89a9 -size 63760 +oid sha256:ede89923763221905dbae3033521df9f1cbc8963d3e79a6e1a560bfc034687e5 +size 67281 diff --git a/screenshots/de/features.home.impl_HomeView_Day_9_de.png b/screenshots/de/features.home.impl_HomeView_Day_9_de.png index 9c81fb4fb1..08e3a7d89a 100644 --- a/screenshots/de/features.home.impl_HomeView_Day_9_de.png +++ b/screenshots/de/features.home.impl_HomeView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1790960b72437802d90f756b037565e0466e9088ca0205f3ebb269d56d22fd37 -size 90881 +oid sha256:ab9eaf4843f6d0cf375d78749235753da89f6488d52e68be411209906943197c +size 84935 diff --git a/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_de.png index 1e1846298a..2258304d98 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c039b7577f65380d5c54ae7d9a82d62f8a43f4888c86c799fb5b982ba6817d8 -size 45019 +oid sha256:6d255b02f1bc12f10201111717a41404171556b8a5a4d45c65370db6d1fdef0e +size 49852 diff --git a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_4_de.png b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_4_de.png index a11f674a7a..64cdb63c15 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_4_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.error_ErrorView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14e81841b45d0400c65a3a052e8c0c15d48ce88f7f4b50d4e453f92bdb82bbb4 -size 33097 +oid sha256:3cfdfd9b233eacb527f3f108fe89eaeab38c6338852cddeb7803deb4ec8f3468 +size 41492 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_de.png index bad5f73502..90b3890bc9 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:754f8340cc0f39b0c2e63065bf6d03b3716d74176973b0380f348a866c0b233f -size 30062 +oid sha256:35aed1260eddc19b72ba7f9a4a09f75635ec24f0b2910ac506e484a0140cf019 +size 38921 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_de.png index 7021172235..7d5c5b3a7e 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f8884d4a3a61239a030dac21660f0cb6d9ed54d3db08c7b2a48e6b18894a0bbf -size 30043 +oid sha256:b85fde469fec530130cfa2c9cfbe00d96b25795bec3010570054a73cd0d3f352 +size 38889 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_de.png index 97e470d460..589ff5978d 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:101ae89accacc3707b71a091eaacb7676ffc24a92d4cfd48edcf077a414130fa -size 30642 +oid sha256:355be1eec264a02a8662b312208b8e47908081dc1e82dbb6b54277e396c63b01 +size 39466 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_de.png index 3c9eff4eb0..387b28e38a 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40b967dec26c18a3122b3a80f8e29bb0e7b3d16452f4f8061c729134ac5f9f53 -size 30819 +oid sha256:e5925d26ac2ee7a415304f4d7f7456b0e6dc281ba5389d192a4d7adb868f8c51 +size 39606 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_de.png index 152fb7112b..2ab873a790 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:50a6ffd3a59bcf661d5e666736d1189c3c5eaa4bee573644f0a9255d0ffe3a3d -size 34079 +oid sha256:88628fa76195ff667c743484a077c44e8cd9701a051706c47911abfb806a84e7 +size 43642 diff --git a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_de.png b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_de.png index da8006965a..e0a7b37ac0 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1f9958366956cc133eed94df188a51dacfdb3de4195d91cfdc16cf6cbdf412e -size 33794 +oid sha256:5707358f700b47a57dac17491b7eacfe70f045ab0fceb240071d8b264c85622e +size 42617 diff --git a/screenshots/de/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_de.png index 9cd8daefdb..fa7a594d8d 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57f7c6b4d39222cf3e8e92777a0aa319f2654687dd298ce1f60cecdb3e2ce0c1 -size 32149 +oid sha256:d4f376a429697bd619122b695cda372e5320dbeea106490e5769970427893303 +size 34302 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_de.png index 2def92650e..e122019fb7 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5fca6a90b7a667ed9d4d5c0cf2616664468b3ff6dd59d6460651c3e3aa3fae08 -size 17847 +oid sha256:5dc912e2c23ace736a849c38fc51051f99ad7c92a304685e59942d29acbe786a +size 19424 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_de.png new file mode 100644 index 0000000000..855fcbcaa3 --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab3d38acf432c2fd2252af4f728303919de081f80bac9f408ff916d6ffb85b86 +size 25747 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_de.png index 8582608925..6f847cf896 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fb7142589d7c830c72fa5b7bc853027b83a2b864e43c849107d35c0a849c4f02 -size 27470 +oid sha256:d3f51352e91d5eb2d80d61d43b8004718437129040c810e326888df256688d77 +size 28368 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_de.png index 442f156ff0..8b15b0e596 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:34243ec18f06c11de6103bf7787d80b366f12890f01ffe31674ae77ee113dbf1 -size 24679 +oid sha256:779b8306902a7a736b28c832854d8f0107da72497ac4a2427db56f85c647235c +size 26240 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_de.png new file mode 100644 index 0000000000..d615c54d4d --- /dev/null +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59c3e6ab7c7bea73de824e785dc4d28fc66d19a06266128c715e3de70d72f16f +size 26459 diff --git a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_de.png b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_de.png index 67228c7c86..e41385a7ab 100644 --- a/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_de.png +++ b/screenshots/de/features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:437eda5bc2439120a5bca6b88e307d5f0ba1cdce4683e3bb946e7f174419c6e5 -size 34336 +oid sha256:7297874baa52933de2b305a8bbc16f58a001c2bd96331f19575085477d5a4afd +size 35381 diff --git a/screenshots/de/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_de.png b/screenshots/de/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_de.png index 4bf92d9c4d..3cbafb85e6 100644 --- a/screenshots/de/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_de.png +++ b/screenshots/de/features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae1141874f7bfefc4d2ed324f9606a2f68e35894cb7e34be28a299283e45fc6d -size 26294 +oid sha256:86e3e8b778551e041a265bb44d1d38b89ba482374f07165d329038c29bc002b6 +size 32517 diff --git a/screenshots/de/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_de.png b/screenshots/de/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_de.png index 1d308c6908..4ec720ee80 100644 --- a/screenshots/de/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_de.png +++ b/screenshots/de/features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e5009998aeb9113c7572494c77b5c619a6f8ef31236eddda3e91ecfc5a34b5c -size 67431 +oid sha256:c8d8e5573f6fda64ba0a314135a9525f89c34e43ec955b4a3ddf0b83865b4ea4 +size 71692 diff --git a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_8_de.png b/screenshots/de/features.messages.impl.timeline_TimelineView_Day_8_de.png deleted file mode 100644 index 65f68e3f9a..0000000000 --- a/screenshots/de/features.messages.impl.timeline_TimelineView_Day_8_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:49a4829e1f8768ccf77c60ccd76853eb6bc24a545728fb80c75ed9fd900fd19b -size 55427 diff --git a/screenshots/de/features.messages.impl_MessagesView_Day_11_de.png b/screenshots/de/features.messages.impl_MessagesView_Day_11_de.png index 5782aa30b6..d5c2ae6469 100644 --- a/screenshots/de/features.messages.impl_MessagesView_Day_11_de.png +++ b/screenshots/de/features.messages.impl_MessagesView_Day_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:696d10fb1ac5464bd89726955a1ae65fc70b1fd5dd03c74be808ef24abeb3ca1 -size 69375 +oid sha256:f71c4bc5e9fa42c31ec582f932a730c93d4936fcc28d98e77c6d8655458b561a +size 73622 diff --git a/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_0_de.png b/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_0_de.png index 9c1a6d041e..46af5af5a6 100644 --- a/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_0_de.png +++ b/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd194f574a10021900922b975c3168b16f52e6710e1630e53784f25466ad0be9 -size 41559 +oid sha256:2c3b9c7fb4fd1171684e92341fb957d3de64b3cd3ceca35f843684c29c40e98c +size 42406 diff --git a/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_1_de.png b/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_1_de.png index 99ddb60522..c67c7ad892 100644 --- a/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_1_de.png +++ b/screenshots/de/features.preferences.impl.root_PreferencesRootViewDark_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:166e8fb118c62ddef9f92be1ae2ff427d60d8a3bc9a348b047c6d3a165afd730 -size 41377 +oid sha256:af20c31aedd05e357a026a6de8d39edff03321ea054d1cfb246313190bf4c756 +size 42219 diff --git a/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_0_de.png b/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_0_de.png index 54daf8b831..ec273a1146 100644 --- a/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_0_de.png +++ b/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7484ed26275f9b1198ff8ae6b9e1ccf149be88d43cce04bf4be7443abfac1f52 -size 42781 +oid sha256:7bc7ec5c5e68c1b8cd9c085b5d385f1b67943da758bf234cce74f773a4a8fb41 +size 43673 diff --git a/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_1_de.png b/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_1_de.png index 546348fc80..a0aa940b28 100644 --- a/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_1_de.png +++ b/screenshots/de/features.preferences.impl.root_PreferencesRootViewLight_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f3ca986d2446bb2920809b20c0be5ccb0adf21383782613720d44784c3c5bab5 -size 42822 +oid sha256:683d033942db3e1d619228aa34b8db2d294ad156e3332d4d6e09d3a460873944 +size 43714 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 6d1d7aba15..6bd90ed7b5 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:98a2048354e01703cc5a3b63a273682176b45f39dc79432e75c5f2961e71e941 -size 22986 +oid sha256:9b2f1a3efba14b4b4e449ac5303e0cd468da4c729f12a17b0d75d39b609eeb39 +size 23724 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 e11e0938c6..459beef9de 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:fbe3d66e2749b8af8e922fb75a723b5885d3909e7fdf94f913d9a73189f6cefa -size 69959 +oid sha256:cbf9d22c06327a92b61f618019fea562a9bd063a45a8b501820eedca485a7c5b +size 65348 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 8c3409315d..790719248b 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:cb4abd8d65e77aecba3d8fa4a4f5e0417b11b8b1b8e438da0b24e14fa5472bdf -size 34714 +oid sha256:c54e8c7ea8c2d7cb5c80f938cb975f20fe35f9f28c0debdb712ae924e420ba12 +size 35307 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_de.png index a4bc8d4e44..b4ef5c647d 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:39a79b789373312096c863a37afc548827a4d662571aa6c8efd62ff9c60b2a00 -size 65296 +oid sha256:2feb956a7e10edf6957276a759a0da2b59108244ccc8b3eb9f022567d811ec3a +size 57456 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png index 80e56f1da6..e215718ae6 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c2a9304396e74bc9bb11174efbcc8ce6cff94fb028c0c4f0dfa5589922dae39 -size 62950 +oid sha256:c1b25c5d57b0a2a1f01fa63f40363bc4d56b108e1d8936790086a064a05d9860 +size 55654 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png index 875ef8326c..ca4cdab956 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d95bf342ddba5663a36a1f435351e7a3017cad73f7cd58504913681feced1ce2 -size 65157 +oid sha256:c286a545d54c8e5c4c034dab7359c9d0fb944a6ff1708f879ca33f15f2ca5f0d +size 57283 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png index a04a0cd23a..6832f0b60f 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5ab43cd09460063624d2e583b71af3bb3a286890cbf07744d101042aa7c45f5 -size 56783 +oid sha256:9c26673e8de7a4897071caf4c3bad20f7ed64d32f85467c4f8684cce7e37c018 +size 50618 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png index 7da0708b92..ef4bcfbdbf 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41d2484c7ddee013f9cf001dc2eb0ff8a99ac22b7e70816752c97893d1db4c95 -size 54265 +oid sha256:66eae2c2d57bd76459d17f91d26a2c311882183688566d9ad1a3d6767272891a +size 48007 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png index 6d24520c56..7c60317c17 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3afe4b55dd9e11397b9f4b5a99cfc6f5a1a4cebcbdc8cdfb0f81f43eb6912f15 -size 63039 +oid sha256:80e66292743ea24c7b25619de3e51c9ad16e7a8e63c012e1a13f014db67eeba0 +size 57101 diff --git a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_de.png b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_de.png index c0656d9b7e..5eba80a67f 100644 --- a/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ad55fc63c50a403a3218e9168df15c92f91430e60bd4adde45247080cf50543 -size 62971 +oid sha256:cbcee06277f0e6161349efa0744f0074839f88c42edefad9a6e0c8c313b682b5 +size 58701 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png index 0446bc13ad..3494b47e33 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5bf22144267e8ebed2c074cfe017aebcd5c59f5ad55cf81775802654aa0f5450 -size 52254 +oid sha256:693353e6e2319ba5e5d0fc1c5e73d909de82fca9f65149f7dd9734a1ec05b1c4 +size 53029 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png index 6be2aa5649..57295800c3 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d768711fbfe3c3086657733175ad23601160ba9485365d1ed24b56e81c54061f -size 70451 +oid sha256:a6c5d5d9e1b27bf4beee58329fc251dc7a8f2e18173eb517292011d1245a12aa +size 71905 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png index e4b304c7a2..ec0e861e46 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ac6592c003e271d3578152b1c579b457fd64673789173ec37d1a73cd55422cb -size 64133 +oid sha256:205cf04d8fe00211a71e45830516ee371a43990bee56f9c836c9f2185bbcea26 +size 65533 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png index e5930b5c27..0ec81bf440 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf48c5af53b599814c1a43db660283f091e4a1948839e211eb117b931df79a77 -size 63967 +oid sha256:042ad0318615d36b091a9ad4221549177a1b76b777998f28650ff47fe1777e35 +size 65365 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png index 094c990d90..e92c0c560a 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3664e7b03b65c06d0e79fa2b6d690cb1e1bcb33df279ce2e01b15b447f1a41d -size 57833 +oid sha256:b34465c4795584129f2d94050f8586851233966e5bd8fc836deebceb1bb7d8dd +size 59248 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png index 1c27d4d4f9..6c829ca930 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:06b099b4780f03abf3a9e3a6417c7981a83276bc5c689f9508db3c8e54a4631b -size 61079 +oid sha256:6daac5a3bf35601522c3448d731e85409fa9e13d1a06be2cd907f542d0bf22b4 +size 61828 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png index bc7cefa438..21ec47f5d5 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fdeb03d0a6a5edac44e9c9f6d27843ac86194d5791188c23d874ecbd5343f782 -size 65469 +oid sha256:488e717f60a1d6c80260f248f729bc5817593c4d68cab567066f6929668557d1 +size 66207 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png index fa0f3ecc71..e4217d8080 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63856a50b0fa099695709dc720e600ae9b36b62cb3bfac28a940607c72efd5c5 -size 54966 +oid sha256:0efae1f7954ae4587ba9a0822c0fbbe50d09fdb0c7a5eba1e4c89fb5bf839c8b +size 55674 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png index e5930b5c27..0ec81bf440 100644 --- a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf48c5af53b599814c1a43db660283f091e4a1948839e211eb117b931df79a77 -size 63967 +oid sha256:042ad0318615d36b091a9ad4221549177a1b76b777998f28650ff47fe1777e35 +size 65365 diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_de.png new file mode 100644 index 0000000000..fc9c3e2365 --- /dev/null +++ b/screenshots/de/features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:353deccaf44203d369a40c95032787afd5946b12b76c8fecde6a8b8028df7631 +size 15419 diff --git a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_de.png b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_de.png index cd690a7726..f90bd43fda 100644 --- a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:673a833d5c5e9026b680a73017ca6e6dd9f3e33c0b13a0de4967133b85a13bfa -size 33146 +oid sha256:8aea2569247c60180b1569b09efc58dc4c4a93b2848c3bba52ae2278e9a0ddf4 +size 32050 diff --git a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_de.png b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_de.png index bd1a2e7ac3..d602040589 100644 --- a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc67b423cec2885955d8b9df9df2a0fae2767c9ab96be944824efcb07dc70b25 -size 35233 +oid sha256:da2490c21a2b8833b53356584ddb4a23f327f6f11671eeaccbfbcf5e8d37f055 +size 34124 diff --git a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_de.png b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_de.png index 98bfbf4ddf..f5f384d9ab 100644 --- a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:24961d4b8ba165e40edc46675151005c34ec7b6de8cb3755aaab3481e87ca9ac -size 30661 +oid sha256:7f8fa9504a4a1df35f5b7b5c229301e465f6b2fd0c44d00420703931c9cb9e47 +size 30250 diff --git a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_de.png b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_de.png index 98bfbf4ddf..f5f384d9ab 100644 --- a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:24961d4b8ba165e40edc46675151005c34ec7b6de8cb3755aaab3481e87ca9ac -size 30661 +oid sha256:7f8fa9504a4a1df35f5b7b5c229301e465f6b2fd0c44d00420703931c9cb9e47 +size 30250 diff --git a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_de.png b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_de.png index 198b0c2a5a..a10ee76fed 100644 --- a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e514066d66b1e868c7229302478e48fa5e9a72fdccbe54d9e179889544f73ea5 -size 28037 +oid sha256:de51dc6fdc942bde0a1d42194feee7829943974b645b792ce32e446fd73b76fe +size 28030 diff --git a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_de.png b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_de.png index 8a01bb44d8..11c1b8b41e 100644 --- a/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_de.png +++ b/screenshots/de/features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66197931c626c563b2c6fcbf1fc8f57366bbc1b9a22c3d4dc18d64457e5a8d24 -size 31131 +oid sha256:945f3e19bc6903b198cc9ccd9af8a776c40590b7591738b962c270138b18b871 +size 30034 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png index bbd4881433..5851c87606 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fb9f15f43fe78b8cb9683297c3adec0b8354f3afe9b7deb523e0c94964c2ca7c -size 56601 +oid sha256:4724101065e860281aa3f7d3b8e3b535be689d4e79bf225f96fb15cc22c6cf53 +size 55567 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png index 3bfa26d702..18298e6114 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be327333c430fe7de69ee8540ee2f499e2e02575e95c05fc54b5264fa79b8771 -size 31384 +oid sha256:746a6d203bc1cda887c23af882ec45114802c484e6723ee6c0708ec5930ff7aa +size 31750 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png index 4bded04dba..9f2bcc511b 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9070e72ccf6ba4553cd093f686f55329221b88df7b188716f20b2029ad639517 -size 57820 +oid sha256:47289c65fd7948a9949655e802143bd531bc69119ee4fafcb385e0d2b74b390a +size 56808 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png index 0ef6abe726..2ea9a94558 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9223b4e39ba96f63148d6b33ffb70cd3893926032bcf1b05e76193873f47716 -size 19654 +oid sha256:aee6c8b8303af4242c9672867eaa0af30013263d4170e60f2483ad02b43f712b +size 19052 diff --git a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_6_de.png b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_6_de.png index 27e87d2a1f..2a1647145f 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_6_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5989462acb327dea61c68b082349b9bba499bf98968563f8c144a04169e205e6 -size 29897 +oid sha256:b5ce88089419f3aa972b12f52bd15720ccf5b6f6cf17459750b16c4ff444a3cc +size 35837 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 45d287b5ec..fc8480727b 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:c7a8a805ff40cfc6194a414a2d1c1babc5dc2335fb5c96bb72f6f2f412c91346 -size 30052 +oid sha256:05578b1d3db4deb866bc0bffd899c2a59b498f8e87b046bfc5c0d56d1dbc4c2d +size 30020 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 91845d6b8f..8f3b1f77d9 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:f6ccfe1ff08087bd75a8e0017f5d12540cc567423801050dc091005722f3d9b1 -size 24575 +oid sha256:e2a8edde33dcd34fa936c57e0d9d71a6fedfea12f2a22dfd1e1d09c496d624e2 +size 24329 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 16fde1067e..f5220b6f4d 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:55711397eb8fa3717a3891e56c078cca643520b2d0fefeede118b19db8676341 -size 31204 +oid sha256:b4b047dac7afc81637645deddc9f5798c1c29d4f58af220d258df1880d5cf461 +size 30453 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 b366ffe07c..1a3d8adc29 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:89bcd852bb60044ba429d5c0a884b05d3a28403d985f95bd1582f1f45baca003 -size 54044 +oid sha256:4315d98ad25d51464e166b387b4300fd221315d9e6be17b735296c27e6ac0613 +size 52709 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 e8642f7bb8..b0e3928a6c 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:5f8fde96567da32ec9a97eecfb1224b5ae23aa0c7608792036f452eebbad466a -size 51217 +oid sha256:4da0c481bf69057e27beb209e281b5d3feb0c474bb7b145c4ea6e4c1193b9d76 +size 45544 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 f38d37867b..afd8927f7a 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:3e343b3df1a386702c6163393ff05d342abbc9c245ba93129d24e7be5acdaa39 -size 30079 +oid sha256:0ced60024867e61852b6a515d3b457dc3e3f0bf4f2565b105e529cd6cee05873 +size 30241 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 60f40910a3..45e07ce005 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:5ffebfde2aa3d3f3a7e9f7a3dbf8b9e6b8044657815735d2d8c401d2caa8ab51 -size 30225 +oid sha256:34ad9afc2f63d8d25263ec095bec2eca2b9c5eb9c0a2baf0e500e8f06fafd393 +size 30220 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 faa2a0b84a..0c516f1f36 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:4253142dd34410c924bfd0499042a05b9ad59afa7073957835a8d4afc6a7d5a6 -size 25470 +oid sha256:5a086a64f8292be4e439d17b081fa98fa6dd571bb8707b7d29256b7a3115a680 +size 25684 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 534874b570..1deac439e1 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:b4fae7c1d5e7bd4f10658bc1777af60ae110278e283a03ca52855e990448f8a4 -size 31022 +oid sha256:b3a431355948e88681bc67407ced464ea3d35ee225820e49af6cc1b19df2fa9a +size 31127 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 e95bd5c15d..f3a2515aad 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:da72832a3646008468a061de42964b7d98d563d3a2244f63d168c4a2f38247e6 -size 32513 +oid sha256:e7511a9c88430b8ef33575754546593bbba0de0653c7b915eb4fd08e28d46f35 +size 32623 diff --git a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_de.png index 92a9ecfc08..92583b6be9 100644 --- a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_de.png +++ b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4463c9d76c95a063e481cd12d8a5c8432b06acf4072927cbe1cf659ca22759e3 -size 26490 +oid sha256:92b0b1674e1c7a21aa8655de176df36e13f83527eac71668d5704ac883326b8e +size 31643 diff --git a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_de.png index 1232360bfd..8dc8cf1e8b 100644 --- a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_de.png +++ b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:16187cb579ae21c620fc41fc70b3ae17136ea423d7793263c4b943ca4b3e54cb -size 31781 +oid sha256:d37a361c48255eaf0ec25d3f6aa43c1da2fca4e3bf805407f32c2dd5697a4340 +size 36154 diff --git a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_de.png index 6d9d44a999..e087600f05 100644 --- a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_de.png +++ b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59c6624f279aaa202ae5e85488dfa28893c13f02d2e76b0fbe6586b35a55181d -size 32515 +oid sha256:c299ab24b5ea713c4844cc558b900f709be44e05638c02cfd3baa37784425ee8 +size 36839 diff --git a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_de.png index 7451aa805a..11b1caadee 100644 --- a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_de.png +++ b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:805d79eefc2a5cb1dd4fbb7294301ad785bb9cfe04c8c80c102c4f8d6f51fa4d -size 26384 +oid sha256:68b6dd8e7eea116b88b51b97efa4e73fa4a2675785f227d88a79f2ebfa664d52 +size 31498 diff --git a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_de.png b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_de.png index ab750ae07a..ed9e845bf3 100644 --- a/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_de.png +++ b/screenshots/de/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4725f3d6a5c06f692fec640eddfd5f6ecd1cb3fb38c9f137ffbdd7df3cadc27 -size 28437 +oid sha256:c0e2149fe04be272b692451d28779737616fc79e00f7a98c7ff6db1a29c2a0f6 +size 32956 diff --git a/screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_de.png b/screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_de.png new file mode 100644 index 0000000000..b990d04681 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07aabff0edce8dcf8ec265a984b80471bc9992c4673e14cea580b529361d826f +size 51274 diff --git a/screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_de.png b/screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_de.png new file mode 100644 index 0000000000..b990d04681 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07aabff0edce8dcf8ec265a984b80471bc9992c4673e14cea580b529361d826f +size 51274 diff --git a/screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_de.png b/screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_de.png new file mode 100644 index 0000000000..b05eab9cf4 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9831e628d692bf5950ee80b9ded876b1ea0f4b4aa06992665ba37322389959d9 +size 51859 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png index bcdf552747..5d1f16dd7f 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31e3ddc060f3c87cd761dd58ff73ef00b0af8e2fba6bf06e27f0396e52a04df3 -size 54661 +oid sha256:b63be55a00b8674d61d3a0e3130b67798831b823e006ecb9862c967bcc14af73 +size 48887 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_de.png index d8e327cec9..8db17f8870 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7cc7260e1f01727bc96317f278158a36cdb0a6ee544937e1f7b2b2e5aee9b71f -size 51358 +oid sha256:0ffbf38bbc9531fac752db135cc15a47c668c082ad44d99295c338c1360a762a +size 21528 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_de.png index f584c028e1..a45c969ded 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:407a338096b8e758eb4663016fc1448fffc7756b5055c5be015782d4f9d34de7 -size 51832 +oid sha256:ac0ed373337031699ee229e701ab80d7840a52fca701da27e558a5bf2fa52733 +size 46050 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_de.png index ff8e29ea59..b46cd6611a 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:044869f6f523e6ab43de53e7ff13a8c1771a929030f60a8191329f385be67835 -size 24752 +oid sha256:30310d98ac621fb1b112deec973f9bcd607902ffaa306dfb46c4f1b3f6033618 +size 45839 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_de.png index eafb1f2805..ee9f81265b 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9027ed5e27a1d640ab50b4c544d622c718d3bef6df477bf66b99ee605ccec7c -size 51770 +oid sha256:1ef23c8c965b0a30ad3ff9fa4967e11116e7d65147b09964327754b2e18519aa +size 46031 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_de.png index f584c028e1..3433c03e14 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:407a338096b8e758eb4663016fc1448fffc7756b5055c5be015782d4f9d34de7 -size 51832 +oid sha256:05fa0b8de55786d8e1fa17b3eef33ed0559ff511d27fdf18254330ab4d50814d +size 29573 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_de.png index a7c70bf14d..5f01844e68 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e771cd9a182dab3615661aebdeba6069cbf04218f60d709a529693e8ad6005e0 -size 52416 +oid sha256:471dac9ac225468f8778a7126510588dcc9373da1243b9a9b852f3d066be7cd4 +size 62487 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png index 919ee0cbcd..5f01844e68 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6df150ce5cdb2e3233444c122b6bbd0b71fcfb8819eccd15f7ddbafd7e2d4d6 -size 47665 +oid sha256:471dac9ac225468f8778a7126510588dcc9373da1243b9a9b852f3d066be7cd4 +size 62487 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png index bab63e3455..e5b6aea68e 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f53320f4b69908a32f3723a1d098eac5c993574e877dd1ce5faac9028ad4fb4e -size 46743 +oid sha256:84ee198afa3631015c7e97ba63085cff41ff35cdc5d27730916a0b63e541bf92 +size 45701 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png index a62aca41d7..ee9f81265b 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12d639b33a6424d0807bff2545b874b16abb2c0147662d04f21df28d915fe2e4 -size 49225 +oid sha256:1ef23c8c965b0a30ad3ff9fa4967e11116e7d65147b09964327754b2e18519aa +size 46031 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png index 0cfbaa9762..64d8d2dfff 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:55626ae74436af585b326f621d6d5d75729d180c4d653882f81e1484dac753fe -size 52976 +oid sha256:5a76f9c1b0e509ff6921c2f0ce5c4e94513ecdf037c89845cbd1198326a85084 +size 46483 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_de.png index f7ed121780..9f3b06d002 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2cbad28899d0c9f55f4abcd04e5ea3fcd896d7d7e1649ce52eb9b23bbe7b6e91 -size 65600 +oid sha256:3f4c9ca3bd72b801faa443e486c014e13028b41b1457438bdc916e49c94fd2a9 +size 62858 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_de.png new file mode 100644 index 0000000000..ea75d6dc6c --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14cc7e1ded2ac32c9ab30cdab5f41ab0623bd30e5ecaa5a92e332d4442682931 +size 42427 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_de.png new file mode 100644 index 0000000000..9f366decb4 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51a4539dc71b21f5a5ed0e2ecb81e0cf5284e646ae30f13dee117b3efca1b58a +size 35316 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_de.png new file mode 100644 index 0000000000..3875c8e4b6 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7623c8df791a67f10a417053c3cc77b23504b9761dc173fbd297a1501d7516b0 +size 42730 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_de.png new file mode 100644 index 0000000000..b4c5604772 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a0828e126ac554d0dc8bb1411afd6678d4b27af584370b363bfb790469a5580 +size 46430 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_de.png index a174686a2d..ce55465ab0 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f561351b6dbd13b6cd2f55f8df9f31c84453594acf511cdde27855639ba4ea7c -size 65148 +oid sha256:c3a7498158997a5a2066a485517f6c93d17c26379247af55e9e474ad56348c17 +size 62658 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_de.png index 44e0015abe..b0c90290c7 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d20dafcb3552d24835bbeec5a288cad29015ceaaee123d64fa32123a51c3cb4 -size 65727 +oid sha256:eb30cc79a305d9cf053f5771e4c8cc884f9f2b43a511479d5cceba9b2fb2af72 +size 62967 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png index 04a8ae33bd..6754d01065 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd49f1b0f3dae2a57e4a63b54a2cb98dffab50ed3b2cb9d46f951eb1ea2f99c8 -size 51549 +oid sha256:3fc9f4c6d46b3367599b13d91f3c2999c3e5ca9c4e9a23ec682323eba5a264af +size 57356 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_de.png index 9a5f939b49..34571c85fb 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92888d4d51a087f628d2c0604d0f02c3a58e2eca5c1e41d1dd01884afb1c1e6a -size 65549 +oid sha256:a48e68089cc50619635388edf34c22e9731025fc41e100b92705c44d16b06da2 +size 64405 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_de.png index 3a76a16c3e..34571c85fb 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1998f0764fd6706169015fecbe7958f5ea88ccf6718c6fcc31b50259213eda69 -size 65612 +oid sha256:a48e68089cc50619635388edf34c22e9731025fc41e100b92705c44d16b06da2 +size 64405 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_de.png index b307d30172..4bcceb16d2 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dce718324779855609745640fccecda621d121e61186915c626b4f8cd4e8693e -size 62663 +oid sha256:5cfdf54e90f9ce10681e864c930c2faede907295b66cc76ab492eb4cf26b48c3 +size 64600 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_de.png index 6432c76e48..162d08a132 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ffb5c13b625568456542d7405e9f8f05ebe986de32587c68fbcd7c356cd30cb3 -size 27683 +oid sha256:be7f479ac2ef41098a6c5e14dfb691f732bf4dc6913aa8dc45bc0325f6790a63 +size 62843 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_de.png index 5d8f1260f7..69f766576f 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57ba25b77977622a483522f5e360fb9763e4c089a8576d3b51b611a463e81d7c -size 51821 +oid sha256:66bc0585bfb5451813c1be93976c12c6b0641f663b338933f310008a2d7130db +size 60369 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png index eb68edb577..4ad76fb2fd 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:851affa2b63b0c70a282c182bf1ce615283c6d0ed732ee3b3102d3dcb862349c -size 57340 +oid sha256:5e384b9256cf2a479fd20cf35a12dcddfebf717aa984e08803a48e30f167835d +size 50507 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_de.png index 510202c600..23f4566d1c 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8dc0ed7717de76041c6a5e9c32c3246039a8881ced121276b58b3012bbfb4096 -size 52718 +oid sha256:77936d932f152408acbcc08c2d0e468ff71f228de412b76d64326741f00bfe74 +size 22192 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_de.png index fbbf3768e6..ba206f3135 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4919373598bd77b7aa9e3aebad6abf4f8ddcf0123894507d76ce63157d347ea7 -size 53335 +oid sha256:f0912cbfc808cf5a0a0e16b7b20cb2b7b3a6309e5f37dc70fdd58c4d451b6df6 +size 47590 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_de.png index e0478af982..59841e7d26 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b4a7e16a3c70933cc7f4ef68636df5d1669789500690f17a5a25f122f9f50b2 -size 25412 +oid sha256:3ffffc75a7d777b38b51188cb7aeca5ee443dec7c0a63929ab65ce65d52ec8e0 +size 47334 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_de.png index 98d9beba84..f49c75354a 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:65020e3887540431951a3e99ce31e19dc401b4bbc232b16ded6e59d51f1712c9 -size 53206 +oid sha256:d59f6556c7f4c39ccd2e5dc552c2018321651e0a6325740da66c07078afed396 +size 47590 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_de.png index fbbf3768e6..7fed91d2de 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4919373598bd77b7aa9e3aebad6abf4f8ddcf0123894507d76ce63157d347ea7 -size 53335 +oid sha256:c64e1a0dfdc09e58406dda836cdbb61453fb1a020c326bc4bf3f1046357e7225 +size 30804 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_de.png index 579756c731..59a51fb317 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73fa1e4a25773720a0e9999b293488017c854576f40cc738fb3b67b59f2b1f05 -size 54167 +oid sha256:d7c165d765ebba90862eabb42b1fca2ec2132e292c2b27bc67b915b34a8c7718 +size 64534 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png index 386a05f453..59a51fb317 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:711800e228ac74d8971a383ecd85f560d050000f886d6107aa7ea0c9d6099d95 -size 49348 +oid sha256:d7c165d765ebba90862eabb42b1fca2ec2132e292c2b27bc67b915b34a8c7718 +size 64534 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png index ac8d242b19..d0ac6369c4 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4624bd99900eb3d30256aa81dbe6c48f017480ebc4c97d3fbf47529ffd62e899 -size 49078 +oid sha256:25a36fac5577512763276853f331d1c6b7ca66d5363f2974cf2a93ecc081dabe +size 47262 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png index f70a5bf36d..f49c75354a 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:612ffe06d38570e32215b9f117f979382832a9aed3fddcde38b0a461bf1b653d -size 51684 +oid sha256:d59f6556c7f4c39ccd2e5dc552c2018321651e0a6325740da66c07078afed396 +size 47590 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png index 867cb18108..85126df232 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11ebd0e210579c60b07136685c82f3d73648a3742344d4d15a5ed3df9b48ced9 -size 55476 +oid sha256:ad979d8842f604873e47914d96892f0e68579b1f0e72f1527266340a71ad2768 +size 48204 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_de.png index d1ce6902de..864c32b235 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:90db4ee471ec887f00a9e580ef839a4611216107ec615da90330b7d6be276b77 -size 68316 +oid sha256:1609ad886bda6464023ce5bbe5d0481f4d261aab4b3bace7c533a1bffcf4589f +size 65203 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_de.png new file mode 100644 index 0000000000..a250e63f31 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6fe5fbc711c2c1b323f4ac05b99273250d937616addd16537b6e59c2677460b +size 44040 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_de.png new file mode 100644 index 0000000000..53176f2955 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c87795a614f80b51cced1fdd3bca44fa8cc340c87e0f407fb55630adb24579b +size 37378 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_de.png new file mode 100644 index 0000000000..0ba632c505 --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d67d9ece1f3e2184e703aaa10ffffae4c4393a252bf005d881fd04a766af53e +size 44994 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_de.png new file mode 100644 index 0000000000..28eb79f8ed --- /dev/null +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bb901470cae356324c49c51d09e3bdb73e39faa6db0d18ea9bef4903d9dc95b +size 48562 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_de.png index 1d2eff636f..eeb39eda6c 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9488bea7d8ea64ac2d2987dcf69b4a51bfb6b81e33b1035195860cc90ae9f291 -size 67707 +oid sha256:2e7e0e331e495c0ab367348836811d1e93785f20a3307a6afdef6383b40f0227 +size 64964 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_de.png index 6f1dca9c23..fc11352ad2 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbf7bda1bff05828fe71045a012b8bcc1f4c047256d8aea6f8f8579e08295dea -size 68546 +oid sha256:701b0b0bf9e0b0b33122f719de44c92a93a569375a176ad486b54f2789b8cb62 +size 65423 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png index 6ec398b86b..751d75ff7e 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00b2576dacba4388bb8259a7c6fbacbe713c805695efc4ea6e98c50f0cd28196 -size 53621 +oid sha256:b569e7f7d33f47d2ea98088d9fe9a84986eba40081a78c3eaf9646115cf52a65 +size 59854 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_de.png index 3f1bf5f183..7317dfdf1d 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d32e9542eb673f6e4f0f05ad017615f0c3274683e48f3ec13277e2d98d4db0f -size 68200 +oid sha256:8ff12fcb931ec685028ef6f9826d9b4626aa3fffd7f496e99dd05e5445163d3e +size 66589 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_de.png index 1b18135ef5..7317dfdf1d 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4dd6427f42936ef21702492e5e96a7abaa6873edde04169603ed2124d76f4984 -size 68323 +oid sha256:8ff12fcb931ec685028ef6f9826d9b4626aa3fffd7f496e99dd05e5445163d3e +size 66589 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_de.png index e04844391b..ab704a6321 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:88d3cb4770828935c271cc10fc436c85f0af19bf77a5f58a6abd6fde1af367ec -size 65168 +oid sha256:b268474bc233b94aece069148e14ddd64e936a0980e0f2087955563042b6faf9 +size 66999 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_de.png index 1e24950be3..2985f52e97 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:99ae8ce6973aeacb8d1054722038b9840365b239569f6dbee5c2f234e84c14d3 -size 28626 +oid sha256:3d741419ca1227e56f91420928d86294daebee5a766ca91170a379f20aecdf6c +size 65202 diff --git a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_de.png b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_de.png index fa87fbe737..7aa8786d05 100644 --- a/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_de.png +++ b/screenshots/de/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0c6701f9c4faa4495cd92e7414821f39f9adc3d3f755d21302a5c66cab6f5e3 -size 53331 +oid sha256:edb49a6728feb9337beeebccf376de82608c69e2daf98a368f4326297645ff23 +size 62803 diff --git a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png index 6b2e354a36..b6ea8e0124 100644 --- a/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png +++ b/screenshots/de/features.space.impl.leave_LeaveSpaceView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2fb101aadb226cf66041f2abda6edc1fb9877765ad9d88607135503bdc2037dd -size 37509 +oid sha256:b555c8a2b269a132e1344e2959ac15eb2dff7ad485a929bdefc0abefb5c7e9b7 +size 38028 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_de.png index f1620e0b31..ea2c4d0f36 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9a4da42e5fb1bdd969d83c99f39bdd160fd277124499420b5f39f5e081a9f0c -size 48298 +oid sha256:51ca53f9c4bae68ce223da3fb7b7a08dd0beb6e9c0ebdc98c7f3e9396794325f +size 48597 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_10_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_10_de.png index 1d5e374608..cb13bd106e 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_10_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2afa86e0dc92132e23429bebe2d170977944012e3690d341e96c876e5ee8715a -size 28087 +oid sha256:981fa0c97956df43d3e278da0b043d9baecc427a0c7b1ef6b7a326e9f9d3736f +size 28458 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_11_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_11_de.png index 73b5c74c39..e97935ee33 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_11_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dad66c15257d320ba504995128924c88e7f121e0924ba66a5b789cd98819118b -size 29432 +oid sha256:89d4b4173e001c79a6019105b5ca2c1b3dbc993be67232c73e3205f2891f769a +size 29799 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_de.png index f1620e0b31..ea2c4d0f36 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9a4da42e5fb1bdd969d83c99f39bdd160fd277124499420b5f39f5e081a9f0c -size 48298 +oid sha256:51ca53f9c4bae68ce223da3fb7b7a08dd0beb6e9c0ebdc98c7f3e9396794325f +size 48597 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_de.png index 2c2febe8f0..b534c6c5c2 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c2f88235b71a5e8dc496b54ae3d6abf60ffd99372ad952b2588e4eb3d3a4104 -size 43338 +oid sha256:da24f298107887de836c9320588c47e23720b6cc36735472f2bf5b8b545eb072 +size 43720 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_3_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_3_de.png index 54c412001b..ff421ffaa7 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_3_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28438f4a4ea6e9e101ecb016a96a6d8acffabe78531d140245aae599f170742d -size 42487 +oid sha256:14c673c38607f967e65af7680d92bf2a2181fa007bb35fe92adc861368bb7542 +size 48256 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_de.png index ec4adfbf25..3a7369516a 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:89d0fb5b05db746127691b5cb40c88276d140a572122bb943e2dc80a1f8b8eb3 -size 36261 +oid sha256:f135edc8a5c101dc30e7511deda402f12bd20b5e738c4a56a83997311f032746 +size 43311 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_7_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_7_de.png index eb202b9f3e..d1e82e7ea0 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_7_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:95807c82c054157fefd82e05648f5c099613c33d816280280f40a92479009cb2 -size 43937 +oid sha256:ee0b85b15784537aad5f07512654c169161a7523ac5cf00002f07913c3e82b4c +size 52268 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_8_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_8_de.png index 8854711555..327668f4ed 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_8_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_8_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe27d8667d4a0220b4f1cee7b131793dad65469b79f7dc3929c782c9025b9750 -size 45031 +oid sha256:10da3f148a9dd3b2f541c2600c08f90953c572b62f554dce81032f42fd1248c7 +size 53399 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_de.png index dad036e985..bda11656cc 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a44eb83631c42b8f0ed4a72aa7ccf0720484363b8b9dd45bc8b35908c94f0e0c -size 27220 +oid sha256:d144997c48307010cbe9ab727fe94bbac12958d8d54f2b9adf45f9b03ff3babd +size 27588 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_de.png index 7efb530cfd..c2615a560e 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c035769839244b97f2bab01baa770c8b3cfa9f30eccf7e66187301ed984df318 -size 29546 +oid sha256:a669aae91bcaa235e8f9134cd9f38b2ece4852c19b0e98782745a9585e24ff7e +size 29913 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_de.png index d991096b7a..14ccff2fcb 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cabad8bafdf955fd6d82d8b14aaa1bea56ea6a73f51a2bd6a82538c527b2fb5 -size 41205 +oid sha256:701803c3724f739d97efc2157f60bf31de162aeefacb452df8e74db8270c1400 +size 42153 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_de.png index 8a415cf1db..c0b06633f0 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:42a7336ec373fa8b8b92d75f13f9328dd3594017dda18096a4af1fddecb44484 -size 25461 +oid sha256:176d023f205cd78de09bccbfc43badfd8fb1efcb575c8d1aa99de7b8378e4649 +size 29726 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_de.png index 6ce10e25a8..53bdfa5554 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2518686a8c0d1b3fc0a345b3d778c2b15cdabf645835a565e2c31ab027571bef -size 21505 +oid sha256:9cabb111b200cc2275e150063c6e4ebc92d32b4877b047fc0658caa178320f1c +size 26786 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_de.png index eb202b9f3e..d1e82e7ea0 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:95807c82c054157fefd82e05648f5c099613c33d816280280f40a92479009cb2 -size 43937 +oid sha256:ee0b85b15784537aad5f07512654c169161a7523ac5cf00002f07913c3e82b4c +size 52268 diff --git a/screenshots/de/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_de.png b/screenshots/de/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_de.png index d286963ece..8f600a63b1 100644 --- a/screenshots/de/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_de.png +++ b/screenshots/de/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:06e84aad3494762d9f82db6f89a1c82b29e9fac055ded4f92fe109a553eb7016 -size 33335 +oid sha256:ab26718ed14a6ed33a82d5b8aaf7311455d8fa6e9a061ba5af833299f6f54f5a +size 34125 diff --git a/screenshots/de/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_de.png index 26cd7d10c5..1244f3032d 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1656124036ba98fb559a863aba4d81fefcd9b4f52ab9cab852520dfa67bd5373 -size 38156 +oid sha256:39293a575ddbd303a4b184ce6db806423cf94073e52e5d879acf86a6e4ea99d0 +size 38154 diff --git a/screenshots/html/data.js b/screenshots/html/data.js index 73bb02be34..3d2e829373 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,80 +1,80 @@ // 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",20453,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20466,], ["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",20453,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20453,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20453,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20453,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20453,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20453,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20453,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20453,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20453,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20453,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20453,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20466,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20466,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20466,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20466,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20466,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20466,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20466,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20466,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20466,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20466,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20466,], ["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",20453,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20453,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20466,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20466,], ["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",20453,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20453,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20466,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20466,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20466,], ["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",20453,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20453,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20453,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20453,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20453,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20453,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20453,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20453,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20453,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20453,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20453,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20453,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20453,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20453,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20453,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20466,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20466,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20466,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20466,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20466,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20466,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20466,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20466,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20466,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20466,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20466,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20466,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20466,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20466,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20466,], ["libraries.designsystem.theme.components_AllIcons_Icons_en","",0,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20453,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20453,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20453,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20453,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20453,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20466,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20466,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20466,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20466,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20466,], ["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",20453,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20466,], ["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",20453,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20466,], ["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",20453,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20466,], ["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",20453,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20466,], ["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",20453,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20466,], ["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,], @@ -84,20 +84,23 @@ 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","",20453,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en","",20453,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en","",20453,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en","",20453,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en","",20453,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en","",20453,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en","",20453,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en","",20453,], -["features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en","",20453,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_0_en","",20466,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_1_en","",20466,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_2_en","",20466,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_3_en","",20466,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_4_en","",20466,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_5_en","",20466,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_6_en","",20466,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_7_en","",20466,], +["features.messages.impl.attachments.preview_AttachmentsPreviewView_8_en","",20466,], ["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",20453,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20466,], ["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,], +["libraries.matrix.ui.components_AvatarPickerView_Day_0_en","libraries.matrix.ui.components_AvatarPickerView_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_0_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_1_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_1_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_2_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_2_en",0,], @@ -123,22 +126,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",20453,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20466,], ["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",20453,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20453,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20453,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20453,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20453,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20453,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20453,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20466,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20466,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20466,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20466,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20466,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20466,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20466,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20453,], -["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20453,], -["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20453,], -["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20453,], -["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20453,], +["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20466,], +["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20466,], +["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20466,], +["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20466,], +["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20466,], ["features.rageshake.impl.bugreport_BugReportViewNight_0_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_1_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_2_en","",0,], @@ -148,137 +151,139 @@ export const screenshots = [ ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20453,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20453,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20466,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20466,], ["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], ["features.call.impl.ui_CallScreenView_Day_0_en","features.call.impl.ui_CallScreenView_Night_0_en",0,], -["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20453,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20453,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20453,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20453,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20453,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20453,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20466,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20466,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20466,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20466,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20466,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20466,], ["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",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20453,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20453,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20453,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20453,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20453,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20453,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20453,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en",20453,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en",20458,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20466,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20466,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20466,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20466,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20466,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20466,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20466,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_5_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_5_en",20466,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_6_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_6_en",20466,], ["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",20453,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20453,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20453,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20453,], -["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20453,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20466,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20466,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20466,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20466,], +["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20466,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20453,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20466,], ["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",20453,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20453,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20453,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20453,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20453,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20453,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20453,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20453,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20466,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20466,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20466,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20466,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20466,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20466,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20466,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20466,], ["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",20453,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20453,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20453,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20453,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20453,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20453,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20453,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20453,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20453,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20453,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20466,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20466,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20466,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20466,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20466,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20466,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20466,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20466,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20466,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20466,], ["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","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20453,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20453,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20453,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20453,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20453,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20453,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en","",20467,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20466,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en","",20467,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20466,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20466,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20466,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20466,], ["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",20453,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20453,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20453,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20453,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20453,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20453,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20453,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20453,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20453,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20453,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20453,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20453,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20453,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20453,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20453,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20453,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20453,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20453,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20453,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20453,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20466,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20466,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20466,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20466,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20466,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20466,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20466,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20466,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20466,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20466,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20466,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20466,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20466,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20466,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20466,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20466,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20466,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20466,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20466,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20466,], ["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","",20453,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20453,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20453,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20453,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20453,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20453,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20453,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20466,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20466,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20466,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20466,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20466,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20466,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20466,], ["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",20453,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20453,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20453,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20466,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20466,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20466,], ["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",20453,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20466,], ["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",20453,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20453,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20453,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20453,], -["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en",20453,], -["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en",20453,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20453,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20453,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20453,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20453,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20466,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20466,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20466,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20466,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_0_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_0_en",20466,], +["features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Day_1_en","features.linknewdevice.impl.screens.desktop_DesktopNoticeView_Night_1_en",20466,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20466,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20466,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20466,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20466,], ["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,], @@ -293,22 +298,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",20453,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20453,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20453,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20453,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20453,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20453,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20453,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20453,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20453,], -["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20453,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20453,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20453,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20453,], -["libraries.matrix.ui.components_EditableAvatarView_Day_0_en","libraries.matrix.ui.components_EditableAvatarView_Night_0_en",0,], -["libraries.matrix.ui.components_EditableAvatarView_Day_1_en","libraries.matrix.ui.components_EditableAvatarView_Night_1_en",0,], -["libraries.matrix.ui.components_EditableAvatarView_Day_2_en","libraries.matrix.ui.components_EditableAvatarView_Night_2_en",0,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20466,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20466,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20466,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20466,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20466,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",20466,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",20466,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",20466,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",20466,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",20466,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20466,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20466,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",20466,], ["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,], @@ -316,28 +318,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",20453,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20453,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20466,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20466,], ["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",20453,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en",20453,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en",20453,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en",20453,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en",20453,], -["features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en",20453,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20453,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20453,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20453,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_0_en","features.linknewdevice.impl.screens.error_ErrorView_Night_0_en",20453,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_1_en","features.linknewdevice.impl.screens.error_ErrorView_Night_1_en",20453,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_2_en","features.linknewdevice.impl.screens.error_ErrorView_Night_2_en",20453,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_3_en","features.linknewdevice.impl.screens.error_ErrorView_Night_3_en",20453,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_4_en","features.linknewdevice.impl.screens.error_ErrorView_Night_4_en",20453,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_5_en","features.linknewdevice.impl.screens.error_ErrorView_Night_5_en",20453,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_6_en","features.linknewdevice.impl.screens.error_ErrorView_Night_6_en",20453,], -["features.linknewdevice.impl.screens.error_ErrorView_Day_7_en","features.linknewdevice.impl.screens.error_ErrorView_Night_7_en",20453,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_0_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_0_en",20466,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_1_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_1_en",20466,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_2_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_2_en",20466,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_3_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_3_en",20466,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_4_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_4_en",20466,], +["features.linknewdevice.impl.screens.number_EnterNumberView_Day_5_en","features.linknewdevice.impl.screens.number_EnterNumberView_Night_5_en",20466,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20466,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20466,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20466,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_0_en","features.linknewdevice.impl.screens.error_ErrorView_Night_0_en",20466,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_1_en","features.linknewdevice.impl.screens.error_ErrorView_Night_1_en",20466,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_2_en","features.linknewdevice.impl.screens.error_ErrorView_Night_2_en",20466,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_3_en","features.linknewdevice.impl.screens.error_ErrorView_Night_3_en",20466,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_4_en","features.linknewdevice.impl.screens.error_ErrorView_Night_4_en",20466,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_5_en","features.linknewdevice.impl.screens.error_ErrorView_Night_5_en",20466,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_6_en","features.linknewdevice.impl.screens.error_ErrorView_Night_6_en",20466,], +["features.linknewdevice.impl.screens.error_ErrorView_Day_7_en","features.linknewdevice.impl.screens.error_ErrorView_Night_7_en",20466,], ["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,], @@ -356,44 +358,46 @@ 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",20453,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20453,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20453,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20466,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20466,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20466,], ["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",20453,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20453,], +["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20466,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20466,], ["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.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en","features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en",20453,], -["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20453,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20453,], -["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20453,], -["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20453,], -["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20453,], +["features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Day_0_en","features.messages.impl.crypto.historyvisible_HistoryVisibleStateView_Night_0_en",20466,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20466,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20466,], +["features.home.impl.spaces_HomeSpacesView_Day_2_en","features.home.impl.spaces_HomeSpacesView_Night_2_en",20467,], +["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20466,], +["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",20466,], +["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20466,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20453,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20453,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20466,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20466,], ["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",20453,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20453,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20453,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20453,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20453,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20453,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20453,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20453,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20453,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20453,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20453,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20453,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20466,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20466,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20466,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20466,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20466,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20466,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20466,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20466,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20466,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20466,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20466,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20466,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.ruler_HorizontalRuler_Day_0_en","libraries.designsystem.ruler_HorizontalRuler_Night_0_en",0,], ["libraries.designsystem.theme.components_IconButton_Buttons_en","",0,], @@ -406,8 +410,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",20453,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20453,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20466,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20466,], ["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,], @@ -415,115 +419,115 @@ 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",20453,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20466,], ["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",20453,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20466,], ["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",20453,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20466,], ["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20453,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20453,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20466,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20466,], ["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",20453,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20453,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20453,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20466,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20466,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20466,], ["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",20453,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20453,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20453,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20453,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20466,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20466,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20466,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20466,], ["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",20453,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20453,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20453,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20453,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20453,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20453,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20453,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20453,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20466,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20466,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20466,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20466,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20466,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20466,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20466,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20466,], ["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",20453,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20453,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20453,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20453,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20453,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20453,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20453,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20453,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20453,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20453,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20453,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20466,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20466,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20466,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20466,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20466,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20466,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20466,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20466,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20466,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20466,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], -["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20453,], -["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20453,], +["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20466,], +["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20466,], ["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",20453,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20453,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20453,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20453,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20453,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20453,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20453,], -["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20453,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20466,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20466,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20466,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20466,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20466,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20466,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20466,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20466,], ["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",20453,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en",0,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en",20453,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en",20453,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en",0,], -["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en",20453,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_0_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_0_en",20466,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_1_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_1_en",20467,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_2_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_2_en",20466,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_3_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_3_en",20466,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_4_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_4_en",20467,], +["features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Day_5_en","features.linknewdevice.impl.screens.root_LinkNewDeviceRootView_Night_5_en",20466,], ["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",20453,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20466,], ["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,], @@ -578,38 +582,41 @@ 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",20453,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20453,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20453,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20453,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20466,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20466,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20466,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20466,], ["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",20453,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20453,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20453,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20453,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20453,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20453,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20453,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20453,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20453,], -["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20453,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20453,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20453,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20453,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20453,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20453,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20453,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20453,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20453,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20453,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20453,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20453,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20453,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20453,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20453,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20453,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20466,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20466,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20466,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20466,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20466,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20466,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20466,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20466,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20466,], +["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20466,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20466,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20466,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20466,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20466,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20466,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20466,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20466,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20466,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20466,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20466,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20466,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20466,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20466,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20466,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20466,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20453,], +["features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_0_en","features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_0_en",20467,], +["features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_1_en","features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_1_en",20467,], +["features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Day_2_en","features.securityandprivacy.impl.manageauthorizedspaces_ManageAuthorizedSpacesView_Night_2_en",20467,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20466,], ["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,], @@ -622,22 +629,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",20453,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20453,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20466,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20466,], ["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",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20453,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20453,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20466,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20466,], ["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,], @@ -645,14 +652,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","",20453,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20453,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20466,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20466,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20453,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20466,], ["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","",20453,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20466,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -666,7 +673,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",20453,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20466,], ["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,], @@ -675,7 +682,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",20453,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20466,], ["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,], @@ -683,26 +690,27 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessagesReactionButton_Day_1_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_1_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_2_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_2_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_3_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_3_en",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20453,], -["features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en","features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en",20453,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20453,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20453,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20453,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20453,], -["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20453,], -["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20453,], -["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20453,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20453,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20453,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20453,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20453,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20453,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20453,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20453,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20453,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20453,], +["features.messages.impl_MessagesViewA11y_en","",0,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20466,], +["features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Day_0_en","features.messages.impl.crypto.historyvisible_MessagesViewWithHistoryVisible_Night_0_en",20466,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20466,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20466,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20466,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20466,], +["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20466,], +["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20466,], +["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20466,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20466,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20466,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20466,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20466,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20466,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20466,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20466,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20466,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20466,], ["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",20453,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20466,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], @@ -713,112 +721,113 @@ 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",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20453,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20453,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20453,], +["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20466,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20466,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20466,], ["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",20453,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20453,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20453,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20453,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20453,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20453,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20453,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20453,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20466,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20466,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20466,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20466,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20466,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20466,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20466,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20466,], ["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",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20453,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20466,], ["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",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20453,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20453,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20466,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20466,], ["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",20453,], -["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",0,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20453,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20453,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20453,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20453,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20466,], +["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",20467,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20466,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20466,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20466,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20466,], ["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",20453,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20453,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20453,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20466,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20466,], ["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",20453,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20453,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20453,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20453,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20453,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20453,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20453,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20453,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20453,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20453,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20453,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20453,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20453,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20453,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20466,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20466,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20466,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20466,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20466,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20466,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20466,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20466,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20466,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20466,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20466,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20466,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20466,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20466,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20453,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20453,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20453,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20453,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20453,], +["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",20466,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20466,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20466,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20466,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20466,], ["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",20453,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20453,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20453,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20453,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20453,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20453,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20453,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20453,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20453,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20453,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20453,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20466,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20466,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20466,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20466,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20466,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20466,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20466,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20466,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20466,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20466,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20466,], ["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,], @@ -832,207 +841,208 @@ 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","",20453,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20453,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20453,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20453,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20466,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20466,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20466,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20466,], ["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","",20453,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20453,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20466,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20466,], ["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",20453,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20453,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20453,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20453,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20453,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20453,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20453,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20453,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20453,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20453,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20453,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20453,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20453,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20453,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20453,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20453,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20453,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20453,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20453,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20453,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20453,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20453,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20453,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20453,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20453,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20453,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20453,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20466,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20466,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20466,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20466,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20466,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20466,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20466,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20466,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20466,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20466,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20466,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20466,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20466,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20466,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20466,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20466,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20466,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20466,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20466,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20466,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20466,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20466,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20466,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20466,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20466,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20466,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20466,], ["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",20453,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20453,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20466,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20466,], ["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",20453,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20453,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20453,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20453,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20453,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20453,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20453,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20466,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20466,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20466,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20466,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20466,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20466,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20466,], ["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",20453,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20453,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20453,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20453,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20453,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20453,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20453,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20453,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20453,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20453,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20453,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20453,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20453,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20453,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20453,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20453,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20453,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20466,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20466,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20466,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20466,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20466,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20466,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20466,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20466,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20466,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20466,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20466,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20466,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20466,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20466,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20466,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20466,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20466,], ["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",20453,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20453,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20453,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20453,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20453,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20453,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20453,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20453,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20453,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20453,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20453,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20453,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20453,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20466,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20466,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20466,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20466,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20466,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20466,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20466,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20466,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20466,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20466,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20466,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20466,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20466,], ["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",20453,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20453,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20453,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20453,], -["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20453,], -["features.roomdetails.impl_RoomDetails_0_en","",20453,], -["features.roomdetails.impl_RoomDetails_10_en","",20453,], -["features.roomdetails.impl_RoomDetails_11_en","",20453,], -["features.roomdetails.impl_RoomDetails_12_en","",20453,], -["features.roomdetails.impl_RoomDetails_13_en","",20453,], -["features.roomdetails.impl_RoomDetails_14_en","",20453,], -["features.roomdetails.impl_RoomDetails_15_en","",20453,], -["features.roomdetails.impl_RoomDetails_16_en","",20453,], -["features.roomdetails.impl_RoomDetails_17_en","",20453,], -["features.roomdetails.impl_RoomDetails_18_en","",20453,], -["features.roomdetails.impl_RoomDetails_19_en","",20453,], -["features.roomdetails.impl_RoomDetails_1_en","",20453,], -["features.roomdetails.impl_RoomDetails_2_en","",20453,], -["features.roomdetails.impl_RoomDetails_3_en","",20453,], -["features.roomdetails.impl_RoomDetails_4_en","",20453,], -["features.roomdetails.impl_RoomDetails_5_en","",20453,], -["features.roomdetails.impl_RoomDetails_6_en","",20453,], -["features.roomdetails.impl_RoomDetails_7_en","",20453,], -["features.roomdetails.impl_RoomDetails_8_en","",20453,], -["features.roomdetails.impl_RoomDetails_9_en","",20453,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20453,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20453,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20453,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20453,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20453,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20453,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20453,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20453,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20453,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20466,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20466,], +["features.roomdetails.impl_RoomDetailsA11y_en","",0,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20466,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en",20466,], +["features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en","features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en",20466,], +["features.roomdetails.impl_RoomDetails_0_en","",20466,], +["features.roomdetails.impl_RoomDetails_10_en","",20466,], +["features.roomdetails.impl_RoomDetails_11_en","",20466,], +["features.roomdetails.impl_RoomDetails_12_en","",20466,], +["features.roomdetails.impl_RoomDetails_13_en","",20466,], +["features.roomdetails.impl_RoomDetails_14_en","",20466,], +["features.roomdetails.impl_RoomDetails_15_en","",20466,], +["features.roomdetails.impl_RoomDetails_16_en","",20466,], +["features.roomdetails.impl_RoomDetails_17_en","",20466,], +["features.roomdetails.impl_RoomDetails_18_en","",20466,], +["features.roomdetails.impl_RoomDetails_19_en","",20466,], +["features.roomdetails.impl_RoomDetails_1_en","",20466,], +["features.roomdetails.impl_RoomDetails_2_en","",20466,], +["features.roomdetails.impl_RoomDetails_3_en","",20466,], +["features.roomdetails.impl_RoomDetails_4_en","",20466,], +["features.roomdetails.impl_RoomDetails_5_en","",20466,], +["features.roomdetails.impl_RoomDetails_6_en","",20466,], +["features.roomdetails.impl_RoomDetails_7_en","",20466,], +["features.roomdetails.impl_RoomDetails_8_en","",20466,], +["features.roomdetails.impl_RoomDetails_9_en","",20466,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20466,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20466,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20466,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20466,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20466,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20466,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20466,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20466,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20466,], ["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",20453,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20453,], -["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20453,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20453,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20453,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20453,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20453,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20453,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20453,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20466,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20466,], +["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20466,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20466,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20466,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20466,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20466,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20466,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20466,], ["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",20453,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20453,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20453,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20453,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20453,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20453,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20453,], -["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20453,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20453,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20453,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20453,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20453,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20453,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20453,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20453,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20453,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20453,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20466,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20466,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20466,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20466,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20466,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20466,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20466,], +["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",20466,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20466,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20466,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20466,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20466,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20466,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20466,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20466,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20466,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20466,], ["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",20453,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20453,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20453,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20453,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20453,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20453,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20453,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20453,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20453,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20453,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20453,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20453,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20453,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20453,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20466,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20466,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20466,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20466,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20466,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20466,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20466,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20466,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20466,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20466,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20466,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20466,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20466,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20466,], ["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,], @@ -1055,16 +1065,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",20453,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20453,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20453,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20453,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20453,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20453,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20453,], -["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20453,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20466,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20466,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20466,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20466,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20466,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20466,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20466,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20466,], ["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",0,], +["features.home.impl.components_RoomSummaryRow_Day_37_en","features.home.impl.components_RoomSummaryRow_Night_37_en",20467,], ["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,], @@ -1072,109 +1082,117 @@ 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",20453,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20453,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20453,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20466,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20466,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20466,], ["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",20453,], -["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20453,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en",20453,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en",20453,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en",20453,], -["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en",20453,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20453,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20453,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20466,], +["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20466,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_0_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_0_en",20466,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_1_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_1_en",20466,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_2_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_2_en",20466,], +["features.linknewdevice.impl.screens.scan_ScanQrCodeView_Day_3_en","features.linknewdevice.impl.screens.scan_ScanQrCodeView_Night_3_en",20466,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20466,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20466,], ["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","",20453,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20466,], ["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","",20453,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20453,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20453,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20453,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20453,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20453,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20453,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20453,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20453,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20453,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20453,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20453,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20453,], -["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20453,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20466,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20466,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20466,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20466,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20466,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20466,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20466,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20466,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20466,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20466,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20466,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20466,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_20_en","",20467,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_21_en","",20467,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_22_en","",20467,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_23_en","",20467,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_20_en","",20467,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_21_en","",20467,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_22_en","",20467,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_23_en","",20467,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",20466,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",20466,], ["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,], @@ -1187,12 +1205,12 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_0_en","libraries.matrix.ui.components_SelectedUser_Night_0_en",0,], ["libraries.matrix.ui.components_SelectedUser_Day_1_en","libraries.matrix.ui.components_SelectedUser_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedUsersRowList_Day_0_en","libraries.matrix.ui.components_SelectedUsersRowList_Night_0_en",0,], -["libraries.textcomposer.components_SendButton_Day_0_en","libraries.textcomposer.components_SendButton_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20453,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20453,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20453,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20453,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20453,], +["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",20466,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20466,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20466,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20466,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20466,], ["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,], @@ -1202,28 +1220,28 @@ 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",20453,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20453,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20453,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20453,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20453,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20453,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20453,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20453,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20466,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20466,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20466,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20466,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20466,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20466,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20466,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20466,], ["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",20453,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20453,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20453,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20453,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20453,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20453,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20453,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20453,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20453,], -["features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en","features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en",20453,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20453,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20466,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20466,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20466,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20466,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20466,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20466,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20466,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20466,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20466,], +["features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Day_0_en","features.linknewdevice.impl.screens.qrcode_ShowQrCodeView_Night_0_en",20466,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20466,], ["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,], @@ -1233,102 +1251,102 @@ 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",20453,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20466,], ["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",20453,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20466,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20453,], -["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20453,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20453,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20466,], +["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20466,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20466,], ["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",20453,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20453,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20453,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20453,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20453,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20453,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20453,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20453,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20453,], -["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20453,], -["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20453,], -["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20453,], -["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20453,], -["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20453,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20453,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20453,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20453,], -["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20453,], -["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20453,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20466,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20466,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20466,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20466,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20466,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20466,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20466,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20466,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20466,], +["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20466,], +["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20466,], +["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20466,], +["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20466,], +["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20466,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20466,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20466,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20466,], +["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20466,], +["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20466,], ["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",20453,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20453,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20453,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20453,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20453,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20453,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20453,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20466,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20466,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20466,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20466,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20466,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20466,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20466,], ["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",20453,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20466,], ["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",20453,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20466,], ["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",20453,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20453,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20453,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20453,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20453,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20453,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20453,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20453,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20453,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20453,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20453,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20453,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20453,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20453,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20453,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20466,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20466,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20466,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20466,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20466,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20466,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20466,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20466,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20466,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20466,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20466,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20466,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20466,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20466,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20466,], ["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",20453,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20453,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20466,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20466,], ["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,], @@ -1340,16 +1358,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",20453,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20453,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20453,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20453,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20453,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20466,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20466,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20466,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20466,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20466,], ["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",20453,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20453,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20466,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20466,], ["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,], @@ -1359,18 +1377,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",20453,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20466,], ["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",20453,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20466,], ["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,], @@ -1378,18 +1396,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",20453,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20466,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20466,], ["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",20453,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20453,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20466,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20466,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20466,], ["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",20453,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20466,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20466,], ["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,], @@ -1398,41 +1416,41 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20466,], ["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",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20466,], ["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",20453,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20466,], ["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","",20453,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20466,], ["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",20453,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20453,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20466,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20466,], ["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",20453,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20466,], ["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",20453,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20453,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20453,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20466,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20466,], ["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",20453,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20453,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20466,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20466,], ["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",20453,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20466,], ["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,], @@ -1441,8 +1459,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",20453,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20466,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20466,], ["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,], @@ -1457,8 +1475,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",20453,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20453,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20466,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20466,], ["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,], @@ -1481,85 +1499,84 @@ 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",20453,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20453,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20466,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20466,], ["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",20453,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20453,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20453,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20453,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20453,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20453,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20453,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20453,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20466,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20466,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20466,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20466,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20466,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20466,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20466,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20466,], ["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",20453,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20466,], ["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",20453,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20466,], ["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",20453,], +["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",20453,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20453,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20453,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20453,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20453,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20453,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20453,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20453,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20466,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20466,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20466,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20466,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20466,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20466,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20466,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20466,], ["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",20453,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20453,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20453,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20453,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20453,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20453,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20466,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20466,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20466,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20466,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20466,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20466,], ["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","",20453,], -["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20466,], ["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",20453,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20453,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20453,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20453,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20466,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20466,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20466,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20466,], ["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",20453,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20466,], ["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",20453,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20466,], ["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",20453,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20453,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20453,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20453,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20453,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20453,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20453,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20453,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20453,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20453,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20453,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20453,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20466,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20466,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20466,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20466,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20466,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20466,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20466,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20466,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20466,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20466,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20466,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20466,], ["features.verifysession.impl.ui_VerificationUserProfileContent_Day_0_en","features.verifysession.impl.ui_VerificationUserProfileContent_Night_0_en",0,], ["libraries.designsystem.ruler_VerticalRuler_Day_0_en","libraries.designsystem.ruler_VerticalRuler_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_1_en",0,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20453,], -["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20453,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20466,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20466,], ["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",20453,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20466,], ["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,], @@ -1573,9 +1590,9 @@ export const screenshots = [ ["libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en","libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en","libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en",0,], -["libraries.textcomposer.components_VoiceMessageDeleteButton_Day_0_en","libraries.textcomposer.components_VoiceMessageDeleteButton_Night_0_en",0,], +["libraries.textcomposer.components_VoiceMessageDeleteButtonIcon_Day_0_en","libraries.textcomposer.components_VoiceMessageDeleteButtonIcon_Night_0_en",0,], ["libraries.textcomposer.components_VoiceMessagePreview_Day_0_en","libraries.textcomposer.components_VoiceMessagePreview_Night_0_en",0,], -["libraries.textcomposer.components_VoiceMessageRecorderButton_Day_0_en","libraries.textcomposer.components_VoiceMessageRecorderButton_Night_0_en",0,], +["libraries.textcomposer.components_VoiceMessageRecorderButtonIcon_Day_0_en","libraries.textcomposer.components_VoiceMessageRecorderButtonIcon_Night_0_en",0,], ["libraries.textcomposer.components_VoiceMessageRecording_Day_0_en","libraries.textcomposer.components_VoiceMessageRecording_Night_0_en",0,], ["libraries.designsystem.components.media_WaveformPlaybackView_Day_0_en","libraries.designsystem.components.media_WaveformPlaybackView_Night_0_en",0,], ["libraries.designsystem.ruler_WithRulers_Day_0_en","libraries.designsystem.ruler_WithRulers_Night_0_en",0,], From 85ec7faebe279923cc1b66b022af04de170bb20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 14 Jan 2026 12:47:10 +0100 Subject: [PATCH 346/347] Setting version for the release 26.01.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 f00099753c..8ae9e90dad 100644 --- a/plugins/src/main/kotlin/Versions.kt +++ b/plugins/src/main/kotlin/Versions.kt @@ -33,13 +33,13 @@ import org.gradle.jvm.toolchain.JavaLanguageVersion * Year of the version on 2 digits. * Do not update this value. it is updated by the release script. */ -private const val versionYear = 25 +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 = 12 +private const val versionMonth = 1 /** * Release number in the month. Value must be in [0,99]. From fddda246abad93cce8317726609a27b4473c2f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 14 Jan 2026 12:50:35 +0100 Subject: [PATCH 347/347] Adding fastlane file for version 26.01.0 --- fastlane/metadata/android/en-US/changelogs/202601000.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/202601000.txt diff --git a/fastlane/metadata/android/en-US/changelogs/202601000.txt b/fastlane/metadata/android/en-US/changelogs/202601000.txt new file mode 100644 index 0000000000..98c450dce0 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/202601000.txt @@ -0,0 +1,2 @@ +Main changes in this version: iterated on spaces, improved the room list stability and performance, and a long list of bug fixes. +Full changelog: https://github.com/element-hq/element-x-android/releases