diff --git a/CHANGES.md b/CHANGES.md index f747e9ded9..1d248fbfcc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,20 @@ +Changes in Element X v25.06.2 +============================= + +## What's Changed +### 🐛 Bugfixes +* Fix crash when using Element Call on API <= 30 by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4847 +* Element Call: add delay before selecting the default audio device by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4854 +* Fix for message composer losing focus in Compose 1.8.0 by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4853 +### Dependency upgrades +* chore(deps): update plugin dependencycheck to v12.1.2 by @renovate in https://github.com/element-hq/element-x-android/pull/4840 +* deps (matrix rust sdk) : bump version to 25.06.10 by @ganfra in https://github.com/element-hq/element-x-android/pull/4855 +### Others +* feat: Support matrix: links by @ShadowRZ in https://github.com/element-hq/element-x-android/pull/4839 + + +**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v25.06.1...v25.06.2 + ## What's Changed ### ✨ Features * Enable support for Android Auto. by @bmarty in https://github.com/element-hq/element-x-android/pull/4818 diff --git a/appnav/src/main/res/values-in/translations.xml b/appnav/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..8314323845 --- /dev/null +++ b/appnav/src/main/res/values-in/translations.xml @@ -0,0 +1,5 @@ + + + "Keluar & Tingkatkan" + "Homeserver Anda tidak lagi mendukung protokol lama. Silakan keluar dan masuk kembali untuk terus menggunakan aplikasi." + 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 52443fa4a1..47237d5f77 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 @@ -16,7 +16,6 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService import io.element.android.services.appnavstate.test.FakeAppForegroundStateService import io.element.android.tests.testutils.testCoroutineDispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test @@ -29,7 +28,6 @@ class MatrixSessionCacheTest { assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull() } - @OptIn(ExperimentalCoroutinesApi::class) @Test fun `test getSyncOrchestratorOrNull`() = runTest { val fakeAuthenticationService = FakeMatrixAuthenticationService() diff --git a/fastlane/metadata/android/en-US/changelogs/202506030.txt b/fastlane/metadata/android/en-US/changelogs/202506030.txt new file mode 100644 index 0000000000..f52df1a372 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/202506030.txt @@ -0,0 +1,2 @@ +Main changes in this version: add support for tombstoned rooms, improve notification reliability. +Full changelog: https://github.com/element-hq/element-x-android/releases \ No newline at end of file diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt index 363ace4b79..e16428de3b 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt @@ -44,6 +44,7 @@ import io.element.android.services.appnavstate.api.ActiveRoomsHolder import io.element.android.services.appnavstate.api.AppForegroundStateService import io.element.android.services.toolbox.api.systemclock.SystemClock import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -52,6 +53,7 @@ import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive import timber.log.Timber import java.util.UUID +import kotlin.time.Duration.Companion.seconds class CallScreenPresenter @AssistedInject constructor( @Assisted private val callType: CallType, @@ -165,6 +167,13 @@ class CallScreenPresenter @AssistedInject constructor( // If the call was joined, we need to hang up first. Then the UI will be dismissed automatically. sendHangupMessage(widgetId, interceptor) isJoinedCall = false + + coroutineScope.launch { + // Wait for a couple of seconds to receive the hangup message + // If we don't get it in time, we close the screen anyway + delay(2.seconds) + close(callWidgetDriver.value, navigator) + } } else { coroutineScope.launch { close(callWidgetDriver.value, navigator) diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenView.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenView.kt index f1aa192d28..7547d8e7c7 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenView.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenView.kt @@ -38,6 +38,7 @@ import io.element.android.features.call.impl.pip.PictureInPictureEvents import io.element.android.features.call.impl.pip.PictureInPictureState import io.element.android.features.call.impl.pip.PictureInPictureStateProvider import io.element.android.features.call.impl.pip.aPictureInPictureState +import io.element.android.features.call.impl.utils.InvalidAudioDeviceReason import io.element.android.features.call.impl.utils.WebViewAudioManager import io.element.android.features.call.impl.utils.WebViewPipController import io.element.android.features.call.impl.utils.WebViewWidgetMessageInterceptor @@ -105,6 +106,14 @@ internal fun CallScreenView( } else { var webViewAudioManager by remember { mutableStateOf(null) } val coroutineScope = rememberCoroutineScope() + + var invalidAudioDeviceReason by remember { mutableStateOf(null) } + invalidAudioDeviceReason?.let { + InvalidAudioDeviceDialog(invalidAudioDeviceReason = it) { + invalidAudioDeviceReason = null + } + } + CallWebView( modifier = Modifier .padding(padding) @@ -130,7 +139,11 @@ internal fun CallScreenView( }, onError = { state.eventSink(CallScreenEvents.OnWebViewError(it)) }, ) - webViewAudioManager = WebViewAudioManager(webView, coroutineScope) + webViewAudioManager = WebViewAudioManager( + webView = webView, + coroutineScope = coroutineScope, + onInvalidAudioDeviceAdded = { invalidAudioDeviceReason = it }, + ) state.eventSink(CallScreenEvents.SetupMessageChannels(interceptor)) val pipController = WebViewPipController(webView) pipState.eventSink(PictureInPictureEvents.SetPipController(pipController)) @@ -157,6 +170,21 @@ internal fun CallScreenView( } } +@Composable +private fun InvalidAudioDeviceDialog( + invalidAudioDeviceReason: InvalidAudioDeviceReason, + onDismiss: () -> Unit, +) { + ErrorDialog( + content = when (invalidAudioDeviceReason) { + InvalidAudioDeviceReason.BT_AUDIO_DEVICE_DISABLED -> { + stringResource(R.string.call_invalid_audio_device_bluetooth_devices_disabled) + } + }, + onSubmit = onDismiss, + ) +} + @Composable private fun CallWebView( url: AsyncData, @@ -277,3 +305,9 @@ internal fun CallScreenPipViewPreview( requestPermissions = { _, _ -> }, ) } + +@PreviewsDayNight +@Composable +internal fun InvalidAudioDeviceDialogPreview() = ElementPreview { + InvalidAudioDeviceDialog(invalidAudioDeviceReason = InvalidAudioDeviceReason.BT_AUDIO_DEVICE_DISABLED) {} +} diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WebViewAudioManager.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WebViewAudioManager.kt index dc55ff2ac4..b7d1fdf466 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WebViewAudioManager.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WebViewAudioManager.kt @@ -40,8 +40,22 @@ import kotlin.time.Duration.Companion.milliseconds class WebViewAudioManager( private val webView: WebView, private val coroutineScope: CoroutineScope, + private val onInvalidAudioDeviceAdded: (InvalidAudioDeviceReason) -> Unit, ) { - // The list of device types that are considered as communication devices, sorted by likelihood of it being used for communication. + /** + * Whether to disable bluetooth audio devices. This must be done on Android versions lower than Android 12, + * since the WebView approach breaks when using the legacy Bluetooth audio APIs. + */ + private val disableBluetoothAudioDevices = Build.VERSION.SDK_INT < Build.VERSION_CODES.S + + /** + * This flag indicates whether the WebView audio is enabled or not. By default, it is enabled. + */ + private val isWebViewAudioEnabled = AtomicBoolean(true) + + /** + * The list of device types that are considered as communication devices, sorted by likelihood of it being used for communication. + */ private val wantedDeviceTypes = listOf( // Paired bluetooth device with microphone AudioDeviceInfo.TYPE_BLUETOOTH_SCO, @@ -60,6 +74,10 @@ class WebViewAudioManager( private val audioManager = webView.context.getSystemService(Context.AUDIO_SERVICE) as AudioManager + /** + * This wake lock is used to turn off the screen when the proximity sensor is triggered during a call, + * if the selected audio device is the built-in earpiece. + */ private val proximitySensorWakeLock by lazy { webView.context.getSystemService() ?.takeIf { it.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) } @@ -296,12 +314,13 @@ class WebViewAudioManager( * @param availableDevices The list of available audio devices to select from. If not provided, it will use the current list of audio devices. */ private fun selectDefaultAudioDevice(availableDevices: List = listAudioDevices()) { - val selectedDevice = availableDevices.minByOrNull { - wantedDeviceTypes.indexOf(it.type).let { index -> - // If the device type is not in the wantedDeviceTypes list, we give it a low priority - if (index == -1) Int.MAX_VALUE else index + val selectedDevice = availableDevices + .minByOrNull { + wantedDeviceTypes.indexOf(it.type).let { index -> + // If the device type is not in the wantedDeviceTypes list, we give it a low priority + if (index == -1) Int.MAX_VALUE else index + } } - } expectedNewCommunicationDeviceId = selectedDevice?.id audioManager.selectAudioDevice(selectedDevice) @@ -361,6 +380,13 @@ class WebViewAudioManager( // On Android 11 and lower, we don't have the concept of communication devices // We have to call the right methods based on the device type if (device != null) { + if (device.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO && disableBluetoothAudioDevices) { + Timber.w("Bluetooth audio devices are disabled on this Android version") + setAudioEnabled(false) + onInvalidAudioDeviceAdded(InvalidAudioDeviceReason.BT_AUDIO_DEVICE_DISABLED) + return + } + setAudioEnabled(true) isSpeakerphoneOn = device.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER isBluetoothScoOn = device.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO } else { @@ -380,6 +406,19 @@ class WebViewAudioManager( proximitySensorWakeLock?.release() } } + + /** + * Sets whether the audio is enabled for Element Call in the WebView. + * It will only perform the change if the audio state has changed. + */ + private fun setAudioEnabled(enabled: Boolean) { + coroutineScope.launch(Dispatchers.Main) { + Timber.d("Setting audio enabled in Element Call: $enabled") + if (isWebViewAudioEnabled.getAndSet(enabled) != enabled) { + webView.evaluateJavascript("controls.setAudioEnabled($enabled);", null) + } + } + } } /** @@ -434,6 +473,10 @@ private fun isBuiltIn(type: Int): Boolean = when (type) { else -> false } +enum class InvalidAudioDeviceReason { + BT_AUDIO_DEVICE_DISABLED, +} + /** * This class is used to serialize the audio device information to JSON. */ diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WebViewPipController.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WebViewPipController.kt index 8fea797425..f46db3ca2b 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WebViewPipController.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WebViewPipController.kt @@ -11,6 +11,10 @@ import android.webkit.WebView import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine +/** + * Documentation about the `controls` command can be found here: + * https://github.com/element-hq/element-call/blob/livekit/docs/controls.md#picture-in-picture + */ class WebViewPipController( private val webView: WebView, ) : PipController { diff --git a/features/call/impl/src/main/res/values-fr/translations.xml b/features/call/impl/src/main/res/values-fr/translations.xml index bd04a5b362..bab8f6376d 100644 --- a/features/call/impl/src/main/res/values-fr/translations.xml +++ b/features/call/impl/src/main/res/values-fr/translations.xml @@ -3,5 +3,6 @@ "Appel en cours" "Cliquez pour retourner à l’appel." "☎️ Appel en cours" + "Element Call ne prend pas en charge l’utilisation d’accessoires Bluetooth dans cette version d’Android. Sélectionnez une autre sortie audio." "Appel Element entrant" diff --git a/features/call/impl/src/main/res/values-nb/translations.xml b/features/call/impl/src/main/res/values-nb/translations.xml index 5ae5554314..b93abc6d87 100644 --- a/features/call/impl/src/main/res/values-nb/translations.xml +++ b/features/call/impl/src/main/res/values-nb/translations.xml @@ -3,5 +3,6 @@ "Pågående samtale" "Trykk for å gå tilbake til samtalen" "☎️ Samtale pågår" + "Element Call støtter ikke bruk av Bluetooth-lydenheter i denne Android-versjonen. Velg en annen lydenhet." "Innkommende Element-anrop" diff --git a/features/call/impl/src/main/res/values/localazy.xml b/features/call/impl/src/main/res/values/localazy.xml index 5a386b2416..5ab2caa4fd 100644 --- a/features/call/impl/src/main/res/values/localazy.xml +++ b/features/call/impl/src/main/res/values/localazy.xml @@ -3,5 +3,6 @@ "Ongoing call" "Tap to return to the call" "☎️ Call in progress" + "Element Call does not support using Bluetooth audio devices in this Android version. Please select a different audio device." "Incoming Element Call" 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 4611c7a211..c11f08fc14 100644 --- a/features/createroom/impl/src/main/res/values-es/translations.xml +++ b/features/createroom/impl/src/main/res/values-es/translations.xml @@ -21,6 +21,10 @@ Puedes cambiar esto en cualquier momento en los ajustes de la sala." "Tema (opcional)" "Directorio de salas" "Se ha producido un error al intentar iniciar un chat" + "Unirse a una sala por su dirección" + "Dirección no válida" "Introducir…" + "Sala encontrada" + "No se encontró la sala" "p. ej., #nombre-de-la-sala:matrix.org" diff --git a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationView.kt b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationView.kt index 9e61f030c5..3b0d8b6e1a 100644 --- a/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationView.kt +++ b/features/deactivation/impl/src/main/kotlin/io/element/android/features/logout/impl/AccountDeactivationView.kt @@ -5,8 +5,6 @@ * Please see LICENSE files in the repository root for full details. */ -@file:OptIn(ExperimentalComposeUiApi::class) - package io.element.android.features.logout.impl import androidx.compose.foundation.clickable @@ -32,7 +30,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.autofill.ContentType import androidx.compose.ui.graphics.Color diff --git a/features/deactivation/impl/src/main/res/values-in/translations.xml b/features/deactivation/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..e255ad34e9 --- /dev/null +++ b/features/deactivation/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,14 @@ + + + "Harap konfirmasi bahwa Anda ingin menonaktifkan akun Anda. Tindakan ini tidak dapat diurungkan." + "Hapus semua pesan saya" + "Peringatan: Pengguna masa depan mungkin melihat percakapan yang tidak lengkap." + "Penonaktifan akun Anda %1$s, ini akan:" + "tidak dapat diurungkan" + "%1$s akun Anda (Anda tidak dapat masuk kembali, dan ID Anda tidak dapat digunakan kembali)." + "Nonaktifkan secara permanen" + "Mengeluarkan Anda dari semua ruangan obrolan." + "Hapus informasi akun Anda dari server identitas kami." + "Pesan Anda akan tetap terlihat oleh pengguna terdaftar tetapi tidak akan tersedia bagi pengguna baru atau tidak terdaftar jika Anda memilih untuk menghapusnya." + "Nonaktifkan akun" + diff --git a/features/ftue/impl/src/main/res/values-es/translations.xml b/features/ftue/impl/src/main/res/values-es/translations.xml index 20338b999f..36015aa6dd 100644 --- a/features/ftue/impl/src/main/res/values-es/translations.xml +++ b/features/ftue/impl/src/main/res/values-es/translations.xml @@ -12,7 +12,7 @@ "Esperando en otro dispositivo…" "Puedes cambiar la configuración más tarde." "Activa las notificaciones y nunca te pierdas un mensaje" - "Introduzca la clave de recuperación" + "Introduce la clave de recuperación" "Las llamadas, las encuestas, la búsqueda y más se agregarán más adelante este año." "El historial de mensajes de las salas cifradas aún no está disponible." "Nos encantaría saber de ti, haznos saber lo que piensas a través de la página de configuración." diff --git a/features/invite/impl/src/main/res/values-es/translations.xml b/features/invite/impl/src/main/res/values-es/translations.xml index c3660e35af..a88f9bc28d 100644 --- a/features/invite/impl/src/main/res/values-es/translations.xml +++ b/features/invite/impl/src/main/res/values-es/translations.xml @@ -1,5 +1,10 @@ + "No verás ningún mensaje ni invitación a sala que provenga de este usuario" + "Bloquear usuario" + "Denunciar esta sala a tu proveedor de cuentas." + "Describe el motivo de la denuncia…" + "Rechazar y bloquear" "¿Estás seguro de que quieres rechazar la invitación a unirte a %1$s?" "Rechazar la invitación" "¿Estás seguro de que quieres rechazar este chat privado con %1$s?" diff --git a/features/invite/impl/src/main/res/values-ru/translations.xml b/features/invite/impl/src/main/res/values-ru/translations.xml index da7bb1c449..90d467e62c 100644 --- a/features/invite/impl/src/main/res/values-ru/translations.xml +++ b/features/invite/impl/src/main/res/values-ru/translations.xml @@ -1,6 +1,8 @@ + "Вы не увидите сообщений или приглашений в комнату от этого пользователя" "Заблокировать пользователя" + "Сообщите об этой комнате своему поставщику учетной записи." "Опишите причину жалобы…" "Отклонить и заблокировать" "Вы уверены, что хотите отклонить приглашение в %1$s?" diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomFlowNode.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomFlowNode.kt index 4d3d9be86c..ecd4c920c8 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomFlowNode.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomFlowNode.kt @@ -79,7 +79,7 @@ class JoinRoomFlowNode @AssistedInject constructor( JoinRoomView( state = state, onBackClick = ::navigateUp, - onJoinSuccess = ::navigateUp, + onJoinSuccess = {}, onForgetSuccess = ::navigateUp, onCancelKnockSuccess = {}, onKnockSuccess = {}, diff --git a/features/joinroom/impl/src/main/res/values-in/translations.xml b/features/joinroom/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..4988e2dd58 --- /dev/null +++ b/features/joinroom/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,18 @@ + + + "Batalkan permintaan" + "Ya, batalkan" + "Apakah Anda yakin ingin membatalkan permintaan Anda untuk bergabung dengan ruangan ini?" + "Batalkan permintaan untuk bergabung" + "Gabung dengan ruangan" + "Ketuk untuk bergabung" + "Pesan (opsional)" + "Anda akan menerima undangan untuk bergabung dengan ruangan jika permintaan Anda diterima." + "Permintaan untuk bergabung dikirim" + "%1$s belum mendukung space. Anda dapat mengakses space di web." + "Space belum didukung" + "Klik tombol di bawah ini dan administrator kamar akan diberi tahu. Anda akan dapat bergabung dengan percakapan setelah disetujui." + "Anda harus menjadi anggota ruangan ini untuk melihat riwayat pesan." + "Ingin bergabung dengan ruangan ini?" + "Pratinjau tidak tersedia" + diff --git a/features/knockrequests/impl/src/main/res/values-in/translations.xml b/features/knockrequests/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..08480082c5 --- /dev/null +++ b/features/knockrequests/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,35 @@ + + + "Ya, terima semua" + "Apakah Anda yakin ingin menerima semua permintaan untuk bergabung?" + "Terima semua permintaan" + "Terima semua" + "Kami tidak dapat menerima semua permintaan. Apakah Anda ingin mencoba lagi?" + "Gagal menerima semua permintaan" + "Menerima semua permintaan untuk bergabung" + "Kami tidak dapat menerima permintaan ini. Apakah Anda ingin mencoba lagi?" + "Gagal menerima permintaan" + "Menerima permintaan untuk bergabung" + "Ya, tolak dan cekal" + "Apakah Anda yakin ingin menolak dan mencekal %1$s? Pengguna ini tidak akan dapat meminta akses untuk bergabung ke ruangan ini lagi." + "Tolak dan cekal akses" + "Menolak dan mencekal akses" + "Ya, tolak" + "Apakah Anda yakin ingin menolak permintaan %1$s untuk bergabung ke ruangan ini?" + "Tolak akses" + "Tolak dan cekal" + "Kami tidak dapat menolak permintaan ini. Apakah Anda ingin mencoba lagi?" + "Gagal menolak permintaan" + "Menolak permintaan untuk bergabung" + "Ketika seseorang akan meminta untuk bergabung dengan ruangan, Anda akan dapat melihat permintaan mereka di sini." + "Tidak ada permintaan yang tertunda untuk bergabung" + "Memuat permintaan untuk bergabung…" + "Permintaan untuk bergabung" + + "%1$s +%2$d lainnya ingin bergabung ke ruangan ini" + + "Lihat semua" + "Terima" + "%1$s ingin bergabung ke ruangan ini" + "Lihat" + diff --git a/features/leaveroom/api/src/main/res/values-es/translations.xml b/features/leaveroom/api/src/main/res/values-es/translations.xml index cb393481d8..81b169e5c9 100644 --- a/features/leaveroom/api/src/main/res/values-es/translations.xml +++ b/features/leaveroom/api/src/main/res/values-es/translations.xml @@ -2,6 +2,6 @@ "¿Estás seguro de que quieres salir de esta conversación? Esta conversación no es pública y no podrás volver a unirte sin una invitación." "¿Estás seguro de que quieres salir de esta sala? Eres la única persona aquí. Si te vas, nadie podrá unirse en el futuro, ni siquiera tú." - "¿Estás seguro de que quieres abandonar esta sala? Esta sala no es pública y no podrás volver a entrar sin una invitación." + "¿Seguro que quieres salir de esta sala? Esta sala no es pública y no podrás volver a entrar sin una invitación." "¿Seguro que quieres salir de la sala?" diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt index f92b058786..4710e4bd50 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationPresenter.kt @@ -26,6 +26,10 @@ import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.location.AssetType +import io.element.android.libraries.matrix.api.room.message.ReplyParameters +import io.element.android.libraries.matrix.api.room.message.replyInThread +import io.element.android.libraries.matrix.ui.messages.reply.eventId +import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.launch import javax.inject.Inject @@ -98,6 +102,18 @@ class SendLocationPresenter @Inject constructor( event: SendLocationEvents.SendLocation, mode: SendLocationState.Mode, ) { + val replyMode = messageComposerContext.composerMode as? MessageComposerMode.Reply + val replyParams = replyMode?.replyToDetails?.let { details -> + if (replyMode.inThread) { + replyInThread(details.eventId()) + } else { + ReplyParameters( + inReplyToEventId = details.eventId(), + enforceThreadReply = false, + replyWithinThread = false + ) + } + } when (mode) { SendLocationState.Mode.PinLocation -> { val geoUri = event.cameraPosition.toGeoUri() @@ -106,7 +122,8 @@ class SendLocationPresenter @Inject constructor( geoUri = geoUri, description = null, zoomLevel = MapDefaults.DEFAULT_ZOOM.toInt(), - assetType = AssetType.PIN + assetType = AssetType.PIN, + replyParameters = replyParams, ) analyticsService.capture( Composer( @@ -124,7 +141,8 @@ class SendLocationPresenter @Inject constructor( geoUri = geoUri, description = null, zoomLevel = MapDefaults.DEFAULT_ZOOM.toInt(), - assetType = AssetType.SENDER + assetType = AssetType.SENDER, + replyParameters = replyParams, ) analyticsService.capture( Composer( diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt index 267a359608..7addee38e4 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/send/SendLocationPresenterTest.kt @@ -22,6 +22,7 @@ import io.element.android.features.location.impl.common.permissions.PermissionsS import io.element.android.features.messages.test.FakeMessageComposerContext import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.location.AssetType +import io.element.android.libraries.matrix.api.room.message.ReplyParameters import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.core.aBuildMeta @@ -263,7 +264,7 @@ class SendLocationPresenterTest { @Test fun `share sender location`() = runTest { - val sendLocationResult = lambdaRecorder> { _, _, _, _, _ -> + val sendLocationResult = lambdaRecorder> { _, _, _, _, _, _ -> Result.success(Unit) } val joinedRoom = FakeJoinedRoom( @@ -310,6 +311,7 @@ class SendLocationPresenterTest { value(null), value(15), value(AssetType.SENDER), + value(null), ) assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(1) @@ -326,7 +328,7 @@ class SendLocationPresenterTest { @Test fun `share pin location`() = runTest { - val sendLocationResult = lambdaRecorder> { _, _, _, _, _ -> + val sendLocationResult = lambdaRecorder> { _, _, _, _, _, _ -> Result.success(Unit) } val joinedRoom = FakeJoinedRoom( @@ -373,6 +375,7 @@ class SendLocationPresenterTest { value(null), value(15), value(AssetType.PIN), + value(null), ) assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(1) @@ -389,7 +392,7 @@ class SendLocationPresenterTest { @Test fun `composer context passes through analytics`() = runTest { - val sendLocationResult = lambdaRecorder> { _, _, _, _, _ -> + val sendLocationResult = lambdaRecorder> { _, _, _, _, _, _ -> Result.success(Unit) } val joinedRoom = FakeJoinedRoom( diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/pin/SetupPinView.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/pin/SetupPinView.kt index 3e51849a76..81bfa4c1a4 100644 --- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/pin/SetupPinView.kt +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/pin/SetupPinView.kt @@ -19,6 +19,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -124,6 +125,7 @@ private fun SetupPinContent( } @Composable +@ReadOnlyComposable private fun SetupPinFailure.content(): String { return when (this) { SetupPinFailure.ForbiddenPin -> stringResource(id = R.string.screen_app_lock_setup_pin_forbidden_dialog_content) @@ -132,6 +134,7 @@ private fun SetupPinFailure.content(): String { } @Composable +@ReadOnlyComposable private fun SetupPinFailure.title(): String { return when (this) { SetupPinFailure.ForbiddenPin -> stringResource(id = R.string.screen_app_lock_setup_pin_forbidden_dialog_title) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/error/ChangeServerError.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/error/ChangeServerError.kt index e3fdfc2d04..6d678854c1 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/error/ChangeServerError.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/error/ChangeServerError.kt @@ -9,6 +9,7 @@ package io.element.android.features.login.impl.error import androidx.annotation.StringRes import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.ui.res.stringResource import io.element.android.features.login.impl.R import io.element.android.features.login.impl.changeserver.UnauthorizedAccountProviderException @@ -21,6 +22,7 @@ sealed class ChangeServerError : Throwable() { val messageStr: String? = null, ) : ChangeServerError() { @Composable + @ReadOnlyComposable fun message(): String = messageStr ?: stringResource(messageId ?: CommonStrings.error_unknown) } diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt index c72f1a0308..5cb0c23d9c 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt @@ -29,7 +29,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.autofill.ContentType import androidx.compose.ui.focus.FocusDirection @@ -170,7 +169,6 @@ fun LoginPasswordView( } } -@OptIn(ExperimentalComposeUiApi::class) @Composable private fun LoginForm( state: LoginPasswordState, diff --git a/features/login/impl/src/main/res/values-es/translations.xml b/features/login/impl/src/main/res/values-es/translations.xml index 390f701b0a..d4841e2171 100644 --- a/features/login/impl/src/main/res/values-es/translations.xml +++ b/features/login/impl/src/main/res/values-es/translations.xml @@ -1,22 +1,27 @@ - "Cambiar el proveedor de la cuenta" - "Dirección del servidor principal" - "Introduzca un término de búsqueda o una dirección de dominio." + "Cambiar proveedor de cuentas" + "Dirección del servidor base" + "Introduce un término de búsqueda o una dirección de dominio." "Busca una empresa, comunidad o servidor privado." - "Encontrar un proveedor de cuenta" + "Encontrar un proveedor de cuentas" "Aquí es donde se alojarán tus conversaciones — justo como utilizarías un proveedor de correo electrónico para guardar tus correos electrónicos." "Estás a punto de iniciar sesión en %s" "Aquí es donde se alojarán tus conversaciones — justo como utilizarías un proveedor de correo electrónico para guardar tus correos electrónicos." "Estás a punto de crear una cuenta en %s" "Matrix.org es un servidor grande y gratuito en la red pública Matrix para una comunicación segura y descentralizada, administrado por la Fundación Matrix.org." "Otro" - "Usa un proveedor de cuenta diferente, como tu propio servidor privado o una cuenta de trabajo." - "Cambiar el proveedor de la cuenta" - "No hemos podido acceder a este servidor. Comprueba que has introducido correctamente la dirección del servidor. Si la dirección es correcta, ponte en contacto con el administrador del servidor para obtener más ayuda." - "Sliding sync no está disponible debido a un problema en el archivo well-known: + "Usa un proveedor de cuentas diferente, como tu propio servidor privado o una cuenta de trabajo." + "Cambiar proveedor de cuentas" + "No hemos podido acceder a este servidor base. Comprueba que has introducido correctamente la dirección. Si es correcta, ponte en contacto con el administrador de tu servidor base para obtener más ayuda." + "El servidor no está disponible debido a un problema en el archivo .well-known: %1$s" - "Dirección del homeserver" + "El proveedor de cuentas seleccionado no admite sliding sync. Es necesario actualizar el servidor para usar %1$s." + "%1$s no está autorizado para conectarse a %2$s." + "Esta aplicación se ha configurado para permitir: %1$s." + "No se permite el proveedor de cuentas %1$s." + "URL del servidor base" + "Introduce una dirección de dominio." "¿Cuál es la dirección de tu servidor?" "Selecciona tu servidor" "Crear cuenta" @@ -24,12 +29,13 @@ "Usuario y/o contraseña incorrectos" "Este no es un id de usuario válido. Formato esperado: \'@user:homeserver.org\'" "Este servidor está configurado para utilizar tokens de actualización. Estos no son compatibles cuando se utiliza el inicio de sesión basado en contraseña." - "El servidor seleccionado no admite contraseñas ni inicio de sesión OIDC. Póngase en contacto con su administrador o elija otro homeserver." + "El servidor base seleccionado no admite el inicio de sesión usando contraseña ni OIDC. Ponte en contacto con tu administrador o elige otro servidor base." "Introduce tus datos" "Matrix es una red abierta para una comunicación segura y descentralizada." "¡Hola de nuevo!" "Iniciar sesión en %1$s" "Iniciar sesión manualmente" + "Iniciar sesión en %1$s" "Iniciar sesión con un código QR" "Crear cuenta" "Bienvenido al %1$s más rápido de todos los tiempos. Diseñado para la velocidad y la simplicidad." @@ -56,7 +62,7 @@ Intenta iniciar sesión manualmente o escanea el código QR con otro dispositivo." "Código QR no admitido" - "Tu proveedor de cuenta no es compatible con %1$s." + "Tu proveedor de cuentas no es compatible con %1$s." "%1$s no admitido" "Listo para escanear" "Abre %1$s en un dispositivo de escritorio" @@ -64,7 +70,7 @@ Intenta iniciar sesión manualmente o escanea el código QR con otro dispositivo "Selecciona %1$s" "«Vincular un dispositivo nuevo»" "Escanea el código QR con este dispositivo" - "Solo disponible si tu proveedor de cuenta lo admite." + "Sólo disponible si tu proveedor de cuentas lo admite." "Abre %1$s en otro dispositivo para obtener el código QR" "Usa el código QR que se muestra en el otro dispositivo." "Intentar de nuevo" @@ -76,12 +82,13 @@ Intenta iniciar sesión manualmente o escanea el código QR con otro dispositivo "Empezar de nuevo" "Se ha producido un error inesperado. Vuelve a intentarlo." "A la espera de tu otro dispositivo" - "Puede que el proveedor de tu cuenta te pida el siguiente código para verificar el inicio de sesión." + "Puede que tu proveedor de cuentas te pida el siguiente código para verificar el inicio de sesión." "Tu código de verificación" - "Cambiar el proveedor de la cuenta" + "Cambiar proveedor de cuentas" "Un servidor privado para los empleados de Element." "Matrix es una red abierta para una comunicación segura y descentralizada." "Aquí es donde se alojarán tus conversaciones — justo como utilizarías un proveedor de correo electrónico para guardar tus correos electrónicos." "Estás a punto de iniciar sesión en %1$s" + "Elegir proveedor de cuentas" "Estás a punto de crear una cuenta en %1$s" diff --git a/features/login/impl/src/main/res/values-nb/translations.xml b/features/login/impl/src/main/res/values-nb/translations.xml index 88c063d701..0054906e65 100644 --- a/features/login/impl/src/main/res/values-nb/translations.xml +++ b/features/login/impl/src/main/res/values-nb/translations.xml @@ -89,5 +89,6 @@ Prøv å logge på manuelt, eller skann QR-koden med en annen enhet." "Matrix er et åpent nettverk for sikker, desentralisert kommunikasjon." "Det er her samtalene dine vil ligge - akkurat som du ville brukt en e-postleverandør til å oppbevare e-postene dine." "Du er i ferd med å logge inn på %1$s" + "Velg kontoleverandør" "Du er i ferd med å opprette en konto på %1$s" diff --git a/features/login/impl/src/main/res/values-ru/translations.xml b/features/login/impl/src/main/res/values-ru/translations.xml index b16ff24a92..17aaaa4530 100644 --- a/features/login/impl/src/main/res/values-ru/translations.xml +++ b/features/login/impl/src/main/res/values-ru/translations.xml @@ -14,8 +14,12 @@ "Используйте другого поставщика учетных записей, например, собственный частный сервер или рабочую учетную запись." "Сменить поставщика учетной записи" "Нам не удалось связаться с этим домашним сервером. Убедитесь, что вы правильно ввели URL-адрес домашнего сервера. Если URL-адрес указан правильно, обратитесь к администратору домашнего сервера за дополнительной помощью." - "Sliding sync недоступен из-за проблемы в известном файле: + "Сервер недоступен из-за проблемы в файле .well-known: %1$s" + "Выбранный провайдер аккаунтов не поддерживает Sliding sync. Для использования %1$s необходимо обновление сервера." + "%1$s отказано в подключении к %2$s." + "Это приложение настроено таким образом, чтобы разрешить: %1$s." + "Поставщик учетной записи %1$s не разрешен." "URL-адрес домашнего сервера" "Введите адрес домена." "Какой адрес у вашего сервера?" @@ -31,6 +35,7 @@ "Рады видеть вас снова!" "Войти в %1$s" "Войти вручную" + "Войти в %1$s" "Войти QR-кодом" "Создать учетную запись" "Добро пожаловать в самый быстрый клиент %1$s. Ориентирован на скорость и простоту." @@ -84,5 +89,6 @@ "Matrix — это открытая сеть для безопасной децентрализованной связи." "Здесь будут храниться ваши разговоры — точно так же, как если бы вы использовали почтового провайдера для хранения своих писем." "Вы собираетесь войти в %1$s" + "Выберите поставщика учетной записи" "Вы собираетесь создать учетную запись на %1$s" diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt index b045d10199..c66ec1ee51 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt @@ -9,6 +9,7 @@ package io.element.android.features.messages.impl import io.element.android.features.messages.impl.attachments.Attachment 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.UserId import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import kotlinx.collections.immutable.ImmutableList @@ -19,4 +20,5 @@ interface MessagesNavigator { fun onReportContentClick(eventId: EventId, senderId: UserId) fun onEditPollClick(eventId: EventId) fun onPreviewAttachment(attachments: ImmutableList) + fun onNavigateToRoom(roomId: RoomId) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt index fc6d01d3a9..84d20fbf94 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt @@ -49,18 +49,21 @@ import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.inputs import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.designsystem.utils.OnLifecycleEvent +import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.RoomScope import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.matrix.api.analytics.toAnalyticsViewRoom 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.UserId +import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias 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.room.BaseRoom import io.element.android.libraries.matrix.api.room.alias.matches import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.mediaplayer.api.MediaPlayer +import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.CoroutineScope @@ -70,6 +73,7 @@ import kotlinx.coroutines.launch class MessagesNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, + @ApplicationContext private val context: Context, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, private val room: BaseRoom, @@ -157,7 +161,7 @@ class MessagesNode @AssistedInject constructor( callbacks.forEach { it.onUserDataClick(permalink.userId) } } is PermalinkData.RoomLink -> { - handleRoomLinkClick(activity, permalink, eventSink) + handleRoomLinkClick(permalink, eventSink) } is PermalinkData.FallbackLink -> { if (customTab) { @@ -173,7 +177,6 @@ class MessagesNode @AssistedInject constructor( } private fun handleRoomLinkClick( - context: Context, roomLink: PermalinkData.RoomLink, eventSink: (TimelineEvents) -> Unit, ) { @@ -183,7 +186,7 @@ class MessagesNode @AssistedInject constructor( eventSink(TimelineEvents.FocusOnEvent(eventId)) } else { // Click on the same room, ignore - context.toast("Already viewing this room!") + displaySameRoomToast() } } else { callbacks.forEach { it.onPermalinkClick(roomLink) } @@ -210,6 +213,15 @@ class MessagesNode @AssistedInject constructor( callbacks.forEach { it.onPreviewAttachments(attachments) } } + override fun onNavigateToRoom(roomId: RoomId) { + if (roomId == room.roomId) { + displaySameRoomToast() + } else { + val permalinkData = PermalinkData.RoomLink(roomId.toRoomIdOrAlias()) + callbacks.forEach { it.onPermalinkClick(permalinkData) } + } + } + private fun onViewAllPinnedMessagesClick() { callbacks.forEach { it.onViewAllPinnedEvents() } } @@ -230,6 +242,10 @@ class MessagesNode @AssistedInject constructor( callbacks.forEach { it.onViewKnockRequests() } } + private fun displaySameRoomToast() { + context.toast(CommonStrings.screen_room_permalink_same_room_android) + } + @Composable override fun View(modifier: Modifier) { val activity = requireNotNull(LocalActivity.current) @@ -255,13 +271,13 @@ class MessagesNode @AssistedInject constructor( onCreatePollClick = this::onCreatePollClick, onJoinCallClick = this::onJoinCallClick, onViewAllPinnedMessagesClick = this::onViewAllPinnedMessagesClick, + modifier = modifier, knockRequestsBannerView = { knockRequestsBannerRenderer.View( modifier = Modifier, onViewRequestsClick = this::onViewKnockRequestsClick ) }, - modifier = modifier, ) roomMemberModerationRenderer.Render( state = state.roomMemberModerationState, 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 74cb9799f2..3390b55d5e 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 @@ -152,11 +152,8 @@ class MessagesPresenter @AssistedInject constructor( val userEventPermissions by userEventPermissions(syncUpdateFlow.value) - val roomName: AsyncData by remember { - derivedStateOf { roomInfo.name?.let { AsyncData.Success(it) } ?: AsyncData.Uninitialized } - } - val roomAvatar: AsyncData by remember { - derivedStateOf { AsyncData.Success(roomInfo.avatarData()) } + val roomAvatar by remember { + derivedStateOf { roomInfo.avatarData() } } val heroes by remember { derivedStateOf { roomInfo.heroes().toPersistentList() } @@ -245,7 +242,7 @@ class MessagesPresenter @AssistedInject constructor( return MessagesState( roomId = room.roomId, - roomName = roomName, + roomName = roomInfo.name, roomAvatar = roomAvatar, heroes = heroes, composerState = composerState, @@ -270,6 +267,7 @@ class MessagesPresenter @AssistedInject constructor( pinnedMessagesBannerState = pinnedMessagesBannerState, dmUserVerificationState = dmUserVerificationState, roomMemberModerationState = roomMemberModerationState, + successorRoom = roomInfo.successorRoom, eventSink = { handleEvents(it) } ) } @@ -291,7 +289,7 @@ class MessagesPresenter @AssistedInject constructor( return AvatarData( id = id.value, name = name, - url = avatarUrl ?: room.info().avatarUrl, + url = avatarUrl, size = AvatarSize.TimelineRoom ) } 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 8ba2cbd039..bedce147dc 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 @@ -26,13 +26,14 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.encryption.identity.IdentityState +import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import kotlinx.collections.immutable.ImmutableList @Immutable data class MessagesState( val roomId: RoomId, - val roomName: AsyncData, - val roomAvatar: AsyncData, + val roomName: String?, + val roomAvatar: AvatarData, val heroes: ImmutableList, val userEventPermissions: UserEventPermissions, val composerState: MessageComposerState, @@ -56,5 +57,8 @@ data class MessagesState( val pinnedMessagesBannerState: PinnedMessagesBannerState, val dmUserVerificationState: IdentityState?, val roomMemberModerationState: RoomMemberModerationState, + val successorRoom: SuccessorRoom?, val eventSink: (MessagesEvents) -> Unit -) +) { + val isTombstoned = successorRoom != null +} 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 c366a1e4cf..8fa539dd94 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 @@ -44,6 +44,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.matrix.api.core.RoomId 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.textcomposer.model.MessageComposerMode import io.element.android.libraries.textcomposer.model.aTextEditorStateRich import kotlinx.collections.immutable.persistentListOf @@ -57,10 +58,7 @@ open class MessagesStateProvider : PreviewParameterProvider { aMessagesState(composerState = aMessageComposerState(showAttachmentSourcePicker = true)), aMessagesState(userEventPermissions = aUserEventPermissions(canSendMessage = false)), aMessagesState(showReinvitePrompt = true), - aMessagesState( - roomName = AsyncData.Uninitialized, - roomAvatar = AsyncData.Uninitialized, - ), + aMessagesState(roomName = null), aMessagesState(composerState = aMessageComposerState(showTextFormatting = true)), aMessagesState( enableVoiceMessages = true, @@ -85,14 +83,15 @@ open class MessagesStateProvider : PreviewParameterProvider { currentPinnedMessageIndex = 0, ), ), - aMessagesState(roomName = AsyncData.Success("A DM with a very looong name"), dmUserVerificationState = IdentityState.Verified), - aMessagesState(roomName = AsyncData.Success("A DM with a very looong name"), dmUserVerificationState = IdentityState.VerificationViolation), + aMessagesState(roomName = "A DM with a very looong name", dmUserVerificationState = IdentityState.Verified), + aMessagesState(roomName = "A DM with a very looong name", dmUserVerificationState = IdentityState.VerificationViolation), + aMessagesState(successorRoom = SuccessorRoom(RoomId("!id:domain"), null)), ) } fun aMessagesState( - roomName: AsyncData = AsyncData.Success("Room name"), - roomAvatar: AsyncData = AsyncData.Success(AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom)), + roomName: String? = "Room name", + roomAvatar: AvatarData = AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom), userEventPermissions: UserEventPermissions = aUserEventPermissions(), composerState: MessageComposerState = aMessageComposerState( textEditorState = aTextEditorStateRich(initialText = "Hello", initialFocus = true), @@ -119,6 +118,7 @@ fun aMessagesState( pinnedMessagesBannerState: PinnedMessagesBannerState = aLoadedPinnedMessagesBannerState(), dmUserVerificationState: IdentityState? = null, roomMemberModerationState: RoomMemberModerationState = aRoomMemberModerationState(), + successorRoom: SuccessorRoom? = null, eventSink: (MessagesEvents) -> Unit = {}, ) = MessagesState( roomId = RoomId("!id:domain"), @@ -147,6 +147,7 @@ fun aMessagesState( pinnedMessagesBannerState = pinnedMessagesBannerState, dmUserVerificationState = dmUserVerificationState, roomMemberModerationState = roomMemberModerationState, + successorRoom = successorRoom, eventSink = eventSink, ) 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 ee76562b2c..a772015787 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 @@ -82,14 +82,14 @@ import io.element.android.features.messages.impl.voicemessages.composer.VoiceMes import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorView import io.element.android.features.roomcall.api.RoomCallState import io.element.android.libraries.androidutils.ui.hideKeyboard -import io.element.android.libraries.designsystem.atomic.molecules.IconTitlePlaceholdersRowMolecule +import io.element.android.libraries.designsystem.atomic.molecules.ComposerAlertMolecule 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.CompositeAvatar +import io.element.android.libraries.designsystem.components.avatar.RoomAvatar import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog 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.theme.components.BottomSheetDragHandle import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Scaffold @@ -101,8 +101,10 @@ import io.element.android.libraries.designsystem.utils.OnLifecycleEvent import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState 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.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.user.MatrixUser import io.element.android.libraries.textcomposer.model.TextEditorState import io.element.android.libraries.ui.strings.CommonStrings @@ -190,8 +192,9 @@ fun MessagesView( Column { ConnectivityIndicatorView(isOnline = state.hasNetworkConnection) MessagesViewTopBar( - roomName = state.roomName.dataOrNull(), - roomAvatar = state.roomAvatar.dataOrNull(), + roomName = state.roomName, + roomAvatar = state.roomAvatar, + isTombstoned = state.isTombstoned, heroes = state.heroes, roomCallState = state.roomCallState, dmUserIdentityState = state.dmUserVerificationState, @@ -211,8 +214,8 @@ fun MessagesView( onMessageLongClick = ::onMessageLongClick, onUserDataClick = { hidingKeyboard { - state.eventSink(MessagesEvents.OnUserClicked(it)) - } + state.eventSink(MessagesEvents.OnUserClicked(it)) + } }, onLinkClick = { link, customTab -> if (customTab) { @@ -410,6 +413,9 @@ private fun MessagesViewContent( MessagesViewComposerBottomSheetContents( subcomposing = subcomposing, state = state, + onRoomSuccessorClick = { roomId -> + state.timelineState.eventSink(TimelineEvents.NavigateToRoom(roomId = roomId)) + }, onLinkClick = { url, customTab -> onLinkClick(Link(url), customTab) }, ) }, @@ -424,52 +430,59 @@ private fun MessagesViewContent( private fun MessagesViewComposerBottomSheetContents( subcomposing: Boolean, state: MessagesState, + onRoomSuccessorClick: (RoomId) -> Unit, onLinkClick: (String, Boolean) -> Unit, ) { - if (state.userEventPermissions.canSendMessage) { - Column(modifier = Modifier.fillMaxWidth()) { - SuggestionsPickerView( - modifier = Modifier - .heightIn(max = 230.dp) - // Consume all scrolling, preventing the bottom sheet from being dragged when interacting with the list of suggestions - .nestedScroll(object : NestedScrollConnection { - override fun onPostScroll(consumed: Offset, available: Offset, source: NestedScrollSource): Offset { - return available - } - }), - roomId = state.roomId, - roomName = state.roomName.dataOrNull(), - roomAvatarData = state.roomAvatar.dataOrNull(), - suggestions = state.composerState.suggestions, - onSelectSuggestion = { - state.composerState.eventSink(MessageComposerEvents.InsertSuggestion(it)) + when { + state.successorRoom != null -> { + SuccessorRoomBanner(roomSuccessor = state.successorRoom, onRoomSuccessorClick = onRoomSuccessorClick) + } + state.userEventPermissions.canSendMessage -> { + Column(modifier = Modifier.fillMaxWidth()) { + SuggestionsPickerView( + modifier = Modifier + .heightIn(max = 230.dp) + // Consume all scrolling, preventing the bottom sheet from being dragged when interacting with the list of suggestions + .nestedScroll(object : NestedScrollConnection { + override fun onPostScroll(consumed: Offset, available: Offset, source: NestedScrollSource): Offset { + return available + } + }), + roomId = state.roomId, + roomName = state.roomName, + roomAvatarData = state.roomAvatar, + suggestions = state.composerState.suggestions, + onSelectSuggestion = { + state.composerState.eventSink(MessageComposerEvents.InsertSuggestion(it)) + } + ) + // 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, + ) + } + val verificationViolation = state.identityChangeState.roomMemberIdentityStateChanges.firstOrNull { + it.identityState == IdentityState.VerificationViolation + } + if (verificationViolation != null) { + DisabledComposerView(modifier = Modifier.fillMaxWidth()) + } else { + MessageComposerView( + state = state.composerState, + voiceMessageState = state.voiceMessageComposerState, + subcomposing = subcomposing, + enableVoiceMessages = state.enableVoiceMessages, + modifier = Modifier.fillMaxWidth(), + ) } - ) - // 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, - ) - } - val verificationViolation = state.identityChangeState.roomMemberIdentityStateChanges.firstOrNull { - it.identityState == IdentityState.VerificationViolation - } - if (verificationViolation != null) { - DisabledComposerView(modifier = Modifier.fillMaxWidth()) - } else { - MessageComposerView( - state = state.composerState, - voiceMessageState = state.voiceMessageComposerState, - subcomposing = subcomposing, - enableVoiceMessages = state.enableVoiceMessages, - modifier = Modifier.fillMaxWidth(), - ) } } - } else { - CantSendMessageBanner() + else -> { + CantSendMessageBanner() + } } } @@ -477,7 +490,8 @@ private fun MessagesViewComposerBottomSheetContents( @Composable private fun MessagesViewTopBar( roomName: String?, - roomAvatar: AvatarData?, + roomAvatar: AvatarData, + isTombstoned: Boolean, heroes: ImmutableList, roomCallState: RoomCallState, dmUserIdentityState: IdentityState?, @@ -499,19 +513,13 @@ private fun MessagesViewTopBar( verticalAlignment = Alignment.CenterVertically, ) { val titleModifier = Modifier.weight(1f, fill = false) - if (roomName != null && roomAvatar != null) { - RoomAvatarAndNameRow( - roomName = roomName, - roomAvatar = roomAvatar, - heroes = heroes, - modifier = titleModifier - ) - } else { - IconTitlePlaceholdersRowMolecule( - iconSize = AvatarSize.TimelineRoom.dp, - modifier = titleModifier - ) - } + RoomAvatarAndNameRow( + roomName = roomName, + roomAvatar = roomAvatar, + isTombstoned = isTombstoned, + heroes = heroes, + modifier = titleModifier + ) when (dmUserIdentityState) { IdentityState.Verified -> { @@ -545,23 +553,26 @@ private fun MessagesViewTopBar( @Composable private fun RoomAvatarAndNameRow( - roomName: String, + roomName: String?, roomAvatar: AvatarData, heroes: ImmutableList, + isTombstoned: Boolean, modifier: Modifier = Modifier ) { Row( modifier = modifier, verticalAlignment = Alignment.CenterVertically ) { - CompositeAvatar( + RoomAvatar( avatarData = roomAvatar, heroes = heroes, + isTombstoned = isTombstoned, ) Text( modifier = Modifier.padding(horizontal = 8.dp), - text = roomName, + text = roomName ?: stringResource(CommonStrings.common_no_room_name), style = ElementTheme.typography.fontBodyLgMedium, + fontStyle = FontStyle.Italic.takeIf { roomName == null }, maxLines = 1, overflow = TextOverflow.Ellipsis ) @@ -588,6 +599,22 @@ private fun CantSendMessageBanner() { } } +@Composable +private fun SuccessorRoomBanner( + roomSuccessor: SuccessorRoom, + onRoomSuccessorClick: (RoomId) -> Unit, + modifier: Modifier = Modifier, +) { + ComposerAlertMolecule( + avatar = null, + content = stringResource(R.string.screen_room_timeline_tombstoned_room_message).toAnnotatedString(), + onSubmitClick = { onRoomSuccessorClick(roomSuccessor.roomId) }, + modifier = modifier, + isCritical = false, + submitText = stringResource(R.string.screen_room_timeline_tombstoned_room_action) + ) +} + @PreviewsDayNight @Composable internal fun MessagesViewPreview(@PreviewParameter(MessagesStateProvider::class) state: MessagesState) = ElementPreview { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index ee4f278366..9c2760bf6c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -169,7 +169,7 @@ class DefaultActionListPresenter @AssistedInject constructor( if (timelineItem.isRemote && timelineItem.content.canBeForwarded()) { add(TimelineItemAction.Forward) } - if (timelineItem.isEditable) { + if (timelineItem.isEditable && usersEventPermissions.canSendMessage) { if (timelineItem.content is TimelineItemEventContentWithAttachment) { // Caption if (timelineItem.content.caption == null) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt index 8eb4bb8554..a16f1efa19 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt @@ -30,6 +30,7 @@ import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.material3.ripple import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment @@ -38,7 +39,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.clearAndSetSemantics -import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.onClick import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.traversalIndex import androidx.compose.ui.text.style.TextAlign @@ -52,6 +53,7 @@ import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUser import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUserSendFailure.ChangedIdentity import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUserSendFailure.None import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUserSendFailure.UnsignedDevice +import io.element.android.features.messages.impl.timeline.a11y.a11yReactionAction import io.element.android.features.messages.impl.timeline.components.MessageShieldView import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent @@ -394,6 +396,7 @@ private fun VerifiedUserSendFailureView( modifier: Modifier = Modifier, ) { @Composable + @ReadOnlyComposable fun VerifiedUserSendFailure.headline(): String { return when (this) { is None -> "" @@ -436,11 +439,10 @@ private fun EmojiButton( } else { Color.Transparent } - val description = if (isHighlighted) { - stringResource(id = CommonStrings.a11y_remove_reaction_with, emoji) - } else { - stringResource(id = CommonStrings.a11y_react_with, emoji) - } + val a11yClickLabel = a11yReactionAction( + emoji = emoji, + userAlreadyReacted = isHighlighted, + ) Box( modifier = modifier .size(48.dp) @@ -452,7 +454,12 @@ private fun EmojiButton( interactionSource = remember { MutableInteractionSource() } ) .semantics { - contentDescription = description + onClick( + label = a11yClickLabel, + ) { + onClick(emoji) + true + } }, contentAlignment = Alignment.Center ) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/ComposerDraftService.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/ComposerDraftService.kt index d34651f7a4..489e5bd046 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/ComposerDraftService.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/ComposerDraftService.kt @@ -8,9 +8,10 @@ package io.element.android.features.messages.impl.draft 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.room.draft.ComposerDraft interface ComposerDraftService { - suspend fun loadDraft(roomId: RoomId, isVolatile: Boolean): ComposerDraft? - suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?, isVolatile: Boolean) + suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?, isVolatile: Boolean): ComposerDraft? + suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?, isVolatile: Boolean) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/ComposerDraftStore.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/ComposerDraftStore.kt index d1297c1056..c460acb065 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/ComposerDraftStore.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/ComposerDraftStore.kt @@ -8,9 +8,10 @@ package io.element.android.features.messages.impl.draft 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.room.draft.ComposerDraft interface ComposerDraftStore { - suspend fun loadDraft(roomId: RoomId): ComposerDraft? - suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?) + suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?): ComposerDraft? + suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/DefaultComposerDraftService.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/DefaultComposerDraftService.kt index 1499aeac1d..57909c5a8a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/DefaultComposerDraftService.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/DefaultComposerDraftService.kt @@ -10,6 +10,7 @@ package io.element.android.features.messages.impl.draft import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.di.RoomScope 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.room.draft.ComposerDraft import javax.inject.Inject @@ -18,12 +19,12 @@ class DefaultComposerDraftService @Inject constructor( private val volatileComposerDraftStore: VolatileComposerDraftStore, private val matrixComposerDraftStore: MatrixComposerDraftStore, ) : ComposerDraftService { - override suspend fun loadDraft(roomId: RoomId, isVolatile: Boolean): ComposerDraft? { - return getStore(isVolatile).loadDraft(roomId) + override suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?, isVolatile: Boolean): ComposerDraft? { + return getStore(isVolatile).loadDraft(roomId, threadRoot) } - override suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?, isVolatile: Boolean) { - getStore(isVolatile).updateDraft(roomId, draft) + override suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?, isVolatile: Boolean) { + getStore(isVolatile).updateDraft(roomId, threadRoot, draft) } private fun getStore(isVolatile: Boolean): ComposerDraftStore { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/MatrixComposerDraftStore.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/MatrixComposerDraftStore.kt index b850e7b559..88000546dd 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/MatrixComposerDraftStore.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/MatrixComposerDraftStore.kt @@ -9,6 +9,7 @@ package io.element.android.features.messages.impl.draft 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.ThreadId import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import timber.log.Timber import javax.inject.Inject @@ -20,26 +21,26 @@ import javax.inject.Inject class MatrixComposerDraftStore @Inject constructor( private val client: MatrixClient, ) : ComposerDraftStore { - override suspend fun loadDraft(roomId: RoomId): ComposerDraft? { + override suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?): ComposerDraft? { return client.getRoom(roomId)?.use { room -> - room.loadComposerDraft() + room.loadComposerDraft(threadRoot) .onFailure { Timber.e(it, "Failed to load composer draft for room $roomId") } .onSuccess { draft -> - room.clearComposerDraft() + room.clearComposerDraft(threadRoot) Timber.d("Loaded composer draft for room $roomId : $draft") } .getOrNull() } } - override suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?) { + override suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?) { client.getRoom(roomId)?.use { room -> val updateDraftResult = if (draft == null) { - room.clearComposerDraft() + room.clearComposerDraft(threadRoot) } else { - room.saveComposerDraft(draft) + room.saveComposerDraft(draft, threadRoot) } updateDraftResult .onFailure { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/VolatileComposerDraftStore.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/VolatileComposerDraftStore.kt index 568f68a2d6..b7b714f5c9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/VolatileComposerDraftStore.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/draft/VolatileComposerDraftStore.kt @@ -8,6 +8,7 @@ package io.element.android.features.messages.impl.draft 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.room.draft.ComposerDraft import javax.inject.Inject @@ -17,18 +18,20 @@ import javax.inject.Inject * Currently it's used to store draft message when moving to edit mode. */ class VolatileComposerDraftStore @Inject constructor() : ComposerDraftStore { - private val drafts: MutableMap = mutableMapOf() + private val drafts: MutableMap = mutableMapOf() - override suspend fun loadDraft(roomId: RoomId): ComposerDraft? { + override suspend fun loadDraft(roomId: RoomId, threadRoot: ThreadId?): ComposerDraft? { + val key = threadRoot?.value ?: roomId.value // Remove the draft from the map when it is loaded - return drafts.remove(roomId) + return drafts.remove(key) } - override suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?) { + override suspend fun updateDraft(roomId: RoomId, threadRoot: ThreadId?, draft: ComposerDraft?) { + val key = threadRoot?.value ?: roomId.value if (draft == null) { - drafts.remove(roomId) + drafts.remove(key) } else { - drafts[roomId] = draft + drafts[key] = draft } } } 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 728087fe1c..f7187c5021 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 @@ -219,7 +219,12 @@ class MessageComposerPresenter @AssistedInject constructor( ) LaunchedEffect(Unit) { - val draft = draftService.loadDraft(room.roomId, isVolatile = false) + val draft = draftService.loadDraft( + roomId = room.roomId, + // TODO support threads in composer + threadRoot = null, + isVolatile = false + ) if (draft != null) { applyDraft(draft, markdownTextEditorState, richTextEditorState) } @@ -539,7 +544,9 @@ class MessageComposerPresenter @AssistedInject constructor( draftService.updateDraft( roomId = room.roomId, draft = draft, - isVolatile = isVolatile + isVolatile = isVolatile, + // TODO support threads in composer + threadRoot = null, ) } @@ -700,7 +707,12 @@ class MessageComposerPresenter @AssistedInject constructor( fromEdit: Boolean, ) { // Use the volatile draft only when coming from edit mode otherwise. - val draft = draftService.loadDraft(room.roomId, isVolatile = true).takeIf { fromEdit } + val draft = draftService.loadDraft( + roomId = room.roomId, + // TODO support threads in composer + threadRoot = null, + isVolatile = true + ).takeIf { fromEdit } if (draft != null) { applyDraft(draft, markdownTextEditorState, richTextEditorState) } else { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsPickerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsPickerView.kt index 9d774d5841..cc8f536f5f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsPickerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsPickerView.kt @@ -27,6 +27,7 @@ import io.element.android.features.messages.impl.R 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.anAvatarData 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 @@ -45,7 +46,7 @@ import kotlinx.collections.immutable.persistentListOf fun SuggestionsPickerView( roomId: RoomId, roomName: String?, - roomAvatarData: AvatarData?, + roomAvatarData: AvatarData, suggestions: ImmutableList, onSelectSuggestion: (ResolvedSuggestion) -> Unit, modifier: Modifier = Modifier, @@ -155,7 +156,7 @@ internal fun SuggestionsPickerViewPreview() { SuggestionsPickerView( roomId = RoomId("!room:matrix.org"), roomName = "Room", - roomAvatarData = null, + roomAvatarData = anAvatarData(), suggestions = persistentListOf( ResolvedSuggestion.AtRoom, ResolvedSuggestion.Member(roomMember), 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 a7901ff52d..1c9e18c9e6 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 @@ -106,7 +106,8 @@ class PinnedMessagesListPresenter @AssistedInject constructor( renderTypingNotifications = false, typingMembers = persistentListOf(), reserveSpace = false, - ) + ), + predecessorRoom = room.predecessorRoom(), ) } val timelineProtectionState = timelineProtectionPresenter.present() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineEvents.kt index 464a5caa22..da6837df21 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineEvents.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineEvents.kt @@ -9,6 +9,7 @@ package io.element.android.features.messages.impl.timeline import io.element.android.features.messages.impl.timeline.model.TimelineItem 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.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import kotlin.time.Duration @@ -30,6 +31,7 @@ sealed interface TimelineEvents { data class ComputeVerifiedUserSendFailure(val event: TimelineItem.Event) : EventFromTimelineItem data class ShowShieldDialog(val messageShield: MessageShield) : EventFromTimelineItem data class LoadMore(val direction: Timeline.PaginationDirection) : EventFromTimelineItem + data class NavigateToRoom(val roomId: RoomId) : EventFromTimelineItem /** * Events coming from a poll item. 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 4684b8cfdd..d8c43e7de7 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 @@ -178,6 +178,9 @@ class TimelinePresenter @AssistedInject constructor( is TimelineEvents.ComputeVerifiedUserSendFailure -> { resolveVerifiedUserSendFailureState.eventSink(ResolveVerifiedUserSendFailureEvents.ComputeForMessage(event.event)) } + is TimelineEvents.NavigateToRoom -> { + navigator.onNavigateToRoom(event.roomId) + } } } @@ -257,8 +260,9 @@ class TimelinePresenter @AssistedInject constructor( userHasPermissionToSendMessage = userHasPermissionToSendMessage, userHasPermissionToSendReaction = userHasPermissionToSendReaction, roomCallState = roomCallState, - pinnedEventIds = roomInfo.pinnedEventIds.orEmpty(), + pinnedEventIds = roomInfo.pinnedEventIds, typingNotificationState = typingNotificationState, + predecessorRoom = room.predecessorRoom(), ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt index af4b7622fe..a3cdb34c94 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineState.kt @@ -15,6 +15,7 @@ import io.element.android.features.messages.impl.typing.TypingNotificationState import io.element.android.features.roomcall.api.RoomCallState 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.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import kotlinx.collections.immutable.ImmutableList import kotlin.time.Duration @@ -77,4 +78,5 @@ data class TimelineRoomInfo( val roomCallState: RoomCallState, val pinnedEventIds: List, val typingNotificationState: TypingNotificationState, + val predecessorRoom: PredecessorRoom?, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt index d47379da3d..8bb66b4f60 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineStateProvider.kt @@ -30,6 +30,7 @@ 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.core.UniqueId import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield @@ -246,6 +247,7 @@ internal fun aTimelineRoomInfo( userHasPermissionToSendMessage: Boolean = true, pinnedEventIds: List = emptyList(), typingNotificationState: TypingNotificationState = aTypingNotificationState(), + predecessorRoom: PredecessorRoom? = null, ) = TimelineRoomInfo( isDm = isDm, name = name, @@ -254,4 +256,5 @@ internal fun aTimelineRoomInfo( roomCallState = aStandByCallState(), pinnedEventIds = pinnedEventIds, typingNotificationState = typingNotificationState, + predecessorRoom = predecessorRoom, ) 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 b3b8331a16..cc9bf3cf84 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 @@ -76,8 +76,6 @@ import io.element.android.libraries.testtags.testTag import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.utils.time.isTalkbackActive import io.element.android.wysiwyg.link.Link -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine @@ -225,7 +223,6 @@ private fun MessageShieldDialog(state: TimelineState) { ) } -@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) @Composable private fun TimelinePrefetchingHelper( lazyListState: LazyListState, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/a11y/Reactions.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/a11y/Reactions.kt new file mode 100644 index 0000000000..9da0168b38 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/a11y/Reactions.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.messages.impl.timeline.a11y + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.res.pluralStringResource +import androidx.compose.ui.res.stringResource +import io.element.android.features.messages.impl.R +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +@ReadOnlyComposable +fun a11yReactionAction( + emoji: String, + userAlreadyReacted: Boolean, +): String { + return if (userAlreadyReacted) { + stringResource(id = CommonStrings.a11y_remove_reaction_with, emoji) + } else { + stringResource(id = CommonStrings.a11y_react_with, emoji) + } +} + +@Composable +@ReadOnlyComposable +fun a11yReactionDetails( + emoji: String, + userAlreadyReacted: Boolean, + reactionCount: Int, +): String { + val reaction = if (emoji.startsWith("mxc://")) { + stringResource(CommonStrings.common_an_image) + } else { + emoji + } + return if (userAlreadyReacted) { + if (reactionCount == 1) { + stringResource(R.string.screen_room_timeline_reaction_you_a11y, reaction) + } else { + pluralStringResource( + R.plurals.screen_room_timeline_reaction_including_you_a11y, + reactionCount - 1, + reactionCount - 1, + reaction, + ) + } + } else { + pluralStringResource( + R.plurals.screen_room_timeline_reaction_a11y, + reactionCount, + reactionCount, + reaction, + ) + } +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt index 4bcf8df61c..8434242abd 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt @@ -21,7 +21,6 @@ internal fun ATimelineItemEventRow( timelineRoomInfo: TimelineRoomInfo = aTimelineRoomInfo(), renderReadReceipts: Boolean = false, isLastOutgoingMessage: Boolean = false, - isHighlighted: Boolean = false, timelineProtectionState: TimelineProtectionState = aTimelineProtectionState(), ) = TimelineItemEventRow( event = event, @@ -29,7 +28,6 @@ internal fun ATimelineItemEventRow( renderReadReceipts = renderReadReceipts, timelineProtectionState = timelineProtectionState, isLastOutgoingMessage = isLastOutgoingMessage, - isHighlighted = isHighlighted, onEventClick = {}, onLongClick = {}, onLinkClick = {}, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt index 2b48a99dcd..c8bae78f13 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageEventBubble.kt @@ -7,7 +7,6 @@ package io.element.android.features.messages.impl.timeline.components -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box @@ -59,7 +58,6 @@ private val avatarRadius = AvatarSize.TimelineSender.dp / 2 private const val BUBBLE_WIDTH_RATIO = 0.78f private val MIN_BUBBLE_WIDTH = 80.dp -@OptIn(ExperimentalFoundationApi::class) @Composable fun MessageEventBubble( state: BubbleState, @@ -184,7 +182,7 @@ internal fun MessageEventBubblePreview(@PreviewParameter(BubbleStateProvider::cl contentAlignment = Alignment.Center, ) { Text( - text = "${state.groupPosition.javaClass.simpleName} m:${state.isMine.to01()} h:${state.isHighlighted.to01()}", + text = "${state.groupPosition.javaClass.simpleName} isMine:${state.isMine.to01()}", style = ElementTheme.typography.fontBodyXsRegular, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageShieldView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageShieldView.kt index c2d2c3a3de..9d7d4caac5 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageShieldView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageShieldView.kt @@ -80,6 +80,7 @@ internal fun MessageShield.toText(): String { is MessageShield.UnverifiedIdentity -> CommonStrings.event_shield_reason_unverified_identity is MessageShield.SentInClear -> CommonStrings.event_shield_reason_sent_in_clear is MessageShield.VerificationViolation -> CommonStrings.event_shield_reason_previously_verified + is MessageShield.MismatchedSender -> CommonStrings.event_shield_mismatched_sender } ) } @@ -91,7 +92,8 @@ internal fun MessageShield.toIcon(): ImageVector { is MessageShield.UnknownDevice, is MessageShield.UnsignedDevice, is MessageShield.UnverifiedIdentity, - is MessageShield.VerificationViolation -> CompoundIcons.HelpSolid() + is MessageShield.VerificationViolation, + is MessageShield.MismatchedSender -> CompoundIcons.HelpSolid() is MessageShield.SentInClear -> CompoundIcons.LockOff() } } @@ -122,6 +124,9 @@ internal fun MessageShieldViewPreview() { MessageShieldView( shield = MessageShield.VerificationViolation(false) ) + MessageShieldView( + shield = MessageShield.MismatchedSender(false) + ) } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageStateEventContainer.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageStateEventContainer.kt index 010132b47a..ac9be4de74 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageStateEventContainer.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessageStateEventContainer.kt @@ -7,12 +7,8 @@ package io.element.android.features.messages.impl.timeline.components -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ripple @@ -28,17 +24,14 @@ import io.element.android.libraries.designsystem.theme.components.Surface private val CORNER_RADIUS = 8.dp -@OptIn(ExperimentalFoundationApi::class) @Composable fun MessageStateEventContainer( - @Suppress("UNUSED_PARAMETER") isHighlighted: Boolean, interactionSource: MutableInteractionSource, onClick: () -> Unit, onLongClick: () -> Unit, modifier: Modifier = Modifier, content: @Composable () -> Unit = {}, ) { - // Ignore isHighlighted for now, we need a design decision on it. val backgroundColor = Color.Transparent val shape = RoundedCornerShape(CORNER_RADIUS) Surface( @@ -60,22 +53,9 @@ fun MessageStateEventContainer( @PreviewsDayNight @Composable internal fun MessageStateEventContainerPreview() = ElementPreview { - Column { - MessageStateEventContainer( - isHighlighted = false, - interactionSource = remember { MutableInteractionSource() }, - onClick = {}, - onLongClick = {}, - ) { - Spacer(modifier = Modifier.size(width = 120.dp, height = 32.dp)) - } - MessageStateEventContainer( - isHighlighted = true, - interactionSource = remember { MutableInteractionSource() }, - onClick = {}, - onLongClick = {}, - ) { - Spacer(modifier = Modifier.size(width = 120.dp, height = 32.dp)) - } - } + MessageStateEventContainer( + interactionSource = remember { MutableInteractionSource() }, + onClick = {}, + onLongClick = {}, + ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt index dec03748ce..b0026fb449 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt @@ -9,7 +9,6 @@ package io.element.android.features.messages.impl.timeline.components import androidx.annotation.DrawableRes import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.combinedClickable @@ -30,12 +29,17 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.onClick import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil3.compose.AsyncImage import io.element.android.compound.theme.ElementTheme import io.element.android.features.messages.impl.R +import io.element.android.features.messages.impl.timeline.a11y.a11yReactionAction +import io.element.android.features.messages.impl.timeline.a11y.a11yReactionDetails import io.element.android.features.messages.impl.timeline.model.AggregatedReaction import io.element.android.features.messages.impl.timeline.model.AggregatedReactionProvider import io.element.android.features.messages.impl.timeline.model.aTimelineItemReactions @@ -50,7 +54,6 @@ import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.ui.media.MediaRequestData @Composable -@OptIn(ExperimentalFoundationApi::class) @Suppress("ModifierClickableOrder") // This is needed to display the right ripple shape fun MessagesReactionButton( onClick: () -> Unit, @@ -70,6 +73,27 @@ fun MessagesReactionButton( buttonColor } + val a11yText = when (content) { + is MessagesReactionsButtonContent.Icon -> stringResource(id = R.string.screen_room_timeline_add_reaction) + is MessagesReactionsButtonContent.Text -> content.text + is MessagesReactionsButtonContent.Reaction -> { + a11yReactionDetails( + emoji = content.reaction.key, + userAlreadyReacted = content.isHighlighted, + reactionCount = content.reaction.count, + ) + } + } + + val a11yClickLabel = if (content is MessagesReactionsButtonContent.Reaction) { + a11yReactionAction( + emoji = content.reaction.key, + userAlreadyReacted = content.isHighlighted + ) + } else { + "" + } + Surface( modifier = modifier .background(Color.Transparent) @@ -88,7 +112,18 @@ fun MessagesReactionButton( // Inner border, to highlight when selected .border(BorderStroke(1.dp, borderColor), RoundedCornerShape(corner = CornerSize(12.dp))) .background(buttonColor, RoundedCornerShape(corner = CornerSize(12.dp))) - .padding(vertical = 4.dp, horizontal = 10.dp), + .padding(vertical = 4.dp, horizontal = 10.dp) + .clearAndSetSemantics { + contentDescription = a11yText + if (content is MessagesReactionsButtonContent.Reaction) { + onClick( + label = a11yClickLabel + ) { + onClick() + true + } + } + }, color = buttonColor ) { when (content) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt index 1386a5a666..ed26d6558e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemCallNotifyView.kt @@ -7,7 +7,6 @@ package io.element.android.features.messages.impl.timeline.components -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.border import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement @@ -39,7 +38,6 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.text.toDp import io.element.android.libraries.ui.strings.CommonStrings -@OptIn(ExperimentalFoundationApi::class) @Composable internal fun TimelineItemCallNotifyView( event: TimelineItem.Event, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 55ee0d7a4f..18d0658dd6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -32,7 +32,6 @@ import androidx.compose.runtime.movableContentOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalViewConfiguration @@ -120,7 +119,6 @@ fun TimelineItemEventRow( timelineProtectionState: TimelineProtectionState, renderReadReceipts: Boolean, isLastOutgoingMessage: Boolean, - isHighlighted: Boolean, onEventClick: () -> Unit, onLongClick: () -> Unit, onLinkClick: (Link) -> Unit, @@ -196,7 +194,6 @@ fun TimelineItemEventRow( TimelineItemEventRowContent( event = event, timelineProtectionState = timelineProtectionState, - isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, onContentClick = onContentClick, @@ -230,7 +227,6 @@ fun TimelineItemEventRow( TimelineItemEventRowContent( event = event, timelineProtectionState = timelineProtectionState, - isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, onContentClick = onContentClick, @@ -281,12 +277,10 @@ private fun SwipeSensitivity( } } -@OptIn(ExperimentalComposeUiApi::class) @Composable private fun TimelineItemEventRowContent( event: TimelineItem.Event, timelineProtectionState: TimelineProtectionState, - isHighlighted: Boolean, timelineRoomInfo: TimelineRoomInfo, interactionSource: MutableInteractionSource, onContentClick: () -> Unit, @@ -340,7 +334,6 @@ private fun TimelineItemEventRowContent( val bubbleState = BubbleState( groupPosition = event.groupPosition, isMine = event.isMine, - isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, ) MessageEventBubble( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt index 771940da0b..c537c89b6d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt @@ -7,7 +7,6 @@ package io.element.android.features.messages.impl.timeline.components -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth @@ -21,6 +20,7 @@ import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Brush import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.isTraversalGroup import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -32,6 +32,7 @@ import io.element.android.features.messages.impl.timeline.components.layout.Cont import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLegacyCallInviteContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionEvent @@ -48,7 +49,6 @@ import io.element.android.libraries.ui.utils.time.isTalkbackActive import io.element.android.wysiwyg.link.Link import kotlin.time.DurationUnit -@OptIn(ExperimentalFoundationApi::class) @Composable internal fun TimelineItemRow( timelineItem: TimelineItem, @@ -113,7 +113,6 @@ internal fun TimelineItemRow( event = timelineItem, renderReadReceipts = renderReadReceipts, isLastOutgoingMessage = isLastOutgoingMessage, - isHighlighted = timelineItem.isEvent(focusedEventId), onClick = { onContentClick(timelineItem) }, onReadReceiptsClick = onReadReceiptClick, onLongClick = { onLongClick(timelineItem) }, @@ -140,6 +139,8 @@ internal fun TimelineItemRow( } else { timelineItem.safeSenderName } + // For Polls, allow the answers to be traversed by Talkback + isTraversalGroup = timelineItem.content is TimelineItemPollContent } // Custom clickable that applies over the whole item for accessibility .then( @@ -157,7 +158,6 @@ internal fun TimelineItemRow( renderReadReceipts = renderReadReceipts, timelineProtectionState = timelineProtectionState, isLastOutgoingMessage = isLastOutgoingMessage, - isHighlighted = timelineItem.isEvent(focusedEventId), onEventClick = { onContentClick(timelineItem) }, onLongClick = { onLongClick(timelineItem) }, onLinkClick = onLinkClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt index 6bd0e24908..2f66d586a9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt @@ -40,7 +40,6 @@ fun TimelineItemStateEventRow( event: TimelineItem.Event, renderReadReceipts: Boolean, isLastOutgoingMessage: Boolean, - isHighlighted: Boolean, onClick: () -> Unit, onLongClick: () -> Unit, onReadReceiptsClick: (event: TimelineItem.Event) -> Unit, @@ -60,7 +59,6 @@ fun TimelineItemStateEventRow( contentAlignment = Alignment.Center ) { MessageStateEventContainer( - isHighlighted = isHighlighted, interactionSource = interactionSource, onClick = onClick, onLongClick = onLongClick, @@ -107,7 +105,6 @@ internal fun TimelineItemStateEventRowPreview() = ElementPreview { ), renderReadReceipts = true, isLastOutgoingMessage = false, - isHighlighted = false, onClick = {}, onLongClick = {}, onReadReceiptsClick = {}, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemVirtualRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemVirtualRow.kt index 2507fb9f01..45b167b68f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemVirtualRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemVirtualRow.kt @@ -41,7 +41,16 @@ fun TimelineItemVirtualRow( when (virtual.model) { is TimelineItemDaySeparatorModel -> TimelineItemDaySeparatorView(virtual.model) TimelineItemReadMarkerModel -> TimelineItemReadMarkerView() - TimelineItemRoomBeginningModel -> TimelineItemRoomBeginningView(roomName = timelineRoomInfo.name) + TimelineItemRoomBeginningModel -> { + TimelineItemRoomBeginningView( + predecessorRoom = timelineRoomInfo.predecessorRoom, + roomName = timelineRoomInfo.name, + isDm = timelineRoomInfo.isDm, + onPredecessorRoomClick = { roomId -> + eventSink(TimelineEvents.NavigateToRoom(roomId)) + }, + ) + } is TimelineItemLoadingIndicatorModel -> { TimelineLoadingMoreIndicator(virtual.model.direction) val latestEventSink by rememberUpdatedState(eventSink) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiItem.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiItem.kt index a27de9c324..b6ad695aa8 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiItem.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiItem.kt @@ -22,7 +22,6 @@ import androidx.compose.runtime.remember 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.clearAndSetSemantics import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.unit.TextUnit @@ -30,11 +29,11 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.element.android.compound.theme.ElementTheme import io.element.android.emojibasebindings.Emoji +import io.element.android.features.messages.impl.timeline.a11y.a11yReactionAction import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.text.toDp import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.ui.strings.CommonStrings @Composable fun EmojiItem( @@ -49,11 +48,10 @@ fun EmojiItem( } else { Color.Transparent } - val description = if (isSelected) { - stringResource(id = CommonStrings.a11y_remove_reaction_with, item.unicode) - } else { - stringResource(id = CommonStrings.a11y_react_with, item.unicode) - } + val description = a11yReactionAction( + emoji = item.unicode, + userAlreadyReacted = isSelected, + ) Box( modifier = modifier .sizeIn(minWidth = 40.dp, minHeight = 40.dp) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt index d419197146..41d3873a65 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt @@ -8,7 +8,6 @@ package io.element.android.features.messages.impl.timeline.components.event import android.text.SpannedString -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Column @@ -57,7 +56,6 @@ import io.element.android.libraries.ui.utils.time.isTalkbackActive import io.element.android.wysiwyg.compose.EditorStyledText import io.element.android.wysiwyg.link.Link -@OptIn(ExperimentalFoundationApi::class) @Composable fun TimelineItemImageView( content: TimelineItemImageContent, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt index daabcba4d5..dd16f2faf3 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt @@ -7,7 +7,6 @@ package io.element.android.features.messages.impl.timeline.components.event -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Column @@ -39,7 +38,6 @@ import io.element.android.libraries.ui.strings.CommonStrings private const val STICKER_SIZE_IN_DP = 128 -@OptIn(ExperimentalFoundationApi::class) @Composable fun TimelineItemStickerView( content: TimelineItemStickerContent, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt index edd37d0b5c..18a59325d5 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt @@ -8,7 +8,6 @@ package io.element.android.features.messages.impl.timeline.components.event import android.text.SpannedString -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable @@ -67,7 +66,6 @@ import io.element.android.libraries.ui.utils.time.isTalkbackActive import io.element.android.wysiwyg.compose.EditorStyledText import io.element.android.wysiwyg.link.Link -@OptIn(ExperimentalFoundationApi::class) @Composable fun TimelineItemVideoView( content: TimelineItemVideoContent, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryView.kt index b1aa726628..c14d792252 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/reactionsummary/ReactionSummaryView.kt @@ -27,6 +27,7 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ExperimentalMaterial3Api @@ -45,12 +46,17 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil3.compose.AsyncImage import io.element.android.compound.theme.ElementTheme +import io.element.android.features.messages.impl.timeline.a11y.a11yReactionDetails import io.element.android.features.messages.impl.timeline.components.REACTION_IMAGE_ASPECT_RATIO import io.element.android.features.messages.impl.timeline.model.AggregatedReaction import io.element.android.libraries.designsystem.components.avatar.Avatar @@ -140,9 +146,7 @@ private fun ReactionSummaryViewContent( HorizontalPager(state = pagerState) { page -> LazyColumn(modifier = Modifier.fillMaxHeight()) { items(summary.reactions[page].senders) { sender -> - val user = sender.user ?: MatrixUser(userId = sender.senderId) - SenderRow( avatarData = user.getAvatarData(AvatarSize.UserListItem), name = user.displayName ?: user.userId.value, @@ -166,21 +170,32 @@ private fun AggregatedReactionButton( } else { Color.Transparent } - val textColor = if (isHighlighted) { MaterialTheme.colorScheme.inversePrimary } else { ElementTheme.colors.textPrimary } - val roundedCornerShape = RoundedCornerShape(corner = CornerSize(percent = 50)) + val a11yText = a11yReactionDetails( + emoji = reaction.key, + userAlreadyReacted = reaction.isHighlighted, + reactionCount = reaction.count, + ) Surface( modifier = Modifier .background(buttonColor, roundedCornerShape) .clip(roundedCornerShape) .clickable(onClick = onClick) - .padding(vertical = 8.dp, horizontal = 12.dp), - color = buttonColor + .padding(vertical = 8.dp, horizontal = 12.dp) + .selectable( + selected = isHighlighted, + role = Role.Tab, + onClick = onClick, + ) + .clearAndSetSemantics { + contentDescription = a11yText + }, + color = buttonColor, ) { Row( verticalAlignment = Alignment.CenterVertically, @@ -230,7 +245,8 @@ private fun SenderRow( 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 = 4.dp, end = 16.dp, bottom = 4.dp) + .semantics(mergeDescendants = true) {}, verticalAlignment = Alignment.CenterVertically ) { Avatar(avatarData) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineItemRoomBeginningView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineItemRoomBeginningView.kt index 645f36602c..72035cdc3d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineItemRoomBeginningView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineItemRoomBeginningView.kt @@ -7,6 +7,7 @@ package io.element.android.features.messages.impl.timeline.components.virtual +import androidx.compose.foundation.layout.Arrangement.spacedBy import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth @@ -19,44 +20,83 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.features.messages.impl.R +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.toAnnotatedString import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.utils.allBooleans +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.room.tombstone.PredecessorRoom @Composable fun TimelineItemRoomBeginningView( roomName: String?, + predecessorRoom: PredecessorRoom?, + isDm: Boolean, + onPredecessorRoomClick: (RoomId) -> Unit, modifier: Modifier = Modifier ) { - Box( - modifier = modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - contentAlignment = Alignment.Center, + Column( + modifier = modifier.fillMaxWidth() ) { - val text = if (roomName == null) { - stringResource(id = R.string.screen_room_timeline_beginning_of_room_no_name) - } else { - stringResource(id = R.string.screen_room_timeline_beginning_of_room, roomName) + if (predecessorRoom != null) { + ComposerAlertMolecule( + avatar = null, + content = stringResource(R.string.screen_room_timeline_upgraded_room_message).toAnnotatedString(), + onSubmitClick = { onPredecessorRoomClick(predecessorRoom.roomId) }, + isCritical = false, + submitText = stringResource(R.string.screen_room_timeline_upgraded_room_action) + ) + } + // Only display for non-DM room + if (!isDm) { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + contentAlignment = Alignment.Center, + ) { + val text = if (roomName == null) { + stringResource(id = R.string.screen_room_timeline_beginning_of_room_no_name) + } else { + stringResource(id = R.string.screen_room_timeline_beginning_of_room, roomName) + } + Text( + color = ElementTheme.colors.textSecondary, + style = ElementTheme.typography.fontBodyMdRegular, + text = text, + textAlign = TextAlign.Center, + ) + } } - Text( - color = ElementTheme.colors.textSecondary, - style = ElementTheme.typography.fontBodyMdRegular, - text = text, - textAlign = TextAlign.Center, - ) } } @PreviewsDayNight @Composable internal fun TimelineItemRoomBeginningViewPreview() = ElementPreview { - Column { - TimelineItemRoomBeginningView( - roomName = null, - ) - TimelineItemRoomBeginningView( - roomName = "Room Name", - ) + Column(verticalArrangement = spacedBy(16.dp)) { + allBooleans.forEach { isDm -> + TimelineItemRoomBeginningView( + predecessorRoom = null, + roomName = null, + isDm = isDm, + onPredecessorRoomClick = {}, + ) + TimelineItemRoomBeginningView( + predecessorRoom = null, + roomName = "Room Name", + isDm = isDm, + onPredecessorRoomClick = {}, + ) + TimelineItemRoomBeginningView( + predecessorRoom = PredecessorRoom(RoomId("!roomId:matrix.org"), EventId("\$eventId:matrix.org")), + roomName = "Room Name", + isDm = isDm, + onPredecessorRoomClick = {}, + ) + } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleState.kt index 07219f4281..81aa459413 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleState.kt @@ -13,7 +13,6 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItemGrou data class BubbleState( val groupPosition: TimelineItemGroupPosition, val isMine: Boolean, - val isHighlighted: Boolean, val timelineRoomInfo: TimelineRoomInfo, ) { /** True to cut out the top start corner of the bubble, to give margin for the sender avatar. */ diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleStateProvider.kt index 97b69b1f64..02a6e19504 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/bubble/BubbleStateProvider.kt @@ -21,15 +21,11 @@ open class BubbleStateProvider : PreviewParameterProvider { TimelineItemGroupPosition.None, ).map { groupPosition -> sequenceOf(false, true).map { isMine -> - sequenceOf(false, true).map { isHighlighted -> - aBubbleState( - groupPosition = groupPosition, - isMine = isMine, - isHighlighted = isHighlighted, - ) - } + aBubbleState( + groupPosition = groupPosition, + isMine = isMine, + ) } - .flatten() } .flatten() } @@ -37,11 +33,9 @@ open class BubbleStateProvider : PreviewParameterProvider { internal fun aBubbleState( groupPosition: TimelineItemGroupPosition = TimelineItemGroupPosition.First, isMine: Boolean = false, - isHighlighted: Boolean = false, timelineRoomInfo: TimelineRoomInfo = aTimelineRoomInfo(), ) = BubbleState( groupPosition = groupPosition, isMine = isMine, - isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, ) diff --git a/features/messages/impl/src/main/res/values-cs/translations.xml b/features/messages/impl/src/main/res/values-cs/translations.xml index af33e7376d..3b43f897e2 100644 --- a/features/messages/impl/src/main/res/values-cs/translations.xml +++ b/features/messages/impl/src/main/res/values-cs/translations.xml @@ -43,6 +43,10 @@ "%1$d změny místnosti" "%1$d změn místnosti" + "Přejít do nové místnosti" + "Tato místnost byla nahrazena a již není aktivní" + "Zobrazit staré zprávy" + "Tato místnost je pokračováním jiné místnosti" "%1$s, %2$s a %3$d další" "%1$s, %2$s a %3$d další" diff --git a/features/messages/impl/src/main/res/values-es/translations.xml b/features/messages/impl/src/main/res/values-es/translations.xml index f078bf28d7..54b15f66a5 100644 --- a/features/messages/impl/src/main/res/values-es/translations.xml +++ b/features/messages/impl/src/main/res/values-es/translations.xml @@ -9,8 +9,8 @@ "Viajes y lugares" "Símbolos" "Bloquear usuario" - "Marque si quieres ocultar todos los mensajes actuales y futuros de este usuario" - "Este mensaje se notificará al administrador de su homeserver. No podrán leer ningún mensaje cifrado." + "Marca esta casilla si quieres ocultar todos los mensajes actuales y futuros de este usuario" + "Se denunciará este mensaje al administrador de tu servidor base. No será capaz de leer ningún mensaje cifrado." "Motivo para denunciar este contenido" "Cámara" "Hacer foto" diff --git a/features/messages/impl/src/main/res/values-fr/translations.xml b/features/messages/impl/src/main/res/values-fr/translations.xml index 132d175eb8..2f45ed5e56 100644 --- a/features/messages/impl/src/main/res/values-fr/translations.xml +++ b/features/messages/impl/src/main/res/values-fr/translations.xml @@ -35,6 +35,15 @@ "Afficher moins" "Message copié" "Vous n’êtes pas autorisé à publier dans ce salon" + + "%1$d membre a réagi avec %2$s" + "%1$d membres ont réagi avec %2$s" + + + "Vous et %1$d membre avez réagi avec %2$s" + "Vous et %1$d membres avez réagi avec %2$s" + + "Vous avez réagi avec %1$s" "Afficher moins" "Afficher plus" "Nouveau" diff --git a/features/messages/impl/src/main/res/values-nb/translations.xml b/features/messages/impl/src/main/res/values-nb/translations.xml index beb88017f2..f5fb2229fa 100644 --- a/features/messages/impl/src/main/res/values-nb/translations.xml +++ b/features/messages/impl/src/main/res/values-nb/translations.xml @@ -35,6 +35,15 @@ "Vis mindre" "Melding kopiert" "Du har ikke tillatelse til å legge ut innlegg i dette rommet" + + "%1$d medlem reagerte med %2$s" + "%1$d medlemmer reagerte med %2$s" + + + "Du og %1$d medlem reagerte med%2$s" + "Du og %1$d medlemmer reagerte med%2$s" + + "Du reagerte med %1$s" "Vis mindre" "Vis mer" "Ny" diff --git a/features/messages/impl/src/main/res/values/localazy.xml b/features/messages/impl/src/main/res/values/localazy.xml index 73d266f799..984eb1231f 100644 --- a/features/messages/impl/src/main/res/values/localazy.xml +++ b/features/messages/impl/src/main/res/values/localazy.xml @@ -28,13 +28,22 @@ "Everyone" "Send again" "Your message failed to send" - "Add emoji" + "Add a reaction" "This is the beginning of %1$s." "This is the beginning of this conversation." "Unsupported call. Ask if the caller can use the new Element X app." "Show less" "Message copied" "You do not have permission to post to this room" + + "%1$d member reacted with %2$s" + "%1$d members reacted with %2$s" + + + "You and %1$d member reacted with %2$s" + "You and %1$d members reacted with %2$s" + + "You reacted with %1$s" "Show less" "Show more" "New" @@ -42,6 +51,10 @@ "%1$d room change" "%1$d room changes" + "Jump to new room" + "This room has been replaced and is no longer active" + "See old messages" + "This room is a continuation of another room" "%1$s, %2$s and %3$d other" "%1$s, %2$s and %3$d others" diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt index 92fc0d8171..32638d7b8d 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt @@ -9,6 +9,7 @@ package io.element.android.features.messages.impl import io.element.android.features.messages.impl.attachments.Attachment 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.UserId import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.tests.testutils.lambda.lambdaError @@ -20,6 +21,7 @@ class FakeMessagesNavigator( private val onReportContentClickLambda: (eventId: EventId, senderId: UserId) -> Unit = { _, _ -> lambdaError() }, private val onEditPollClickLambda: (eventId: EventId) -> Unit = { _ -> lambdaError() }, private val onPreviewAttachmentLambda: (attachments: ImmutableList) -> Unit = { _ -> lambdaError() }, + private val onNavigateToRoomLambda: (roomId: RoomId) -> Unit = { _ -> lambdaError() } ) : MessagesNavigator { override fun onShowEventDebugInfoClick(eventId: EventId?, debugInfo: TimelineItemDebugInfo) { onShowEventDebugInfoClickLambda(eventId, debugInfo) @@ -40,4 +42,8 @@ class FakeMessagesNavigator( override fun onPreviewAttachment(attachments: ImmutableList) { onPreviewAttachmentLambda(attachments) } + + override fun onNavigateToRoom(roomId: RoomId) { + onNavigateToRoomLambda(roomId) + } } 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 e42941da0d..f24175c33e 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 @@ -50,6 +50,7 @@ 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.core.EventId +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.media.MediaSource @@ -57,6 +58,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.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId @@ -117,9 +119,9 @@ class MessagesPresenterTest { presenter.testWithLifecycleOwner { val initialState = consumeItemsUntilTimeout().last() assertThat(initialState.roomId).isEqualTo(A_ROOM_ID) - assertThat(initialState.roomName).isEqualTo(AsyncData.Success("")) + assertThat(initialState.roomName).isEqualTo("") assertThat(initialState.roomAvatar) - .isEqualTo(AsyncData.Success(AvatarData(id = A_ROOM_ID.value, name = "", url = AN_AVATAR_URL, size = AvatarSize.TimelineRoom))) + .isEqualTo(AvatarData(id = A_ROOM_ID.value, name = "", url = AN_AVATAR_URL, size = AvatarSize.TimelineRoom)) assertThat(initialState.userEventPermissions.canSendMessage).isTrue() assertThat(initialState.userEventPermissions.canRedactOwn).isTrue() assertThat(initialState.hasNetworkConnection).isTrue() @@ -1130,6 +1132,57 @@ class MessagesPresenterTest { } } + @Test + fun `present - room with successor room includes successor info in state`() = runTest { + val successorRoomId = RoomId("!successor:server.org") + 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) }, + initialRoomInfo = aRoomInfo( + successorRoom = SuccessorRoom( + roomId = successorRoomId, + reason = successorReason + ) + ) + ), + typingNoticeResult = { Result.success(Unit) }, + ) + val presenter = createMessagesPresenter(joinedRoom = room) + presenter.testWithLifecycleOwner { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.successorRoom).isNotNull() + assertThat(initialState.successorRoom?.roomId).isEqualTo(successorRoomId) + assertThat(initialState.successorRoom?.reason).isEqualTo(successorReason) + } + } + + @Test + 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) }, + initialRoomInfo = aRoomInfo(successorRoom = null) + ), + typingNoticeResult = { Result.success(Unit) }, + ) + val presenter = createMessagesPresenter(joinedRoom = room) + presenter.testWithLifecycleOwner { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.successorRoom).isNull() + } + } + @Test fun `present - when room is encrypted and a DM, the DM user's identity state is fetched onResume`() = runTest { val room = FakeJoinedRoom( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt index 4f6ac91890..51f5640ece 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt @@ -52,7 +52,9 @@ import io.element.android.features.messages.impl.timeline.components.receipt.aRe 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.event.aTimelineItemTextContent +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.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.timeline.item.event.getAvatarUrl import io.element.android.libraries.matrix.api.timeline.item.event.getDisplayName import io.element.android.libraries.matrix.api.user.MatrixUser @@ -65,6 +67,7 @@ import io.element.android.tests.testutils.EnsureNeverCalledWithParam import io.element.android.tests.testutils.EnsureNeverCalledWithTwoParams import io.element.android.tests.testutils.EnsureNeverCalledWithTwoParamsAndResult import io.element.android.tests.testutils.EventsRecorder +import io.element.android.tests.testutils.assertNoNodeWithText import io.element.android.tests.testutils.clickOn import io.element.android.tests.testutils.ensureCalledOnce import io.element.android.tests.testutils.pressBack @@ -107,7 +110,7 @@ class MessagesViewTest { state = state, onRoomDetailsClick = callback, ) - rule.onNodeWithText(state.roomName.dataOrNull().orEmpty(), useUnmergedTree = true).performClick() + rule.onNodeWithText(state.roomName.orEmpty(), useUnmergedTree = true).performClick() } } @@ -391,7 +394,10 @@ class MessagesViewTest { rule.setMessagesView( state = state, ) - rule.onAllNodesWithText("👍️").onFirst().performClick() + rule.onAllNodesWithText( + text = "👍️", + useUnmergedTree = true, + ).onFirst().performClick() eventsRecorder.assertSingle(MessagesEvents.ToggleReaction("👍️", timelineItem.eventOrTransactionId)) } @@ -411,7 +417,10 @@ class MessagesViewTest { rule.setMessagesView( state = state, ) - rule.onAllNodesWithText("👍️").onFirst().performTouchInput { longClick() } + rule.onAllNodesWithText( + text = "👍️", + useUnmergedTree = true, + ).onFirst().performTouchInput { longClick() } eventsRecorder.assertSingle(ReactionSummaryEvents.ShowReactionSummary(timelineItem.eventId!!, timelineItem.reactionsState.reactions, "👍️")) } @@ -554,6 +563,36 @@ class MessagesViewTest { rule.onNodeWithText("This is a pinned message").performClick() eventsRecorder.assertSingle(TimelineEvents.FocusOnEvent(AN_EVENT_ID, debounce = FOCUS_ON_PINNED_EVENT_DEBOUNCE_DURATION_IN_MILLIS.milliseconds)) } + + @Test + fun `clicking on successor room button emits expected event`() { + val eventsRecorder = EventsRecorder() + val successorRoomId = RoomId("!successor:server.org") + val state = aMessagesState( + successorRoom = SuccessorRoom( + roomId = successorRoomId, + reason = "This room has been upgraded" + ), + timelineState = aTimelineState(eventSink = eventsRecorder) + ) + rule.setMessagesView(state = state) + val text = rule.activity.getString(R.string.screen_room_timeline_tombstoned_room_action) + // The bottomsheet subcompose seems to make the node to appear twice + rule.onAllNodesWithText(text).onFirst().performClick() + eventsRecorder.assertSingle(TimelineEvents.NavigateToRoom(successorRoomId)) + } + + @Test + fun `no banner shown when there is no successor room`() { + val eventsRecorder = EventsRecorder(expectEvents = false) + val state = aMessagesState( + successorRoom = null, + eventSink = eventsRecorder + ) + rule.setMessagesView(state = state) + rule.assertNoNodeWithText(R.string.screen_room_timeline_tombstoned_room_message) + rule.assertNoNodeWithText(R.string.screen_room_timeline_tombstoned_room_action) + } } private fun AndroidComposeTestRule.setMessagesView( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt index 6e9c525214..a082b36b39 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt @@ -81,8 +81,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -124,8 +122,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -167,8 +163,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -262,8 +256,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -405,8 +397,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -500,8 +490,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -525,6 +513,49 @@ class ActionListPresenterTest { } } + @Test + fun `present - compute for my message no permission`() = runTest { + val presenter = createActionListPresenter(isDeveloperModeEnabled = true, isPinFeatureEnabled = true) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + val messageEvent = aMessageEvent( + isMine = true, + content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = A_MESSAGE) + ) + initialState.eventSink.invoke( + ActionListEvents.ComputeForMessage( + event = messageEvent, + userEventPermissions = aUserEventPermissions( + canRedactOwn = false, + canRedactOther = false, + canSendMessage = false, + canSendReaction = false, + canPinUnpin = false, + ) + ) + ) + val successState = awaitItem() + assertThat(successState.target).isEqualTo( + ActionListState.Target.Success( + event = messageEvent, + sentTimeFull = "0 Full true", + displayEmojiReactions = false, + verifiedUserSendFailure = VerifiedUserSendFailure.None, + actions = persistentListOf( + TimelineItemAction.Forward, + TimelineItemAction.CopyLink, + TimelineItemAction.CopyText, + TimelineItemAction.ViewSource, + ) + ) + ) + initialState.eventSink.invoke(ActionListEvents.Clear) + assertThat(awaitItem().target).isEqualTo(ActionListState.Target.None) + } + } + @Test fun `present - compute for a media item`() = runTest { val presenter = createActionListPresenter(isDeveloperModeEnabled = true, isPinFeatureEnabled = true) @@ -747,8 +778,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -789,8 +818,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) assertThat(awaitItem().target).isEqualTo(ActionListState.Target.None) } } @@ -818,8 +845,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -866,8 +891,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -921,8 +944,6 @@ class ActionListPresenterTest { ) ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/draft/FakeComposerDraftService.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/draft/FakeComposerDraftService.kt index 6fd4172340..d87b11c951 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/draft/FakeComposerDraftService.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/draft/FakeComposerDraftService.kt @@ -8,12 +8,22 @@ package io.element.android.features.messages.impl.draft 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.room.draft.ComposerDraft class FakeComposerDraftService : ComposerDraftService { - var loadDraftLambda: (RoomId, Boolean) -> ComposerDraft? = { _, _ -> null } - override suspend fun loadDraft(roomId: RoomId, isVolatile: Boolean): ComposerDraft? = loadDraftLambda(roomId, isVolatile) + var loadDraftLambda: (RoomId, ThreadId?, Boolean) -> ComposerDraft? = { _, _, _ -> null } + override suspend fun loadDraft( + roomId: RoomId, + threadRoot: ThreadId?, + isVolatile: Boolean + ): ComposerDraft? = loadDraftLambda(roomId, threadRoot, isVolatile) - var saveDraftLambda: (RoomId, ComposerDraft?, Boolean) -> Unit = { _, _, _ -> } - override suspend fun updateDraft(roomId: RoomId, draft: ComposerDraft?, isVolatile: Boolean) = saveDraftLambda(roomId, draft, isVolatile) + var saveDraftLambda: (RoomId, ThreadId?, ComposerDraft?, Boolean) -> Unit = { _, _, _, _ -> } + override suspend fun updateDraft( + roomId: RoomId, + threadRoot: ThreadId?, + draft: ComposerDraft?, + isVolatile: Boolean + ) = saveDraftLambda(roomId, threadRoot, draft, isVolatile) } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/draft/VolatileComposerDraftStoreTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/draft/VolatileComposerDraftStoreTest.kt index 176037358e..9ec43f3621 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/draft/VolatileComposerDraftStoreTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/draft/VolatileComposerDraftStoreTest.kt @@ -11,6 +11,7 @@ import com.google.common.truth.Truth.assertThat 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.test.A_ROOM_ID +import io.element.android.libraries.matrix.test.A_THREAD_ID import kotlinx.coroutines.test.runTest import org.junit.Test @@ -21,27 +22,51 @@ class VolatileComposerDraftStoreTest { @Test fun `when storing a non-null draft and then loading it, it's loaded and removed`() = runTest { - val initialDraft = sut.loadDraft(roomId) + val initialDraft = sut.loadDraft(roomId = roomId, threadRoot = null) assertThat(initialDraft).isNull() - sut.updateDraft(roomId, draft) + sut.updateDraft(roomId = roomId, threadRoot = null, draft = draft) - val loadedDraft = sut.loadDraft(roomId) + val loadedDraft = sut.loadDraft(roomId = roomId, threadRoot = null) assertThat(loadedDraft).isEqualTo(draft) - val loadedDraftAfter = sut.loadDraft(roomId) + val loadedDraftAfter = sut.loadDraft(roomId = roomId, threadRoot = null) assertThat(loadedDraftAfter).isNull() + + // In thread: + val threadRoot = A_THREAD_ID + val initialThreadDraft = sut.loadDraft(roomId = roomId, threadRoot = threadRoot) + assertThat(initialThreadDraft).isNull() + + sut.updateDraft(roomId = roomId, threadRoot = threadRoot, draft = draft) + + val loadedThreadDraft = sut.loadDraft(roomId = roomId, threadRoot = threadRoot) + assertThat(loadedThreadDraft).isEqualTo(draft) + + val loadedThreadDraftAfter = sut.loadDraft(roomId = roomId, threadRoot = threadRoot) + assertThat(loadedThreadDraftAfter).isNull() } @Test fun `when storing a null draft and then loading it, it's removing the previous one`() = runTest { - val initialDraft = sut.loadDraft(roomId) + val initialDraft = sut.loadDraft(roomId = roomId, threadRoot = null) assertThat(initialDraft).isNull() - sut.updateDraft(roomId, draft) - sut.updateDraft(roomId, null) + sut.updateDraft(roomId = roomId, threadRoot = null, draft = draft) + sut.updateDraft(roomId = roomId, threadRoot = null, draft = null) - val loadedDraft = sut.loadDraft(roomId) + val loadedDraft = sut.loadDraft(roomId = roomId, threadRoot = null) assertThat(loadedDraft).isNull() + + // In thread: + val threadRoot = A_THREAD_ID + val initialThreadDraft = sut.loadDraft(roomId = roomId, threadRoot = threadRoot) + assertThat(initialThreadDraft).isNull() + + sut.updateDraft(roomId = roomId, threadRoot = threadRoot, draft = draft) + sut.updateDraft(roomId = roomId, threadRoot = threadRoot, draft = null) + + val loadedThreadDraft = sut.loadDraft(roomId = roomId, threadRoot = threadRoot) + assertThat(loadedThreadDraft).isNull() } } 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 f3d815d563..1a7a1d930e 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 @@ -37,6 +37,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService 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.ThreadId import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.VideoInfo import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder @@ -178,10 +179,10 @@ class MessageComposerPresenterTest { @Test fun `present - change mode to edit`() = runTest { - val loadDraftLambda = lambdaRecorder { _: RoomId, _: Boolean -> + val loadDraftLambda = lambdaRecorder { _: RoomId, _: ThreadId?, _: Boolean -> ComposerDraft(A_MESSAGE, A_MESSAGE, ComposerDraftType.NewMessage) } - val updateDraftLambda = lambdaRecorder { _: RoomId, _: ComposerDraft?, _: Boolean -> } + val updateDraftLambda = lambdaRecorder { _: RoomId, _: ThreadId?, _: ComposerDraft?, _: Boolean -> } val draftService = FakeComposerDraftService().apply { this.loadDraftLambda = loadDraftLambda this.saveDraftLambda = updateDraftLambda @@ -207,23 +208,23 @@ class MessageComposerPresenterTest { .isCalledExactly(2) .withSequence( // Automatic load of draft - listOf(value(A_ROOM_ID), value(false)), + listOf(value(A_ROOM_ID), value(null), value(false)), // Load of volatile draft when closing edit mode - listOf(value(A_ROOM_ID), value(true)) + listOf(value(A_ROOM_ID), value(null), value(true)) ) assert(updateDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), any(), value(true)) + .with(value(A_ROOM_ID), value(null), any(), value(true)) } } @Test fun `present - change mode to edit caption`() = runTest { - val loadDraftLambda = lambdaRecorder { _: RoomId, _: Boolean -> + val loadDraftLambda = lambdaRecorder { _: RoomId, _: ThreadId?, _: Boolean -> ComposerDraft(A_MESSAGE, A_MESSAGE, ComposerDraftType.NewMessage) } - val updateDraftLambda = lambdaRecorder { _: RoomId, _: ComposerDraft?, _: Boolean -> } + val updateDraftLambda = lambdaRecorder { _: RoomId, _: ThreadId?, _: ComposerDraft?, _: Boolean -> } val draftService = FakeComposerDraftService().apply { this.loadDraftLambda = loadDraftLambda this.saveDraftLambda = updateDraftLambda @@ -249,13 +250,13 @@ class MessageComposerPresenterTest { .isCalledExactly(2) .withSequence( // Automatic load of draft - listOf(value(A_ROOM_ID), value(false)), + listOf(value(A_ROOM_ID), value(null), value(false)), // Load of volatile draft when closing edit mode - listOf(value(A_ROOM_ID), value(true)) + listOf(value(A_ROOM_ID), value(null), value(true)) ) assert(updateDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), any(), value(true)) + .with(value(A_ROOM_ID), value(null), any(), value(true)) } } @@ -303,10 +304,10 @@ class MessageComposerPresenterTest { @Test fun `present - change mode to reply after edit`() = runTest { - val loadDraftLambda = lambdaRecorder { _: RoomId, _: Boolean -> + val loadDraftLambda = lambdaRecorder { _: RoomId, _: ThreadId?, _: Boolean -> ComposerDraft(A_MESSAGE, A_MESSAGE, ComposerDraftType.NewMessage) } - val updateDraftLambda = lambdaRecorder { _: RoomId, _: ComposerDraft?, _: Boolean -> } + val updateDraftLambda = lambdaRecorder { _: RoomId, _: ThreadId?, _: ComposerDraft?, _: Boolean -> } val draftService = FakeComposerDraftService().apply { this.loadDraftLambda = loadDraftLambda this.saveDraftLambda = updateDraftLambda @@ -333,11 +334,11 @@ class MessageComposerPresenterTest { assert(loadDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), value(false)) + .with(value(A_ROOM_ID), value(null), value(false)) assert(updateDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), any(), value(true)) + .with(value(A_ROOM_ID), value(null), any(), value(true)) } } @@ -1246,7 +1247,7 @@ class MessageComposerPresenterTest { @Test fun `present - when there is no draft, nothing is restored`() = runTest { - val loadDraftLambda = lambdaRecorder { _, _ -> null } + val loadDraftLambda = lambdaRecorder { _, _, _ -> null } val composerDraftService = FakeComposerDraftService().apply { this.loadDraftLambda = loadDraftLambda } @@ -1257,7 +1258,7 @@ class MessageComposerPresenterTest { awaitFirstItem() assert(loadDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), value(false)) + .with(value(A_ROOM_ID), value(null), value(false)) ensureAllEventsConsumed() } @@ -1265,7 +1266,7 @@ class MessageComposerPresenterTest { @Test fun `present - when there is a draft for new message with plain text, it is restored`() = runTest { - val loadDraftLambda = lambdaRecorder { _, _ -> + val loadDraftLambda = lambdaRecorder { _, _, _ -> ComposerDraft(plainText = A_MESSAGE, htmlText = null, draftType = ComposerDraftType.NewMessage) } val composerDraftService = FakeComposerDraftService().apply { @@ -1286,7 +1287,7 @@ class MessageComposerPresenterTest { } assert(loadDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), value(false)) + .with(value(A_ROOM_ID), value(null), value(false)) ensureAllEventsConsumed() } @@ -1294,7 +1295,7 @@ class MessageComposerPresenterTest { @Test fun `present - when there is a draft for new message with rich text, it is restored`() = runTest { - val loadDraftLambda = lambdaRecorder { _, _ -> + val loadDraftLambda = lambdaRecorder { _, _, _ -> ComposerDraft( plainText = A_MESSAGE, htmlText = A_MESSAGE, @@ -1320,14 +1321,14 @@ class MessageComposerPresenterTest { } assert(loadDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), value(false)) + .with(value(A_ROOM_ID), value(null), value(false)) ensureAllEventsConsumed() } } @Test fun `present - when there is a draft for edit, it is restored`() = runTest { - val loadDraftLambda = lambdaRecorder { _, _ -> + val loadDraftLambda = lambdaRecorder { _, _, _ -> ComposerDraft( plainText = A_MESSAGE, htmlText = null, @@ -1354,7 +1355,7 @@ class MessageComposerPresenterTest { } assert(loadDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), value(false)) + .with(value(A_ROOM_ID), value(null), value(false)) ensureAllEventsConsumed() } @@ -1362,7 +1363,7 @@ class MessageComposerPresenterTest { @Test fun `present - when there is a draft for reply, it is restored`() = runTest { - val loadDraftLambda = lambdaRecorder { _, _ -> + val loadDraftLambda = lambdaRecorder { _, _, _ -> ComposerDraft( plainText = A_MESSAGE, htmlText = null, @@ -1400,7 +1401,7 @@ class MessageComposerPresenterTest { } assert(loadDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), value(false)) + .with(value(A_ROOM_ID), value(null), value(false)) assert(loadReplyDetailsLambda) .isCalledOnce() @@ -1412,7 +1413,7 @@ class MessageComposerPresenterTest { @Test fun `present - when save draft event is invoked and composer is empty then service is called with null draft`() = runTest { - val saveDraftLambda = lambdaRecorder { _, _, _ -> } + val saveDraftLambda = lambdaRecorder { _, _, _, _ -> } val composerDraftService = FakeComposerDraftService().apply { this.saveDraftLambda = saveDraftLambda } @@ -1425,13 +1426,13 @@ class MessageComposerPresenterTest { advanceUntilIdle() assert(saveDraftLambda) .isCalledOnce() - .with(value(A_ROOM_ID), value(null), value(false)) + .with(value(A_ROOM_ID), value(null), value(null), value(false)) } } @Test fun `present - when save draft event is invoked and composer is not empty then service is called`() = runTest { - val saveDraftLambda = lambdaRecorder { _, _, _ -> } + val saveDraftLambda = lambdaRecorder { _, _, _, _ -> } val composerDraftService = FakeComposerDraftService().apply { this.saveDraftLambda = saveDraftLambda } @@ -1478,27 +1479,32 @@ class MessageComposerPresenterTest { .withSequence( listOf( value(A_ROOM_ID), + value(null), value(ComposerDraft(plainText = A_MESSAGE, htmlText = null, draftType = ComposerDraftType.NewMessage)), value(false) ), listOf( value(A_ROOM_ID), + value(null), value(ComposerDraft(plainText = A_MESSAGE, htmlText = A_MESSAGE, draftType = ComposerDraftType.NewMessage)), value(false) ), listOf( value(A_ROOM_ID), + value(null), value(ComposerDraft(plainText = A_MESSAGE, htmlText = A_MESSAGE, draftType = ComposerDraftType.NewMessage)), // The volatile draft created when switching to edit mode. value(true) ), listOf( value(A_ROOM_ID), + value(null), value(ComposerDraft(plainText = A_MESSAGE, htmlText = A_MESSAGE, draftType = ComposerDraftType.Edit(AN_EVENT_ID))), value(false) ), listOf( value(A_ROOM_ID), + value(null), // When moving from edit mode, text composer is cleared, so the draft is null value(null), value(false) 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 a95cf4f31f..2cc7d9764a 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 @@ -32,6 +32,7 @@ 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.UniqueId 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 import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.Timeline @@ -64,6 +65,7 @@ import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf @@ -80,7 +82,7 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds @Suppress("LargeClass") -@OptIn(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) class TimelinePresenterTest { @get:Rule val warmUpRule = WarmUpRule() @@ -705,6 +707,73 @@ class TimelinePresenterTest { } } + @Test + fun `present - timeline room info includes predecessor room when room has predecessor`() = runTest { + val predecessorRoomId = RoomId("!predecessor:server.org") + val predecessorEventId = EventId("\$predecessorEvent:server.org") + val predecessorRoom = PredecessorRoom( + roomId = predecessorRoomId, + lastEventId = predecessorEventId + ) + + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + canUserSendMessageResult = { _, _ -> Result.success(true) }, + predecessorRoomResult = { predecessorRoom } + ), + ) + + val presenter = createTimelinePresenter(room = room) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitFirstItem() + assertThat(initialState.timelineRoomInfo.predecessorRoom).isNotNull() + assertThat(initialState.timelineRoomInfo.predecessorRoom?.roomId).isEqualTo(predecessorRoomId) + assertThat(initialState.timelineRoomInfo.predecessorRoom?.lastEventId).isEqualTo(predecessorEventId) + } + } + + @Test + fun `present - timeline room info no predecessor`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + canUserSendMessageResult = { _, _ -> Result.success(true) }, + predecessorRoomResult = { null } + ), + ) + val presenter = createTimelinePresenter(room = room) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitFirstItem() + assertThat(initialState.timelineRoomInfo.predecessorRoom).isNull() + } + } + + @Test + fun `present - timeline event navigate to room`() = runTest { + val room = FakeJoinedRoom( + baseRoom = FakeBaseRoom( + canUserSendMessageResult = { _, _ -> Result.success(true) }, + ), + ) + val onNavigateToRoomLambda = lambdaRecorder {} + val navigator = FakeMessagesNavigator( + onNavigateToRoomLambda = onNavigateToRoomLambda + ) + val presenter = createTimelinePresenter(room = room, messagesNavigator = navigator) + presenter.test { + val initialState = awaitFirstItem() + initialState.eventSink(TimelineEvents.NavigateToRoom(A_ROOM_ID)) + assert(onNavigateToRoomLambda) + .isCalledOnce() + .with( + value(A_ROOM_ID) + ) + } + } + private suspend fun ReceiveTurbine.awaitFirstItem(): T { return awaitItem() } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemPollViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemPollViewTest.kt index b89a3830be..3935d6d615 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemPollViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemPollViewTest.kt @@ -47,7 +47,10 @@ class TimelineItemPollViewTest { ) } val answer = content.answerItems[answerIndex].answer - rule.onNode(hasText(answer.text)).performClick() + rule.onNode( + matcher = hasText(answer.text), + useUnmergedTree = true, + ).performClick() eventsRecorder.assertSingle(TimelineEvents.SelectPollAnswer(content.eventId!!, answer.id)) } diff --git a/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/pollcontent/PollAnswerView.kt b/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/pollcontent/PollAnswerView.kt index 6243bd38d9..59d13fed1e 100644 --- a/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/pollcontent/PollAnswerView.kt +++ b/features/poll/api/src/main/kotlin/io/element/android/features/poll/api/pollcontent/PollAnswerView.kt @@ -20,9 +20,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.res.pluralStringResource +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 io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.poll.api.R import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon @@ -32,14 +36,42 @@ import io.element.android.libraries.designsystem.theme.progressIndicatorTrackCol import io.element.android.libraries.designsystem.toEnabledColor import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.ui.strings.CommonPlurals +import io.element.android.libraries.ui.strings.CommonStrings @Composable internal fun PollAnswerView( answerItem: PollAnswerItem, modifier: Modifier = Modifier, ) { + val nbVotesText = pluralStringResource( + id = CommonPlurals.common_poll_votes_count, + count = answerItem.votesCount, + answerItem.votesCount, + ) + val a11yText = buildString { + val sentenceDelimiter = stringResource(CommonStrings.common_sentence_delimiter) + append(answerItem.answer.text.removeSuffix(".")) + if (answerItem.showVotes) { + append(sentenceDelimiter) + append(nbVotesText) + if (answerItem.votesCount != 0) { + append(sentenceDelimiter) + (answerItem.percentage * 100).toInt().let { percent -> + append(pluralStringResource(R.plurals.a11y_polls_percent_of_total, percent, percent)) + } + } + if (answerItem.isWinner) { + append(sentenceDelimiter) + append(stringResource(R.string.a11y_polls_winning_answer)) + } + } + } Row( - modifier = modifier.fillMaxWidth(), + modifier = modifier + .fillMaxWidth() + .clearAndSetSemantics { + contentDescription = a11yText + }, ) { Icon( imageVector = if (answerItem.isSelected) { @@ -70,11 +102,6 @@ internal fun PollAnswerView( style = if (answerItem.isWinner) ElementTheme.typography.fontBodyLgMedium else ElementTheme.typography.fontBodyLgRegular, ) if (answerItem.showVotes) { - val text = pluralStringResource( - id = CommonPlurals.common_poll_votes_count, - count = answerItem.votesCount, - answerItem.votesCount - ) Row( modifier = Modifier.align(Alignment.Bottom), verticalAlignment = Alignment.CenterVertically, @@ -87,13 +114,13 @@ internal fun PollAnswerView( ) Spacer(modifier = Modifier.width(2.dp)) Text( - text = text, + text = nbVotesText, style = ElementTheme.typography.fontBodySmMedium, color = ElementTheme.colors.textPrimary, ) } else { Text( - text = text, + text = nbVotesText, style = ElementTheme.typography.fontBodySmRegular, color = ElementTheme.colors.textSecondary, ) diff --git a/features/poll/api/src/main/res/values-fr/translations.xml b/features/poll/api/src/main/res/values-fr/translations.xml new file mode 100644 index 0000000000..a085a9d40e --- /dev/null +++ b/features/poll/api/src/main/res/values-fr/translations.xml @@ -0,0 +1,8 @@ + + + + "%1$d pour cent du total des votes" + "%1$d pour cent du total des votes" + + "C’est la réponse gagnante" + diff --git a/features/poll/api/src/main/res/values-nb/translations.xml b/features/poll/api/src/main/res/values-nb/translations.xml new file mode 100644 index 0000000000..332f319e7c --- /dev/null +++ b/features/poll/api/src/main/res/values-nb/translations.xml @@ -0,0 +1,8 @@ + + + + "%1$d prosent av totalt antall stemmer" + "%1$d prosent av totalt antall stemmer" + + "Dette er vinnersvaret" + diff --git a/features/poll/api/src/main/res/values/localazy.xml b/features/poll/api/src/main/res/values/localazy.xml new file mode 100644 index 0000000000..2d1142194c --- /dev/null +++ b/features/poll/api/src/main/res/values/localazy.xml @@ -0,0 +1,8 @@ + + + + "%1$d percent of total votes" + "%1$d percents of total votes" + + "This is the winning answer" + 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 f8384279bf..038fb397f3 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 @@ -143,7 +143,7 @@ fun CreatePollView( trailingContent = ListItemContent.Custom { Icon( imageVector = CompoundIcons.Delete(), - contentDescription = null, + contentDescription = stringResource(R.string.screen_create_poll_delete_option_a11y, answer.text), modifier = Modifier.clickable(answer.canDelete) { state.eventSink(CreatePollEvents.RemoveAnswer(index)) }, diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt index 0ad8f8fe84..1101276577 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/history/PollHistoryView.kt @@ -8,7 +8,6 @@ package io.element.android.features.poll.impl.history import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -30,6 +29,8 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.isTraversalGroup +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp @@ -52,7 +53,7 @@ import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun PollHistoryView( state: PollHistoryState, @@ -179,7 +180,9 @@ private fun PollHistoryList( if (pollHistoryItems.isEmpty()) { item { Column( - modifier = Modifier.fillParentMaxSize().padding(bottom = 24.dp), + modifier = Modifier + .fillParentMaxSize() + .padding(bottom = 24.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { @@ -192,7 +195,9 @@ private fun PollHistoryList( text = emptyStringResource, style = ElementTheme.typography.fontBodyLgRegular, color = ElementTheme.colors.textSecondary, - modifier = Modifier.fillMaxWidth().padding(vertical = 24.dp, horizontal = 16.dp), + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 24.dp, horizontal = 16.dp), textAlign = TextAlign.Center, ) @@ -228,7 +233,10 @@ private fun PollHistoryItemRow( modifier: Modifier = Modifier, ) { Surface( - modifier = modifier, + modifier = modifier.semantics(mergeDescendants = true) { + // Allow the answers to be traversed by Talkback + isTraversalGroup = true + }, border = BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary), shape = RoundedCornerShape(size = 12.dp) ) { diff --git a/features/poll/impl/src/main/res/values-fr/translations.xml b/features/poll/impl/src/main/res/values-fr/translations.xml index 8a0c8ea5d5..badf3888e2 100644 --- a/features/poll/impl/src/main/res/values-fr/translations.xml +++ b/features/poll/impl/src/main/res/values-fr/translations.xml @@ -5,6 +5,7 @@ "Masquer les votes" "Option %1$d" "Vos modifications n’ont pas été enregistrées. Êtes-vous certain de vouloir quitter ?" + "Supprimer l’option %1$s" "Question ou sujet" "Quel est le sujet du sondage ?" "Créer un sondage" diff --git a/features/poll/impl/src/main/res/values-nb/translations.xml b/features/poll/impl/src/main/res/values-nb/translations.xml index 5e363ff4a2..7396cf9cf9 100644 --- a/features/poll/impl/src/main/res/values-nb/translations.xml +++ b/features/poll/impl/src/main/res/values-nb/translations.xml @@ -5,6 +5,7 @@ "Skjul stemmer" "Alternativ %1$d" "Endringene dine er ikke lagret. Er du sikker på at du vil gå tilbake?" + "Slett alternativet %1$s" "Spørsmål eller emne" "Hva handler avstemningen om?" "Opprett avstemning" diff --git a/features/poll/impl/src/main/res/values/localazy.xml b/features/poll/impl/src/main/res/values/localazy.xml index 7a7a15ea3c..6019d908b4 100644 --- a/features/poll/impl/src/main/res/values/localazy.xml +++ b/features/poll/impl/src/main/res/values/localazy.xml @@ -5,6 +5,7 @@ "Hide votes" "Option %1$d" "Your changes have not been saved. Are you sure you want to go back?" + "Delete option %1$s" "Question or topic" "What is the poll about?" "Create Poll" diff --git a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt index 3da8d50d49..54df066bbe 100644 --- a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt +++ b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/history/PollHistoryViewTest.kt @@ -131,7 +131,10 @@ class PollHistoryViewTest { rule.setPollHistoryViewView( state = state, ) - rule.onNodeWithText(answer.text).performClick() + rule.onNodeWithText( + text = answer.text, + useUnmergedTree = true, + ).performClick() eventsRecorder.assertSingle( PollHistoryEvents.SelectPollAnswer(eventId, answer.id) ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt index 5b91c65f08..58f93fc665 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt @@ -8,6 +8,7 @@ package io.element.android.features.preferences.impl.advanced import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.ui.res.stringResource import io.element.android.libraries.designsystem.components.preferences.DropdownOption import io.element.android.libraries.matrix.api.media.MediaPreviewValue @@ -26,14 +27,17 @@ data class AdvancedSettingsState( enum class ThemeOption : DropdownOption { System { @Composable + @ReadOnlyComposable override fun getText(): String = stringResource(CommonStrings.common_system) }, Dark { @Composable + @ReadOnlyComposable override fun getText(): String = stringResource(CommonStrings.common_dark) }, Light { @Composable + @ReadOnlyComposable override fun getText(): String = stringResource(CommonStrings.common_light) } } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt index 8f2543c161..f73fecaf3c 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt @@ -38,6 +38,7 @@ import io.element.android.libraries.designsystem.theme.components.IconSource import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.utils.OnLifecycleEvent +import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsEvents import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.toImmutableList @@ -149,7 +150,7 @@ private fun NotificationSettingsContentView( Text(stringResource(R.string.full_screen_intent_banner_message)) }, onClick = { - state.fullScreenIntentPermissionsState.openFullScreenIntentSettings() + state.fullScreenIntentPermissionsState.eventSink(FullScreenIntentPermissionsEvents.OpenSettings) } ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt index 6a94670c7d..b9a001e812 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.features.preferences.impl.R import io.element.android.libraries.designsystem.components.async.AsyncActionView -import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar +import io.element.android.libraries.designsystem.components.avatar.RoomAvatar 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.PreferencePage @@ -97,7 +97,7 @@ fun EditDefaultNotificationSettingView( Text(text = subtitle) }, leadingContent = ListItemContent.Custom { - CompositeAvatar( + RoomAvatar( avatarData = summary.avatarData, heroes = summary.heroesAvatar, ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/ClearCacheUseCase.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/ClearCacheUseCase.kt index 5662e4fd46..9b90c8ba53 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/ClearCacheUseCase.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/tasks/ClearCacheUseCase.kt @@ -59,6 +59,7 @@ class DefaultClearCacheUseCase @Inject constructor( seenInvitesStore.clear() // Ensure any error will be displayed again pushService.setIgnoreRegistrationError(matrixClient.sessionId, false) + pushService.resetBatteryOptimizationState() // Ensure the app is restarted defaultCacheService.onClearedCache(matrixClient.sessionId) } diff --git a/features/preferences/impl/src/main/res/values-es/translations.xml b/features/preferences/impl/src/main/res/values-es/translations.xml index 1ae1660faa..afdc23d90b 100644 --- a/features/preferences/impl/src/main/res/values-es/translations.xml +++ b/features/preferences/impl/src/main/res/values-es/translations.xml @@ -8,14 +8,22 @@ "URL base personalizada de Element Call" "Define una URL base personalizada para Element Call." "URL no válida, asegúrate de incluir el protocolo (http/https) y la dirección correcta." + "Ocultar avatares en las invitaciones a salas" + "Ocultar vistas previas de multimedia en la cronología" "Sube fotos y vídeos más rápido y reduce el uso de datos" "Optimizar la calidad de los medios" + "Moderación y seguridad" "Proveedor de notificaciones push" "Desactiva el editor de texto enriquecido para escribir Markdown manualmente." "Confirmaciones de lectura" "Si se desactiva, las confirmaciones de lectura no se enviarán a nadie. Seguirás recibiendo confirmaciones de lectura de otros usuarios." "Compartir presencia" "Si se desactiva, no podrás enviar ni recibir confirmaciones de lectura ni notificaciones de escritura." + "Ocultar siempre" + "Mostrar siempre" + "En las salas privadas" + "Siempre se puede mostrar un ítem multimedia oculto pulsando sobre él" + "Mostrar multimedia en la cronología" "Habilita la opción para ver el contenido en bruto del mensaje en la cronología." "No tienes usuarios bloqueados" "Desbloquear" @@ -45,7 +53,7 @@ Si continúas, es posible que algunos de tus ajustes cambien." "La configuración no se ha corregido, por favor inténtalo de nuevo." "Chats grupales" "Invitaciones" - "Tu servidor principal no admite esta opción en salas cifradas, puede que no recibas notificaciones en algunas salas." + "Tu servidor base no admite esta opción en salas cifradas, puede que no recibas notificaciones de algunas salas." "Menciones" "Todos" "Menciones" @@ -55,6 +63,7 @@ Si continúas, es posible que algunos de tus ajustes cambien." "ajustes del sistema" "Notificaciones del sistema desactivadas" "Notificaciones" + "Historial de notificaciones push" "Solucionar problemas" "Solucionar problemas con las notificaciones" diff --git a/features/preferences/impl/src/main/res/values-ru/translations.xml b/features/preferences/impl/src/main/res/values-ru/translations.xml index dcdebe4282..70b15002a6 100644 --- a/features/preferences/impl/src/main/res/values-ru/translations.xml +++ b/features/preferences/impl/src/main/res/values-ru/translations.xml @@ -23,6 +23,7 @@ "Всегда показывать" "В личных комнатах" "Скрытый медиафайл всегда можно отобразить, нажав на него." + "Показать медиафайлы в хронологии" "Включить опцию просмотра источника сообщения в ленте." "У вас нет заблокированных пользователей" "Разблокировать" @@ -62,6 +63,7 @@ "настройки системы" "Системные уведомления выключены" "Уведомления" + "История уведомлений" "Устранение неполадок" "Уведомления об устранении неполадок" diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/tasks/DefaultClearCacheUseCaseTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/tasks/DefaultClearCacheUseCaseTest.kt index ab391bfc62..cfdc63984c 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/tasks/DefaultClearCacheUseCaseTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/tasks/DefaultClearCacheUseCaseTest.kt @@ -46,8 +46,10 @@ class DefaultClearCacheUseCaseTest { resetLambda = resetFtueLambda, ) val setIgnoreRegistrationErrorLambda = lambdaRecorder { _, _ -> } + val resetBatteryOptimizationStateResult = lambdaRecorder { } val pushService = FakePushService( - setIgnoreRegistrationErrorLambda = setIgnoreRegistrationErrorLambda + setIgnoreRegistrationErrorLambda = setIgnoreRegistrationErrorLambda, + resetBatteryOptimizationStateResult = resetBatteryOptimizationStateResult, ) val seenInvitesStore = InMemorySeenInvitesStore(setOf(A_ROOM_ID)) assertThat(seenInvitesStore.seenRoomIds().first()).isNotEmpty() @@ -68,6 +70,7 @@ class DefaultClearCacheUseCaseTest { resetFtueLambda.assertions().isCalledOnce() setIgnoreRegistrationErrorLambda.assertions().isCalledOnce() .with(value(matrixClient.sessionId), value(false)) + resetBatteryOptimizationStateResult.assertions().isCalledOnce() assertThat(awaitItem()).isEqualTo(matrixClient.sessionId) assertThat(seenInvitesStore.seenRoomIds().first()).isEmpty() assertThat(activeRoomsHolder.getActiveRoom(A_SESSION_ID)).isNull() diff --git a/features/rageshake/impl/src/main/res/values-es/translations.xml b/features/rageshake/impl/src/main/res/values-es/translations.xml index 7398dbc6de..cdeb467cfa 100644 --- a/features/rageshake/impl/src/main/res/values-es/translations.xml +++ b/features/rageshake/impl/src/main/res/values-es/translations.xml @@ -6,12 +6,12 @@ "Editar captura de pantalla" "Describe el problema. ¿Qué has hecho? ¿Qué esperabas que ocurriera? ¿Qué ocurrió realmente? Por favor, detállalo todo lo que puedas." "Describe el problema…" - "Si es posible, escriba la descripción en inglés." - "La descripción es demasiado corta. Proporcione más detalles sobre lo sucedido. ¡Gracias!" + "Si es posible, escribe la descripción en inglés." + "La descripción es demasiado corta. Proporciona más detalles sobre lo sucedido. ¡Gracias!" "Enviar registros de fallos" "Permitir registros" "Enviar captura de pantalla" - "Los registros se incluirán con su mensaje para asegurarse de que todo funciona correctamente. Para enviar tu mensaje sin registros, desactiva esta configuración." + "Los registros se incluirán con tu mensaje para asegurarse de que todo funciona correctamente. Para enviar tu mensaje sin registros, desactiva esta opción." "%1$s se cerró inesperadamente la última vez que se lo usaste. ¿Quieres compartir un informe de error con nosotros?" "Ver los registros" diff --git a/features/reportroom/impl/src/main/res/values-es/translations.xml b/features/reportroom/impl/src/main/res/values-es/translations.xml new file mode 100644 index 0000000000..7391dc7ca3 --- /dev/null +++ b/features/reportroom/impl/src/main/res/values-es/translations.xml @@ -0,0 +1,8 @@ + + + "Tu denuncia se ha enviado correctamente, pero hemos encontrado un problema al intentar salir de la sala. Inténtalo de nuevo." + "No se pudo salir de la sala" + "Denuncia esta sala a tu administrador. Si los mensajes están cifrados, tu administrador no podrá leerlos." + "Describe el motivo de la denuncia…" + "Denunciar sala" + diff --git a/features/reportroom/impl/src/main/res/values-ru/translations.xml b/features/reportroom/impl/src/main/res/values-ru/translations.xml index de5871f29f..d413f25b44 100644 --- a/features/reportroom/impl/src/main/res/values-ru/translations.xml +++ b/features/reportroom/impl/src/main/res/values-ru/translations.xml @@ -1,6 +1,8 @@ + "Ваш отчет был успешно отправлен, но мы столкнулись с проблемой при попытке покинуть комнату. Пожалуйста, попробуйте еще раз." "Невозможно покинуть комнату" "Сообщите об этой комнате своему администратору. Если сообщения зашифрованы, ваш администратор не сможет их прочитать." "Опишите причину…" + "Комната отчетов" diff --git a/features/roomaliasresolver/impl/src/main/res/values-in/translations.xml b/features/roomaliasresolver/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..b5745b8827 --- /dev/null +++ b/features/roomaliasresolver/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,4 @@ + + + "Gagal menyelesaikan alias ruangan." + 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 505751c412..3e34f8d62b 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 @@ -210,6 +210,7 @@ class RoomDetailsPresenter @Inject constructor( canShowSecurityAndPrivacy = canShowSecurityAndPrivacy, hasMemberVerificationViolations = hasMemberVerificationViolations, canReportRoom = canReportRoom, + isTombstoned = roomInfo.successorRoom != null, eventSink = ::handleEvents, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt index 5addbf3db8..e589eaaed9 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt @@ -49,6 +49,7 @@ data class RoomDetailsState( val canShowSecurityAndPrivacy: Boolean, val hasMemberVerificationViolations: Boolean, val canReportRoom: Boolean, + val isTombstoned: Boolean, val eventSink: (RoomDetailsEvent) -> Unit ) { val roomBadges = buildList { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt index d2cb4c5944..64f9976841 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt @@ -53,6 +53,7 @@ open class RoomDetailsStateProvider : PreviewParameterProvider aRoomDetailsState(knockRequestsCount = null, canShowKnockRequests = true), aRoomDetailsState(knockRequestsCount = 4, canShowKnockRequests = true), aRoomDetailsState(hasMemberVerificationViolations = true), + aRoomDetailsState(isTombstoned = true), aDmRoomDetailsState(dmRoomMemberVerificationState = UserProfileVerificationState.VERIFIED), aDmRoomDetailsState(dmRoomMemberVerificationState = UserProfileVerificationState.VERIFICATION_VIOLATION), // Add other state here @@ -118,6 +119,7 @@ fun aRoomDetailsState( canShowSecurityAndPrivacy: Boolean = true, hasMemberVerificationViolations: Boolean = false, canReportRoom: Boolean = true, + isTombstoned: Boolean = false, eventSink: (RoomDetailsEvent) -> Unit = {}, ) = RoomDetailsState( roomId = roomId, @@ -148,6 +150,7 @@ fun aRoomDetailsState( canShowSecurityAndPrivacy = canShowSecurityAndPrivacy, hasMemberVerificationViolations = hasMemberVerificationViolations, canReportRoom = canReportRoom, + isTombstoned = isTombstoned, eventSink = eventSink, ) 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 8f7502dee5..254c31023d 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 @@ -48,8 +48,8 @@ import io.element.android.libraries.designsystem.atomic.molecules.MatrixBadgeRow import io.element.android.libraries.designsystem.components.ClickableLinkText 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.CompositeAvatar import io.element.android.libraries.designsystem.components.avatar.DmAvatars +import io.element.android.libraries.designsystem.components.avatar.RoomAvatar import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.button.MainActionButton import io.element.android.libraries.designsystem.components.list.ListItemContent @@ -138,6 +138,7 @@ fun RoomDetailsView( roomName = state.roomName, roomAlias = state.roomAlias, heroes = state.heroes, + isTombstoned = state.isTombstoned, openAvatarPreview = { avatarUrl -> openAvatarPreview(state.roomName, avatarUrl) }, @@ -380,6 +381,7 @@ private fun RoomHeaderSection( roomName: String, roomAlias: RoomAlias?, heroes: ImmutableList, + isTombstoned: Boolean, openAvatarPreview: (url: String) -> Unit, onSubtitleClick: (String) -> Unit, ) { @@ -389,11 +391,12 @@ private fun RoomHeaderSection( .padding(horizontal = 16.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { - CompositeAvatar( + RoomAvatar( avatarData = AvatarData(roomId.value, roomName, avatarUrl, AvatarSize.RoomHeader), heroes = heroes.map { user -> user.getAvatarData(size = AvatarSize.RoomHeader) }.toPersistentList(), + isTombstoned = isTombstoned, modifier = Modifier .clickable(enabled = avatarUrl != null) { openAvatarPreview(avatarUrl!!) } .testTag(TestTags.roomDetailAvatar) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index c5d2a93e2a..88da5b6ebc 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -12,7 +12,6 @@ import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -136,7 +135,6 @@ fun RoomMemberListView( } } -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @Composable private fun RoomMemberList( roomMembers: AsyncData, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt index 55126b33cd..d2d5db00e9 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt @@ -33,7 +33,6 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.ui.room.getRoomMemberAsState import io.element.android.libraries.matrix.ui.room.roomMemberIdentityStateChange import io.element.android.libraries.ui.strings.CommonStrings -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -55,7 +54,6 @@ class RoomMemberDetailsPresenter @AssistedInject constructor( private val userProfilePresenter = userProfilePresenterFactory.create(roomMemberId) - @OptIn(ExperimentalCoroutinesApi::class) @Composable override fun present(): UserProfileState { val coroutineScope = rememberCoroutineScope() diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt index 74a7d992b7..b1a7a7df21 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt @@ -11,7 +11,6 @@ import androidx.activity.compose.BackHandler import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box @@ -225,7 +224,6 @@ fun ChangeRolesView( } } -@OptIn(ExperimentalFoundationApi::class) @Composable private fun SearchResultsList( currentRole: RoomMember.Role, 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 c98d65b90a..ffce0a6b76 100644 --- a/features/roomdetails/impl/src/main/res/values-es/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-es/translations.xml @@ -3,7 +3,7 @@ "Necesitarás una dirección de sala para que sea visible en el directorio." "Dirección de la sala" "Se ha producido un error al actualizar la configuración de notificaciones." - "Tu servidor principal no admite esta opción en salas cifradas, puede que no recibas notificaciones en algunas salas." + "Tu servidor base no admite esta opción en salas cifradas, puede que no recibas notificaciones de algunas salas." "Encuestas" "Solo administradores" "Vetar personas" @@ -74,7 +74,7 @@ "Sacar y vetar a un miembro" "Solo eliminar miembro" "Quitar veto" - "Podrán volver a unirse a esta sala si son invitados de nuevo." + "Podrá volver a unirse a esta sala si se le invita." "Quitar veto al usuario" "Vetados" "Miembros" @@ -93,7 +93,7 @@ "Se ha producido un error al cargar la configuración de las notificaciones." "No se pudo restaurar el modo predeterminado, por favor vuelve a intentarlo de nuevo." "No se pudo cambiar el modo, por favor inténtalo de nuevo." - "Tu servidor principal no admite esta opción en salas cifradas, no recibirás notificaciones en esta sala." + "Tu servidor base no admite esta opción en salas cifradas, no recibirás notificaciones de esta sala." "Todos los mensajes" "Únicamente Menciones y Palabras clave" "En esta sala, notificarme por" 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 fc311b403f..559c020986 100644 --- a/features/roomdetails/impl/src/main/res/values-fr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fr/translations.xml @@ -71,7 +71,7 @@ "%1$d personne" "%1$d personnes" - "Retirer et bannir ce membre" + "Bannir du salon" "Retirer le membre uniquement" "Débannir" "Il pourra rejoindre le salon à nouveau si il est invité." diff --git a/features/roomdirectory/impl/src/main/res/values-in/translations.xml b/features/roomdirectory/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..3cf6342e1b --- /dev/null +++ b/features/roomdirectory/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,5 @@ + + + "Gagal memuat" + "Direktori ruangan" + diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt index 7435424b15..5825c0a1e5 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt @@ -12,6 +12,8 @@ import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.fullscreenintent.api.aFullScreenIntentPermissionsState import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.push.api.battery.BatteryOptimizationState +import io.element.android.libraries.push.api.battery.aBatteryOptimizationState import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentSet @@ -31,10 +33,12 @@ internal fun aRoomsContentState( securityBannerState: SecurityBannerState = SecurityBannerState.None, summaries: ImmutableList = aRoomListRoomSummaryList(), fullScreenIntentPermissionsState: FullScreenIntentPermissionsState = aFullScreenIntentPermissionsState(), + batteryOptimizationState: BatteryOptimizationState = aBatteryOptimizationState(), seenRoomInvites: Set = emptySet(), ) = RoomListContentState.Rooms( securityBannerState = securityBannerState, fullScreenIntentPermissionsState = fullScreenIntentPermissionsState, + batteryOptimizationState = batteryOptimizationState, summaries = summaries, seenRoomInvites = seenRoomInvites.toPersistentSet(), ) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt index 7746f98204..9e8199cd80 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt @@ -52,6 +52,7 @@ import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.preferences.api.store.SessionPreferencesStore +import io.element.android.libraries.push.api.battery.BatteryOptimizationState import io.element.android.libraries.push.api.notifications.NotificationCleaner import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analyticsproviders.api.trackers.captureInteraction @@ -88,6 +89,7 @@ class RoomListPresenter @Inject constructor( private val analyticsService: AnalyticsService, private val acceptDeclineInvitePresenter: Presenter, private val fullScreenIntentPermissionsPresenter: Presenter, + private val batteryOptimizationPresenter: Presenter, private val notificationCleaner: NotificationCleaner, private val logoutPresenter: Presenter, private val appPreferencesStore: AppPreferencesStore, @@ -248,6 +250,7 @@ class RoomListPresenter @Inject constructor( RoomListContentState.Rooms( securityBannerState = securityBannerState, fullScreenIntentPermissionsState = fullScreenIntentPermissionsPresenter.present(), + batteryOptimizationState = batteryOptimizationPresenter.present(), summaries = roomSummaries.dataOrNull().orEmpty().toPersistentList(), seenRoomInvites = seenRoomInvites.toPersistentSet(), ) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt index f685d5f379..0cf6147df7 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt @@ -18,6 +18,7 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.push.api.battery.BatteryOptimizationState import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableSet @@ -78,6 +79,7 @@ sealed interface RoomListContentState { data class Rooms( val securityBannerState: SecurityBannerState, val fullScreenIntentPermissionsState: FullScreenIntentPermissionsState, + val batteryOptimizationState: BatteryOptimizationState, val summaries: ImmutableList, val seenRoomInvites: ImmutableSet, ) : RoomListContentState diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt index 4a221d3c97..cb4818ddd1 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListStateProvider.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.push.api.battery.aBatteryOptimizationState import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -45,6 +46,7 @@ open class RoomListStateProvider : PreviewParameterProvider { aRoomListState(contentState = aSkeletonContentState()), aRoomListState(searchState = aRoomListSearchState(isSearchActive = true, query = "Test")), aRoomListState(contentState = aRoomsContentState(securityBannerState = SecurityBannerState.SetUpRecovery)), + aRoomListState(contentState = aRoomsContentState(batteryOptimizationState = aBatteryOptimizationState(shouldDisplayBanner = true))), ) } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/BatteryOptimizationBanner.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/BatteryOptimizationBanner.kt new file mode 100644 index 0000000000..8fde1834d2 --- /dev/null +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/BatteryOptimizationBanner.kt @@ -0,0 +1,45 @@ +/* + * 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.roomlist.impl.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import io.element.android.features.roomlist.impl.R +import io.element.android.libraries.designsystem.components.Announcement +import io.element.android.libraries.designsystem.components.AnnouncementType +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.push.api.battery.BatteryOptimizationEvents +import io.element.android.libraries.push.api.battery.BatteryOptimizationState +import io.element.android.libraries.push.api.battery.aBatteryOptimizationState + +@Composable +internal fun BatteryOptimizationBanner( + state: BatteryOptimizationState, + modifier: Modifier = Modifier, +) { + Announcement( + modifier = modifier.roomListBannerPadding(), + title = stringResource(R.string.banner_battery_optimization_title_android), + description = stringResource(R.string.banner_battery_optimization_content_android), + type = AnnouncementType.Actionable( + actionText = stringResource(R.string.banner_battery_optimization_submit_android), + onActionClick = { state.eventSink(BatteryOptimizationEvents.RequestDisableOptimizations) }, + onDismissClick = { state.eventSink(BatteryOptimizationEvents.Dismiss) }, + ), + ) +} + +@PreviewsDayNight +@Composable +internal fun BatteryOptimizationBannerPreview() = ElementPreview { + BatteryOptimizationBanner( + state = aBatteryOptimizationState(), + ) +} diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/FullScreenIntentPermissionBanner.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/FullScreenIntentPermissionBanner.kt index 7e84a26ab3..339b5f4fa6 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/FullScreenIntentPermissionBanner.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/FullScreenIntentPermissionBanner.kt @@ -15,6 +15,7 @@ import io.element.android.libraries.designsystem.components.Announcement import io.element.android.libraries.designsystem.components.AnnouncementType import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsEvents import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.fullscreenintent.api.aFullScreenIntentPermissionsState import io.element.android.libraries.ui.strings.CommonStrings @@ -29,8 +30,8 @@ fun FullScreenIntentPermissionBanner( description = stringResource(R.string.full_screen_intent_banner_message), type = AnnouncementType.Actionable( actionText = stringResource(CommonStrings.action_continue), - onDismissClick = state.dismissFullScreenIntentBanner, - onActionClick = state.openFullScreenIntentSettings, + onDismissClick = { state.eventSink(FullScreenIntentPermissionsEvents.Dismiss) }, + onActionClick = { state.eventSink(FullScreenIntentPermissionsEvents.OpenSettings) }, ), modifier = modifier.roomListBannerPadding(), ) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt index 0118a4fb81..b27f21c7f6 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt @@ -149,7 +149,7 @@ private fun EmptyView( onDismissClick = { eventSink(RoomListEvents.DismissBanner) }, ) } - else -> Unit + SecurityBannerState.None -> Unit } } } @@ -234,6 +234,10 @@ private fun RoomsViewList( item { FullScreenIntentPermissionBanner(state = state.fullScreenIntentPermissionsState) } + } else if (state.batteryOptimizationState.shouldDisplayBanner) { + item { + BatteryOptimizationBanner(state = state.batteryOptimizationState) + } } } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt index 7e5265c965..1be57d631a 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt @@ -7,7 +7,6 @@ package io.element.android.features.roomlist.impl.components -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement @@ -45,7 +44,7 @@ import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryProvid import io.element.android.features.roomlist.impl.model.RoomSummaryDisplayType import io.element.android.libraries.core.extensions.orEmpty import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom -import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar +import io.element.android.libraries.designsystem.components.avatar.RoomAvatar 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 @@ -122,7 +121,7 @@ internal fun RoomSummaryRow( timestamp = room.timestamp, isHighlighted = room.isHighlighted ) - LastMessageAndIndicatorRow(room = room) + MessagePreviewAndIndicatorRow(room = room) } } RoomSummaryDisplayType.KNOCKED -> { @@ -149,7 +148,7 @@ internal fun RoomSummaryRow( Spacer(modifier = Modifier.height(4.dp)) } Text( - text = stringResource(id = R.string.screen_join_room_knock_sent_title), + text = stringResource(id = R.string.screen_roomlist_knock_event_sent_description), maxLines = 1, overflow = TextOverflow.Ellipsis, style = ElementTheme.typography.fontBodyMdRegular, @@ -161,7 +160,6 @@ internal fun RoomSummaryRow( } } -@OptIn(ExperimentalFoundationApi::class) @Composable private fun RoomSummaryScaffoldRow( room: RoomListRoomSummary, @@ -186,10 +184,11 @@ private fun RoomSummaryScaffoldRow( .padding(horizontal = 16.dp, vertical = 11.dp) .height(IntrinsicSize.Min), ) { - CompositeAvatar( + RoomAvatar( avatarData = room.avatarData, heroes = room.heroes, - hideAvatarImages = hideAvatarImage, + isTombstoned = room.isTombstoned, + hideAvatarImage = hideAvatarImage, ) Spacer(modifier = Modifier.width(16.dp)) Column( @@ -257,7 +256,7 @@ private fun InviteSubtitle( } @Composable -private fun LastMessageAndIndicatorRow( +private fun MessagePreviewAndIndicatorRow( room: RoomListRoomSummary, modifier: Modifier = Modifier, ) { @@ -265,12 +264,15 @@ private fun LastMessageAndIndicatorRow( modifier = modifier.fillMaxWidth(), horizontalArrangement = spacedBy(28.dp) ) { - // Last Message - val attributedLastMessage = room.lastMessage as? AnnotatedString - ?: AnnotatedString(room.lastMessage.orEmpty().toString()) + val messagePreview = if (room.isTombstoned) { + stringResource(R.string.screen_roomlist_tombstoned_room_description) + } else { + room.lastMessage.orEmpty() + } + val annotatedMessagePreview = messagePreview as? AnnotatedString ?: AnnotatedString(text = messagePreview.toString()) Text( modifier = Modifier.weight(1f), - text = attributedLastMessage, + text = annotatedMessagePreview, color = ElementTheme.roomListRoomMessage(), style = ElementTheme.typography.fontBodyMdRegular, minLines = 2, diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt index d1581f545b..98b7f8d853 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt @@ -67,6 +67,7 @@ class RoomListRoomSummaryFactory @Inject constructor( heroes = roomInfo.heroes.map { user -> user.getAvatarData(size = AvatarSize.RoomListItem) }.toImmutableList(), + isTombstoned = roomInfo.successorRoom != null, ) } } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt index a1c1156c2a..4b2c1e7afc 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummary.kt @@ -36,6 +36,7 @@ data class RoomListRoomSummary( val isDm: Boolean, val isFavorite: Boolean, val inviteSender: InviteSender?, + val isTombstoned: Boolean, val heroes: ImmutableList, ) { val isHighlighted = userDefinedNotificationMode != RoomNotificationMode.MUTE && diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt index e71c8849b7..111c4bc86b 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt @@ -110,6 +110,11 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider = emptyList(), + isTombstoned: Boolean = false, ) = RoomListRoomSummary( id = id, roomId = RoomId(id), @@ -165,4 +171,5 @@ internal fun aRoomListRoomSummary( displayType = displayType, canonicalAlias = canonicalAlias, heroes = heroes.toImmutableList(), + isTombstoned = isTombstoned, ) diff --git a/features/roomlist/impl/src/main/res/values-cs/translations.xml b/features/roomlist/impl/src/main/res/values-cs/translations.xml index 927f9a40b9..7c15f1c82a 100644 --- a/features/roomlist/impl/src/main/res/values-cs/translations.xml +++ b/features/roomlist/impl/src/main/res/values-cs/translations.xml @@ -15,7 +15,6 @@ "Odmítnout chat" "Žádné pozvánky" "%1$s (%2$s) vás pozval(a)" - "Žádost o vstup odeslána" "Jedná se o jednorázový proces, prosíme o strpení." "Nastavení vašeho účtu" "Vytvořte novou konverzaci nebo místnost" @@ -37,9 +36,11 @@ Prozatím můžete zrušit výběr filtrů, abyste viděli své další chaty""Nepřečtené" "Gratulujeme! Nemáte žádné nepřečtené zprávy!" + "Žádost o vstup odeslána" "Všechny chaty" "Označit jako přečtené" "Označit jako nepřečtené" + "Tato místnost byla aktualizována" "Zdá se, že používáte nové zařízení. Ověřte přihlášení, abyste měli přístup k zašifrovaným zprávám." "Ověřte, že jste to vy" diff --git a/features/roomlist/impl/src/main/res/values-cy/translations.xml b/features/roomlist/impl/src/main/res/values-cy/translations.xml index de6fe0cf0f..7d779e0904 100644 --- a/features/roomlist/impl/src/main/res/values-cy/translations.xml +++ b/features/roomlist/impl/src/main/res/values-cy/translations.xml @@ -15,7 +15,6 @@ "Gwrthod sgwrs" "Dim Gwahoddiadau" "Mae %1$s (%2$s) wedi eich gwahodd" - "Anfonwyd y cais i ymuno" "Mae hon yn broses un tro, diolch am aros." "Creu eich cyfrif." "Crëwch sgwrs neu ystafell newydd" @@ -37,6 +36,7 @@ Am y tro, gallwch ddad-ddewis hidlwyr er mwyn gweld eich sgyrsiau eraill""Heb ei ddarllen" "Llongyfarchiadau! Does gennych chi ddim negeseuon heb eu darllen!" + "Anfonwyd y cais i ymuno" "Sgyrsiau" "Marcio fel wedi\'i ddarllen" "Marcio fel heb ei ddarllen" diff --git a/features/roomlist/impl/src/main/res/values-de/translations.xml b/features/roomlist/impl/src/main/res/values-de/translations.xml index 59cd4dc0c6..bd09aad06d 100644 --- a/features/roomlist/impl/src/main/res/values-de/translations.xml +++ b/features/roomlist/impl/src/main/res/values-de/translations.xml @@ -15,7 +15,6 @@ "Einladung ablehnen" "Keine Einladungen" "%1$s (%2$s) hat dich eingeladen" - "Beitrittsanfrage geschickt" "Dies ist ein einmaliger Vorgang, danke fürs Warten." "Dein Konto wird eingerichtet." "Eine Unterthaltung oder Raum erstellen" @@ -37,6 +36,7 @@ Deaktivieren Sie den entsprechenden Filter, um Ihre anderen Chatrooms zu sehen"< "Ungelesen" "Glückwunsch! Sie haben keine ungelesenen Nachrichten!" + "Beitrittsanfrage geschickt" "Chats" "Als gelesen markieren" "Als ungelesen markieren" diff --git a/features/roomlist/impl/src/main/res/values-el/translations.xml b/features/roomlist/impl/src/main/res/values-el/translations.xml index cd91ad7efa..596592f594 100644 --- a/features/roomlist/impl/src/main/res/values-el/translations.xml +++ b/features/roomlist/impl/src/main/res/values-el/translations.xml @@ -15,7 +15,6 @@ "Απόρριψη συνομιλίας" "Χωρίς προσκλήσεις" "%1$s (%2$s) σέ προσκάλεσε" - "Το αίτημα συμμετοχής στάλθηκε" "Αυτή είναι μια εφάπαξ διαδικασία, ευχαριστώ που περίμενες." "Ρύθμιση του λογαριασμού σου." "Δημιουργία νέας συνομιλίας ή δωματίου" @@ -37,6 +36,7 @@ "Μη αναγνωσμένα" "Συγχαρητήρια! Δεν έχεις μη αναγνωσμένα μηνύματα!" + "Το αίτημα συμμετοχής στάλθηκε" "Συνομιλίες" "Επισήμανση ως αναγνωσμένου" "Επισήμανση ως μη αναγνωσμένου" diff --git a/features/roomlist/impl/src/main/res/values-es/translations.xml b/features/roomlist/impl/src/main/res/values-es/translations.xml index fced9f1141..a58f9e743a 100644 --- a/features/roomlist/impl/src/main/res/values-es/translations.xml +++ b/features/roomlist/impl/src/main/res/values-es/translations.xml @@ -15,7 +15,6 @@ "Rechazar el chat" "Sin invitaciones" "%1$s (%2$s) te invitó" - "Solicitud de unión enviada" "Este proceso solo se hace una vez, gracias por esperar." "Configura tu cuenta" "Crear una nueva conversación o sala" @@ -37,6 +36,7 @@ Por ahora, puedes deseleccionar los filtros para ver tus otros chats" "No leídos" "¡Felicidades! ¡No tienes ningún mensaje sin leer!" + "Solicitud de unión enviada" "Chats" "Marcar como leído" "Marcar como no leído" diff --git a/features/roomlist/impl/src/main/res/values-et/translations.xml b/features/roomlist/impl/src/main/res/values-et/translations.xml index a7e3f822bf..ecba029e6e 100644 --- a/features/roomlist/impl/src/main/res/values-et/translations.xml +++ b/features/roomlist/impl/src/main/res/values-et/translations.xml @@ -15,7 +15,6 @@ "Keeldu vestlusest" "Kutseid pole" "%1$s (%2$s) saatis sulle kutse" - "Liitumispalve on saadetud" "Tänud, et ootad - seda toimingut on vaja teha vaid üks kord." "Seadistame sinu kasutajakontot." "Loo uus vestlus või jututuba" @@ -37,6 +36,7 @@ Aga seni… oma teiste vestluste nägemiseks pead eemaldama filtrid" "Lugemata" "Õnnitleme! Sul pole ühtegi lugemata sõnumit!" + "Liitumispalve on saadetud" "Vestlused" "Märgi loetuks" "Märgi mitteloetuks" diff --git a/features/roomlist/impl/src/main/res/values-eu/translations.xml b/features/roomlist/impl/src/main/res/values-eu/translations.xml index 977ae65fe3..8289dc97d4 100644 --- a/features/roomlist/impl/src/main/res/values-eu/translations.xml +++ b/features/roomlist/impl/src/main/res/values-eu/translations.xml @@ -11,7 +11,6 @@ "Baztertu txata" "Ez dago gonbidapenik" "%1$s(e)k (%2$s) gonbidatu zaitu" - "Sartzeko eskaera bidali da" "Behin egin beharreko prozesua da; eskerrik asko itxaroteagatik." "Zure kontua konfiguratzen." "Sortu elkarrizketa edo gela berria" @@ -33,6 +32,7 @@ Oraingoz, iragazkiak desautatu ditzakezu zure gainerako txatak ikusteko""Irakurri gabeak" "Bejondeizula! Ez duzu irakurri gabeko mezurik!" + "Sartzeko eskaera bidali da" "Txatak" "Markatu irakurritzat" "Markatu irakurri gabetzat" diff --git a/features/roomlist/impl/src/main/res/values-fa/translations.xml b/features/roomlist/impl/src/main/res/values-fa/translations.xml index b5a277bb3a..f2b8757107 100644 --- a/features/roomlist/impl/src/main/res/values-fa/translations.xml +++ b/features/roomlist/impl/src/main/res/values-fa/translations.xml @@ -11,7 +11,6 @@ "رد گپ" "بدون دعوت" "%1$s (%2$s) دعوتتان کرد" - "درخواست پیوستن فرستاده شد" "فرایندی یک باره است. ممنون از شکیباییتان." "برپایی حسابتان." "ایجاد اتاق یا گفت‌وگویی جدید" @@ -31,6 +30,7 @@ "نخوانده‌ها" "تبریک! هیچ پیام نخوانده‌ای ندارید!" + "درخواست پیوستن فرستاده شد" "گپ‌ها" "علامت‌گذاری به عنوان خوانده شده" "نشان به ناخوانده" diff --git a/features/roomlist/impl/src/main/res/values-fi/translations.xml b/features/roomlist/impl/src/main/res/values-fi/translations.xml index 27c4972452..910564ba32 100644 --- a/features/roomlist/impl/src/main/res/values-fi/translations.xml +++ b/features/roomlist/impl/src/main/res/values-fi/translations.xml @@ -15,7 +15,6 @@ "Hylkää keskustelu" "Ei kutsuja" "%1$s (%2$s) kutsui sinut" - "Liittymispyyntö lähetetty" "Tämä on kertaluonteinen prosessi, kiitos odottamisesta." "Tiliä määritetään." "Luo uusi keskustelu tai huone" @@ -37,6 +36,7 @@ Toistaiseksi voit poistaa suodattimien valinnan, jotta näet muut keskustelut."< "Lukemattomat" "Onnittelut! Sinulla ei ole lukemattomia viestejä!" + "Liittymispyyntö lähetetty" "Keskustelut" "Merkitse luetuksi" "Merkitse lukemattomaksi" diff --git a/features/roomlist/impl/src/main/res/values-fr/translations.xml b/features/roomlist/impl/src/main/res/values-fr/translations.xml index 0c6805086a..4ffd377d4f 100644 --- a/features/roomlist/impl/src/main/res/values-fr/translations.xml +++ b/features/roomlist/impl/src/main/res/values-fr/translations.xml @@ -15,7 +15,6 @@ "Refuser l’invitation" "Aucune invitation" "%1$s (%2$s) vous a invité(e)" - "Demande de rejoindre le salon envoyée" "Il s’agit d’une opération ponctuelle, merci d’attendre quelques instants." "Configuration de votre compte." "Créer une nouvelle discussion ou un nouveau salon" @@ -37,6 +36,7 @@ En attendant, vous pouvez désélectionner des filtres pour voir vos autres salo "Non-lus" "Félicitations ! Vous n’avez plus de messages non-lus !" + "Demande de rejoindre le salon envoyée" "Conversations" "Marquer comme lu" "Marquer comme non lu" diff --git a/features/roomlist/impl/src/main/res/values-hu/translations.xml b/features/roomlist/impl/src/main/res/values-hu/translations.xml index 145919ffb7..4c1b882ef6 100644 --- a/features/roomlist/impl/src/main/res/values-hu/translations.xml +++ b/features/roomlist/impl/src/main/res/values-hu/translations.xml @@ -15,7 +15,6 @@ "Csevegés elutasítása" "Nincsenek meghívások" "%1$s (%2$s) meghívta" - "Csatlakozási kérés elküldve" "Ez egy egyszeri folyamat, köszönjük a türelmét." "A fiók beállítása." "Új beszélgetés vagy szoba létrehozása" @@ -37,6 +36,7 @@ Egyelőre törölheti a szűrőket a többi csevegés megtekintéséhez.""Olvasatlan" "Gratulálunk! Nincs olvasatlan üzenete!" + "Csatlakozási kérés elküldve" "Összes csevegés" "Megjelölés olvasottként" "Megjelölés olvasatlanként" diff --git a/features/roomlist/impl/src/main/res/values-in/translations.xml b/features/roomlist/impl/src/main/res/values-in/translations.xml index 310e2a256c..2b390790e1 100644 --- a/features/roomlist/impl/src/main/res/values-in/translations.xml +++ b/features/roomlist/impl/src/main/res/values-in/translations.xml @@ -15,7 +15,6 @@ "Tolak obrolan" "Tidak ada undangan" "%1$s (%2$s) mengundang Anda" - "Permintaan untuk bergabung dikirim" "Ini adalah proses satu kali, terima kasih telah menunggu." "Menyiapkan akun Anda." "Buat percakapan atau ruangan baru" @@ -37,6 +36,7 @@ Untuk sementara, Anda dapat membatalkan pilihan saringan untuk melihat percakapa "Belum dibaca" "Selamat! Anda tidak memiliki pesan yang belum dibaca!" + "Permintaan untuk bergabung dikirim" "Semua Obrolan" "Tandai sebagai dibaca" "Tandai sebagai belum dibaca" diff --git a/features/roomlist/impl/src/main/res/values-it/translations.xml b/features/roomlist/impl/src/main/res/values-it/translations.xml index 464267ab27..981fb27d96 100644 --- a/features/roomlist/impl/src/main/res/values-it/translations.xml +++ b/features/roomlist/impl/src/main/res/values-it/translations.xml @@ -15,7 +15,6 @@ "Rifiuta l\'invito alla conversazione" "Nessun invito" "%1$s (%2$s) ti ha invitato" - "Richiesta di accesso inviata" "Si tratta di una procedura che si effettua una sola volta, grazie per l\'attesa." "Configurazione del tuo account." "Crea una nuova conversazione o stanza" @@ -37,6 +36,7 @@ Per il momento, puoi deselezionare i filtri per vedere le altre conversazioni."< "Non letti" "Congratulazioni! Non hai messaggi non letti!" + "Richiesta di accesso inviata" "Tutte le conversazioni" "Segna come letto" "Segna come non letto" diff --git a/features/roomlist/impl/src/main/res/values-nb/translations.xml b/features/roomlist/impl/src/main/res/values-nb/translations.xml index 7e4de08fae..b4fc0b1950 100644 --- a/features/roomlist/impl/src/main/res/values-nb/translations.xml +++ b/features/roomlist/impl/src/main/res/values-nb/translations.xml @@ -15,7 +15,6 @@ "Avslå chat" "Ingen invitasjoner" "%1$s(%2$s) inviterte deg" - "Forespørsel om å bli med sendt" "Dette er en engangsprosess, takk for at du venter." "Setter opp kontoen din." "Opprett en ny samtale eller et nytt rom" @@ -37,6 +36,7 @@ Inntil videre kan du velge bort filtre for å se de andre chattene dine""Uleste" "Gratulerer! Du har ingen uleste meldinger!" + "Forespørsel om å bli med sendt" "Chatter" "Marker som lest" "Merk som ulest" diff --git a/features/roomlist/impl/src/main/res/values-nl/translations.xml b/features/roomlist/impl/src/main/res/values-nl/translations.xml index 425e21d5ed..fc207da016 100644 --- a/features/roomlist/impl/src/main/res/values-nl/translations.xml +++ b/features/roomlist/impl/src/main/res/values-nl/translations.xml @@ -13,7 +13,6 @@ "Chat weigeren" "Geen uitnodigingen" "%1$s (%2$s) heeft je uitgenodigd" - "Verzoek om toe te treden verzonden" "Dit is een eenmalig proces, bedankt voor het wachten." "Je account instellen." "Begin een nieuw gesprek of maak een nieuwe kamer" @@ -35,6 +34,7 @@ Voor nu kun je filters deselecteren om je andere chats te zien" "Ongelezen" "Gefeliciteerd! Je hebt geen ongelezen berichten!" + "Verzoek om toe te treden verzonden" "Chats" "Markeren als gelezen" "Markeren als ongelezen" diff --git a/features/roomlist/impl/src/main/res/values-pl/translations.xml b/features/roomlist/impl/src/main/res/values-pl/translations.xml index bc7f2cb189..8bb236e71a 100644 --- a/features/roomlist/impl/src/main/res/values-pl/translations.xml +++ b/features/roomlist/impl/src/main/res/values-pl/translations.xml @@ -15,7 +15,6 @@ "Odrzuć czat" "Brak zaproszeń" "%1$s (%2$s) zaprosił Cię" - "Wysłano prośbę o dołączenie" "Jest to jednorazowy proces, dziękujemy za czekanie." "Konfigurowanie Twojego konta." "Utwórz nową rozmowę lub pokój" @@ -37,6 +36,7 @@ Na razie możesz wyczyścić filtry, aby zobaczyć pozostałe czaty" "Nieprzeczytane" "Gratulacje! Nie masz żadnych nieprzeczytanych wiadomości!" + "Wysłano prośbę o dołączenie" "Wszystkie czaty" "Oznacz jako przeczytane" "Oznacz jako nieprzeczytane" diff --git a/features/roomlist/impl/src/main/res/values-pt-rBR/translations.xml b/features/roomlist/impl/src/main/res/values-pt-rBR/translations.xml index 00a47154c2..01b75db869 100644 --- a/features/roomlist/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/roomlist/impl/src/main/res/values-pt-rBR/translations.xml @@ -15,7 +15,6 @@ "Recusar chat" "Sem convites" "%1$s(%2$s) convidou você" - "Pedido de adesão enviado" "Este é um processo único, obrigado por esperar." "Configurando sua conta." "Criar uma nova conversa ou sala" @@ -37,6 +36,7 @@ Por enquanto, você pode desmarcar os filtros para ver seus outros bate-papos""Não lidos" "Parabéns! Você não tem nenhuma mensagem não lida!" + "Pedido de adesão enviado" "Conversas" "Marcar como lido" "Marcar como não lido" diff --git a/features/roomlist/impl/src/main/res/values-pt/translations.xml b/features/roomlist/impl/src/main/res/values-pt/translations.xml index 4d87f54b8b..b332c4f1f8 100644 --- a/features/roomlist/impl/src/main/res/values-pt/translations.xml +++ b/features/roomlist/impl/src/main/res/values-pt/translations.xml @@ -15,7 +15,6 @@ "Rejeitar conversa" "Sem convites" "%1$s (%2$s) convidou-te" - "Pedido de adesão enviado" "Este processo só acontece uma única vez, obrigado por esperares." "A configurar a tua conta…" "Criar uma nova conversa ou sala" @@ -37,6 +36,7 @@ Por enquanto, podes anular a seleção dos filtros para veres as tuas outras con "Por ler" "Parabéns! Não tens nenhuma mensagem por ler!" + "Pedido de adesão enviado" "Conversas" "Marcar como lida" "Marcar como não lida" diff --git a/features/roomlist/impl/src/main/res/values-ro/translations.xml b/features/roomlist/impl/src/main/res/values-ro/translations.xml index b332101f2c..2d7bdd8a95 100644 --- a/features/roomlist/impl/src/main/res/values-ro/translations.xml +++ b/features/roomlist/impl/src/main/res/values-ro/translations.xml @@ -13,7 +13,6 @@ "Refuzați conversația" "Nicio invitație" "%1$s (%2$s) v-a invitat." - "Cererea de alăturare a fost trimisă" "Acesta este un proces care se desfășoară o singură dată, vă mulțumim pentru așteptare." "Contul dumneavoastră se configurează" "Creați o conversație sau o cameră nouă" @@ -35,6 +34,7 @@ Deocamdată, puteți deselecta filtrele pentru a vedea celelalte chat-uri""Necitite" "Felicitari! Nu aveți mesaje necitite!" + "Cererea de alăturare a fost trimisă" "Toate conversatiile" "Marcați ca citită" "Marcați ca necitită" diff --git a/features/roomlist/impl/src/main/res/values-ru/translations.xml b/features/roomlist/impl/src/main/res/values-ru/translations.xml index c51fbc21d4..1ae52ac1a5 100644 --- a/features/roomlist/impl/src/main/res/values-ru/translations.xml +++ b/features/roomlist/impl/src/main/res/values-ru/translations.xml @@ -15,7 +15,6 @@ "Отклонить чат" "Нет приглашений" "%1$s (%2$s) пригласил вас" - "Запрос на присоединение отправлен" "Это одноразовый процесс, спасибо, что подождали." "Настройка учетной записи." "Создайте новую беседу или комнату" @@ -37,6 +36,7 @@ "Непрочитанные" "Поздравляем! У вас нет непрочитанных сообщений!" + "Запрос на присоединение отправлен" "Все чаты" "Пометить как прочитанное" "Отметить как непрочитанное" diff --git a/features/roomlist/impl/src/main/res/values-sk/translations.xml b/features/roomlist/impl/src/main/res/values-sk/translations.xml index fb9da3707d..9898a0cbad 100644 --- a/features/roomlist/impl/src/main/res/values-sk/translations.xml +++ b/features/roomlist/impl/src/main/res/values-sk/translations.xml @@ -15,7 +15,6 @@ "Odmietnuť konverzáciu" "Žiadne pozvánky" "%1$s (%2$s) vás pozval/a" - "Žiadosť o pripojenie bola odoslaná" "Ide o jednorazový proces, ďakujeme za trpezlivosť." "Nastavenie vášho účtu." "Vytvorte novú konverzáciu alebo miestnosť" @@ -37,6 +36,7 @@ Zatiaľ môžete zrušiť výber filtrov, aby ste videli ostatné konverzácie"< "Neprečítané" "Gratulujeme! Nemáte žiadne neprečítané správy!" + "Žiadosť o pripojenie bola odoslaná" "Všetky konverzácie" "Označiť ako prečítané" "Označiť ako neprečítané" diff --git a/features/roomlist/impl/src/main/res/values-sv/translations.xml b/features/roomlist/impl/src/main/res/values-sv/translations.xml index 9c69cb1937..9cc2fe2f99 100644 --- a/features/roomlist/impl/src/main/res/values-sv/translations.xml +++ b/features/roomlist/impl/src/main/res/values-sv/translations.xml @@ -15,7 +15,6 @@ "Avböj chatt" "Inga inbjudningar" "%1$s (%2$s) bjöd in dig" - "Begäran om att gå med skickad" "Detta är en engångsprocess, tack för att du väntar." "Konfigurerar ditt konto" "Skapa en ny konversation eller ett nytt rum" @@ -37,6 +36,7 @@ För tillfället kan du avmarkera filter för att se dina andra chattar""Olästa" "Grattis! Du har inga olästa meddelanden!" + "Begäran om att gå med skickad" "Alla chattar" "Markera som läst" "Markera som oläst" diff --git a/features/roomlist/impl/src/main/res/values-tr/translations.xml b/features/roomlist/impl/src/main/res/values-tr/translations.xml index 1502b4fcaf..6f42809ef3 100644 --- a/features/roomlist/impl/src/main/res/values-tr/translations.xml +++ b/features/roomlist/impl/src/main/res/values-tr/translations.xml @@ -15,7 +15,6 @@ "Sohbeti reddet" "Davet Yok" "%1$s (%2$s) sizi davet etti" - "Katılma isteği gönderildi" "Bu tek seferlik bir işlemdir, beklediğiniz için teşekkürler." "Hesabınızı ayarlanıyor." "Yeni bir sohbet veya oda oluşturun" @@ -37,6 +36,7 @@ "Okunmamış" "Tebrikler! Okunmamış mesajınız yok!" + "Katılma isteği gönderildi" "Sohbetler" "Okundu olarak işaretle" "Okunmamış olarak işaretle" diff --git a/features/roomlist/impl/src/main/res/values-uk/translations.xml b/features/roomlist/impl/src/main/res/values-uk/translations.xml index 26875754d3..16836724df 100644 --- a/features/roomlist/impl/src/main/res/values-uk/translations.xml +++ b/features/roomlist/impl/src/main/res/values-uk/translations.xml @@ -15,7 +15,6 @@ "Відхилити бесіду" "Немає запрошень" "%1$s (%2$s) запрошує вас" - "Запит на приєднання надіслано" "Це одноразовий процес, дякую за очікування." "Налаштування облікового запису." "Створити нову розмову або кімнату" @@ -37,6 +36,7 @@ "Непрочитані" "Вітаємо! У вас немає непрочитаних повідомлень!" + "Запит на приєднання надіслано" "Бесіди" "Позначити прочитаним" "Позначити непрочитаним" diff --git a/features/roomlist/impl/src/main/res/values-zh-rTW/translations.xml b/features/roomlist/impl/src/main/res/values-zh-rTW/translations.xml index 4a13d33c6c..1bc2ae181c 100644 --- a/features/roomlist/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/roomlist/impl/src/main/res/values-zh-rTW/translations.xml @@ -15,7 +15,6 @@ "拒絕聊天" "沒有邀請" "%1$s(%2$s)邀請您" - "已傳送加入請求" "這是一次性的程序,感謝您耐心等候。" "正在設定您的帳號。" "建立新的對話或聊天室" @@ -37,6 +36,7 @@ "未讀" "恭喜! 您沒有任何未讀的訊息!" + "已傳送加入請求" "所有聊天室" "標為已讀" "標為未讀" diff --git a/features/roomlist/impl/src/main/res/values-zh/translations.xml b/features/roomlist/impl/src/main/res/values-zh/translations.xml index 7c5d778ddf..e7e97040dd 100644 --- a/features/roomlist/impl/src/main/res/values-zh/translations.xml +++ b/features/roomlist/impl/src/main/res/values-zh/translations.xml @@ -15,7 +15,6 @@ "拒绝聊天" "没有邀请" "%1$s (%2$s)邀请了你" - "加入请求已发送" "这是一个一次性的过程,感谢您的等待。" "设置您的账户。" "创建新的对话或聊天室" @@ -37,6 +36,7 @@ "未读" "恭喜! 没有任何未读消息!" + "加入请求已发送" "全部聊天" "标记为已读" "标记为未读" diff --git a/features/roomlist/impl/src/main/res/values/localazy.xml b/features/roomlist/impl/src/main/res/values/localazy.xml index d72af71f84..90432433c2 100644 --- a/features/roomlist/impl/src/main/res/values/localazy.xml +++ b/features/roomlist/impl/src/main/res/values/localazy.xml @@ -1,5 +1,8 @@ + "Disable battery optimization for this app, to make sure all notifications are received." + "Disable optimization" + "Notifications not arriving?" "Recover your cryptographic identity and message history with a recovery key if you have lost all your existing devices." "Set up recovery" "Set up recovery to protect your account" @@ -15,7 +18,6 @@ "Decline chat" "No Invites" "%1$s (%2$s) invited you" - "Request to join sent" "This is a one time process, thanks for waiting." "Setting up your account." "Create a new conversation or room" @@ -37,9 +39,11 @@ For now, you can deselect filters in order to see your other chats" "Unreads" "Congrats! You don’t have any unread messages!" + "Request to join sent" "Chats" "Mark as read" "Mark as unread" + "This room has been upgraded" "Looks like you’re using a new device. Verify with another device to access your encrypted messages." "Verify it’s you" diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt index 446a864f0b..3184a44a1c 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTest.kt @@ -75,6 +75,7 @@ import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.preferences.api.store.SessionPreferencesStore import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore +import io.element.android.libraries.push.api.battery.aBatteryOptimizationState import io.element.android.libraries.push.api.notifications.NotificationCleaner import io.element.android.libraries.push.test.notifications.FakeNotificationCleaner import io.element.android.services.analytics.api.AnalyticsService @@ -712,6 +713,7 @@ class RoomListPresenterTest { analyticsService = analyticsService, acceptDeclineInvitePresenter = acceptDeclineInvitePresenter, fullScreenIntentPermissionsPresenter = { aFullScreenIntentPermissionsState() }, + batteryOptimizationPresenter = { aBatteryOptimizationState() }, notificationCleaner = notificationCleaner, logoutPresenter = { aDirectLogoutState() }, appPreferencesStore = appPreferencesStore, diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListViewTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListViewTest.kt index 299ef07578..60da841e96 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListViewTest.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListViewTest.kt @@ -5,8 +5,6 @@ * Please see LICENSE files in the repository root for full details. */ -@file:OptIn(ExperimentalCoroutinesApi::class) - package io.element.android.features.roomlist.impl import androidx.activity.ComponentActivity @@ -30,7 +28,6 @@ import io.element.android.tests.testutils.clickOn import io.element.android.tests.testutils.ensureCalledOnce import io.element.android.tests.testutils.ensureCalledOnceWithParam import io.element.android.tests.testutils.setSafeContent -import kotlinx.coroutines.ExperimentalCoroutinesApi import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListBaseRoomSummaryTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListBaseRoomSummaryTest.kt index 4d5ef13d0b..e6bfb1a9cb 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListBaseRoomSummaryTest.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListBaseRoomSummaryTest.kt @@ -84,6 +84,7 @@ internal fun createRoomListRoomSummary( displayType: RoomSummaryDisplayType = RoomSummaryDisplayType.ROOM, heroes: List = emptyList(), timestamp: String? = null, + isTombstoned: Boolean = false, ) = RoomListRoomSummary( id = A_ROOM_ID.value, roomId = A_ROOM_ID, @@ -104,4 +105,5 @@ internal fun createRoomListRoomSummary( inviteSender = null, isDm = false, heroes = heroes.toPersistentList(), + isTombstoned = isTombstoned, ) diff --git a/features/roommembermoderation/impl/src/main/res/values-fr/translations.xml b/features/roommembermoderation/impl/src/main/res/values-fr/translations.xml index 9aabe07e11..5a09dddf4e 100644 --- a/features/roommembermoderation/impl/src/main/res/values-fr/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-fr/translations.xml @@ -1,6 +1,6 @@ - "Retirer et bannir ce membre" + "Bannir du salon" "Bannir" "Il ne pourra pas rejoindre le salon à nouveau, même si il est invité." "Êtes-vous certain de vouloir bannir ce membre ?" diff --git a/features/roommembermoderation/impl/src/main/res/values-ru/translations.xml b/features/roommembermoderation/impl/src/main/res/values-ru/translations.xml index ca4610dd31..6d89f42fe1 100644 --- a/features/roommembermoderation/impl/src/main/res/values-ru/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-ru/translations.xml @@ -6,9 +6,15 @@ "Вы уверены, что хотите заблокировать этого участника?" "Блокировка %1$s" "Удалить" + "Они снова смогут присоединиться в эту комнату если их пригласят." "Вы действительно хотите удалить этого участника?" "Посмотреть профиль" "Удалить участника из комнаты" "Удалить участника и запретить присоединяться в будущем?" "Удаление %1$s…" + "Разблокировать в комнате" + "Разблокировать" + "Они смогут снова войти в комнату, если их пригласят." + "Вы действительно хотите разблокировать этого участника?" + "Разблокировка %1$s" diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt index ed5a381754..6a46431c35 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt @@ -7,7 +7,6 @@ package io.element.android.features.securebackup.impl.enter -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.WindowInsets @@ -71,7 +70,7 @@ fun SecureBackupEnterRecoveryKeyView( } } -@OptIn(ExperimentalFoundationApi::class, ExperimentalLayoutApi::class) +@OptIn(ExperimentalLayoutApi::class) @Composable private fun Content( state: SecureBackupEnterRecoveryKeyState, diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/views/RecoveryKeyView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/views/RecoveryKeyView.kt index 9c24d463ba..fc05b6d316 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/views/RecoveryKeyView.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/views/RecoveryKeyView.kt @@ -22,7 +22,6 @@ import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.autofill.ContentType import androidx.compose.ui.draw.alpha @@ -169,7 +168,6 @@ private fun RecoveryKeyWithCopy( } } -@OptIn(ExperimentalComposeUiApi::class) @Composable private fun RecoveryKeyFormContent( state: RecoveryKeyViewState, diff --git a/features/securebackup/impl/src/main/res/values-es/translations.xml b/features/securebackup/impl/src/main/res/values-es/translations.xml index 4d4413690b..da6f4f2391 100644 --- a/features/securebackup/impl/src/main/res/values-es/translations.xml +++ b/features/securebackup/impl/src/main/res/values-es/translations.xml @@ -9,7 +9,7 @@ "Permitir almacenamiento de claves" "Cambiar la clave de recuperación" "Recupera tu identidad criptográfica y tu historial de mensajes con una clave de recuperación si has perdido todos tus dispositivos actuales." - "Introduzca la clave de recuperación" + "Introduce la clave de recuperación" "Tu almacén de claves no está sincronizado actualmente." "Configurar la recuperación" "Accede a tus mensajes cifrados si pierdes todos tus dispositivos o cierras sesión de %1$s en cualquier lugar." diff --git a/features/userprofile/shared/src/main/res/values-in/translations.xml b/features/userprofile/shared/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..e368bc9692 --- /dev/null +++ b/features/userprofile/shared/src/main/res/values-in/translations.xml @@ -0,0 +1,19 @@ + + + "Blokir" + "Pengguna yang diblokir tidak akan dapat mengirim Anda pesan dan semua pesan mereka akan disembunyikan. Anda dapat membuka blokirnya kapan saja." + "Blokir pengguna" + "Buka blokir" + "Anda akan dapat melihat semua pesan dari mereka lagi." + "Buka blokir pengguna" + "Blokir" + "Pengguna yang diblokir tidak akan dapat mengirim Anda pesan dan semua pesan mereka akan disembunyikan. Anda dapat membuka blokirnya kapan saja." + "Blokir pengguna" + "Profil" + "Buka blokir" + "Anda akan dapat melihat semua pesan dari mereka lagi." + "Buka blokir pengguna" + "Gunakan aplikasi web untuk memverifikasi pengguna ini." + "Verifikasi %1$s" + "Terjadi kesalahan saat mencoba memulai obrolan" + diff --git a/features/verifysession/impl/src/main/res/values-es/translations.xml b/features/verifysession/impl/src/main/res/values-es/translations.xml index e22eb179b0..0f92e96395 100644 --- a/features/verifysession/impl/src/main/res/values-es/translations.xml +++ b/features/verifysession/impl/src/main/res/values-es/translations.xml @@ -18,7 +18,7 @@ "Comparar números" "Tu nueva sesión ya está verificada. Tienes acceso a tus mensajes cifrados y otros usuarios lo considerarán de confianza." "Ahora puedes confiar en la identidad de este usuario al enviar o recibir mensajes." - "Introduzca la clave de recuperación" + "Introduce la clave de recuperación" "O bien se agotó el tiempo de solicitud, se rechazó la solicitud o hubo una discrepancia en la verificación." "Demuestra que eres tú para acceder a tu historial de mensajes cifrados." "Abrir una sesión existente" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d4db6807c4..296f70d939 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ android_gradle_plugin = "8.10.1" kotlin = "2.1.21" kotlinpoet = "2.2.0" -ksp = "2.1.21-2.0.1" +ksp = "2.1.21-2.0.2" firebaseAppDistribution = "5.1.1" # AndroidX @@ -39,7 +39,7 @@ serialization_json = "1.8.1" #other detekt = "1.23.8" coil = "3.2.0" -showkase = "1.0.3" +showkase = "1.0.4" appyx = "1.7.1" sqldelight = "2.1.0" wysiwyg = "2.38.3" @@ -147,7 +147,7 @@ test_junit = "junit:junit:4.13.2" test_runner = "androidx.test:runner:1.6.2" test_mockk = "io.mockk:mockk:1.14.2" test_konsist = "com.lemonappdev:konsist:0.17.3" -test_turbine = "app.cash.turbine:turbine:1.2.0" +test_turbine = "app.cash.turbine:turbine:1.2.1" test_truth = "com.google.truth:truth:1.4.4" test_parameter_injector = "com.google.testparameterinjector:test-parameter-injector:1.18" test_robolectric = "org.robolectric:robolectric:4.14.1" @@ -172,7 +172,7 @@ jsoup = "org.jsoup:jsoup:1.20.1" appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = "app.cash.molecule:molecule-runtime:2.1.0" timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.6.10" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.6.18" matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } @@ -186,15 +186,15 @@ vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0" telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" } telephoto_flick = { module = "me.saket.telephoto:flick-android", version.ref = "telephoto" } statemachine = "com.freeletics.flowredux:compose:1.2.2" -maplibre = "org.maplibre.gl:android-sdk:11.10.1" +maplibre = "org.maplibre.gl:android-sdk:11.10.3" 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" # Analytics -posthog = "com.posthog:posthog-android:3.17.0" -sentry = "io.sentry:sentry-android:8.13.2" +posthog = "com.posthog:posthog-android:3.19.0" +sentry = "io.sentry:sentry-android:8.13.3" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.28.0" @@ -237,7 +237,7 @@ anvil = { id = "dev.zacsweers.anvil", version.ref = "anvil" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } ktlint = "org.jlleitschuh.gradle.ktlint:12.3.0" dependencygraph = "com.savvasdalkitsis.module-dependency-graph:0.12" -dependencycheck = "org.owasp.dependencycheck:12.1.2" +dependencycheck = "org.owasp.dependencycheck:12.1.3" dependencyanalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependencyAnalysis" } paparazzi = "app.cash.paparazzi:1.3.5" sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } diff --git a/libraries/dateformatter/impl/src/main/res/values-in/translations.xml b/libraries/dateformatter/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..4771c4e658 --- /dev/null +++ b/libraries/dateformatter/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,5 @@ + + + "%1$s pada %2$s" + "Bulan ini" + diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/ComposerAlertMolecule.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/ComposerAlertMolecule.kt index 33706239dc..0108779913 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/ComposerAlertMolecule.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/ComposerAlertMolecule.kt @@ -39,7 +39,7 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable fun ComposerAlertMolecule( - avatar: AvatarData, + avatar: AvatarData?, content: AnnotatedString, onSubmitClick: () -> Unit, modifier: Modifier = Modifier, @@ -71,9 +71,9 @@ fun ComposerAlertMolecule( Row( horizontalArrangement = Arrangement.spacedBy(16.dp) ) { - Avatar( - avatarData = avatar, - ) + if (avatar != null) { + Avatar(avatarData = avatar) + } Text( text = content, modifier = Modifier.weight(1f), diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt index a2b0049ad6..764a208a82 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt @@ -370,7 +370,7 @@ fun Modifier.avatarBloom( val initialsBitmap = initialsBitmap( width = BloomDefaults.ENCODE_SIZE_PX.toDp(), height = BloomDefaults.ENCODE_SIZE_PX.toDp(), - text = avatarData.initial, + text = avatarData.initialLetter, textColor = avatarColors.foreground, backgroundColor = avatarColors.background, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index 94ffd9c0fb..106e52d350 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -7,9 +7,7 @@ package io.element.android.libraries.designsystem.components.avatar -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.size import androidx.compose.foundation.shape.CircleShape @@ -21,21 +19,16 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.semantics.clearAndSetSemantics -import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import coil3.compose.AsyncImagePainter import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImageContent -import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup -import io.element.android.libraries.designsystem.text.toSp import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.utils.CommonDrawables import timber.log.Timber @@ -50,21 +43,18 @@ fun Avatar( // If true, will show initials even if avatarData.url is not null hideImage: Boolean = false, ) { - val commonModifier = modifier - .size(forcedAvatarSize ?: avatarData.size.dp) - .clip(CircleShape) if (avatarData.url.isNullOrBlank() || hideImage) { - InitialsAvatar( + InitialLetterAvatar( avatarData = avatarData, forcedAvatarSize = forcedAvatarSize, - modifier = commonModifier, + modifier = modifier, contentDescription = contentDescription, ) } else { ImageAvatar( avatarData = avatarData, forcedAvatarSize = forcedAvatarSize, - modifier = commonModifier, + modifier = modifier, contentDescription = contentDescription, ) } @@ -77,11 +67,14 @@ private fun ImageAvatar( modifier: Modifier = Modifier, contentDescription: String? = null, ) { + val size = forcedAvatarSize ?: avatarData.size.dp SubcomposeAsyncImage( model = avatarData, contentDescription = contentDescription, contentScale = ContentScale.Crop, modifier = modifier + .size(size) + .clip(CircleShape) ) { val collectedState by painter.state.collectAsState() when (val state = collectedState) { @@ -90,13 +83,13 @@ private fun ImageAvatar( SideEffect { Timber.e(state.result.throwable, "Error loading avatar $state\n${state.result}") } - InitialsAvatar( + InitialLetterAvatar( avatarData = avatarData, forcedAvatarSize = forcedAvatarSize, contentDescription = contentDescription, ) } - else -> InitialsAvatar( + else -> InitialLetterAvatar( avatarData = avatarData, forcedAvatarSize = forcedAvatarSize, contentDescription = contentDescription, @@ -106,33 +99,20 @@ private fun ImageAvatar( } @Composable -private fun InitialsAvatar( +private fun InitialLetterAvatar( avatarData: AvatarData, forcedAvatarSize: Dp?, contentDescription: String?, modifier: Modifier = Modifier, ) { val avatarColors = AvatarColorsProvider.provide(avatarData.id) - Box( - modifier.background(color = avatarColors.background) - ) { - val fontSize = (forcedAvatarSize ?: avatarData.size.dp).toSp() / 2 - val originalFont = ElementTheme.typography.fontHeadingMdBold - val ratio = fontSize.value / originalFont.fontSize.value - val lineHeight = originalFont.lineHeight * ratio - Text( - modifier = Modifier - .clearAndSetSemantics { - contentDescription?.let { - this.contentDescription = it - } - } - .align(Alignment.Center), - text = avatarData.initial, - style = originalFont.copy(fontSize = fontSize, lineHeight = lineHeight, letterSpacing = 0.sp), - color = avatarColors.foreground, - ) - } + TextAvatar( + text = avatarData.initialLetter, + size = forcedAvatarSize ?: avatarData.size.dp, + colors = avatarColors, + contentDescription = contentDescription, + modifier = modifier + ) } @Preview(group = PreviewGroup.Avatars) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt new file mode 100644 index 0000000000..9c7efa864d --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarCluster.kt @@ -0,0 +1,127 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.designsystem.components.avatar + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.preview.ElementThemedPreview +import io.element.android.libraries.designsystem.preview.PreviewGroup +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toPersistentList +import java.util.Collections +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin + +private const val MAX_AVATAR_COUNT = 4 + +@Composable +fun AvatarCluster( + avatars: ImmutableList, + modifier: Modifier = Modifier, + hideAvatarImages: Boolean = false, + contentDescription: String? = null, +) { + val limitedAvatars = avatars.take(MAX_AVATAR_COUNT) + val numberOfAvatars = limitedAvatars.size + if (numberOfAvatars == 4) { + // Swap 2 and 3 so that the 4th avatar is at the bottom right + Collections.swap(limitedAvatars, 2, 3) + } + when (numberOfAvatars) { + 0 -> { + error("Unsupported number of avatars: 0") + } + 1 -> { + Avatar( + avatarData = limitedAvatars[0], + modifier = modifier, + contentDescription = contentDescription, + hideImage = hideAvatarImages + ) + } + else -> { + val size = limitedAvatars.first().size + val angle = 2 * Math.PI / numberOfAvatars + val offsetRadius = when (numberOfAvatars) { + 2 -> size.dp.value / 4.2 + 3 -> size.dp.value / 4.0 + 4 -> size.dp.value / 3.1 + else -> error("Unsupported number of heroes: $numberOfAvatars") + } + val heroAvatarSize = when (numberOfAvatars) { + 2 -> size.dp / 2.2f + 3 -> size.dp / 2.4f + 4 -> size.dp / 2.2f + else -> error("Unsupported number of heroes: $numberOfAvatars") + } + val angleOffset = when (numberOfAvatars) { + 2 -> PI + 3 -> 7 * PI / 6 + 4 -> 13 * PI / 4 + else -> error("Unsupported number of heroes: $numberOfAvatars") + } + Box( + modifier = modifier + .size(size.dp) + .semantics { + this.contentDescription = contentDescription.orEmpty() + }, + contentAlignment = Alignment.Center, + ) { + limitedAvatars.forEachIndexed { index, heroAvatar -> + val xOffset = (offsetRadius * cos(angle * index.toDouble() + angleOffset)).dp + val yOffset = (offsetRadius * sin(angle * index.toDouble() + angleOffset)).dp + Box( + modifier = Modifier + .size(heroAvatarSize) + .offset( + x = xOffset, + y = yOffset, + ) + ) { + Avatar( + avatarData = heroAvatar, + forcedAvatarSize = heroAvatarSize, + hideImage = hideAvatarImages, + ) + } + } + } + } + } +} + +@Preview(group = PreviewGroup.Avatars) +@Composable +internal fun AvatarClusterPreview() = ElementThemedPreview { + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + for (ngOfAvatars in 1..5) { + AvatarCluster( + avatars = List(ngOfAvatars) { anAvatarData(it) }.toPersistentList(), + ) + } + } +} + +private fun anAvatarData(i: Int) = anAvatarData( + id = ('A' + i).toString(), + name = ('A' + i).toString() +) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarData.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarData.kt index 12b6fe05a3..2e711ee6eb 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarData.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarData.kt @@ -18,7 +18,7 @@ data class AvatarData( val url: String? = null, val size: AvatarSize, ) { - val initial by lazy { + val initialLetter by lazy { // For roomIds, use "#" as initial (name?.takeIf { it.isNotBlank() } ?: id.takeIf { !it.startsWith("!") } ?: "#") .let { dn -> diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/CompositeAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/CompositeAvatar.kt deleted file mode 100644 index c696050f23..0000000000 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/CompositeAvatar.kt +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.libraries.designsystem.components.avatar - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.size -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import io.element.android.libraries.designsystem.preview.ElementThemedPreview -import io.element.android.libraries.designsystem.preview.PreviewGroup -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.toPersistentList -import java.util.Collections -import kotlin.math.PI -import kotlin.math.cos -import kotlin.math.sin - -@Composable -fun CompositeAvatar( - avatarData: AvatarData, - heroes: ImmutableList, - modifier: Modifier = Modifier, - hideAvatarImages: Boolean = false, - contentDescription: String? = null, -) { - if (avatarData.url != null || heroes.isEmpty()) { - Avatar( - avatarData = avatarData, - modifier = modifier, - contentDescription = contentDescription, - hideImage = hideAvatarImages - ) - } else { - val limitedHeroes = heroes.take(4) - val numberOfHeroes = limitedHeroes.size - if (numberOfHeroes == 4) { - // Swap 2 and 3 so that the 4th hero is at the bottom right - Collections.swap(limitedHeroes, 2, 3) - } - when (numberOfHeroes) { - 0 -> { - error("Unsupported number of heroes: 0") - } - 1 -> { - Avatar( - avatarData = heroes[0], - modifier = modifier, - contentDescription = contentDescription, - hideImage = hideAvatarImages - ) - } - else -> { - val angle = 2 * Math.PI / numberOfHeroes - val offsetRadius = when (numberOfHeroes) { - 2 -> avatarData.size.dp.value / 4.2 - 3 -> avatarData.size.dp.value / 4.0 - 4 -> avatarData.size.dp.value / 3.1 - else -> error("Unsupported number of heroes: $numberOfHeroes") - } - val heroAvatarSize = when (numberOfHeroes) { - 2 -> avatarData.size.dp / 2.2f - 3 -> avatarData.size.dp / 2.4f - 4 -> avatarData.size.dp / 2.2f - else -> error("Unsupported number of heroes: $numberOfHeroes") - } - val angleOffset = when (numberOfHeroes) { - 2 -> PI - 3 -> 7 * PI / 6 - 4 -> 13 * PI / 4 - else -> error("Unsupported number of heroes: $numberOfHeroes") - } - Box( - modifier = modifier - .size(avatarData.size.dp) - .semantics { - this.contentDescription = contentDescription.orEmpty() - }, - contentAlignment = Alignment.Center, - ) { - limitedHeroes.forEachIndexed { index, heroAvatar -> - val xOffset = (offsetRadius * cos(angle * index.toDouble() + angleOffset)).dp - val yOffset = (offsetRadius * sin(angle * index.toDouble() + angleOffset)).dp - Box( - modifier = Modifier - .size(heroAvatarSize) - .offset( - x = xOffset, - y = yOffset, - ) - ) { - Avatar( - avatarData = heroAvatar, - forcedAvatarSize = heroAvatarSize, - hideImage = hideAvatarImages, - ) - } - } - } - } - } - } -} - -@Preview(group = PreviewGroup.Avatars) -@Composable -internal fun CompositeAvatarPreview() = ElementThemedPreview { - val mainAvatar = anAvatarData( - id = "Zac", - name = "Zac", - size = AvatarSize.RoomListItem, - ) - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - repeat(6) { nbOfHeroes -> - CompositeAvatar( - avatarData = mainAvatar, - heroes = List(nbOfHeroes) { aHeroAvatarData(it) }.toPersistentList(), - ) - } - } -} - -private fun aHeroAvatarData(i: Int) = anAvatarData( - id = ('A' + i).toString(), - name = ('A' + i).toString() -) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt new file mode 100644 index 0000000000..44d1c9b491 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/RoomAvatar.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.designsystem.components.avatar + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import kotlinx.collections.immutable.ImmutableList + +@Composable +fun RoomAvatar( + avatarData: AvatarData, + heroes: ImmutableList, + modifier: Modifier = Modifier, + isTombstoned: Boolean = false, + hideAvatarImage: Boolean = false, + contentDescription: String? = null, +) { + when { + isTombstoned -> { + TombstonedRoomAvatar( + size = avatarData.size, + modifier = modifier, + contentDescription = contentDescription + ) + } + avatarData.url != null || heroes.isEmpty() -> { + Avatar( + avatarData = avatarData, + modifier = modifier, + contentDescription = contentDescription, + hideImage = hideAvatarImage + ) + } + else -> { + AvatarCluster( + avatars = heroes, + modifier = modifier, + hideAvatarImages = hideAvatarImage, + contentDescription = contentDescription + ) + } + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt new file mode 100644 index 0000000000..65ebba3366 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TextAvatar.kt @@ -0,0 +1,76 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.designsystem.components.avatar + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +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.draw.clip +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.element.android.compound.theme.AvatarColors +import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewGroup +import io.element.android.libraries.designsystem.text.toSp +import io.element.android.libraries.designsystem.theme.components.Text + +@Composable +internal fun TextAvatar( + text: String, + size: Dp, + colors: AvatarColors, + contentDescription: String?, + modifier: Modifier = Modifier, +) { + Box( + modifier + .size(size) + .clip(CircleShape) + .background(color = colors.background) + ) { + val fontSize = size.toSp() / 2 + val originalFont = ElementTheme.typography.fontHeadingMdBold + val ratio = fontSize.value / originalFont.fontSize.value + val lineHeight = originalFont.lineHeight * ratio + Text( + modifier = Modifier + .clearAndSetSemantics { + contentDescription?.let { + this.contentDescription = it + } + } + .align(Alignment.Center), + text = text, + style = originalFont.copy(fontSize = fontSize, lineHeight = lineHeight, letterSpacing = 0.sp), + color = colors.foreground, + ) + } +} + +@Preview(group = PreviewGroup.Avatars) +@Composable +internal fun TextAvatarPreview() = ElementPreview { + TextAvatar( + text = "AB", + size = 40.dp, + colors = AvatarColors( + background = ElementTheme.colors.bgSubtlePrimary, + foreground = ElementTheme.colors.iconPrimary, + ), + contentDescription = null, + ) + } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt new file mode 100644 index 0000000000..fe09be909d --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/TombstonedRoomAvatar.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.designsystem.components.avatar + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import io.element.android.compound.theme.AvatarColors +import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewGroup + +@Composable +fun TombstonedRoomAvatar( + size: AvatarSize, + modifier: Modifier = Modifier, + contentDescription: String? = null, +) { + TextAvatar( + text = "!", + size = size.dp, + colors = AvatarColors( + background = ElementTheme.colors.bgSubtlePrimary, + foreground = ElementTheme.colors.iconTertiary + ), + modifier = modifier, + contentDescription = contentDescription + ) +} + +@Preview(group = PreviewGroup.Avatars) +@Composable +internal fun TombstonedRoomAvatarPreview() = ElementPreview { + TombstonedRoomAvatar( + size = AvatarSize.RoomListItem, + contentDescription = null, + ) +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/media/WaveformPlaybackView.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/media/WaveformPlaybackView.kt index 8986db82ee..767b56410f 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/media/WaveformPlaybackView.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/media/WaveformPlaybackView.kt @@ -19,7 +19,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.CornerRadius import androidx.compose.ui.geometry.Offset @@ -60,7 +59,6 @@ private const val DEFAULT_GRAPHICS_LAYER_ALPHA: Float = 0.99F * @param lineWidth The width of the waveform lines. * @param linePadding The padding between waveform lines. */ -@OptIn(ExperimentalComposeUiApi::class) @Composable fun WaveformPlaybackView( playbackProgress: Float, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt index 258d24cb99..856160d7bf 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.tooling.preview.Preview @@ -27,6 +28,7 @@ import io.element.android.libraries.designsystem.theme.components.Text * will be smaller. */ @Composable +@ReadOnlyComposable fun Dp.applyScaleDown(): Dp = with(LocalDensity.current) { return this@applyScaleDown * fontScale.coerceAtMost(1f) } @@ -37,6 +39,7 @@ fun Dp.applyScaleDown(): Dp = with(LocalDensity.current) { * will be bigger. */ @Composable +@ReadOnlyComposable fun Dp.applyScaleUp(): Dp = with(LocalDensity.current) { return this@applyScaleUp * fontScale.coerceAtLeast(1f) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt index c358517946..eaf6712830 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt @@ -8,6 +8,7 @@ package io.element.android.libraries.designsystem.text import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit @@ -17,6 +18,7 @@ import androidx.compose.ui.unit.TextUnit * Can be used for instance to use Dp unit for text. */ @Composable +@ReadOnlyComposable fun Dp.toSp(): TextUnit = with(LocalDensity.current) { toSp() } /** @@ -24,22 +26,26 @@ fun Dp.toSp(): TextUnit = with(LocalDensity.current) { toSp() } * Can be used for instance to use Sp unit for size. */ @Composable +@ReadOnlyComposable fun TextUnit.toDp(): Dp = with(LocalDensity.current) { toDp() } /** * Convert Px value to Dp, regarding current density. */ @Composable +@ReadOnlyComposable fun Int.toDp(): Dp = with(LocalDensity.current) { toDp() } /** * Convert Dp value to pixels, regarding current density. */ @Composable +@ReadOnlyComposable fun Dp.toPx(): Float = with(LocalDensity.current) { toPx() } /** * Convert Dp value to pixels, regarding current density. */ @Composable +@ReadOnlyComposable fun Dp.roundToPx(): Int = with(LocalDensity.current) { roundToPx() } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/WindowInsetsExtension.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/WindowInsetsExtension.kt index f70cb5424e..a3a471875b 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/WindowInsetsExtension.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/WindowInsetsExtension.kt @@ -9,10 +9,12 @@ package io.element.android.libraries.designsystem.utils import androidx.compose.foundation.layout.WindowInsets import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection @Composable +@ReadOnlyComposable fun WindowInsets.copy( top: Int? = null, right: Int? = null, diff --git a/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataTest.kt b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataTest.kt index 6fe50e995b..01395eb9f1 100644 --- a/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataTest.kt +++ b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataTest.kt @@ -14,30 +14,30 @@ class AvatarDataTest { @Test fun `initial with text should get the first char, uppercased`() { val data = AvatarData("id", "test", null, AvatarSize.InviteSender) - assertThat(data.initial).isEqualTo("T") + assertThat(data.initialLetter).isEqualTo("T") } @Test fun `initial with leading whitespace should get the first non-whitespace char, uppercased`() { val data = AvatarData("id", " test", null, AvatarSize.InviteSender) - assertThat(data.initial).isEqualTo("T") + assertThat(data.initialLetter).isEqualTo("T") } @Test fun `initial with long emoji should get the full emoji`() { val data = AvatarData("id", "\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08 Test", null, AvatarSize.InviteSender) - assertThat(data.initial).isEqualTo("\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08") + assertThat(data.initialLetter).isEqualTo("\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08") } @Test fun `initial with short emoji should get the emoji`() { val data = AvatarData("id", "✂ Test", null, AvatarSize.InviteSender) - assertThat(data.initial).isEqualTo("✂") + assertThat(data.initialLetter).isEqualTo("✂") } @Test fun `initial with a single letter should take that letter`() { val data = AvatarData("id", "T", null, AvatarSize.InviteSender) - assertThat(data.initial).isEqualTo("T") + assertThat(data.initialLetter).isEqualTo("T") } } diff --git a/libraries/eventformatter/impl/src/main/res/values-es/translations.xml b/libraries/eventformatter/impl/src/main/res/values-es/translations.xml index 65f16e35fe..186aad5455 100644 --- a/libraries/eventformatter/impl/src/main/res/values-es/translations.xml +++ b/libraries/eventformatter/impl/src/main/res/values-es/translations.xml @@ -19,6 +19,8 @@ "Eliminaste el avatar de la sala" "%1$s expulsó permanentemente a %2$s" "Expulsaste permanentemente a %1$s" + "Vetaste a %1$s: %2$s" + "%1$s vetó a %2$s: %3$s" "%1$s creó la sala" "Tú creaste la sala" "%1$s invitó a %2$s" @@ -55,6 +57,8 @@ "Rechazaste la invitación" "%1$s echó a %2$s" "Echaste a %1$s" + "Echaste a %1$s: %2$s" + "%1$s echó a %2$s: %3$s" "%1$s envió una invitación a %2$s para unirse a la sala" "Enviaste una invitación a %1$s para unirse a la sala" "%1$s revocó la invitación a %2$s para unirse a la sala" diff --git a/libraries/eventformatter/impl/src/main/res/values-ru/translations.xml b/libraries/eventformatter/impl/src/main/res/values-ru/translations.xml index b2a86a6962..d0f4a39773 100644 --- a/libraries/eventformatter/impl/src/main/res/values-ru/translations.xml +++ b/libraries/eventformatter/impl/src/main/res/values-ru/translations.xml @@ -19,6 +19,8 @@ "Вы удалили изображение комнаты" "%1$s заблокировал %2$s" "Вы заблокировали %1$s" + "Вы заблокировали %1$s: %2$s" + "%1$s заблокирован %2$s: %3$s" "%1$s создал комнату" "Вы создали комнату" "%1$s пригласил %2$s" @@ -55,6 +57,8 @@ "Вы отклонили приглашение" "%1$s удалил %2$s" "Вы удалили %1$s" + "Вы удалили %1$s: %2$s" + "%1$s удален %2$s: %3$s" "%1$s отправила приглашение %2$s присоединиться к комнате" "Вы отправили приглашение присоединиться к комнате %1$s" "%1$s отозвал приглашение %2$s присоединиться к комнате" diff --git a/libraries/eventformatter/impl/src/main/res/values-uz/translations.xml b/libraries/eventformatter/impl/src/main/res/values-uz/translations.xml index 91ac192205..aab758a1a1 100644 --- a/libraries/eventformatter/impl/src/main/res/values-uz/translations.xml +++ b/libraries/eventformatter/impl/src/main/res/values-uz/translations.xml @@ -24,7 +24,7 @@ "%1$ssizni taklif qildi" "%1$sxonaga qo\'shildi" "Siz xonaga qo\'shildingiz" - "%1$s qo\'shilishni so\'radi" + "%1$s qoʻshilishni soʻradi" "%1$s %2$sga qo\'shilishga ruxsat berdi" "Siz %1$sga qo\'shilishaga ruxsat berdingiz" "Siz qoʻshilishni soʻragansiz" 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 bcffe4daf0..00ab0fb57c 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 @@ -112,6 +112,17 @@ enum class FeatureFlags( defaultValue = { false }, isFinished = false, ), + EnableKeyShareOnInvite( + key = "feature.enableKeyShareOnInvite", + title = "Share encrypted history with new members", + description = "When inviting a user to an encrypted room that has history visibility set to \"shared\"," + + " share encrypted history with that user, and accept encrypted history when you are invited to such a room." + + "\nRequires an app restart to take effect." + + "\n\nWARNING: this feature is EXPERIMENTAL and not all security precautions are implemented." + + " Do not enable on production accounts.", + defaultValue = { false }, + isFinished = false, + ), Knock( key = "feature.knock", title = "Ask to join", diff --git a/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsEvents.kt b/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsEvents.kt new file mode 100644 index 0000000000..e0b8433749 --- /dev/null +++ b/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsEvents.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.fullscreenintent.api + +sealed interface FullScreenIntentPermissionsEvents { + data object Dismiss : FullScreenIntentPermissionsEvents + data object OpenSettings : FullScreenIntentPermissionsEvents +} diff --git a/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsState.kt b/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsState.kt index 3d77ebb4b5..5b3f84f977 100644 --- a/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsState.kt +++ b/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsState.kt @@ -10,6 +10,5 @@ package io.element.android.libraries.fullscreenintent.api data class FullScreenIntentPermissionsState( val permissionGranted: Boolean, val shouldDisplayBanner: Boolean, - val dismissFullScreenIntentBanner: () -> Unit, - val openFullScreenIntentSettings: () -> Unit, + val eventSink: (FullScreenIntentPermissionsEvents) -> Unit, ) diff --git a/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsStateProvider.kt b/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsStateProvider.kt index 7dbe340c39..25ab2ab522 100644 --- a/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsStateProvider.kt +++ b/libraries/fullscreenintent/api/src/main/kotlin/io/element/android/libraries/fullscreenintent/api/FullScreenIntentPermissionsStateProvider.kt @@ -10,11 +10,9 @@ package io.element.android.libraries.fullscreenintent.api fun aFullScreenIntentPermissionsState( permissionGranted: Boolean = true, shouldDisplay: Boolean = false, - openFullScreenIntentSettings: () -> Unit = {}, - dismissFullScreenIntentBanner: () -> Unit = {}, + eventSink: (FullScreenIntentPermissionsEvents) -> Unit = {}, ) = FullScreenIntentPermissionsState( permissionGranted = permissionGranted, shouldDisplayBanner = shouldDisplay, - openFullScreenIntentSettings = openFullScreenIntentSettings, - dismissFullScreenIntentBanner = dismissFullScreenIntentBanner, + eventSink = eventSink, ) 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 3e427b6fa6..14cc438f41 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 @@ -23,6 +23,7 @@ import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.SingleIn +import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsEvents import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFactory import io.element.android.services.toolbox.api.intent.ExternalIntentLauncher @@ -60,15 +61,20 @@ class FullScreenIntentPermissionsPresenter @Inject constructor( val coroutineScope = rememberCoroutineScope() val isGranted = notificationManagerCompat.canUseFullScreenIntent() val isBannerDismissed by isFullScreenIntentBannerDismissed.collectAsState(initial = true) + + fun handleEvents(event: FullScreenIntentPermissionsEvents) { + when (event) { + FullScreenIntentPermissionsEvents.Dismiss -> coroutineScope.launch { + dismissFullScreenIntentBanner() + } + FullScreenIntentPermissionsEvents.OpenSettings -> openFullScreenIntentSettings() + } + } + return FullScreenIntentPermissionsState( permissionGranted = isGranted, shouldDisplayBanner = !isBannerDismissed && !isGranted, - dismissFullScreenIntentBanner = { - coroutineScope.launch { - dismissFullScreenIntentBanner() - } - }, - openFullScreenIntentSettings = ::openFullScreenIntentSettings, + eventSink = ::handleEvents, ) } diff --git a/libraries/fullscreenintent/impl/src/test/kotlin/io/element/android/libraries/fullscreenintent/test/FullScreenIntentPermissionsPresenterTest.kt b/libraries/fullscreenintent/impl/src/test/kotlin/io/element/android/libraries/fullscreenintent/test/FullScreenIntentPermissionsPresenterTest.kt index 8cf508562b..0d10032da0 100644 --- a/libraries/fullscreenintent/impl/src/test/kotlin/io/element/android/libraries/fullscreenintent/test/FullScreenIntentPermissionsPresenterTest.kt +++ b/libraries/fullscreenintent/impl/src/test/kotlin/io/element/android/libraries/fullscreenintent/test/FullScreenIntentPermissionsPresenterTest.kt @@ -15,6 +15,7 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.libraries.core.meta.BuildMeta +import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsEvents import io.element.android.libraries.fullscreenintent.impl.FullScreenIntentPermissionsPresenter import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.preferences.test.FakePreferenceDataStoreFactory @@ -76,10 +77,8 @@ class FullScreenIntentPermissionsPresenterTest { }.test { skipItems(1) val loadedItem = awaitItem() - loadedItem.dismissFullScreenIntentBanner() - + loadedItem.eventSink(FullScreenIntentPermissionsEvents.Dismiss) runCurrent() - assertThat(awaitItem().shouldDisplayBanner).isFalse() } } @@ -94,10 +93,8 @@ class FullScreenIntentPermissionsPresenterTest { }.test { skipItems(1) val loadedItem = awaitItem() - loadedItem.openFullScreenIntentSettings() - + loadedItem.eventSink(FullScreenIntentPermissionsEvents.OpenSettings) launchLambda.assertions().isCalledOnce() - cancelAndIgnoreRemainingEvents() } } @@ -115,10 +112,8 @@ class FullScreenIntentPermissionsPresenterTest { }.test { skipItems(1) val loadedItem = awaitItem() - loadedItem.openFullScreenIntentSettings() - + loadedItem.eventSink(FullScreenIntentPermissionsEvents.OpenSettings) launchLambda.assertions().isNeverCalled() - cancelAndIgnoreRemainingEvents() } } 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 338193ed44..f90b70171e 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 @@ -68,6 +68,7 @@ sealed interface NotificationContent { ) : MessageLike data object RoomEncrypted : MessageLike + data object UnableToResolve : MessageLike data class RoomMessage( val senderId: UserId, val messageType: MessageType 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 120321bddf..f6152cf0c6 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 @@ -10,9 +10,11 @@ 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.RoomId import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels +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 kotlinx.coroutines.CoroutineScope @@ -55,6 +57,8 @@ interface BaseRoom : Closeable { */ fun info(): RoomInfo = roomInfoFlow.value + fun predecessorRoom(): PredecessorRoom? + /** * A one-to-one is a room with exactly 2 members. * See [the Matrix spec](https://spec.matrix.org/latest/client-server-api/#default-underride-rules). @@ -216,17 +220,17 @@ interface BaseRoom : Closeable { /** * Store the given `ComposerDraft` in the state store of this room. */ - suspend fun saveComposerDraft(composerDraft: ComposerDraft): Result + suspend fun saveComposerDraft(composerDraft: ComposerDraft, threadRoot: ThreadId?): Result /** * Retrieve the `ComposerDraft` stored in the state store for this room. */ - suspend fun loadComposerDraft(): Result + suspend fun loadComposerDraft(threadRoot: ThreadId?): Result /** * Clear the `ComposerDraft` stored in the state store for this room. */ - suspend fun clearComposerDraft(): Result + suspend fun clearComposerDraft(threadRoot: ThreadId?): Result /** * Reports a room as inappropriate to the server. 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 8702218150..13e2ed44da 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 @@ -14,6 +14,7 @@ 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.history.RoomHistoryVisibility import io.element.android.libraries.matrix.api.room.join.JoinRule +import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/tombstone/PredecessorRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/tombstone/PredecessorRoom.kt new file mode 100644 index 0000000000..cd54b5a07b --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/tombstone/PredecessorRoom.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.matrix.api.room.tombstone + +import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.RoomId + +/** + * + * When a room A is tombstoned, it is replaced by a room B. The room A is the + * predecessor of B, and B is the successor of A. This type holds information + * about the predecessor room. + * + * A room is tombstoned if it has received a m.room.tombstone state event. + * + */ +data class PredecessorRoom( + /** + * The ID of the replaced room. + */ + val roomId: RoomId, + /** + * The event ID of the last known event in the predecessor room. + */ + val lastEventId: EventId, +) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/SuccessorRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/tombstone/SuccessorRoom.kt similarity index 92% rename from libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/SuccessorRoom.kt rename to libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/tombstone/SuccessorRoom.kt index 4aaf3dd2d2..957585a464 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/SuccessorRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/tombstone/SuccessorRoom.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.matrix.api.room +package io.element.android.libraries.matrix.api.room.tombstone import io.element.android.libraries.matrix.api.core.RoomId diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt index a940a0981f..00652a4fa9 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt @@ -131,6 +131,7 @@ interface Timeline : AutoCloseable { * @param zoomLevel Optional zoom level to display the map at. * @param assetType Optional type of the location asset. * Set to SENDER if sharing own location. Set to PIN if sharing any location. + * @param replyParameters Optional reply parameters to use when sending the location. */ suspend fun sendLocation( body: String, @@ -138,6 +139,7 @@ interface Timeline : AutoCloseable { description: String? = null, zoomLevel: Int? = null, assetType: AssetType? = null, + replyParameters: ReplyParameters?, ): Result suspend fun sendVoiceMessage( diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/MessageShield.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/MessageShield.kt index 1630f49301..2fd9ec699a 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/MessageShield.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/MessageShield.kt @@ -28,6 +28,9 @@ sealed interface MessageShield { /** The sender was previously verified but is not anymore. */ data class VerificationViolation(val isCritical: Boolean) : MessageShield + + /** The sender of the event does not match the owner of the device that created the Megolm session. */ + data class MismatchedSender(val isCritical: Boolean) : MessageShield } val MessageShield.isCritical: Boolean @@ -38,4 +41,5 @@ val MessageShield.isCritical: Boolean is MessageShield.UnverifiedIdentity -> isCritical is MessageShield.SentInClear -> isCritical is MessageShield.VerificationViolation -> isCritical + is MessageShield.MismatchedSender -> isCritical } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustClientSessionDelegate.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustClientSessionDelegate.kt index cb1a443ccb..7a3bfb3e6b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustClientSessionDelegate.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustClientSessionDelegate.kt @@ -8,12 +8,12 @@ package io.element.android.libraries.matrix.impl import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.matrix.impl.mapper.toSessionData import io.element.android.libraries.matrix.impl.paths.getSessionPaths import io.element.android.libraries.matrix.impl.util.anonymizedTokens import io.element.android.libraries.sessionstorage.api.SessionStore import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch import org.matrix.rustcomponents.sdk.ClientDelegate import org.matrix.rustcomponents.sdk.ClientSessionDelegate @@ -22,6 +22,8 @@ import timber.log.Timber import java.lang.ref.WeakReference import java.util.concurrent.atomic.AtomicBoolean +private val loggerTag = LoggerTag("RustClientSessionDelegate") + /** * This class is responsible for handling the session data for the Rust SDK. * @@ -29,14 +31,11 @@ import java.util.concurrent.atomic.AtomicBoolean * * IMPORTANT: you must set the [client] property as soon as possible so [didReceiveAuthError] can work properly. */ -@OptIn(ExperimentalCoroutinesApi::class) class RustClientSessionDelegate( private val sessionStore: SessionStore, private val appCoroutineScope: CoroutineScope, coroutineDispatchers: CoroutineDispatchers, ) : ClientSessionDelegate, ClientDelegate { - private val clientLog = Timber.tag("$this") - // Used to ensure several calls to `didReceiveAuthError` don't trigger multiple logouts private val isLoggingOut = AtomicBoolean(false) @@ -64,7 +63,7 @@ class RustClientSessionDelegate( appCoroutineScope.launch(updateTokensDispatcher) { val existingData = sessionStore.getSession(session.userId) ?: return@launch val (anonymizedAccessToken, anonymizedRefreshToken) = session.anonymizedTokens() - clientLog.d( + Timber.tag(loggerTag.value).d( "Saving new session data with token: access token '$anonymizedAccessToken' and refresh token '$anonymizedRefreshToken'. " + "Was token valid: ${existingData.isTokenValid}" ) @@ -75,29 +74,29 @@ class RustClientSessionDelegate( sessionPaths = existingData.getSessionPaths(), ) sessionStore.updateData(newData) - clientLog.d("Saved new session data with access token: '$anonymizedAccessToken'.") + Timber.tag(loggerTag.value).d("Saved new session data with access token: '$anonymizedAccessToken'.") }.invokeOnCompletion { if (it != null) { - clientLog.e(it, "Failed to save new session data.") + Timber.tag(loggerTag.value).e(it, "Failed to save new session data.") } } } override fun didReceiveAuthError(isSoftLogout: Boolean) { - clientLog.w("didReceiveAuthError(isSoftLogout=$isSoftLogout)") + Timber.tag(loggerTag.value).w("didReceiveAuthError(isSoftLogout=$isSoftLogout)") if (isLoggingOut.getAndSet(true).not()) { - clientLog.v("didReceiveAuthError -> do the cleanup") + Timber.tag(loggerTag.value).v("didReceiveAuthError -> do the cleanup") // TODO handle isSoftLogout parameter. appCoroutineScope.launch(updateTokensDispatcher) { val currentClient = client.get() if (currentClient == null) { - clientLog.w("didReceiveAuthError -> no client, exiting") + Timber.tag(loggerTag.value).w("didReceiveAuthError -> no client, exiting") isLoggingOut.set(false) return@launch } val existingData = sessionStore.getSession(currentClient.sessionId.value) val (anonymizedAccessToken, anonymizedRefreshToken) = existingData.anonymizedTokens() - clientLog.d( + Timber.tag(loggerTag.value).d( "Removing session data with access token '$anonymizedAccessToken' " + "and refresh token '$anonymizedRefreshToken'." ) @@ -105,18 +104,18 @@ class RustClientSessionDelegate( // Set isTokenValid to false val newData = existingData.copy(isTokenValid = false) sessionStore.updateData(newData) - clientLog.d("Invalidated session data with access token: '$anonymizedAccessToken'.") + Timber.tag(loggerTag.value).d("Invalidated session data with access token: '$anonymizedAccessToken'.") } else { - clientLog.d("No session data found.") + Timber.tag(loggerTag.value).d("No session data found.") } currentClient.logout(userInitiated = false, ignoreSdkError = true) }.invokeOnCompletion { if (it != null) { - clientLog.e(it, "Failed to remove session data.") + Timber.tag(loggerTag.value).e(it, "Failed to remove session data.") } } } else { - clientLog.v("didReceiveAuthError -> already cleaning up") + Timber.tag(loggerTag.value).v("didReceiveAuthError -> already cleaning up") } } 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 bc8e337ada..8261969918 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 @@ -127,6 +127,7 @@ class RustMatrixClientFactory @Inject constructor( TrustRequirement.UNTRUSTED } ) + .enableShareHistoryOnInvite(featureFlagService.isFeatureEnabled(FeatureFlags.EnableKeyShareOnInvite)) .run { // Apply sliding sync version settings when (slidingSyncType) { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt index d846321811..d7cd9c4092 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt @@ -13,7 +13,6 @@ import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MediaFile import io.element.android.libraries.matrix.api.media.MediaSource -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.withContext import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.use @@ -25,14 +24,12 @@ class RustMediaLoader( dispatchers: CoroutineDispatchers, private val innerClient: Client, ) : MatrixMediaLoader { - @OptIn(ExperimentalCoroutinesApi::class) private val mediaDispatcher = dispatchers.io.limitedParallelism(32) private val cacheDirectory get() = File(baseCacheDirectory, "temp/media").apply { if (!exists()) mkdirs() // Must always ensure that this directory exists because "Clear cache" does not restart an app's process. } - @OptIn(ExperimentalUnsignedTypes::class) override suspend fun loadMediaContent(source: MediaSource): Result = withContext(mediaDispatcher) { runCatchingExceptions { @@ -42,7 +39,6 @@ class RustMediaLoader( } } - @OptIn(ExperimentalUnsignedTypes::class) override suspend fun loadMediaThumbnail( source: MediaSource, width: Long, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt index bab7cdea02..b88b53454a 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt @@ -12,6 +12,7 @@ import io.element.android.libraries.core.extensions.runCatchingExceptions 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.notification.NotificationContent import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.api.notification.NotificationService import io.element.android.services.toolbox.api.systemclock.SystemClock @@ -24,7 +25,7 @@ class RustNotificationService( private val sessionId: SessionId, private val notificationClient: NotificationClient, private val dispatchers: CoroutineDispatchers, - clock: SystemClock, + private val clock: SystemClock, ) : NotificationService { private val notificationMapper: NotificationMapper = NotificationMapper(clock) @@ -43,11 +44,32 @@ class RustNotificationService( val eventIds = requests.flatMap { it.eventIds } for (eventId in eventIds) { val item = items[eventId] + val roomId = RoomId(requests.find { it.eventIds.contains(eventId) }?.roomId!!) if (item != null) { - val roomId = RoomId(requests.find { it.eventIds.contains(eventId) }?.roomId!!) put(EventId(eventId), notificationMapper.map(sessionId, EventId(eventId), roomId, item)) } else { Timber.e("Could not retrieve event for notification with $eventId") + put( + EventId(eventId), + NotificationData( + sessionId = sessionId, + eventId = EventId(eventId), + threadId = null, + roomId = roomId, + senderAvatarUrl = null, + senderDisplayName = null, + senderIsNameAmbiguous = false, + roomAvatarUrl = null, + roomDisplayName = null, + isDirect = false, + isDm = false, + isEncrypted = false, + isNoisy = false, + timestamp = clock.epochMillis(), + content = NotificationContent.MessageLike.UnableToResolve, + hasMention = false + ) + ) } } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoMapper.kt index 2717f6275e..e0dec91899 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomInfoMapper.kt @@ -14,11 +14,11 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.RoomInfo import io.element.android.libraries.matrix.api.room.RoomNotificationMode -import io.element.android.libraries.matrix.api.room.SuccessorRoom import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.impl.room.history.map import io.element.android.libraries.matrix.impl.room.join.map import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper +import io.element.android.libraries.matrix.impl.room.tombstone.map import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toPersistentMap @@ -28,7 +28,6 @@ import uniffi.matrix_sdk_base.EncryptionState import org.matrix.rustcomponents.sdk.Membership as RustMembership import org.matrix.rustcomponents.sdk.RoomInfo as RustRoomInfo import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode -import org.matrix.rustcomponents.sdk.SuccessorRoom as RustSuccessorRoom class RoomInfoMapper { fun map(rustRoomInfo: RustRoomInfo): RoomInfo = rustRoomInfo.let { @@ -88,11 +87,6 @@ fun RustRoomNotificationMode.map(): RoomNotificationMode = when (this) { RustRoomNotificationMode.MUTE -> RoomNotificationMode.MUTE } -fun RustSuccessorRoom.map(): SuccessorRoom = SuccessorRoom( - roomId = RoomId(roomId), - reason = reason, -) - /** * Map a RoomHero to a MatrixUser. There is not need to create a RoomHero type on the application side. */ 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 f86a179af2..b6ff98baed 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 @@ -14,6 +14,7 @@ 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.RoomId import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.MessageEventType @@ -24,12 +25,14 @@ 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.RoomPowerLevels +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.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.RoomPowerLevelsMapper +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 import io.element.android.libraries.matrix.impl.util.mxCallbackFlow @@ -78,6 +81,10 @@ class RustBaseRoom( }) }.stateIn(roomCoroutineScope, started = SharingStarted.Lazily, initialValue = initialRoomInfo) + override fun predecessorRoom(): PredecessorRoom? { + return innerRoom.predecessorRoom()?.map() + } + override suspend fun subscribeToSync() = roomSyncSubscriber.subscribe(roomId) override suspend fun updateMembers() { @@ -260,24 +267,24 @@ class RustBaseRoom( } } - override suspend fun saveComposerDraft(composerDraft: ComposerDraft): Result = withContext(roomDispatcher) { + override suspend fun saveComposerDraft(composerDraft: ComposerDraft, threadRoot: ThreadId?): Result = withContext(roomDispatcher) { runCatchingExceptions { - Timber.d("saveComposerDraft: $composerDraft into $roomId") - innerRoom.saveComposerDraft(composerDraft.into()) + Timber.d("saveComposerDraft: $composerDraft into $roomId for thread root: $threadRoot") + innerRoom.saveComposerDraft(composerDraft.into(), threadRoot = threadRoot?.value) } } - override suspend fun loadComposerDraft(): Result = withContext(roomDispatcher) { + override suspend fun loadComposerDraft(threadRoot: ThreadId?): Result = withContext(roomDispatcher) { runCatchingExceptions { - Timber.d("loadComposerDraft for $roomId") - innerRoom.loadComposerDraft()?.into() + Timber.d("loadComposerDraft for $roomId with thread root: $threadRoot") + innerRoom.loadComposerDraft(threadRoot?.value)?.into() } } - override suspend fun clearComposerDraft(): Result = withContext(roomDispatcher) { + override suspend fun clearComposerDraft(threadRoot: ThreadId?): Result = withContext(roomDispatcher) { runCatchingExceptions { - Timber.d("clearComposerDraft for $roomId") - innerRoom.clearComposerDraft() + Timber.d("clearComposerDraft for $roomId with thread root: $threadRoot") + innerRoom.clearComposerDraft(threadRoot = threadRoot?.value) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/tombstone/PredecessorRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/tombstone/PredecessorRoom.kt new file mode 100644 index 0000000000..08daee4f19 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/tombstone/PredecessorRoom.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl.room.tombstone + +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.room.tombstone.PredecessorRoom +import org.matrix.rustcomponents.sdk.PredecessorRoom as RustPredecessorRoom + +fun RustPredecessorRoom.map(): PredecessorRoom { + return PredecessorRoom( + roomId = RoomId(roomId), + lastEventId = EventId(lastEventId), + ) +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/tombstone/SuccessorRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/tombstone/SuccessorRoom.kt new file mode 100644 index 0000000000..afc0ee96af --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/tombstone/SuccessorRoom.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl.room.tombstone + +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom +import org.matrix.rustcomponents.sdk.SuccessorRoom as RustSuccessorRoom + +fun RustSuccessorRoom.map(): SuccessorRoom { + return SuccessorRoom( + roomId = RoomId(roomId), + reason = reason + ) +} 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 275c55ccc0..53b8127ab8 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt @@ -27,6 +27,11 @@ import org.matrix.rustcomponents.sdk.RoomListService import kotlin.coroutines.CoroutineContext import org.matrix.rustcomponents.sdk.RoomList as InnerRoomList +private val ROOM_LIST_RUST_FILTERS = listOf( + RoomListEntriesDynamicFilterKind.NonLeft, + RoomListEntriesDynamicFilterKind.DeduplicateVersions +) + internal class RoomListFactory( private val innerRoomListService: RoomListService, private val sessionCoroutineScope: CoroutineScope, @@ -55,11 +60,11 @@ internal class RoomListFactory( coroutineScope.launch(coroutineContext) { innerRoomList = innerProvider() - innerRoomList?.let { innerRoomList -> + innerRoomList.let { innerRoomList -> innerRoomList.entriesFlow( pageSize = pageSize, roomListDynamicEvents = dynamicEvents, - initialFilterKind = RoomListEntriesDynamicFilterKind.NonLeft + initialFilterKind = RoomListEntriesDynamicFilterKind.All(ROOM_LIST_RUST_FILTERS), ).onEach { update -> processor.postUpdate(update) }.launchIn(this) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt index f2285b6aad..2f0154c208 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt @@ -485,6 +485,7 @@ class RustTimeline( description: String?, zoomLevel: Int?, assetType: AssetType?, + replyParameters: ReplyParameters?, ): Result = withContext(dispatcher) { runCatchingExceptions { inner.sendLocation( @@ -493,6 +494,7 @@ class RustTimeline( description = description, zoomLevel = zoomLevel?.toUByte(), assetType = assetType?.toInner(), + replyParams = replyParameters?.map(), ) } } 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 6d7ca02784..7cea0e29f4 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 @@ -176,6 +176,7 @@ private fun ShieldState?.map(): MessageShield? { 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) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessor.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessor.kt index 4dded4519d..8403f63188 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessor.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessor.kt @@ -14,11 +14,10 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MembershipCha import io.element.android.libraries.matrix.api.timeline.item.event.OtherState import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent import io.element.android.libraries.matrix.api.timeline.item.event.StateContent -import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem /** * This timeline post-processor removes the room creation event and the self-join event from the timeline for DMs - * or add the RoomBeginning item for non DM room. + * or add the RoomBeginning item. */ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) { fun process( @@ -30,7 +29,7 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) { return when { items.isEmpty() -> items mode == Timeline.Mode.PINNED_EVENTS -> items - isDm -> processForDM(items, roomCreator, hasMoreToLoadBackwards) + isDm -> processForDM(items, roomCreator) hasMoreToLoadBackwards -> items else -> processForRoom(items) } @@ -41,13 +40,7 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) { return items } - private fun processForDM(items: List, roomCreator: UserId?, hasMoreToLoadBackwards: Boolean): List { - val roomBeginningItemIndex = if (!hasMoreToLoadBackwards) { - items.indexOfFirst { it is MatrixTimelineItem.Virtual && it.virtual is VirtualTimelineItem.RoomBeginning }.takeIf { it >= 0 } - } else { - null - } - + private fun processForDM(items: List, roomCreator: UserId?): List { // Find room creation event. // This is usually the first MatrixTimelineItem.Event (so index 1, index 0 is a date) val roomCreationEventIndex = items.indexOfFirst { @@ -69,7 +62,6 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) { } val indicesToRemove = listOfNotNull( - roomBeginningItemIndex, roomCreationEventIndex, selfUserJoinedEventIndex, ) 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 9f64487448..68e9946cb4 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 @@ -41,6 +41,7 @@ class FakeFfiClientBuilder : ClientBuilder(NoPointer) { override fun slidingSyncVersionBuilder(versionBuilder: SlidingSyncVersionBuilder) = this override fun userAgent(userAgent: String) = this override fun username(username: String) = this + override fun enableShareHistoryOnInvite(enableShareHistoryOnInvite: Boolean): ClientBuilder = this override suspend fun buildWithQrCode(qrCodeData: QrCodeData, oidcConfiguration: OidcConfiguration, progressListener: QrLoginProgressListener): Client { return FakeFfiClient() diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiNotificationClient.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiNotificationClient.kt index ec244ede74..180da9cc89 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiNotificationClient.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiNotificationClient.kt @@ -14,8 +14,11 @@ import org.matrix.rustcomponents.sdk.NotificationItemsRequest class FakeFfiNotificationClient( var notificationItemResult: Map = emptyMap(), + val closeResult: () -> Unit = { } ) : NotificationClient(NoPointer) { override suspend fun getNotifications(requests: List): Map { return notificationItemResult } + + override fun close() = closeResult() } 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 c0d7ddf09b..3166acc891 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 @@ -19,6 +19,7 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.services.toolbox.api.systemclock.SystemClock 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 @@ -47,6 +48,33 @@ class RustNotificationServiceTest { ) } + @Test + fun `test unable to resolve event`() = runTest { + val notificationClient = FakeFfiNotificationClient( + notificationItemResult = emptyMap(), + ) + val sut = createRustNotificationService( + notificationClient = notificationClient, + ) + val result = sut.getNotifications(mapOf(A_ROOM_ID to listOf(AN_EVENT_ID))).getOrThrow()[AN_EVENT_ID]!! + assertThat(result.content).isEqualTo( + NotificationContent.MessageLike.UnableToResolve + ) + } + + @Test + fun `close should invoke the close method of the service`() = runTest { + val closeResult = lambdaRecorder { } + val notificationClient = FakeFfiNotificationClient( + closeResult = closeResult, + ) + val sut = createRustNotificationService( + notificationClient = notificationClient, + ) + sut.close() + closeResult.assertions().isCalledOnce() + } + private fun TestScope.createRustNotificationService( notificationClient: NotificationClient = FakeFfiNotificationClient(), clock: SystemClock = FakeSystemClock(), diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessorTest.kt index bb1e4581a1..ba0bef4266 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessorTest.kt @@ -50,7 +50,7 @@ class RoomBeginningPostProcessorTest { } @Test - fun `processor removes timeline start, room creation event and self-join event from DM timeline`() { + fun `processor removes room creation event and self-join event from DM timeline`() { val timelineItems = listOf( timelineStartEvent, roomCreateEvent, @@ -63,7 +63,7 @@ class RoomBeginningPostProcessorTest { roomCreator = A_USER_ID, hasMoreToLoadBackwards = false, ) - assertThat(processedItems).isEmpty() + assertThat(processedItems).containsExactly(timelineStartEvent) } @Test 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 ae9aee8736..c620f5c886 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 @@ -11,6 +11,7 @@ import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.MessageEventType @@ -20,6 +21,7 @@ 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.RoomPowerLevels +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 @@ -66,6 +68,7 @@ class FakeBaseRoom( private val getRoomVisibilityResult: () -> Result = { lambdaError() }, private val forgetResult: () -> Result = { lambdaError() }, private val reportRoomResult: (String?) -> Result = { lambdaError() }, + private val predecessorRoomResult: () -> PredecessorRoom? = { null }, ) : BaseRoom { private val _roomInfoFlow: MutableStateFlow = MutableStateFlow(initialRoomInfo) override val roomInfoFlow: StateFlow = _roomInfoFlow @@ -196,11 +199,14 @@ class FakeBaseRoom( return Result.success(Unit) } - override suspend fun saveComposerDraft(composerDraft: ComposerDraft) = saveComposerDraftLambda(composerDraft) + override suspend fun saveComposerDraft( + composerDraft: ComposerDraft, + threadRoot: ThreadId? + ) = saveComposerDraftLambda(composerDraft) - override suspend fun loadComposerDraft() = loadComposerDraftLambda() + override suspend fun loadComposerDraft(threadRoot: ThreadId?) = loadComposerDraftLambda() - override suspend fun clearComposerDraft() = clearComposerDraftLambda() + override suspend fun clearComposerDraft(threadRoot: ThreadId?) = clearComposerDraftLambda() override suspend fun getUpdatedIsEncrypted(): Result = simulateLongTask { Result.success(info().isEncrypted.orFalse()) @@ -215,6 +221,8 @@ class FakeBaseRoom( } override suspend fun reportRoom(reason: String?) = reportRoomResult(reason) + + override fun predecessorRoom(): PredecessorRoom? = predecessorRoomResult() } fun defaultRoomPowerLevels() = RoomPowerLevels( diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt index 5b6040dee5..0fc88d1d81 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt @@ -15,9 +15,9 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership 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.RoomNotificationMode -import io.element.android.libraries.matrix.api.room.SuccessorRoom 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.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.A_ROOM_ID diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt index 11e462f977..27302a2d87 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt @@ -15,10 +15,10 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership 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.RoomNotificationMode -import io.element.android.libraries.matrix.api.room.SuccessorRoom 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.message.RoomMessage +import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import io.element.android.libraries.matrix.api.user.MatrixUser 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 3aa3a2e186..c4ab0160c4 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 @@ -304,7 +304,8 @@ class FakeTimeline( description: String?, zoomLevel: Int?, assetType: AssetType?, - ) -> Result = { _, _, _, _, _ -> + replyParameters: ReplyParameters?, + ) -> Result = { _, _, _, _, _, _ -> lambdaError() } @@ -314,6 +315,7 @@ class FakeTimeline( description: String?, zoomLevel: Int?, assetType: AssetType?, + replyParameters: ReplyParameters?, ): Result = simulateLongTask { sendLocationLambda( body, @@ -321,6 +323,7 @@ class FakeTimeline( description, zoomLevel, assetType, + replyParameters, ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectRoomInfoProvider.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectRoomInfoProvider.kt index 6d85cc28cb..f6ad30fae1 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectRoomInfoProvider.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectRoomInfoProvider.kt @@ -30,10 +30,12 @@ fun aSelectRoomInfo( canonicalAlias: RoomAlias? = null, avatarUrl: String? = null, heroes: ImmutableList = persistentListOf(), + isTombstoned: Boolean = false, ) = SelectRoomInfo( roomId = roomId, name = name, canonicalAlias = canonicalAlias, avatarUrl = avatarUrl, heroes = heroes, + isTombstoned = isTombstoned, ) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt index 11f6b74b95..06cead3526 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedRoom.kt @@ -29,7 +29,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.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar +import io.element.android.libraries.designsystem.components.avatar.RoomAvatar 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 @@ -53,9 +53,10 @@ fun SelectedRoom( Column( horizontalAlignment = Alignment.CenterHorizontally, ) { - CompositeAvatar( + RoomAvatar( avatarData = roomInfo.getAvatarData(AvatarSize.SelectedRoom), heroes = roomInfo.heroes.map { it.getAvatarData(AvatarSize.SelectedRoom) }.toImmutableList(), + isTombstoned = roomInfo.isTombstoned, ) Text( // If name is null, we do not have space to render "No room name", so just use `#` here. diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SelectRoomInfo.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SelectRoomInfo.kt index 8ca5dcd326..63a0b1cc77 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SelectRoomInfo.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/SelectRoomInfo.kt @@ -21,6 +21,7 @@ data class SelectRoomInfo( val canonicalAlias: RoomAlias?, val avatarUrl: String?, val heroes: ImmutableList, + val isTombstoned: Boolean, ) { fun getAvatarData(size: AvatarSize) = AvatarData( id = roomId.value, @@ -36,4 +37,5 @@ fun RoomSummary.toSelectRoomInfo() = SelectRoomInfo( avatarUrl = info.avatarUrl, heroes = info.heroes, canonicalAlias = info.canonicalAlias, + isTombstoned = info.successorRoom != null, ) diff --git a/libraries/matrixui/src/main/res/values-in/translations.xml b/libraries/matrixui/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..11b1de4d8a --- /dev/null +++ b/libraries/matrixui/src/main/res/values-in/translations.xml @@ -0,0 +1,4 @@ + + + "%1$s (%2$s) mengundang Anda" + diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/AudioItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/AudioItemView.kt index 1bee0dffe3..73786e12a4 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/AudioItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/AudioItemView.kt @@ -7,7 +7,6 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Column @@ -65,7 +64,6 @@ fun AudioItemView( } } -@OptIn(ExperimentalFoundationApi::class) @Composable private fun FilenameRow( audio: MediaItem.Audio, diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/FileItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/FileItemView.kt index bdb6539ecc..cd73365cca 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/FileItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/FileItemView.kt @@ -7,7 +7,6 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Column @@ -65,7 +64,6 @@ fun FileItemView( } } -@OptIn(ExperimentalFoundationApi::class) @Composable private fun FilenameRow( file: MediaItem.File, 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 89f9a30f40..fdb236baa2 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 @@ -7,7 +7,6 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.combinedClickable @@ -84,7 +83,6 @@ fun VoiceItemView( } } -@OptIn(ExperimentalFoundationApi::class) @Composable private fun VoiceInfoRow( state: VoiceMessageState, diff --git a/libraries/mediaviewer/impl/src/main/res/values-in/translations.xml b/libraries/mediaviewer/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..2cdc0cf27c --- /dev/null +++ b/libraries/mediaviewer/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,19 @@ + + + "Berkas ini akan dihapus dari ruangan dan anggota tidak akan memiliki akses ke sana." + "Hapus berkas?" + "Periksa koneksi internet Anda dan coba lagi." + "Dokumen, berkas audio, dan pesan suara yang diunggah ke ruangan ini akan ditampilkan di sini." + "Belum ada berkas yang diunggah" + "Memuat berkas…" + "Memuat media…" + "Berkas" + "Media" + "Gambar dan video yang diunggah ke ruangan ini akan ditampilkan di sini." + "Belum ada media yang diunggah" + "Media dan berkas" + "Format berkas" + "Nama berkas" + "Diunggah oleh" + "Diunggah pada" + 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 3823b1b8e1..1748a02db4 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 @@ -9,6 +9,7 @@ package io.element.android.libraries.permissions.api import android.Manifest import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter @@ -41,6 +42,7 @@ fun PermissionsView( } @Composable +@ReadOnlyComposable private fun String.toDialogContent(): String { return when (this) { Manifest.permission.POST_NOTIFICATIONS -> stringResource(id = R.string.dialog_permission_notification) diff --git a/libraries/permissions/impl/src/main/res/values-in/translations.xml b/libraries/permissions/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..dff88d1314 --- /dev/null +++ b/libraries/permissions/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,5 @@ + + + "Pastikan aplikasi dapat menampilkan notifikasi." + "Periksa izin" + diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt index f9a0496efb..fb1bd14404 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt @@ -67,4 +67,9 @@ interface PushService { * Reset the push history, including the push counter. */ suspend fun resetPushHistory() + + /** + * Reset the battery optimization state. + */ + suspend fun resetBatteryOptimizationState() } diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/battery/BatteryOptimizationEvents.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/battery/BatteryOptimizationEvents.kt new file mode 100644 index 0000000000..ab8d9e92e5 --- /dev/null +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/battery/BatteryOptimizationEvents.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.push.api.battery + +sealed interface BatteryOptimizationEvents { + data object Dismiss : BatteryOptimizationEvents + data object RequestDisableOptimizations : BatteryOptimizationEvents +} diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/battery/BatteryOptimizationState.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/battery/BatteryOptimizationState.kt new file mode 100644 index 0000000000..7e7c2b2bd6 --- /dev/null +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/battery/BatteryOptimizationState.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.push.api.battery + +data class BatteryOptimizationState( + val shouldDisplayBanner: Boolean, + val eventSink: (BatteryOptimizationEvents) -> Unit, +) diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/battery/BatteryOptimizationStateProvider.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/battery/BatteryOptimizationStateProvider.kt new file mode 100644 index 0000000000..d6d4e5774b --- /dev/null +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/battery/BatteryOptimizationStateProvider.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.push.api.battery + +fun aBatteryOptimizationState( + shouldDisplayBanner: Boolean = false, + eventSink: (BatteryOptimizationEvents) -> Unit = {}, +) = BatteryOptimizationState( + shouldDisplayBanner = shouldDisplayBanner, + eventSink = eventSink, +) diff --git a/libraries/push/impl/src/main/AndroidManifest.xml b/libraries/push/impl/src/main/AndroidManifest.xml index 49ca55decc..c08c16ed5f 100644 --- a/libraries/push/impl/src/main/AndroidManifest.xml +++ b/libraries/push/impl/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + + + () + ?.isIgnoringBatteryOptimizations(context.packageName) == true + } + + @SuppressLint("BatteryLife") + override fun requestDisablingBatteryOptimization(): Boolean { + val ignoreBatteryOptimizationsResult = launchAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, withData = true) + if (ignoreBatteryOptimizationsResult) { + return true + } + // Open settings as a fallback if the first attempt fails + return launchAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS, withData = false) + } + + private fun launchAction( + action: String, + withData: Boolean, + ): Boolean { + val intent = Intent() + intent.action = action + if (withData) { + intent.data = ("package:" + context.packageName).toUri() + } + return try { + externalIntentLauncher.launch(intent) + true + } catch (exception: ActivityNotFoundException) { + Timber.w(exception, "Cannot launch intent with action $action.") + false + } + } +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/battery/BatteryOptimizationPresenter.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/battery/BatteryOptimizationPresenter.kt new file mode 100644 index 0000000000..9fa17f0544 --- /dev/null +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/battery/BatteryOptimizationPresenter.kt @@ -0,0 +1,71 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.push.impl.battery + +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.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.lifecycle.compose.LifecycleResumeEffect +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.push.api.battery.BatteryOptimizationEvents +import io.element.android.libraries.push.api.battery.BatteryOptimizationState +import io.element.android.libraries.push.impl.push.MutableBatteryOptimizationStore +import io.element.android.libraries.push.impl.store.PushDataStore +import kotlinx.coroutines.launch +import javax.inject.Inject + +class BatteryOptimizationPresenter @Inject constructor( + private val pushDataStore: PushDataStore, + private val mutableBatteryOptimizationStore: MutableBatteryOptimizationStore, + private val batteryOptimization: BatteryOptimization, +) : Presenter { + @Composable + override fun present(): BatteryOptimizationState { + val coroutineScope = rememberCoroutineScope() + var isRequestSent by remember { mutableStateOf(false) } + var localShouldDisplayBanner by remember { mutableStateOf(true) } + val storeShouldDisplayBanner by pushDataStore.shouldDisplayBatteryOptimizationBannerFlow.collectAsState(initial = false) + var isSystemIgnoringBatteryOptimizations by remember { + mutableStateOf(batteryOptimization.isIgnoringBatteryOptimizations()) + } + + LifecycleResumeEffect(Unit) { + isSystemIgnoringBatteryOptimizations = batteryOptimization.isIgnoringBatteryOptimizations() + if (isRequestSent) { + localShouldDisplayBanner = false + } + onPauseOrDispose {} + } + + fun handleEvents(event: BatteryOptimizationEvents) { + when (event) { + BatteryOptimizationEvents.Dismiss -> coroutineScope.launch { + mutableBatteryOptimizationStore.onOptimizationBannerDismissed() + } + BatteryOptimizationEvents.RequestDisableOptimizations -> { + isRequestSent = true + if (batteryOptimization.requestDisablingBatteryOptimization().not()) { + // If not able to perform the request, ensure that we do not display the banner again + coroutineScope.launch { + mutableBatteryOptimizationStore.onOptimizationBannerDismissed() + } + } + } + } + } + + return BatteryOptimizationState( + shouldDisplayBanner = localShouldDisplayBanner && storeShouldDisplayBanner && !isSystemIgnoringBatteryOptimizations, + eventSink = ::handleEvents, + ) + } +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/di/PushModule.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/di/PushModule.kt index 3e7c7ddae3..bb8b7e1624 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/di/PushModule.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/di/PushModule.kt @@ -10,16 +10,25 @@ package io.element.android.libraries.push.impl.di import android.content.Context import androidx.core.app.NotificationManagerCompat import com.squareup.anvil.annotations.ContributesTo +import dagger.Binds import dagger.Module import dagger.Provides +import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext +import io.element.android.libraries.push.api.battery.BatteryOptimizationState +import io.element.android.libraries.push.impl.battery.BatteryOptimizationPresenter @Module @ContributesTo(AppScope::class) -object PushModule { - @Provides - fun provideNotificationCompatManager(@ApplicationContext context: Context): NotificationManagerCompat { - return NotificationManagerCompat.from(context) +interface PushModule { + companion object { + @Provides + fun provideNotificationCompatManager(@ApplicationContext context: Context): NotificationManagerCompat { + return NotificationManagerCompat.from(context) + } } + + @Binds + fun bindBatteryOptimizationPresenter(presenter: BatteryOptimizationPresenter): Presenter } 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 d5eef83564..9a6b119a26 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 @@ -225,6 +225,11 @@ class DefaultNotifiableEventResolver @Inject constructor( val fallbackNotifiableEvent = fallbackNotifiableEvent(userId, roomId, eventId) ResolvedPushEvent.Event(fallbackNotifiableEvent) } + NotificationContent.MessageLike.UnableToResolve -> { + Timber.tag(loggerTag.value).w("Unable to resolve notification -> fallback") + val fallbackNotifiableEvent = fallbackNotifiableEvent(userId, roomId, eventId) + ResolvedPushEvent.Event(fallbackNotifiableEvent) + } is NotificationContent.MessageLike.RoomRedaction -> { // Note: this case will be handled below val redactedEventId = content.redactedEventId diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt index a426cdcf42..4d9e390690 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.push.impl.history.onUnableToRetrieveSession import io.element.android.libraries.push.impl.notifications.NotificationEventRequest import io.element.android.libraries.push.impl.notifications.NotificationResolverQueue import io.element.android.libraries.push.impl.notifications.channels.NotificationChannels +import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableRingingCallEvent import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent @@ -50,6 +51,7 @@ class DefaultPushHandler @Inject constructor( private val onNotifiableEventReceived: OnNotifiableEventReceived, private val onRedactedEventReceived: OnRedactedEventReceived, private val incrementPushDataStore: IncrementPushDataStore, + private val mutableBatteryOptimizationStore: MutableBatteryOptimizationStore, private val userPushStoreFactory: UserPushStoreFactory, private val pushClientSecret: PushClientSecret, private val buildMeta: BuildMeta, @@ -86,13 +88,24 @@ class DefaultPushHandler @Inject constructor( } else { result.fold( onSuccess = { - pushHistoryService.onSuccess( - providerInfo = request.providerInfo, - eventId = request.eventId, - roomId = request.roomId, - sessionId = request.sessionId, - comment = "Push handled successfully", - ) + if (it is ResolvedPushEvent.Event && it.notifiableEvent is FallbackNotifiableEvent) { + pushHistoryService.onUnableToResolveEvent( + providerInfo = request.providerInfo, + eventId = request.eventId, + roomId = request.roomId, + sessionId = request.sessionId, + reason = "Showing fallback notification", + ) + mutableBatteryOptimizationStore.showBatteryOptimizationBanner() + } else { + pushHistoryService.onSuccess( + providerInfo = request.providerInfo, + eventId = request.eventId, + roomId = request.roomId, + sessionId = request.sessionId, + comment = "Push handled successfully", + ) + } }, onFailure = { exception -> pushHistoryService.onUnableToResolveEvent( @@ -102,6 +115,7 @@ class DefaultPushHandler @Inject constructor( sessionId = request.sessionId, reason = exception.message ?: exception.javaClass.simpleName, ) + mutableBatteryOptimizationStore.showBatteryOptimizationBanner() } ) } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/MutableBatteryOptimizationStore.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/MutableBatteryOptimizationStore.kt new file mode 100644 index 0000000000..14e2cfd97b --- /dev/null +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/MutableBatteryOptimizationStore.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.push.impl.push + +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.push.impl.store.DefaultPushDataStore +import javax.inject.Inject + +interface MutableBatteryOptimizationStore { + suspend fun showBatteryOptimizationBanner() + suspend fun onOptimizationBannerDismissed() + suspend fun reset() +} + +@ContributesBinding(AppScope::class) +class DefaultMutableBatteryOptimizationStore @Inject constructor( + private val defaultPushDataStore: DefaultPushDataStore, +) : MutableBatteryOptimizationStore { + override suspend fun showBatteryOptimizationBanner() { + defaultPushDataStore.setBatteryOptimizationBannerState(DefaultPushDataStore.BATTERY_OPTIMIZATION_BANNER_STATE_SHOW) + } + + override suspend fun onOptimizationBannerDismissed() { + defaultPushDataStore.setBatteryOptimizationBannerState(DefaultPushDataStore.BATTERY_OPTIMIZATION_BANNER_STATE_DISMISSED) + } + + override suspend fun reset() { + defaultPushDataStore.setBatteryOptimizationBannerState(DefaultPushDataStore.BATTERY_OPTIMIZATION_BANNER_STATE_INIT) + } +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/store/DefaultPushDataStore.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/store/DefaultPushDataStore.kt index 2130e91c72..a4d9413cb1 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/store/DefaultPushDataStore.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/store/DefaultPushDataStore.kt @@ -43,10 +43,24 @@ class DefaultPushDataStore @Inject constructor( ) : PushDataStore { private val pushCounter = intPreferencesKey("push_counter") + /** + * Integer preference to track the state of the battery optimization banner. + * Possible values: + * [BATTERY_OPTIMIZATION_BANNER_STATE_INIT]: Should not show the banner + * [BATTERY_OPTIMIZATION_BANNER_STATE_SHOW]: Should show the banner + * [BATTERY_OPTIMIZATION_BANNER_STATE_DISMISSED]: Banner has been shown and user has dismissed it + */ + private val batteryOptimizationBannerState = intPreferencesKey("battery_optimization_banner_state") + override val pushCounterFlow: Flow = context.dataStore.data.map { preferences -> preferences[pushCounter] ?: 0 } + @Suppress("UnnecessaryParentheses") + override val shouldDisplayBatteryOptimizationBannerFlow: Flow = context.dataStore.data.map { preferences -> + (preferences[batteryOptimizationBannerState] ?: BATTERY_OPTIMIZATION_BANNER_STATE_INIT) == BATTERY_OPTIMIZATION_BANNER_STATE_SHOW + } + suspend fun incrementPushCounter() { context.dataStore.edit { settings -> val currentCounterValue = settings[pushCounter] ?: 0 @@ -54,6 +68,18 @@ class DefaultPushDataStore @Inject constructor( } } + suspend fun setBatteryOptimizationBannerState(newState: Int) { + context.dataStore.edit { settings -> + val currentValue = settings[batteryOptimizationBannerState] ?: BATTERY_OPTIMIZATION_BANNER_STATE_INIT + settings[batteryOptimizationBannerState] = when (currentValue) { + BATTERY_OPTIMIZATION_BANNER_STATE_INIT, + BATTERY_OPTIMIZATION_BANNER_STATE_SHOW -> newState + BATTERY_OPTIMIZATION_BANNER_STATE_DISMISSED -> currentValue + else -> error("Invalid value for showBatteryOptimizationBanner: $currentValue") + } + } + } + override fun getPushHistoryItemsFlow(): Flow> { return pushDatabase.pushHistoryQueries.selectAll() .asFlow() @@ -84,4 +110,10 @@ class DefaultPushDataStore @Inject constructor( it.clear() } } + + companion object { + const val BATTERY_OPTIMIZATION_BANNER_STATE_INIT = 0 + const val BATTERY_OPTIMIZATION_BANNER_STATE_SHOW = 1 + const val BATTERY_OPTIMIZATION_BANNER_STATE_DISMISSED = 2 + } } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/store/PushDataStore.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/store/PushDataStore.kt index 13c4e06347..de8f6dbbc1 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/store/PushDataStore.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/store/PushDataStore.kt @@ -11,6 +11,7 @@ import io.element.android.libraries.push.api.history.PushHistoryItem import kotlinx.coroutines.flow.Flow interface PushDataStore { + val shouldDisplayBatteryOptimizationBannerFlow: Flow val pushCounterFlow: Flow /** 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 0fcab9de6d..0fcfe9994d 100644 --- a/libraries/push/impl/src/main/res/values-es/translations.xml +++ b/libraries/push/impl/src/main/res/values-es/translations.xml @@ -64,6 +64,7 @@ "Se encontró %1$d proveedor de push: %2$s" "Se encontraron %1$d proveedores de push: %2$s" + "La aplicación se compiló con compatibilidad para: %1$s" "Detectar proveedores de push" "Verificar que la aplicación pueda mostrar notificaciones." "No se ha hecho clic en la notificación." diff --git a/libraries/push/impl/src/main/res/values/localazy.xml b/libraries/push/impl/src/main/res/values/localazy.xml index 9860c8bef7..069183a3a2 100644 --- a/libraries/push/impl/src/main/res/values/localazy.xml +++ b/libraries/push/impl/src/main/res/values/localazy.xml @@ -13,7 +13,7 @@ "%d notification" "%d notifications" - "Notification" + "You have new messages." "📹 Incoming call" "** Failed to send - please open room" "Join" diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt index f3333e84f7..5ae8ab261e 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/DefaultPushServiceTest.kt @@ -7,13 +7,19 @@ package io.element.android.libraries.push.impl +import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.matrix.test.AN_EVENT_ID 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_SESSION_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.push.api.GetCurrentPushProvider +import io.element.android.libraries.push.api.history.PushHistoryItem +import io.element.android.libraries.push.impl.push.FakeMutableBatteryOptimizationStore +import io.element.android.libraries.push.impl.push.MutableBatteryOptimizationStore import io.element.android.libraries.push.impl.store.InMemoryPushDataStore import io.element.android.libraries.push.impl.store.PushDataStore import io.element.android.libraries.push.impl.test.FakeTestPush @@ -283,6 +289,53 @@ class DefaultPushServiceTest { assertThat(userPushStore.getPushProviderName()).isEqualTo(aPushProvider.name) } + @Test + fun `resetBatteryOptimizationState invokes the store method`() = runTest { + val resetResult = lambdaRecorder { } + val defaultPushService = createDefaultPushService( + mutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore( + resetResult = resetResult, + ), + ) + defaultPushService.resetBatteryOptimizationState() + resetResult.assertions().isCalledOnce() + } + + @Test + fun `resetPushHistory invokes the store method`() = runTest { + val resetResult = lambdaRecorder { } + val defaultPushService = createDefaultPushService( + pushDataStore = InMemoryPushDataStore( + resetResult = resetResult + ), + ) + defaultPushService.resetPushHistory() + resetResult.assertions().isCalledOnce() + } + + @Test + fun `getPushHistoryItemsFlow invokes the store method`() = runTest { + val store = InMemoryPushDataStore() + val aPushHistoryItem = PushHistoryItem( + pushDate = 0L, + formattedDate = "formattedDate", + providerInfo = "providerInfo", + eventId = AN_EVENT_ID, + roomId = A_ROOM_ID, + sessionId = A_SESSION_ID, + hasBeenResolved = false, + comment = null, + ) + val defaultPushService = createDefaultPushService( + pushDataStore = store, + ) + defaultPushService.getPushHistoryItemsFlow().test { + assertThat(awaitItem().isEmpty()).isTrue() + store.emitPushHistoryItems(listOf(aPushHistoryItem)) + assertThat(awaitItem().first()).isEqualTo(aPushHistoryItem) + } + } + private fun createDefaultPushService( testPush: TestPush = FakeTestPush(), userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(), @@ -291,6 +344,7 @@ class DefaultPushServiceTest { sessionObserver: SessionObserver = NoOpSessionObserver(), pushClientSecretStore: PushClientSecretStore = InMemoryPushClientSecretStore(), pushDataStore: PushDataStore = InMemoryPushDataStore(), + mutableBatteryOptimizationStore: MutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore(), ): DefaultPushService { return DefaultPushService( testPush = testPush, @@ -300,6 +354,7 @@ class DefaultPushServiceTest { sessionObserver = sessionObserver, pushClientSecretStore = pushClientSecretStore, pushDataStore = pushDataStore, + mutableBatteryOptimizationStore = mutableBatteryOptimizationStore, ) } } diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/battery/AndroidBatteryOptimizationTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/battery/AndroidBatteryOptimizationTest.kt new file mode 100644 index 0000000000..e3a28550ca --- /dev/null +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/battery/AndroidBatteryOptimizationTest.kt @@ -0,0 +1,113 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.push.impl.battery + +import android.content.ActivityNotFoundException +import android.content.Intent +import android.provider.Settings +import androidx.test.platform.app.InstrumentationRegistry +import com.google.common.truth.Truth.assertThat +import io.element.android.services.toolbox.api.intent.ExternalIntentLauncher +import io.element.android.services.toolbox.test.intent.FakeExternalIntentLauncher +import io.element.android.tests.testutils.lambda.lambdaRecorder +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class AndroidBatteryOptimizationTest { + @Test + fun `isIgnoringBatteryOptimizations should return false`() { + val sut = createAndroidBatteryOptimization() + assertThat(sut.isIgnoringBatteryOptimizations()).isFalse() + } + + @Test + fun `requestDisablingBatteryOptimization is called once with expected intent`() { + val launchLambda = lambdaRecorder { intent -> + assertThat(intent.action).isEqualTo(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) + assertThat(intent.data.toString()).isEqualTo("package:${InstrumentationRegistry.getInstrumentation().context.packageName}") + } + val externalIntentLauncher = FakeExternalIntentLauncher(launchLambda) + val sut = createAndroidBatteryOptimization( + externalIntentLauncher = externalIntentLauncher, + ) + val result = sut.requestDisablingBatteryOptimization() + launchLambda.assertions().isCalledOnce() + assertThat(result).isTrue() + } + + @Test + fun `in case of 1 error, requestDisablingBatteryOptimization returns true`() { + var callNumber = 0 + val launchLambda = lambdaRecorder { intent -> + callNumber++ + when (callNumber) { + 1 -> { + assertThat(intent.action).isEqualTo(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) + assertThat(intent.data.toString()).isEqualTo("package:${InstrumentationRegistry.getInstrumentation().context.packageName}") + throw ActivityNotFoundException("Test exception") + } + 2 -> { + assertThat(intent.action).isEqualTo(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) + assertThat(intent.data).isNull() + // No error + } + else -> { + throw AssertionError("Unexpected call number: $callNumber") + } + } + } + val externalIntentLauncher = FakeExternalIntentLauncher(launchLambda) + val sut = createAndroidBatteryOptimization( + externalIntentLauncher = externalIntentLauncher, + ) + val result = sut.requestDisablingBatteryOptimization() + launchLambda.assertions().isCalledExactly(2) + assertThat(result).isTrue() + } + + @Test + fun `in case of 2 errors, requestDisablingBatteryOptimization returns false`() { + var callNumber = 0 + val launchLambda = lambdaRecorder { intent -> + callNumber++ + when (callNumber) { + 1 -> { + assertThat(intent.action).isEqualTo(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) + assertThat(intent.data.toString()).isEqualTo("package:${InstrumentationRegistry.getInstrumentation().context.packageName}") + throw ActivityNotFoundException("Test exception") + } + 2 -> { + assertThat(intent.action).isEqualTo(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) + assertThat(intent.data).isNull() + throw ActivityNotFoundException("Test exception") + } + else -> { + throw AssertionError("Unexpected call number: $callNumber") + } + } + } + val externalIntentLauncher = FakeExternalIntentLauncher(launchLambda) + val sut = createAndroidBatteryOptimization( + externalIntentLauncher = externalIntentLauncher, + ) + val result = sut.requestDisablingBatteryOptimization() + launchLambda.assertions().isCalledExactly(2) + assertThat(result).isFalse() + } + + private fun createAndroidBatteryOptimization( + externalIntentLauncher: ExternalIntentLauncher = FakeExternalIntentLauncher(), + ): AndroidBatteryOptimization { + return AndroidBatteryOptimization( + context = InstrumentationRegistry.getInstrumentation().context, + externalIntentLauncher = externalIntentLauncher, + ) + } +} diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/battery/BatteryOptimizationPresenterTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/battery/BatteryOptimizationPresenterTest.kt new file mode 100644 index 0000000000..d5dd7c48d4 --- /dev/null +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/battery/BatteryOptimizationPresenterTest.kt @@ -0,0 +1,170 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.push.impl.battery + +import androidx.lifecycle.Lifecycle +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.push.api.battery.BatteryOptimizationEvents +import io.element.android.libraries.push.impl.push.FakeMutableBatteryOptimizationStore +import io.element.android.libraries.push.impl.push.MutableBatteryOptimizationStore +import io.element.android.libraries.push.impl.store.InMemoryPushDataStore +import io.element.android.libraries.push.impl.store.PushDataStore +import io.element.android.tests.testutils.FakeLifecycleOwner +import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.testWithLifecycleOwner +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test + +class BatteryOptimizationPresenterTest { + @get:Rule + val warmUpRule = WarmUpRule() + + @Test + fun `present - initial state`() = runTest { + val presenter = createPresenter( + pushDataStore = InMemoryPushDataStore( + initialShouldDisplayBatteryOptimizationBanner = false, + ), + batteryOptimization = FakeBatteryOptimization( + isIgnoringBatteryOptimizationsResult = false, + ), + ) + val lifeCycleOwner = FakeLifecycleOwner() + presenter.testWithLifecycleOwner(lifeCycleOwner) { + val initialState = awaitItem() + assertThat(initialState.shouldDisplayBanner).isFalse() + lifeCycleOwner.givenState(Lifecycle.State.RESUMED) + } + } + + @Test + fun `present - should display banner`() = runTest { + val presenter = createPresenter( + pushDataStore = InMemoryPushDataStore( + initialShouldDisplayBatteryOptimizationBanner = true, + ), + batteryOptimization = FakeBatteryOptimization( + isIgnoringBatteryOptimizationsResult = false, + ), + ) + presenter.testWithLifecycleOwner { + val initialState = awaitItem() + assertThat(initialState.shouldDisplayBanner).isFalse() + assertThat(awaitItem().shouldDisplayBanner).isTrue() + } + } + + @Test + fun `present - should display banner, but setting already performed`() = runTest { + val presenter = createPresenter( + pushDataStore = InMemoryPushDataStore( + initialShouldDisplayBatteryOptimizationBanner = true, + ), + batteryOptimization = FakeBatteryOptimization( + isIgnoringBatteryOptimizationsResult = true, + ), + ) + presenter.testWithLifecycleOwner { + val initialState = awaitItem() + assertThat(initialState.shouldDisplayBanner).isFalse() + assertThat(awaitItem().shouldDisplayBanner).isFalse() + } + } + + @Test + fun `present - should display banner, user dismisses`() = runTest { + val onOptimizationBannerDismissedResult = lambdaRecorder { } + val presenter = createPresenter( + pushDataStore = InMemoryPushDataStore( + initialShouldDisplayBatteryOptimizationBanner = true, + ), + batteryOptimization = FakeBatteryOptimization( + isIgnoringBatteryOptimizationsResult = false, + ), + mutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore( + onOptimizationBannerDismissedResult = onOptimizationBannerDismissedResult, + ), + ) + presenter.testWithLifecycleOwner { + val initialState = awaitItem() + assertThat(initialState.shouldDisplayBanner).isFalse() + val displayedItem = awaitItem() + assertThat(displayedItem.shouldDisplayBanner).isTrue() + displayedItem.eventSink(BatteryOptimizationEvents.Dismiss) + onOptimizationBannerDismissedResult.assertions().isCalledOnce() + } + } + + @Test + fun `present - should display banner, user continue, error case`() = runTest { + val onOptimizationBannerDismissedResult = lambdaRecorder { } + val requestDisablingBatteryOptimizationResult = lambdaRecorder { false } + val presenter = createPresenter( + pushDataStore = InMemoryPushDataStore( + initialShouldDisplayBatteryOptimizationBanner = true, + ), + batteryOptimization = FakeBatteryOptimization( + isIgnoringBatteryOptimizationsResult = false, + requestDisablingBatteryOptimizationResult = requestDisablingBatteryOptimizationResult + ), + mutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore( + onOptimizationBannerDismissedResult = onOptimizationBannerDismissedResult, + ), + ) + presenter.testWithLifecycleOwner { + val initialState = awaitItem() + assertThat(initialState.shouldDisplayBanner).isFalse() + val displayedItem = awaitItem() + assertThat(displayedItem.shouldDisplayBanner).isTrue() + displayedItem.eventSink(BatteryOptimizationEvents.RequestDisableOptimizations) + requestDisablingBatteryOptimizationResult.assertions().isCalledOnce() + onOptimizationBannerDismissedResult.assertions().isCalledOnce() + } + } + + @Test + fun `present - should display banner, user continue, nominal case`() = runTest { + val requestDisablingBatteryOptimizationResult = lambdaRecorder { true } + val batteryOptimization = FakeBatteryOptimization( + isIgnoringBatteryOptimizationsResult = false, + requestDisablingBatteryOptimizationResult = requestDisablingBatteryOptimizationResult + ) + val presenter = createPresenter( + pushDataStore = InMemoryPushDataStore( + initialShouldDisplayBatteryOptimizationBanner = true, + ), + batteryOptimization = batteryOptimization, + mutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore(), + ) + val lifeCycleOwner = FakeLifecycleOwner() + presenter.testWithLifecycleOwner(lifeCycleOwner) { + val initialState = awaitItem() + assertThat(initialState.shouldDisplayBanner).isFalse() + val displayedItem = awaitItem() + assertThat(displayedItem.shouldDisplayBanner).isTrue() + displayedItem.eventSink(BatteryOptimizationEvents.RequestDisableOptimizations) + requestDisablingBatteryOptimizationResult.assertions().isCalledOnce() + batteryOptimization.isIgnoringBatteryOptimizationsResult = true + lifeCycleOwner.givenState(Lifecycle.State.RESUMED) + assertThat(awaitItem().shouldDisplayBanner).isFalse() + assertThat(awaitItem().shouldDisplayBanner).isFalse() + } + } + + private fun createPresenter( + pushDataStore: PushDataStore = InMemoryPushDataStore(), + mutableBatteryOptimizationStore: MutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore(), + batteryOptimization: BatteryOptimization = FakeBatteryOptimization(), + ) = BatteryOptimizationPresenter( + pushDataStore = pushDataStore, + mutableBatteryOptimizationStore = mutableBatteryOptimizationStore, + batteryOptimization = batteryOptimization + ) +} diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/battery/FakeBatteryOptimization.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/battery/FakeBatteryOptimization.kt new file mode 100644 index 0000000000..0adb3d2520 --- /dev/null +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/battery/FakeBatteryOptimization.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.push.impl.battery + +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeBatteryOptimization( + var isIgnoringBatteryOptimizationsResult: Boolean = false, + private val requestDisablingBatteryOptimizationResult: () -> Boolean = { lambdaError() } +) : BatteryOptimization { + override fun isIgnoringBatteryOptimizations(): Boolean { + return isIgnoringBatteryOptimizationsResult + } + + override fun requestDisablingBatteryOptimization(): Boolean { + return requestDisablingBatteryOptimizationResult() + } +} 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 2ba00156c7..5b93e90064 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 @@ -608,7 +608,32 @@ class DefaultNotifiableEventResolverTest { roomId = A_ROOM_ID, eventId = AN_EVENT_ID, editedEventId = null, - description = "Notification", + description = "You have new messages.", + canBeReplaced = true, + isRedacted = false, + isUpdated = false, + timestamp = A_FAKE_TIMESTAMP, + ) + ) + assertThat(result.getEvent(request)).isEqualTo(Result.success(expectedResult)) + } + + @Test + fun `resolve UnableToResolve`() = runTest { + val sut = createDefaultNotifiableEventResolver( + notificationResult = Result.success( + mapOf(AN_EVENT_ID to aNotificationData(content = NotificationContent.MessageLike.UnableToResolve)) + ) + ) + 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( + FallbackNotifiableEvent( + sessionId = A_SESSION_ID, + roomId = A_ROOM_ID, + eventId = AN_EVENT_ID, + editedEventId = null, + description = "You have new messages.", canBeReplaced = true, isRedacted = false, isUpdated = false, 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 933c830525..64a3b87aa7 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 @@ -86,7 +86,7 @@ class DefaultPushHandlerTest { fun `when classical PushData is received, the notification drawer is informed`() = runTest { val aNotifiableMessageEvent = aNotifiableMessageEvent() val notifiableEventResult = - lambdaRecorder, Result>>> { _, _, -> + lambdaRecorder, Result>>> { _, _ -> val request = NotificationEventRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, A_PUSHER_INFO) Result.success(mapOf(request to Result.success(ResolvedPushEvent.Event(aNotifiableMessageEvent)))) } @@ -268,11 +268,35 @@ class DefaultPushHandlerTest { } @Test - fun `when classical PushData is received, but not able to resolve the event, nothing happen`() = + fun `when classical PushData is received, but a failure occurs (session not found), nothing happen`() { + `test notification resolver failure`( + notificationResolveResult = { _ -> + Result.failure(ResolvingException("Unable to restore session")) + }, + shouldSetOptimizationBatteryBanner = false, + ) + } + + @Test + fun `when classical PushData is received, but not able to resolve the event, the banner to disable battery optimization will be displayed`() { + `test notification resolver failure`( + notificationResolveResult = { requests: List -> + Result.success( + requests.associateWith { Result.failure(ResolvingException("Unable to resolve event")) } + ) + }, + shouldSetOptimizationBatteryBanner = true, + ) + } + + private fun `test notification resolver failure`( + notificationResolveResult: (List) -> Result>>, + shouldSetOptimizationBatteryBanner: Boolean, + ) { runTest { val notifiableEventResult = - lambdaRecorder, Result>>> { _, _ -> - Result.failure(ResolvingException("Unable to resolve")) + lambdaRecorder, Result>>> { _, requests -> + notificationResolveResult(requests) } val onNotifiableEventsReceived = lambdaRecorder, Unit> {} val incrementPushCounterResult = lambdaRecorder {} @@ -286,6 +310,7 @@ class DefaultPushHandlerTest { val pushHistoryService = FakePushHistoryService( onPushReceivedResult = onPushReceivedResult, ) + val showBatteryOptimizationBannerResult = lambdaRecorder {} val defaultPushHandler = createDefaultPushHandler( onNotifiableEventsReceived = onNotifiableEventsReceived, notifiableEventsResult = notifiableEventResult, @@ -297,6 +322,9 @@ class DefaultPushHandlerTest { getUserIdFromSecretResult = { A_USER_ID } ), incrementPushCounterResult = incrementPushCounterResult, + mutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore( + showBatteryOptimizationBannerResult = showBatteryOptimizationBannerResult, + ), pushHistoryService = pushHistoryService, ) defaultPushHandler.handle(aPushData, A_PUSHER_INFO) @@ -313,7 +341,15 @@ class DefaultPushHandlerTest { onPushReceivedResult.assertions() .isCalledOnce() .with(any(), value(AN_EVENT_ID), value(A_ROOM_ID), value(A_USER_ID), value(false), value(true), any()) + showBatteryOptimizationBannerResult.assertions().let { + if (shouldSetOptimizationBatteryBanner) { + it.isCalledOnce() + } else { + it.isNeverCalled() + } + } } + } @Test fun `when ringing call PushData is received, the incoming call will be handled`() = runTest { @@ -542,7 +578,7 @@ class DefaultPushHandlerTest { fun `when receiving several push notifications at the same time, those are batched before being processed`() = runTest { val aNotifiableMessageEvent = aNotifiableMessageEvent() val notifiableEventResult = - lambdaRecorder, Result>>> { _, _, -> + lambdaRecorder, Result>>> { _, _ -> val request = NotificationEventRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, A_PUSHER_INFO) Result.success(mapOf(request to Result.success(ResolvedPushEvent.Event(aNotifiableMessageEvent)))) } @@ -595,8 +631,9 @@ class DefaultPushHandlerTest { onNotifiableEventsReceived: (List) -> Unit = { lambdaError() }, onRedactedEventsReceived: (List) -> Unit = { lambdaError() }, notifiableEventsResult: (SessionId, List) -> Result>> = - { _, _, -> lambdaError() }, + { _, _ -> lambdaError() }, incrementPushCounterResult: () -> Unit = { lambdaError() }, + mutableBatteryOptimizationStore: MutableBatteryOptimizationStore = FakeMutableBatteryOptimizationStore(), userPushStore: UserPushStore = FakeUserPushStore(), pushClientSecret: PushClientSecret = FakePushClientSecret(), buildMeta: BuildMeta = aBuildMeta(), @@ -614,6 +651,7 @@ class DefaultPushHandlerTest { incrementPushCounterResult() } }, + mutableBatteryOptimizationStore = mutableBatteryOptimizationStore, userPushStoreFactory = FakeUserPushStoreFactory { userPushStore }, pushClientSecret = pushClientSecret, buildMeta = buildMeta, diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/FakeMutableBatteryOptimizationStore.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/FakeMutableBatteryOptimizationStore.kt new file mode 100644 index 0000000000..d4d3992f1e --- /dev/null +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/FakeMutableBatteryOptimizationStore.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.push.impl.push + +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeMutableBatteryOptimizationStore( + private val showBatteryOptimizationBannerResult: () -> Unit = { lambdaError() }, + private val onOptimizationBannerDismissedResult: () -> Unit = { lambdaError() }, + private val resetResult: () -> Unit = { lambdaError() }, +) : MutableBatteryOptimizationStore { + override suspend fun showBatteryOptimizationBanner() { + showBatteryOptimizationBannerResult() + } + + override suspend fun onOptimizationBannerDismissed() { + onOptimizationBannerDismissedResult() + } + + override suspend fun reset() { + resetResult() + } +} diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/store/InMemoryPushDataStore.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/store/InMemoryPushDataStore.kt index 7ea038791b..41b0546f33 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/store/InMemoryPushDataStore.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/store/InMemoryPushDataStore.kt @@ -15,18 +15,26 @@ import kotlinx.coroutines.flow.asStateFlow class InMemoryPushDataStore( initialPushCounter: Int = 0, + initialShouldDisplayBatteryOptimizationBanner: Boolean = false, initialPushHistoryItems: List = emptyList(), private val resetResult: () -> Unit = { lambdaError() } ) : PushDataStore { private val mutablePushCounterFlow = MutableStateFlow(initialPushCounter) override val pushCounterFlow: Flow = mutablePushCounterFlow.asStateFlow() + private val mutableShouldDisplayBatteryOptimizationBannerFlow = MutableStateFlow(initialShouldDisplayBatteryOptimizationBanner) + override val shouldDisplayBatteryOptimizationBannerFlow: Flow = mutableShouldDisplayBatteryOptimizationBannerFlow.asStateFlow() + private val mutablePushHistoryItemsFlow = MutableStateFlow(initialPushHistoryItems) override fun getPushHistoryItemsFlow(): Flow> { return mutablePushHistoryItemsFlow.asStateFlow() } + suspend fun emitPushHistoryItems(items: List) { + mutablePushHistoryItemsFlow.emit(items) + } + override suspend fun reset() { resetResult() } diff --git a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt index 5c3c01e8e8..553ac09465 100644 --- a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt +++ b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt @@ -28,6 +28,7 @@ class FakePushService( private val selectPushProviderLambda: suspend (SessionId, PushProvider) -> Unit = { _, _ -> lambdaError() }, private val setIgnoreRegistrationErrorLambda: (SessionId, Boolean) -> Unit = { _, _ -> lambdaError() }, private val resetPushHistoryResult: () -> Unit = { lambdaError() }, + private val resetBatteryOptimizationStateResult: () -> Unit = { lambdaError() }, ) : PushService { override suspend fun getCurrentPushProvider(): PushProvider? { return registeredPushProvider ?: currentPushProvider() @@ -92,4 +93,8 @@ class FakePushService( override suspend fun resetPushHistory() = simulateLongTask { resetPushHistoryResult() } + + override suspend fun resetBatteryOptimizationState() { + resetBatteryOptimizationStateResult() + } } diff --git a/libraries/pushproviders/firebase/src/main/res/values-in/translations.xml b/libraries/pushproviders/firebase/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..0c1a98ae74 --- /dev/null +++ b/libraries/pushproviders/firebase/src/main/res/values-in/translations.xml @@ -0,0 +1,11 @@ + + + "Pastikan bahwa Firebase tersedia." + "Firebase tidak tersedia." + "Firebase tersedia." + "Periksa Firebase" + "Pastikan token Firebase tersedia." + "Token Firebase tidak diketahui." + "Token Firebase: %1$s." + "Periksa token Firebase" + diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt index 4b80ae42ff..8dc54dff8c 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushGatewayResolver.kt @@ -10,6 +10,7 @@ package io.element.android.libraries.pushproviders.unifiedpush import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.data.tryOrNull +import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.di.AppScope import kotlinx.coroutines.withContext import retrofit2.HttpException @@ -29,6 +30,8 @@ interface UnifiedPushGatewayResolver { suspend fun getGateway(endpoint: String): UnifiedPushGatewayResolverResult } +private val loggerTag = LoggerTag("DefaultUnifiedPushGatewayResolver") + @ContributesBinding(AppScope::class) class DefaultUnifiedPushGatewayResolver @Inject constructor( private val unifiedPushApiFactory: UnifiedPushApiFactory, @@ -36,36 +39,36 @@ class DefaultUnifiedPushGatewayResolver @Inject constructor( ) : UnifiedPushGatewayResolver { override suspend fun getGateway(endpoint: String): UnifiedPushGatewayResolverResult { val url = tryOrNull( - onException = { Timber.tag("DefaultUnifiedPushGatewayResolver").d(it, "Cannot parse endpoint as an URL") } + onException = { Timber.tag(loggerTag.value).d(it, "Cannot parse endpoint as an URL") } ) { URL(endpoint) } return if (url == null) { - Timber.tag("DefaultUnifiedPushGatewayResolver").d("ErrorInvalidUrl") + Timber.tag(loggerTag.value).d("ErrorInvalidUrl") UnifiedPushGatewayResolverResult.ErrorInvalidUrl } else { val port = if (url.port != -1) ":${url.port}" else "" val customBase = "${url.protocol}://${url.host}$port" val customUrl = "$customBase/_matrix/push/v1/notify" - Timber.tag("DefaultUnifiedPushGatewayResolver").i("Testing $customUrl") + Timber.tag(loggerTag.value).i("Testing $customUrl") return withContext(coroutineDispatchers.io) { val api = unifiedPushApiFactory.create(customBase) try { val discoveryResponse = api.discover() if (discoveryResponse.unifiedpush.gateway == "matrix") { - Timber.tag("DefaultUnifiedPushGatewayResolver").d("The endpoint seems to be a valid UnifiedPush gateway") + Timber.tag(loggerTag.value).d("The endpoint seems to be a valid UnifiedPush gateway") UnifiedPushGatewayResolverResult.Success(customUrl) } else { // The endpoint returned a 200 OK but didn't promote an actual matrix gateway, which means it doesn't have any - Timber.tag("DefaultUnifiedPushGatewayResolver").w("The endpoint does not seem to be a valid UnifiedPush gateway, using fallback") + Timber.tag(loggerTag.value).w("The endpoint does not seem to be a valid UnifiedPush gateway, using fallback") UnifiedPushGatewayResolverResult.NoMatrixGateway } } catch (throwable: Throwable) { if ((throwable as? HttpException)?.code() == HttpURLConnection.HTTP_NOT_FOUND) { - Timber.tag("DefaultUnifiedPushGatewayResolver").i("Checking for UnifiedPush endpoint yielded 404, using fallback") + Timber.tag(loggerTag.value).i("Checking for UnifiedPush endpoint yielded 404, using fallback") UnifiedPushGatewayResolverResult.NoMatrixGateway } else { - Timber.tag("DefaultUnifiedPushGatewayResolver").e(throwable, "Error checking for UnifiedPush endpoint") + Timber.tag(loggerTag.value).e(throwable, "Error checking for UnifiedPush endpoint") UnifiedPushGatewayResolverResult.Error(customUrl) } } diff --git a/libraries/pushproviders/unifiedpush/src/main/res/values-in/translations.xml b/libraries/pushproviders/unifiedpush/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..8190062b85 --- /dev/null +++ b/libraries/pushproviders/unifiedpush/src/main/res/values-in/translations.xml @@ -0,0 +1,9 @@ + + + "Pastikan distributor UnifiedPush tersedia." + "Tidak ada distributor notifikasi dorongan yang ditemukan." + + "%1$d distributor ditemukan: %2$s." + + "Periksa UnifiedPush" + diff --git a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt index 1f13346b3a..10769b9aec 100644 --- a/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt +++ b/libraries/roomselect/impl/src/main/kotlin/io/element/android/libraries/roomselect/impl/RoomSelectView.kt @@ -33,7 +33,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.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar +import io.element.android.libraries.designsystem.components.avatar.RoomAvatar 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 @@ -214,11 +214,12 @@ private fun RoomSummaryView( .heightIn(56.dp), verticalAlignment = Alignment.CenterVertically ) { - CompositeAvatar( + RoomAvatar( avatarData = roomInfo.getAvatarData(size = AvatarSize.RoomSelectRoomListItem), heroes = roomInfo.heroes.map { user -> user.getAvatarData(size = AvatarSize.RoomSelectRoomListItem) - }.toPersistentList() + }.toPersistentList(), + isTombstoned = roomInfo.isTombstoned, ) Column( modifier = Modifier diff --git a/libraries/testtags/src/main/kotlin/io/element/android/libraries/testtags/Compose.kt b/libraries/testtags/src/main/kotlin/io/element/android/libraries/testtags/Compose.kt index eacc2c1371..7f8700adb4 100644 --- a/libraries/testtags/src/main/kotlin/io/element/android/libraries/testtags/Compose.kt +++ b/libraries/testtags/src/main/kotlin/io/element/android/libraries/testtags/Compose.kt @@ -7,7 +7,6 @@ package io.element.android.libraries.testtags -import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTag @@ -16,7 +15,6 @@ import androidx.compose.ui.semantics.testTagsAsResourceId /** * Add a testTag to a Modifier, to be used by external tool, like TrafficLight for instance. */ -@OptIn(ExperimentalComposeUiApi::class) fun Modifier.testTag(id: TestTag) = semantics { testTag = id.value testTagsAsResourceId = true diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt index c90203b6ae..48ad19f812 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.size +import androidx.compose.foundation.selection.toggleable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ripple import androidx.compose.runtime.Composable @@ -21,6 +22,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons @@ -32,9 +35,10 @@ import io.element.android.libraries.designsystem.theme.iconSuccessPrimaryBackgro @Composable internal fun FormattingOption( state: FormattingOptionState, + toggleable: Boolean, onClick: () -> Unit, imageVector: ImageVector, - contentDescription: String?, + contentDescription: String, modifier: Modifier = Modifier, ) { val backgroundColor = when (state) { @@ -52,6 +56,7 @@ internal fun FormattingOption( modifier = modifier .clickable( onClick = onClick, + enabled = state != FormattingOptionState.Disabled, interactionSource = remember { MutableInteractionSource() }, indication = ripple( bounded = false, @@ -59,6 +64,20 @@ internal fun FormattingOption( ), ) .size(48.dp) + .then( + if (toggleable) { + Modifier.toggleable( + value = state == FormattingOptionState.Selected, + enabled = state != FormattingOptionState.Disabled, + onValueChange = { onClick() }, + ) + } else { + Modifier + } + ) + .clearAndSetSemantics { + this.contentDescription = contentDescription + } ) { Box( modifier = Modifier @@ -84,21 +103,24 @@ internal fun FormattingOptionPreview() = ElementPreview { Row { FormattingOption( state = FormattingOptionState.Default, + toggleable = false, onClick = { }, imageVector = CompoundIcons.Bold(), - contentDescription = null, + contentDescription = "", ) FormattingOption( state = FormattingOptionState.Selected, + toggleable = true, onClick = { }, imageVector = CompoundIcons.Italic(), - contentDescription = null, + contentDescription = "", ) FormattingOption( state = FormattingOptionState.Disabled, + toggleable = false, onClick = { }, imageVector = CompoundIcons.Underline(), - contentDescription = null, + contentDescription = "", ) } } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/TextFormatting.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/TextFormatting.kt index 911707022c..08c1bec23a 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/TextFormatting.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/TextFormatting.kt @@ -104,24 +104,28 @@ internal fun TextFormatting( ) { FormattingOption( state = state.actions[ComposerAction.BOLD].toButtonState(), + toggleable = true, onClick = { onInlineFormatClick(InlineFormat.Bold) }, imageVector = CompoundIcons.Bold(), contentDescription = stringResource(R.string.rich_text_editor_format_bold) ) FormattingOption( state = state.actions[ComposerAction.ITALIC].toButtonState(), + toggleable = true, onClick = { onInlineFormatClick(InlineFormat.Italic) }, imageVector = CompoundIcons.Italic(), contentDescription = stringResource(R.string.rich_text_editor_format_italic) ) FormattingOption( state = state.actions[ComposerAction.UNDERLINE].toButtonState(), + toggleable = true, onClick = { onInlineFormatClick(InlineFormat.Underline) }, imageVector = CompoundIcons.Underline(), contentDescription = stringResource(R.string.rich_text_editor_format_underline) ) FormattingOption( state = state.actions[ComposerAction.STRIKE_THROUGH].toButtonState(), + toggleable = true, onClick = { onInlineFormatClick(InlineFormat.StrikeThrough) }, imageVector = CompoundIcons.Strikethrough(), contentDescription = stringResource(R.string.rich_text_editor_format_strikethrough) @@ -141,6 +145,7 @@ internal fun TextFormatting( FormattingOption( state = state.actions[ComposerAction.LINK].toButtonState(), + toggleable = true, onClick = { linkDialogAction = state.linkAction }, imageVector = CompoundIcons.Link(), contentDescription = stringResource(R.string.rich_text_editor_link) @@ -148,42 +153,49 @@ internal fun TextFormatting( FormattingOption( state = state.actions[ComposerAction.UNORDERED_LIST].toButtonState(), + toggleable = true, onClick = { onToggleListClick(ordered = false) }, imageVector = CompoundIcons.ListBulleted(), contentDescription = stringResource(R.string.rich_text_editor_bullet_list) ) FormattingOption( state = state.actions[ComposerAction.ORDERED_LIST].toButtonState(), + toggleable = true, onClick = { onToggleListClick(ordered = true) }, imageVector = CompoundIcons.ListNumbered(), contentDescription = stringResource(R.string.rich_text_editor_numbered_list) ) FormattingOption( state = state.actions[ComposerAction.INDENT].toButtonState(), + toggleable = false, onClick = { onIndentClick() }, imageVector = CompoundIcons.IndentIncrease(), contentDescription = stringResource(R.string.rich_text_editor_indent) ) FormattingOption( state = state.actions[ComposerAction.UNINDENT].toButtonState(), + toggleable = false, onClick = { onUnindentClick() }, imageVector = CompoundIcons.IndentDecrease(), contentDescription = stringResource(R.string.rich_text_editor_unindent) ) FormattingOption( state = state.actions[ComposerAction.INLINE_CODE].toButtonState(), + toggleable = true, onClick = { onInlineFormatClick(InlineFormat.InlineCode) }, imageVector = CompoundIcons.InlineCode(), contentDescription = stringResource(R.string.rich_text_editor_inline_code) ) FormattingOption( state = state.actions[ComposerAction.CODE_BLOCK].toButtonState(), + toggleable = true, onClick = { onCodeBlockClick() }, imageVector = CompoundIcons.Code(), contentDescription = stringResource(R.string.rich_text_editor_code_block) ) FormattingOption( state = state.actions[ComposerAction.QUOTE].toButtonState(), + toggleable = true, onClick = { onQuoteClick() }, imageVector = CompoundIcons.Quote(), contentDescription = stringResource(R.string.rich_text_editor_quote) diff --git a/libraries/textcomposer/impl/src/main/res/values-cs/translations.xml b/libraries/textcomposer/impl/src/main/res/values-cs/translations.xml index 51c868112e..9693f64835 100644 --- a/libraries/textcomposer/impl/src/main/res/values-cs/translations.xml +++ b/libraries/textcomposer/impl/src/main/res/values-cs/translations.xml @@ -10,8 +10,12 @@ "Nešifrovaná zpráva…" "Vytvořit odkaz" "Upravit odkaz" + "%1$s, stav: %2$s" "Použít tučný text" "Použít kurzívu" + "zakázáno" + "VYP" + "ZAP" "Použít přeškrtnutí" "Použít podtržení" "Přepnout režim celé obrazovky" diff --git a/libraries/textcomposer/impl/src/main/res/values-es/translations.xml b/libraries/textcomposer/impl/src/main/res/values-es/translations.xml index 4102637763..2685733c3e 100644 --- a/libraries/textcomposer/impl/src/main/res/values-es/translations.xml +++ b/libraries/textcomposer/impl/src/main/res/values-es/translations.xml @@ -7,6 +7,7 @@ "Agregar una leyenda" "Mensaje cifrado…" "Mensaje…" + "Mensaje no cifrado…" "Crear un enlace" "Editar enlace" "Aplicar formato negrita" diff --git a/libraries/textcomposer/impl/src/main/res/values-fr/translations.xml b/libraries/textcomposer/impl/src/main/res/values-fr/translations.xml index 56f524e35f..82f646931c 100644 --- a/libraries/textcomposer/impl/src/main/res/values-fr/translations.xml +++ b/libraries/textcomposer/impl/src/main/res/values-fr/translations.xml @@ -10,8 +10,12 @@ "Message non chiffré…" "Créer un lien" "Modifier le lien" + "%1$s, état : %2$s" "Appliquer le format gras" "Appliquer le format italique" + "désactivé" + "désactivé" + "activé" "Appliquer le format barré" "Appliquer le format souligné" "Activer/désactiver le mode plein écran" diff --git a/libraries/textcomposer/impl/src/main/res/values-hu/translations.xml b/libraries/textcomposer/impl/src/main/res/values-hu/translations.xml index 28cfa42f12..cad42803fc 100644 --- a/libraries/textcomposer/impl/src/main/res/values-hu/translations.xml +++ b/libraries/textcomposer/impl/src/main/res/values-hu/translations.xml @@ -10,8 +10,12 @@ "Titkosítatlan üzenet…" "Hivatkozás létrehozása" "Hivatkozás szerkesztése" + "%1$s, állapot: %2$s" "Félkövér formátum alkalmazása" "Dőlt formátum alkalmazása" + "letiltva" + "ki" + "be" "Áthúzott formátum alkalmazása" "Aláhúzott formátum alkalmazása" "Teljes képernyős mód be/ki" diff --git a/libraries/textcomposer/impl/src/main/res/values-nb/translations.xml b/libraries/textcomposer/impl/src/main/res/values-nb/translations.xml index fab385b304..18a724a4b2 100644 --- a/libraries/textcomposer/impl/src/main/res/values-nb/translations.xml +++ b/libraries/textcomposer/impl/src/main/res/values-nb/translations.xml @@ -10,8 +10,12 @@ "Ukryptert melding…" "Opprett en lenke" "Rediger lenke" + "%1$s, tilstand: %2$s" "Bruk fet skrift" "Bruk kursivformat" + "deaktivert" + "av" + "på" "Bruke gjennomstrekingsformat" "Bruke understrekingsformat" "Veksle fullskjermmodus" diff --git a/libraries/textcomposer/impl/src/main/res/values/localazy.xml b/libraries/textcomposer/impl/src/main/res/values/localazy.xml index d79da4a10f..2be7a12577 100644 --- a/libraries/textcomposer/impl/src/main/res/values/localazy.xml +++ b/libraries/textcomposer/impl/src/main/res/values/localazy.xml @@ -10,8 +10,12 @@ "Unencrypted message…" "Create a link" "Edit link" + "%1$s, state: %2$s" "Apply bold format" "Apply italic format" + "disabled" + "off" + "on" "Apply strikethrough format" "Apply underline format" "Toggle full screen mode" diff --git a/libraries/troubleshoot/impl/src/main/res/values-es/translations.xml b/libraries/troubleshoot/impl/src/main/res/values-es/translations.xml index 0ce2686562..9a2e946c6e 100644 --- a/libraries/troubleshoot/impl/src/main/res/values-es/translations.xml +++ b/libraries/troubleshoot/impl/src/main/res/values-es/translations.xml @@ -1,5 +1,6 @@ + "Historial de notificaciones push" "Ejecutar pruebas" "Volver a ejecutar pruebas" "Algunas pruebas fallaron. Por favor, verifica los detalles." diff --git a/libraries/troubleshoot/impl/src/main/res/values-in/translations.xml b/libraries/troubleshoot/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..9863fa60e8 --- /dev/null +++ b/libraries/troubleshoot/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,11 @@ + + + "Jalankan tes" + "Jalankan tes lagi" + "Beberapa tes gagal. Silakan periksa detailnya." + "Jalankan pengujian untuk mendeteksi masalah apa pun dalam konfigurasi Anda yang mungkin membuat notifikasi tidak berperilaku seperti yang diharapkan." + "Mencoba untuk memperbaiki" + "Semua tes berhasil dilalui." + "Pecahkan masalah notifikasi" + "Beberapa tes membutuhkan perhatian Anda. Silakan periksa detailnya." + 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 6a3d4a861f..b4c26ab1e0 100644 --- a/libraries/ui-strings/src/main/res/values-cs/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cs/translations.xml @@ -140,6 +140,9 @@ "Zobrazit zdroj" "Ano" "Ano, zkusit znovu" + "Zakažte optimalizaci baterie pro tuto aplikaci, abyste měli jistotu, že budou přijata všechna oznámení." + "Zakázat optimalizaci" + "Nepřicházejí vám oznámení?" "Váš server nyní podporuje nový, rychlejší protokol. Chcete-li upgradovat, odhlaste se a znovu se přihlaste. Pokud to uděláte nyní, pomůže vám vyhnout se nucenému odhlášení, když bude starý protokol později odstraněn." "Upgrade k dispozici" "O aplikaci" @@ -338,6 +341,7 @@ Opravdu chcete pokračovat?" "Některé znaky nejsou povoleny. Podporovány jsou pouze písmena, číslice a následující symboly ! $ & ‘ ( ) * + / ; = ? @ [ ] - . _" "Některé zprávy nebyly odeslány" "Omlouváme se, došlo k chybě" + "Odesílatel události se neshoduje s vlastníkem zařízení, které ji odeslalo." "Autenticitu této zašifrované zprávy nelze na tomto zařízení zaručit." "Zašifrováno dříve ověřeným uživatelem." "Není zašifrováno." @@ -377,8 +381,13 @@ Opravdu chcete pokračovat?" "%1$s Připnuté zprávy" "Načítání zprávy…" "Zobrazit vše" + "Přejít do nové místnosti" + "Tato místnost byla nahrazena a již není aktivní" + "Zobrazit staré zprávy" + "Tato místnost je pokračováním jiné místnosti" "Chat" "Žádost o vstup odeslána" + "Tato místnost byla aktualizována" "Sdílet polohu" "Sdílet moji polohu" "Otevřít v Mapách Apple" 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 c6747aca86..52c1046030 100644 --- a/libraries/ui-strings/src/main/res/values-cy/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cy/translations.xml @@ -396,7 +396,6 @@ Ydych chi\'n siŵr eich bod am barhau?" "Wrthi\'n llwytho neges…" "Dangos y Cyfan" "Sgwrs" - "Anfonwyd y cais i ymuno" "Rhannu lleoliad" "Rhannu fy lleoliad" "Agor yn Apple Maps" 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 afcc1f784f..94f6dc40fc 100644 --- a/libraries/ui-strings/src/main/res/values-de/translations.xml +++ b/libraries/ui-strings/src/main/res/values-de/translations.xml @@ -372,7 +372,6 @@ Möchten Sie wirklich fortfahren?" "Nachricht wird geladen…" "Alle anzeigen" "Chat" - "Beitrittsanfrage geschickt" "Standort teilen" "Meinen Standort teilen" "In Apple Maps öffnen" 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 efadb6753d..795acf8c29 100644 --- a/libraries/ui-strings/src/main/res/values-el/translations.xml +++ b/libraries/ui-strings/src/main/res/values-el/translations.xml @@ -372,7 +372,6 @@ "Φόρτωση μηνύματος…" "Προβολή Όλων" "Συνομιλία" - "Το αίτημα συμμετοχής στάλθηκε" "Κοινή χρήση τοποθεσίας" "Κοινή χρήση της τοποθεσίας μου" "Άνοιγμα στο Apple Maps" 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 50fbc4479d..2b0c7b84d4 100644 --- a/libraries/ui-strings/src/main/res/values-es/translations.xml +++ b/libraries/ui-strings/src/main/res/values-es/translations.xml @@ -1,16 +1,19 @@ + "Avatar" "Borrar" "%1$d dígito introducido" "%1$d dígitos introducidos" "Ocultar contraseña" + "Unirse a la llamada" "Ir al final" "Sólo menciones" "Silenciado" "Página %1$d" "Pausar" + "Mensaje de voz, duración: %1$s, posición actual: %2$s" "Campo PIN" "Reproducir" "Encuesta" @@ -30,6 +33,7 @@ "Iniciar llamada" "Menú de usuario" "Mostrar detalles" + "Mensaje de voz, duración: %1$s" "Grabar mensaje de voz" "Detener grabación" "Aceptar" @@ -56,9 +60,11 @@ "Desactivar" "Desactivar cuenta" "Rechazar" + "Rechazar y bloquear" "Eliminar encuesta" "Desactivar" "Descartar" + "Descartar" "Hecho" "Editar" "Editar leyenda" @@ -100,8 +106,11 @@ "Eliminar mensaje" "Responder" "Responder en el hilo" + "Denunciar" "Informar de un error" - "Reportar contenido" + "Denunciar contenido" + "Denunciar conversación" + "Denunciar sala" "Restablecer" "Restablecer identidad" "Reintentar" @@ -125,7 +134,7 @@ "Toca para ver opciones" "Intentar de nuevo" "Desprender" - "Ver en la línea de tiempo" + "Ver en la cronología" "Ver fuente" "Sí" "Sí, intentar de nuevo" @@ -145,7 +154,9 @@ "Copiado al portapapeles" "Derechos de autor" "Creando sala…" + "Solicitud cancelada" "Saliste de la sala" + "Invitación rechazada" "Oscuro" "Error de descifrado" "Opciones de desarrollador" @@ -158,6 +169,7 @@ "Edición" "Editando leyenda" "* %1$s %2$s" + "Archivo vacío" "Cifrado" "Cifrado activado" "Introduce tu PIN" @@ -180,8 +192,9 @@ Motivo: %1$s." "En respuesta a %1$s" "Instalar APK" "No se encontró este ID de Matrix, por lo que es posible que no se reciba la invitación." - "Abandonando la sala" + "Saliendo de la sala" "Claro" + "Línea copiada al portapapeles" "Enlace copiado al portapapeles" "Cargando…" "Cargando más…" @@ -202,6 +215,7 @@ Motivo: %1$s." "%1$s (%2$s)" "No hay resultados" "Sala sin nombre" + "No cifrado" "Sin conexión" "Licencias de código abierto" "o" @@ -210,6 +224,7 @@ Motivo: %1$s." "Enlace permanente" "Permiso" "Fijado" + "Comprueba tu conexión a Internet" "Espera, por favor…" "¿Estás seguro de que quieres finalizar esta encuesta?" "Encuesta: %1$s" @@ -222,6 +237,7 @@ Motivo: %1$s." "Política de privacidad" "Reacción" "Reacciones" + "Motivo" "Clave de recuperación" "Recargando…" "Respondiendo a %1$s" @@ -249,6 +265,7 @@ Motivo: %1$s." "Ubicación compartida" "Cerrando sesión" "Algo salió mal" + "Hemos encontrado un problema. Inténtalo de nuevo." "Iniciando chat…" "Sticker" "Terminado" @@ -263,7 +280,7 @@ Motivo: %1$s." "No se puede descifrar" "Enviado desde un dispositivo no seguro" "No tienes acceso a este mensaje" - "La identidad verificada del remitente ha cambiado" + "Se restableció la identidad verificada del remitente" "Las invitaciones no se pudieron enviar a uno o más usuarios." "No se pudo enviar la(s) invitación(es)" "Desbloquear" @@ -283,12 +300,18 @@ Motivo: %1$s." "Esperando…" "Esperando este mensaje" "Tú" - "La identidad de %1$s parece haber cambiado. %2$s" - "La identidad %2$s de %1$s parece haber cambiado. %3$s" + "Se restableció la identidad de %1$s. %2$s" + "Se restableció la identidad de %1$s %2$s. %3$s" "(%1$s)" - "La identidad verificada de %1$s ha cambiado." - "La identidad verificada %2$s de %1$s ha cambiado. %3$s" + "Se restableció la identidad de %1$s." + "Se restableció la identidad de %1$s %2$s. %3$s" "Retirar la verificación" + "El enlace %1$s te está llevando a otro sitio %2$s + +¿Estás seguro de que quieres continuar?" + "Revisa este enlace" + "Sala denunciada" + "Denunciaste y saliste de la sala" "Confirmar" "Error" "Terminado" @@ -335,7 +358,7 @@ Motivo: %1$s." "¿No puedes confirmar? Ve a tu cuenta para restablecer tu identidad." "Retirar la verificación y enviar" "Puedes retirar tu verificación y enviar este mensaje de todos modos, o puedes cancelarlo por ahora e intentarlo de nuevo más tarde después de volver a verificar a %1$s." - "Tu mensaje no se envió porque la identidad verificada de %1$s ha cambiado" + "Tu mensaje no se envió porque la identidad verificada de %1$s fue restablecida" "Enviar mensaje de todos modos" "%1$s utiliza uno o más dispositivos no verificados. Puedes enviar el mensaje de todos modos, o puedes cancelarlo por ahora y volver a intentarlo más tarde, una vez %2$s haya verificado todos sus dispositivos." "Tu mensaje no se envió porque %1$s no ha verificado todos los dispositivos" @@ -349,14 +372,13 @@ Motivo: %1$s." "Cargando mensaje…" "Ver todos" "Chat" - "Solicitud de unión enviada" "Compartir ubicación" "Compartir mi ubicación" "Abrir en Apple Maps" "Abrir en Google Maps" "Abrir en OpenStreetMap" "Compartir esta ubicación" - "Mensaje no enviado porque la identidad verificada de %1$s ha cambiado." + "Mensaje no enviado porque la identidad verificada de %1$s fue restablecida." "Mensaje no enviado porque %1$s no ha verificado todos los dispositivos." "Mensaje no enviado porque no has verificado uno o más de tus dispositivos." "Ubicación" 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 9547e7663a..1ed332da5f 100644 --- a/libraries/ui-strings/src/main/res/values-et/translations.xml +++ b/libraries/ui-strings/src/main/res/values-et/translations.xml @@ -371,8 +371,13 @@ Kas sa oled kindel, et soovid jätkata?" "%1$s esiletõstetud sõnumit" "Laadime sõnumit…" "Näita kõiki" + "Hüppa uude jututuppa" + "See jututuba on asendatud uuega ning pole enam aktiivne" + "Vaata vanu sõnumeid" + "See jututuba on varasema jututoa jätk" "Vestlus" "Liitumispalve on saadetud" + "See jututuba on uuendatud" "Jaga asukohta" "Jaga minu asukohta" "Ava Apple Mapsis" 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 c3c2c12a1c..f3bbd83167 100644 --- a/libraries/ui-strings/src/main/res/values-eu/translations.xml +++ b/libraries/ui-strings/src/main/res/values-eu/translations.xml @@ -330,7 +330,6 @@ Arrazoia: %1$s." "Mezua kargatzen…" "Ikusi guztia" "Txata" - "Sartzeko eskaera bidali da" "Partekatu kokapena" "Partekatu nire kokapena" "Ireki Apple Maps-en" 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 4fb5ceea2d..a6cc73c1f6 100644 --- a/libraries/ui-strings/src/main/res/values-fa/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fa/translations.xml @@ -323,7 +323,6 @@ "بار کردن پشام‌ها…" "نمایش همه" "گپ" - "درخواست پیوستن فرستاده شد" "هم‌رسانی موقعیت" "هم‌رسانی مکانم" "گشودن در نقشه‌های اپل" 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 4c3be6c5c3..aba5d6756e 100644 --- a/libraries/ui-strings/src/main/res/values-fi/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fi/translations.xml @@ -371,8 +371,13 @@ Haluatko varmasti jatkaa?" "Kiinnitetty viesti %1$s" "Viestiä ladataan…" "Näytä kaikki" + "Siirry uuteen huoneeseen" + "Tämä huone on korvattu, eikä se ole enää aktiivinen" + "Katso vanhoja viestejä" + "Tämä huone on jatkoa toiselle huoneelle" "Keskustelu" "Liittymispyyntö lähetetty" + "Tämä huone on päivitetty" "Jaa sijainti" "Jaa sijaintini" "Avaa Apple Mapsissa" diff --git a/libraries/ui-strings/src/main/res/values-fr/translations.xml b/libraries/ui-strings/src/main/res/values-fr/translations.xml index d15958d55a..154710c593 100644 --- a/libraries/ui-strings/src/main/res/values-fr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fr/translations.xml @@ -138,12 +138,16 @@ "Afficher la source" "Oui" "Oui, réessayez" + "Désactivez l’optimisation de la batterie pour cette application afin de vous assurer que toutes les notifications sont reçues." + "Désactiver l’optimisation" + "Ils vous manque des notifications?" "Votre serveur prend désormais en charge un nouveau protocole plus rapide. Déconnectez-vous, puis reconnectez-vous pour effectuer la mise à niveau dès maintenant. En le faisant tout de suite, vous éviterez une déconnexion forcée lorsque l’ancien protocole sera supprimé." "Mise à niveau disponible" "À propos" "Politique d’utilisation acceptable" "Ajout d’une légende" "Paramètres avancés" + "une image" "Statistiques d’utilisation" "Apparence" "Audio" @@ -259,6 +263,7 @@ Raison : %1$s." "Envoi en cours…" "Échec de l’envoi" "Envoyé" + ". " "Serveur non pris en charge" "URL du serveur" "Paramètres" @@ -333,6 +338,7 @@ Raison : %1$s." "Certains caractères ne sont pas autorisés. Seuls les lettres, les chiffres et les symboles suivants sont utilisables ! $ & ‘ ( ) * + / ; = ? @ [ ] - . _" "Certains messages n’ont pas été envoyés" "Désolé, une erreur s’est produite" + "L’expéditeur de ce message ne correspond pas au propriétaire de l’appareil qui l’a envoyé." "L’authenticité de ce message chiffré ne peut être garantie sur cet appareil." "Chiffré par un utilisateur précédemment vérifié." "Non chiffré." @@ -371,8 +377,13 @@ Raison : %1$s." "%1$s Messages épinglés" "Chargement du message…" "Voir tout" + "Aller dans le nouveau salon" + "Ce salon a été remplacé et n’est plus actif" + "Voir les anciens messages" + "Ce salon est la continuation du salon précédent" "Discussion" "Demande de rejoindre le salon envoyée" + "Ce salon a été mis à niveau." "Partage de position" "Partager ma position" "Ouvrir dans Apple Maps" 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 ab14bca3b7..a58cb9db00 100644 --- a/libraries/ui-strings/src/main/res/values-hu/translations.xml +++ b/libraries/ui-strings/src/main/res/values-hu/translations.xml @@ -138,6 +138,9 @@ "Forrás megtekintése" "Igen" "Igen, újrapróbálkozás" + "Kapcsolja ki az alkalmazás akkumulátor-optimalizálását, hogy biztosan megkapja az összes értesítést." + "Optimalizálás letiltása" + "Nem érkeznek meg az értesítések?" "A kiszolgálója mostantól egy új, gyorsabb protokollt támogat. A frissítéshez jelentkezzen ki, majd jelentkezzen be újra. Ha ezt most megteszi, elkerülheti a kényszerített kijelentkeztetést a régi protokollt eltávolításakor." "Frissítés érhető el" "Névjegy" @@ -333,6 +336,7 @@ Biztos, hogy folytatja?" "Egyes karakterek nem engedélyezettek. Csak a betűk, a számjegyek és a következő szimbólumok támogatottak: $ & \'() * +/; =? @ [] - . _" "Néhány üzenet nem került elküldésre" "Elnézést, hiba történt" + "Az esemény feladója nem egyezik az eseményt küldő eszköz tulajdonosával." "A titkosított üzenetek valódiságát ezen az eszközön nem lehet garantálni." "Egy korábban ellenőrzött felhasználó által titkosítva." "Nincs titkosítva." @@ -371,8 +375,13 @@ Biztos, hogy folytatja?" "%1$s kitűzött üzenet" "Üzenet betöltése…" "Összes megtekintése" + "Ugrás az új szobába" + "Ezt a szobát lecserélték, és már nem aktív." + "Régi üzenetek megtekintése" + "Ez a szoba egy másik szoba folytatása" "Csevegés" "Csatlakozási kérés elküldve" + "A szoba verzióját frissítették" "Hely megosztása" "Saját hely megosztása" "Megnyitás az Apple Mapsben" 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 722bf149ac..c27f8ef33b 100644 --- a/libraries/ui-strings/src/main/res/values-in/translations.xml +++ b/libraries/ui-strings/src/main/res/values-in/translations.xml @@ -334,7 +334,6 @@ Alasan: %1$s." "Memuat pesan…" "Lihat Semua" "Obrolan" - "Permintaan untuk bergabung dikirim" "Bagikan lokasi" "Bagikan lokasi saya" "Buka di Apple Maps" 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 c78465247f..4f4446050b 100644 --- a/libraries/ui-strings/src/main/res/values-it/translations.xml +++ b/libraries/ui-strings/src/main/res/values-it/translations.xml @@ -359,7 +359,6 @@ Sei sicuro di voler continuare?" "Caricamento messaggio…" "Mostra tutti" "Conversazione" - "Richiesta di accesso inviata" "Condividi posizione" "Condividi la mia posizione" "Apri in Apple Maps" 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 573107cc01..5536fb3a7e 100644 --- a/libraries/ui-strings/src/main/res/values-nb/translations.xml +++ b/libraries/ui-strings/src/main/res/values-nb/translations.xml @@ -73,7 +73,7 @@ "Avslutt avstemning" "Skriv inn PIN-koden" "Glemt passordet?" - "Fremover" + "Videresend" "Gå tilbake" "Ignorer" "Inviter" @@ -138,12 +138,16 @@ "Vis kilde" "Ja" "Ja, prøv igjen" + "Deaktiver batterioptimalisering for denne appen for å sikre at alle varsler mottas." + "Deaktiver optimalisering" + "Kommer ikke varslene frem?" "Serveren din støtter nå en ny, raskere protokoll. Logg ut og logg inn igjen for å oppgradere nå. Ved å gjøre dette nå, unngår du å bli tvunget til å logge ut når den gamle protokollen fjernes senere." "Oppgradering tilgjengelig" "Om" "Retningslinjer for akseptabel bruk" "Legger til bildetekst" "Avanserte innstillinger" + "et bilde" "Analyse" "Utseende" "Lyd" @@ -333,6 +337,7 @@ Er du sikker på at du vil fortsette?" "Noen tegn er ikke tillatt. Bare bokstaver, sifre og følgende symboler støttes! $ & \'() * +/; =? @ [] - . _" "Noen meldinger er ikke sendt" "Beklager, det oppstod en feil" + "Avsenderen av hendelsen samsvarer ikke med eieren av enheten som sendte den." "Ektheten til denne krypterte meldingen kan ikke garanteres på denne enheten." "Kryptert av en tidligere verifisert bruker." "Ikke kryptert." @@ -343,6 +348,10 @@ Er du sikker på at du vil fortsette?" "Hei, snakk med meg på %1$s: %2$s" "%1$s Android" "Rageshake for å rapportere feil" + "%1$s: %2$s" + "Alternativer" + "Fjern %1$s" + "Innstillinger" "Kunne ikke velge medium, prøv igjen." "Teksting er kanskje ikke synlig for personer som bruker eldre apper." "Kunne ikke behandle medier for opplasting, vennligst prøv igjen." @@ -371,8 +380,13 @@ Er du sikker på at du vil fortsette?" "%1$s Festede meldinger" "Laster inn melding…" "Vis alle" + "Gå til nytt rom" + "Dette rommet har blitt erstattet og er ikke lenger aktivt" + "Se gamle meldinger" + "Dette rommet er en fortsettelse av et annet rom" "Chat" "Forespørsel om å bli med sendt" + "Dette rommet har blitt oppgradert" "Del lokasjon" "Del min lokasjon" "Åpne i Apple Maps" 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 1066ee7e79..fcb11918db 100644 --- a/libraries/ui-strings/src/main/res/values-nl/translations.xml +++ b/libraries/ui-strings/src/main/res/values-nl/translations.xml @@ -323,7 +323,6 @@ Reden: %1$s." "Bericht laden…" "Bekijk alles" "Chat" - "Verzoek om toe te treden verzonden" "Locatie delen" "Deel mijn locatie" "Openen in Apple Maps" 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 76b3177b6a..bb8e162f30 100644 --- a/libraries/ui-strings/src/main/res/values-pl/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pl/translations.xml @@ -378,7 +378,6 @@ Czy na pewno chcesz kontynuować?" "Wczytywanie wiadomości…" "Wyświetl wszystkie" "Czat" - "Wysłano prośbę o dołączenie" "Udostępnij lokalizację" "Udostępnij moją lokalizację" "Otwórz w Apple Maps" 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 d8fddecca2..f5952be07e 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 @@ -372,7 +372,6 @@ Você tem certeza de que deseja continuar?" "Carregando mensagem…" "Ver tudo" "Bate-papo" - "Pedido de adesão enviado" "Compartilhar localização" "Compartilhar minha localização" "Abrir no Apple Maps" 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 d8931a4a99..721755f9f1 100644 --- a/libraries/ui-strings/src/main/res/values-pt/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pt/translations.xml @@ -372,7 +372,6 @@ Tens a certeza de que queres continuar?" "A carregar mensagem…" "Ver todas" "Conversa" - "Pedido de adesão enviado" "Partilhar localização" "Partilhar a minha localização" "Abrir no Apple Maps" 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 76771a4c9f..aad4fc5981 100644 --- a/libraries/ui-strings/src/main/res/values-ro/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ro/translations.xml @@ -327,7 +327,6 @@ Motiv:%1$s." "Se încarcă mesajul…" "Vedeți toate" "Chat" - "Cererea de alăturare a fost trimisă" "Partajați locația" "Distribuiți locația mea" "Deschideți în Apple Maps" 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 67a9e3b03a..7d2f9ba66a 100644 --- a/libraries/ui-strings/src/main/res/values-ru/translations.xml +++ b/libraries/ui-strings/src/main/res/values-ru/translations.xml @@ -308,7 +308,7 @@ "Идентификатор %1$s изменился. %2$s" "Пользователь %1$s сменил имя пользователя на %2$s. %3$s" "(%1$s)" - "Проверенная личность пользователя %1$s изменилась." + "%1$s была сброшена." "%1$s’s %2$s подтвержденная личность изменилась. %3$s" "Вывод верификации" "Ссылка %1$s ведет вас на другой сайт %2$s @@ -364,7 +364,7 @@ "Не можете подтвердить? Перейдите в свою учетную запись, чтобы сбросить свою идентификацию." "Отозвать статус и отправить" "Вы можете либо отозвать свой статус подтверждения и всё равно отправить это сообщение, либо отменить его сейчас и повторить попытку после повторного подтверждения %1$s." - "Ваше сообщение не было отправлено, потому что изменилась подтвержденная личность %1$s" + "Ваше сообщение не было отправлено, потому что подтвержденная личность %1$s была сброшена" "Отправь сообщение в любом случае" "%1$s использует одно или несколько непроверенных устройств. Вы все равно можете отправить сообщение или отменить его пока и повторить попытку позже %2$s, проверив все устройства пользователя." "Ваше сообщение не было отправлено, потому что %1$s не проверил одно или несколько устройств" @@ -377,15 +377,20 @@ "%1$s Закрепленные сообщения" "Загрузка сообщения…" "Посмотреть все" + "Перейти в новую комнату" + "Эта комната была заменена и больше не активна" + "Посмотреть старые сообщения" + "Эта комната является продолжением другой комнаты" "Чат" "Запрос на присоединение отправлен" + "Эта комната была обновлена" "Поделиться местоположением" "Поделиться моим местоположением" "Открыть в Apple Maps" "Открыть в Google Maps" "Открыть в OpenStreetMap" "Поделиться этим местоположением" - "Сообщение не отправлено, потому что верифицированная личность %1$s изменилась." + "Сообщение не отправлено, потому что подтвержденная личность %1$s была сброшена." "Сообщение не отправлено, потому что %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 fa2ccf4b58..14dea09167 100644 --- a/libraries/ui-strings/src/main/res/values-sk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sk/translations.xml @@ -378,7 +378,6 @@ Naozaj chcete pokračovať?" "Načítava sa správa…" "Zobraziť všetko" "Konverzácia" - "Žiadosť o pripojenie bola odoslaná" "Zdieľať polohu" "Zdieľať moju polohu" "Otvoriť v Apple Maps" 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 2733eed812..aa8b4e231e 100644 --- a/libraries/ui-strings/src/main/res/values-sv/translations.xml +++ b/libraries/ui-strings/src/main/res/values-sv/translations.xml @@ -371,8 +371,13 @@ Anledning:%1$s." "%1$s Fästa meddelanden" "Laddar meddelande …" "Visa alla" + "Hoppa till nytt rum" + "Det här rummet har ersatts och är inte längre aktivt" + "Se gamla meddelanden" + "Det här rummet är en fortsättning på ett annat rum" "Chatt" "Begäran om att gå med skickad" + "Det här rummet har uppgraderats" "Dela plats" "Dela min plats" "Öppna i Apple Maps" 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 40bb3fe7e4..fee4cbe5dd 100644 --- a/libraries/ui-strings/src/main/res/values-tr/translations.xml +++ b/libraries/ui-strings/src/main/res/values-tr/translations.xml @@ -348,7 +348,6 @@ Neden: %1$s." "Mesaj yükleniyor…" "Tümünü görüntüle" "Sohbet" - "Katılma isteği gönderildi" "Konum paylaş" "Konumumu paylaş" "Apple Maps\'de aç" 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 b317dd24d4..985a951d93 100644 --- a/libraries/ui-strings/src/main/res/values-uk/translations.xml +++ b/libraries/ui-strings/src/main/res/values-uk/translations.xml @@ -378,7 +378,6 @@ "Завантаження повідомлення…" "Переглянути всі" "Бесіда" - "Запит на приєднання надіслано" "Поділитися розташуванням" "Поділитися моїм розташуванням" "Відкрити в Apple Maps" 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 2f15a5ccd8..f2498383d7 100644 --- a/libraries/ui-strings/src/main/res/values-uz/translations.xml +++ b/libraries/ui-strings/src/main/res/values-uz/translations.xml @@ -1,5 +1,6 @@ + "Avatar" "Oʻchirish" "Parolni yashirish" "Faqat eslatmalar" 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 835b89bc19..f83e689b17 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 @@ -366,7 +366,6 @@ "正在載入訊息……" "檢視全部" "聊天" - "已傳送加入請求" "分享位置" "分享我的位置" "在 Apple Maps 中開啟" 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 c43a8bf1da..c5a29e7f61 100644 --- a/libraries/ui-strings/src/main/res/values-zh/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh/translations.xml @@ -357,7 +357,6 @@ "正在加载消息…" "查看全部" "聊天" - "加入请求已发送" "分享位置" "分享我的位置" "在 Apple Maps 中打开" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 1548788ce4..323b762a43 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -138,12 +138,16 @@ "View source" "Yes" "Yes, try again" + "Disable battery optimization for this app, to make sure all notifications are received." + "Disable optimization" + "Notifications not arriving?" "Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later." "Upgrade available" "About" "Acceptable use policy" "Adding caption" "Advanced settings" + "an image" "Analytics" "Appearance" "Audio" @@ -240,6 +244,10 @@ Reason: %1$s." "Reason" "Recovery key" "Refreshing…" + + "%1$d reply" + "%1$d replies" + "Replying to %1$s" "Report a bug" "Report a problem" @@ -259,6 +267,7 @@ Reason: %1$s." "Sending…" "Sending failed" "Sent" + ". " "Server not supported" "Server URL" "Settings" @@ -333,6 +342,7 @@ Are you sure you want to continue?" "Some characters are not allowed. Only letters, digits and the following symbols are supported ! $ & ‘ ( ) * + / ; = ? @ [ ] - . _" "Some messages have not been sent" "Sorry, an error occurred" + "The sender of the event does not match the owner of the device that sent it." "The authenticity of this encrypted message can\'t be guaranteed on this device." "Encrypted by a previously-verified user." "Not encrypted." @@ -343,6 +353,10 @@ Are you sure you want to continue?" "Hey, talk to me on %1$s: %2$s" "%1$s Android" "Rageshake to report bug" + "%1$s: %2$s" + "Options" + "Remove %1$s" + "Settings" "Failed selecting media, please try again." "Captions might not be visible to people using older apps." "Failed processing media to upload, please try again." @@ -367,12 +381,18 @@ Are you sure you want to continue?" "Failed processing media to upload, please try again." "Could not retrieve user details" "Message in %1$s" + "Already viewing this room!" "%1$s of %2$s" "%1$s Pinned messages" "Loading message…" "View All" + "Jump to new room" + "This room has been replaced and is no longer active" + "See old messages" + "This room is a continuation of another room" "Chat" "Request to join sent" + "This room has been upgraded" "Share location" "Share my location" "Open in Apple Maps" diff --git a/plugins/src/main/kotlin/Versions.kt b/plugins/src/main/kotlin/Versions.kt index ef5abdf881..fa05b0780a 100644 --- a/plugins/src/main/kotlin/Versions.kt +++ b/plugins/src/main/kotlin/Versions.kt @@ -32,7 +32,7 @@ private const val versionYear = 25 private const val versionMonth = 6 // Note: must be in [0,99] -private const val versionReleaseNumber = 2 +private const val versionReleaseNumber = 3 object Versions { const val VERSION_CODE = (2000 + versionYear) * 10_000 + versionMonth * 100 + versionReleaseNumber diff --git a/screenshots/de/features.analytics.impl_AnalyticsOptInView_Day_0_de.png b/screenshots/de/features.analytics.impl_AnalyticsOptInView_Day_0_de.png index 7f499e1a1f..222d7385b2 100644 --- a/screenshots/de/features.analytics.impl_AnalyticsOptInView_Day_0_de.png +++ b/screenshots/de/features.analytics.impl_AnalyticsOptInView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68d4a226ac51845b139f18e51bba0dfc2b9a6bd713a8cb72d379eb9ea9b72818 -size 84909 +oid sha256:b6b99f8f732aacb6a77bf856bbb5e23fb1478bf7ce90eafef9e7ba7b67da215f +size 86774 diff --git a/screenshots/de/features.analytics.impl_AnalyticsOptInView_Day_1_de.png b/screenshots/de/features.analytics.impl_AnalyticsOptInView_Day_1_de.png index 800f0f03bf..9aff4b7a4a 100644 --- a/screenshots/de/features.analytics.impl_AnalyticsOptInView_Day_1_de.png +++ b/screenshots/de/features.analytics.impl_AnalyticsOptInView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60cd358c1a76e51a9b4b9a7580a758519aa03618e0f13e3cf6ded80e433a3d1a -size 84184 +oid sha256:11155727ceed9e3c6f22b149d90dd92b58af5e4be729e6920e7071d9f9734530 +size 84388 diff --git a/screenshots/de/features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_de.png b/screenshots/de/features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_de.png new file mode 100644 index 0000000000..3b7e11cf70 --- /dev/null +++ b/screenshots/de/features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b5cab99263ef7a2ca101b3292221ce1c04f2f0e3a4e96b59cdcd0060bf5f613 +size 25598 diff --git a/screenshots/de/features.ftue.impl.notifications_NotificationsOptInView_Day_0_de.png b/screenshots/de/features.ftue.impl.notifications_NotificationsOptInView_Day_0_de.png index 6caf3c9a0f..6b0618101f 100644 --- a/screenshots/de/features.ftue.impl.notifications_NotificationsOptInView_Day_0_de.png +++ b/screenshots/de/features.ftue.impl.notifications_NotificationsOptInView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cbc979b60abb037029d820842169a8c441ab70ed3332c5103bd9b348c2b70d1f -size 70501 +oid sha256:bea6b7dc353227e8954d60ac072e29cc3321883f4a59fff6d1506a810232726e +size 71375 diff --git a/screenshots/de/features.joinroom.impl_JoinRoomView_Day_13_de.png b/screenshots/de/features.joinroom.impl_JoinRoomView_Day_13_de.png index c77391fe87..ddd6ccd07a 100644 --- a/screenshots/de/features.joinroom.impl_JoinRoomView_Day_13_de.png +++ b/screenshots/de/features.joinroom.impl_JoinRoomView_Day_13_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e2f99bc7839aae2d19d389cc642405e4bc8475b2ccb771540e7182576d986160 -size 33413 +oid sha256:7502335594b906de16b65eab01e5b53ddb88cedd6429ae9b60355552041a1893 +size 33348 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 3c692a69bb..1acc22f4aa 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:9e92456cb9af2df38afb714417227008e7d20038cb265b4b4693abf028371c55 -size 14675 +oid sha256:1551c365ef7522b0ee850f2064585b86c047cce8a28337739d09e71b2458852a +size 14502 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 258af19174..f3cccea8c7 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:4627a0d09d046b1277036329ef6dbfeac3e4d25f90439ab2dab0f50dc44ae855 -size 19452 +oid sha256:7c18bb43dea68bded70fe2fe21f2f14140b49106ccbbf988c06506a84e1aa6ba +size 19265 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 c85ffd8d44..2abaefddfb 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:31fa1df9955825deaf920cd23d3d17d3861e461d5b9cdb3d8f21673886bcb938 -size 30652 +oid sha256:25b5b715c1fc4cc67152c6b29e90fbf718eea81c1b75550292a5a4297d8a9449 +size 30479 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 356494b08c..65d6ddcfa6 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:3b3b589020f23cfba6d50094e54beca90f8d407e256962cc0d8fb136e7a1a14a -size 39233 +oid sha256:2ef41a8c3b3e672299f77eb236f2dd335d26399bb58842788813b90824d6860a +size 39081 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 59b4cf56ff..b2d0ff9590 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:5a9fca64040da057e303f4c9da0c19c52a0cb9ffc4bf1e29d2b0e8f151322e96 -size 34494 +oid sha256:22df7ef05574f86e7090b91fa2b74103a778aed7029f262f57d54e9d6a886647 +size 34350 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 a80ddaa421..f183602a07 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:b2a9305f6faaf67eaac59f762e21c77070fbb572561df1cf92ec8d6bca0d0dce -size 151343 +oid sha256:cb8a3fad1817764b52e0db7c3f5c6b7e103438928399f4344713272a53374662 +size 364750 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 94127b5426..6cedac977c 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:8032ef23e046995a32eb8ac61a735fc0960da6b4904464c3dee027c3bd1b4f9b -size 157194 +oid sha256:51df75495180e7665befca85e0e986d26481660cf6f6f6e1cc95b4caecd36955 +size 370225 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 8c2d51c040..951b754bfd 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:0e7beb51d718e2a5e0532fbe8d6e2118f50e742194366da48df3dba6d6545d72 -size 150535 +oid sha256:84f9227018c9ece9ca911e33b50073f3674cf5c3d2473b109b35c8e3af597fce +size 363930 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 5c9e4cd489..4e388fe750 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:d40a925f1672f1c1c6287b9b9b16c34564a5c40d56a28135fa84e1fec748e39b -size 152711 +oid sha256:fdc57799e07bcddd56f9edde75113bc4cffa1ba8c02370ae3fe0d07b1106da51 +size 365987 diff --git a/screenshots/de/features.messages.impl_MessagesView_Day_6_de.png b/screenshots/de/features.messages.impl_MessagesView_Day_6_de.png index ff5440ae92..60f44fd73a 100644 --- a/screenshots/de/features.messages.impl_MessagesView_Day_6_de.png +++ b/screenshots/de/features.messages.impl_MessagesView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa561a80f58818de91d0daa8fdb5b5324b1b94de7f2dc61d4568b51825142d93 -size 54183 +oid sha256:cb29742520c9662f7eee364c28129f4f76ae5ab8fd9ce02dbf657a3429a3e7aa +size 51530 diff --git a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_0_de.png b/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_0_de.png deleted file mode 100644 index 6f4be1aa17..0000000000 --- a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_0_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:efb039797d56b8a0caba770235a618793ec505702981a1c608237fd7bf582f49 -size 18155 diff --git a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_1_de.png b/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_1_de.png deleted file mode 100644 index cc9557a270..0000000000 --- a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_1_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:00c631e0245b249bef9533f3904441acd1279ee23f5ae0d930283d22035f8f53 -size 22738 diff --git a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_2_de.png b/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_2_de.png deleted file mode 100644 index cd7a349d51..0000000000 --- a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_2_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ea5a3696b6d8eaa5674b417944d9110cc85a0e37dd223d0495b259caf414ffec -size 28416 diff --git a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_8_de.png b/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_8_de.png deleted file mode 100644 index e15d3745bb..0000000000 --- a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_8_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cc604387773fc50481303c325a57813f354ea14724a2f0ea2d46f059ef9e5204 -size 9294 diff --git a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_9_de.png b/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_9_de.png deleted file mode 100644 index 9fc16502c1..0000000000 --- a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_9_de.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:909d70e02e2d76ff69bdbea2f98d891e0bd0257e883aaa7df5a45c2ddde4707b -size 28074 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 index 305047698a..2b58644d33 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:060b934a586c09671d8d9a8cf836f509cc69119b458a7ab11be295374c3de9a5 -size 33881 +oid sha256:6e1b139382c574ef78bcedd2107378ee3e4e395a07bc888e11192bac270aafee +size 12284 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 index eba88dc95e..c7ee196df8 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd5c940af37b03268f32d57e43d35eec59261fa9674d89ba09d2a234d5427e7b -size 34176 +oid sha256:c263b0b8fd4c6bdf53118aa5ed06ef919ae5973ed370580cd3d6290c455f9c39 +size 12524 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 index 7ac6f8ca09..2b58644d33 100644 --- a/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_de.png +++ b/screenshots/de/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a2963041eda1c927be2d82c11ac738b3f44bf0687f8dbd504bdbda6069ec8cb -size 26246 +oid sha256:6e1b139382c574ef78bcedd2107378ee3e4e395a07bc888e11192bac270aafee +size 12284 diff --git a/screenshots/de/features.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_Day_0_de.png b/screenshots/de/features.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_Day_0_de.png index 58a80ad74d..191c360673 100644 --- a/screenshots/de/features.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_Day_0_de.png +++ b/screenshots/de/features.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cee74685fe9d76a5a1389f500fbcb22517ca092625ff0f033bd870713e053537 -size 15121 +oid sha256:dda7469b3c6a9940d7dc9e6c29a52707788af32ca4c17960eb0a29aab0eff4c7 +size 15134 diff --git a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_de.png new file mode 100644 index 0000000000..5cab90546a --- /dev/null +++ b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8edf8f2d1b29db9dfe47756dcd3fcc01fc908736b0c009320cf8bac535881416 +size 18252 diff --git a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_de.png new file mode 100644 index 0000000000..8596d7d68c --- /dev/null +++ b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7203569b41833fe19935273838d59086031b10660f2e12ab5982432e867e5c1c +size 22128 diff --git a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_de.png new file mode 100644 index 0000000000..c3d7c681a1 --- /dev/null +++ b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec50fa44bf08be308a39eb0d607803b079875c12dfd608f2a70ea4b53e164c39 +size 27566 diff --git a/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_de.png new file mode 100644 index 0000000000..f2b320ec01 --- /dev/null +++ b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a577c026a1502e2fe3bef1ff5f39e3857c06a0ab314c2ef4c384bceb7b9088b1 +size 28630 diff --git a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_3_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_4_de.png similarity index 100% rename from screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_3_de.png rename to screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_4_de.png diff --git a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_4_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_5_de.png similarity index 100% rename from screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_4_de.png rename to screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_5_de.png diff --git a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_5_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_6_de.png similarity index 100% rename from screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_5_de.png rename to screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_6_de.png diff --git a/screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_6_de.png b/screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_7_de.png similarity index 100% rename from screenshots/de/features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_6_de.png rename to screenshots/de/features.roommembermoderation.impl_RoomMemberModerationView_Day_7_de.png diff --git a/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_0_de.png b/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_0_de.png index fb3d275ea7..f2f91815ce 100644 --- a/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_0_de.png +++ b/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8bc4d690dd194e80f222aa0f80072c8d15fbe0bf74fc70fb8dc0d90a27d18b9 -size 75795 +oid sha256:01b5e7fd76bd27d28420d6dcae61cc6381a9240e3bca78f4b1191a015eb395e2 +size 73458 diff --git a/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_1_de.png b/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_1_de.png index fb3d275ea7..f2f91815ce 100644 --- a/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_1_de.png +++ b/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8bc4d690dd194e80f222aa0f80072c8d15fbe0bf74fc70fb8dc0d90a27d18b9 -size 75795 +oid sha256:01b5e7fd76bd27d28420d6dcae61cc6381a9240e3bca78f4b1191a015eb395e2 +size 73458 diff --git a/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_2_de.png b/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_2_de.png index 45efba4987..24f0ee5f73 100644 --- a/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_2_de.png +++ b/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c31627e40bf94976fb4cdcd2fe3809c73b6e922ebba3cda9e2bf03d3ba2bb939 -size 76317 +oid sha256:362fa3a6e8da97f67c0c3502be9d53929cf2cec1f7bd6c15ccaa95070d65b24e +size 74006 diff --git a/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_3_de.png b/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_3_de.png index fd97700af2..bd4e5a26b3 100644 --- a/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_3_de.png +++ b/screenshots/de/features.securebackup.impl.disable_SecureBackupDisableView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56b13e7d7fb1e8890e97750568e78d4c67d947a3a54d87e5ff5d254394072b2c -size 48664 +oid sha256:e80fa798011e89eb0cd931dbd384b7c800120dd2df8b2227d6e5d8ec93ef238f +size 46816 diff --git a/screenshots/de/features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_de.png b/screenshots/de/features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_de.png index 4daeb50e88..37a6a0a0e9 100644 --- a/screenshots/de/features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_de.png +++ b/screenshots/de/features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a94bbe83945a488ce4bf4b753d9b06825bd4e7f18943f8e642562273bdc0a5e9 -size 62927 +oid sha256:54862a355da93704e0e6eb779d6a6011296ca2a968117d36cc4eae8fd96173ac +size 69526 diff --git a/screenshots/de/features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_de.png b/screenshots/de/features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_de.png index 43aac0230d..a3886a1e3d 100644 --- a/screenshots/de/features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_de.png +++ b/screenshots/de/features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d097c185b721aecced3cf9d6d49a70f8b3cd09130fef0061059034ce149cc26 -size 47988 +oid sha256:f953a19a979cdee1503766531545b4683bc8b672a26903af8283820768e4a637 +size 53428 diff --git a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_de.png b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_de.png index de2db10cbe..933993102a 100644 --- a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_de.png +++ b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5b792fa5dbd2067080d5972a81881be30df6f5a9335c9aece6245da488b05cf -size 65583 +oid sha256:a3766ba621a245967c15b7b83fa72bd9e4d7546a37f5ea4caf83c6788a1aa5b6 +size 61181 diff --git a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_de.png b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_de.png index de2db10cbe..933993102a 100644 --- a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_de.png +++ b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5b792fa5dbd2067080d5972a81881be30df6f5a9335c9aece6245da488b05cf -size 65583 +oid sha256:a3766ba621a245967c15b7b83fa72bd9e4d7546a37f5ea4caf83c6788a1aa5b6 +size 61181 diff --git a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_de.png b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_de.png index e7072458cc..45fee6dd26 100644 --- a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_de.png +++ b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c78753ad8b299377a12eb844182bb9e86346f66d89eca03dcbc5cda10ef6ff44 -size 55083 +oid sha256:2fe92f15ed85ca629e56dad8c30487aee018a51fc4e9eaf6eab29a2eb4c27d42 +size 51695 diff --git a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_0_de.png b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_0_de.png index 623f2b9bb3..ac9e47eac1 100644 --- a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_0_de.png +++ b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e439033d1bd70cfa0d9574cd4388d6387ffb5181d3b8e4a55a37c224b380e91d -size 65262 +oid sha256:f4915dcc73c8761e491613c91542f65ea0e549bac1852b10770b9087b1f90a48 +size 61415 diff --git a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_1_de.png b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_1_de.png index a0542ada23..6f657e67f8 100644 --- a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_1_de.png +++ b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_1_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd9c3d54b3c95358bc988ffbaed518d6e79ea61aeba475d63d76a623e931b70d -size 61756 +oid sha256:e1fe049a477258416fb2964230845ebf009e35d0a7baabefa624842cf1e8ff89 +size 57768 diff --git a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_2_de.png b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_2_de.png index de2db10cbe..933993102a 100644 --- a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_2_de.png +++ b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_2_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5b792fa5dbd2067080d5972a81881be30df6f5a9335c9aece6245da488b05cf -size 65583 +oid sha256:a3766ba621a245967c15b7b83fa72bd9e4d7546a37f5ea4caf83c6788a1aa5b6 +size 61181 diff --git a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_3_de.png b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_3_de.png index de2db10cbe..933993102a 100644 --- a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_3_de.png +++ b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5b792fa5dbd2067080d5972a81881be30df6f5a9335c9aece6245da488b05cf -size 65583 +oid sha256:a3766ba621a245967c15b7b83fa72bd9e4d7546a37f5ea4caf83c6788a1aa5b6 +size 61181 diff --git a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_4_de.png b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_4_de.png index e7072458cc..45fee6dd26 100644 --- a/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_4_de.png +++ b/screenshots/de/features.securebackup.impl.setup_SecureBackupSetupView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c78753ad8b299377a12eb844182bb9e86346f66d89eca03dcbc5cda10ef6ff44 -size 55083 +oid sha256:2fe92f15ed85ca629e56dad8c30487aee018a51fc4e9eaf6eab29a2eb4c27d42 +size 51695 diff --git a/screenshots/de/features.signedout.impl_SignedOutView_Day_0_de.png b/screenshots/de/features.signedout.impl_SignedOutView_Day_0_de.png index 723a6c8bc5..9c6f85a915 100644 --- a/screenshots/de/features.signedout.impl_SignedOutView_Day_0_de.png +++ b/screenshots/de/features.signedout.impl_SignedOutView_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c89ba76087d550a18167f2358ccdd6bd3366c67f6d6d3b01c991b52f35e36b8 -size 63564 +oid sha256:5e794da71cadd6f1e9f0662a359325c9cae1e8ebc9877537a1fdba6d1c006ce6 +size 63399 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_5_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_5_de.png index 092bef5a65..3df05cb2c1 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_5_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d13f4c555210dea41c0bad3abd6c02cfc43fa93b2bb88b30f2490c61fdb56476 -size 53798 +oid sha256:232c8a93fff37940b058795447f43388cd8d61de1a3ca5aab1545885b3bc566d +size 53704 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_6_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_6_de.png index 96438c9b8b..10f61efd98 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_6_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_6_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:533a08c37bdd563f993d68b4cd5d5b1a010d57d5fa7da2e0306c66b8e7839bbe -size 56238 +oid sha256:9150cab47a9a9560df48ffefb09e7481f23f675a80877dfaf29168a535f4fee2 +size 55496 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 5904cf8f98..fddbf4418c 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:208347b868ef5ddc16b2c06ac5e6a59eaceb6008fc276149683365025778f684 -size 44800 +oid sha256:0a2c484e54b7b0a051c99a472d78efa6d5b9171e23b07fbfd37e66b56df96898 +size 44713 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 1635026b33..d772ada026 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:ce54a0e068a3f68f6fefaa33152ff919b698e743b6e3ec6a1e78568ee8b16fb1 -size 47381 +oid sha256:eea647e460084d645b91ade9261677ceef281d410d6463e5e0688b41c9754aed +size 46617 diff --git a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_9_de.png b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_9_de.png index d43b2e090e..d63a010d55 100644 --- a/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_9_de.png +++ b/screenshots/de/features.verifysession.impl.incoming_IncomingVerificationView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1ce5390b1db7f940a913ea9ba923bf919424a05649f1b39a033a7f5bea9a2fc -size 35670 +oid sha256:b0ae7bbbde765a903beb419aff127b795bb4d49921b93dc60dd1d5218055fbd8 +size 35666 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_de.png index 092bef5a65..3df05cb2c1 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d13f4c555210dea41c0bad3abd6c02cfc43fa93b2bb88b30f2490c61fdb56476 -size 53798 +oid sha256:232c8a93fff37940b058795447f43388cd8d61de1a3ca5aab1545885b3bc566d +size 53704 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_de.png index 96438c9b8b..10f61efd98 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:533a08c37bdd563f993d68b4cd5d5b1a010d57d5fa7da2e0306c66b8e7839bbe -size 56238 +oid sha256:9150cab47a9a9560df48ffefb09e7481f23f675a80877dfaf29168a535f4fee2 +size 55496 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 5904cf8f98..fddbf4418c 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:208347b868ef5ddc16b2c06ac5e6a59eaceb6008fc276149683365025778f684 -size 44800 +oid sha256:0a2c484e54b7b0a051c99a472d78efa6d5b9171e23b07fbfd37e66b56df96898 +size 44713 diff --git a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_de.png b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_de.png index d43b2e090e..d63a010d55 100644 --- a/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_de.png +++ b/screenshots/de/features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1ce5390b1db7f940a913ea9ba923bf919424a05649f1b39a033a7f5bea9a2fc -size 35670 +oid sha256:b0ae7bbbde765a903beb419aff127b795bb4d49921b93dc60dd1d5218055fbd8 +size 35666 diff --git a/screenshots/de/libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_de.png b/screenshots/de/libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_de.png index b1bb373b78..dbad303a62 100644 --- a/screenshots/de/libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_de.png +++ b/screenshots/de/libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26f21bdb866ee13fbcfd0edca7b57425bc14a79c878e31330ac41b375fd18222 -size 31092 +oid sha256:9a552260805265802772756fc44a4e6944f2fa6b3b715c77958753cb52f48a18 +size 31452 diff --git a/screenshots/de/libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_de.png b/screenshots/de/libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_de.png index afc79d353a..fbe511f864 100644 --- a/screenshots/de/libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_de.png +++ b/screenshots/de/libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:efa139e3f0ab0c8978a5d22909ede6e3da4c5772ae9c3af578bbca824ccb1735 -size 31581 +oid sha256:dd9ce1166232db781b60f870a249789e8e723fe3ff9feeed64214774b4a049de +size 31986 diff --git a/screenshots/de/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_de.png b/screenshots/de/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_de.png index 19e7937d63..9f825ec840 100644 --- a/screenshots/de/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_de.png +++ b/screenshots/de/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45a56e54b7b6ed617c7c2a3413b35a4d699ded6d933789dc4b3d471ed404405b -size 22205 +oid sha256:31ba33141179bb2249d0ed3821e630289fe3bb7a85cf4f1b99795c85a507fb52 +size 529081 diff --git a/screenshots/de/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_de.png index ed4394b6fa..6ea8c4a052 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:5bccb7232766f51b2166b9d9621f53f893cf133861f1e77331789a5e2cbc96c1 -size 66072 +oid sha256:5b45550a4e0579982bda9d9f8ceba223a46111baac3aa91cde7fc55c2d4d63ca +size 66196 diff --git a/screenshots/de/libraries.textcomposer_TextComposerFormatting_Day_0_de.png b/screenshots/de/libraries.textcomposer_TextComposerFormatting_Day_0_de.png index ec74e4e56d..4944157b9c 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerFormatting_Day_0_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerFormatting_Day_0_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b860e3abcf9d5a4265ab3dd17316a00d96d46da5e6ed6f7bb60eaf5e5d0122da -size 53402 +oid sha256:8f521b3c6970fad597fab5a24e4b608bfd9a6d1596c1a4675f402a0ac49d7654 +size 53491 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_de.png b/screenshots/de/libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_de.png index 2a405463e7..d2c54e26bb 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:3bbb1d73be9f2f9dd999a42e2e75f95e16a8ca610759bd37ef0ba80c5f564b3b -size 61663 +oid sha256:fe97833d8fb608ade441753fad18ad6e0cce2510b5451e1c5d9b10c18a7e97d4 +size 92039 diff --git a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_5_de.png b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_5_de.png index 3794879115..735caca5a4 100644 --- a/screenshots/de/libraries.textcomposer_TextComposerReply_Day_5_de.png +++ b/screenshots/de/libraries.textcomposer_TextComposerReply_Day_5_de.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c213578bdbc2495a4a26251264d803c51f6c4c4cd6547d46f0738a52fd3af3b -size 59895 +oid sha256:7aa44ff345d0b2bb9a4f2c2c94f4cf5acfe1518c33608a4673f748d5f25ac886 +size 104285 diff --git a/screenshots/html/data.js b/screenshots/html/data.js index 17e97c6284..5edac704cf 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,70 +1,70 @@ // 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",20238,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20252,], ["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",20238,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20238,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20238,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20238,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20238,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20238,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20238,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20238,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20238,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20238,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20252,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20252,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20252,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20252,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20252,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20252,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20252,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20252,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20252,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20252,], ["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,], ["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",20238,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20238,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20238,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20252,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20252,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20252,], ["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",20238,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20238,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20238,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20238,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20238,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20238,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20238,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20238,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20238,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20238,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20238,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20238,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20238,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20238,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20238,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20238,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20238,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20238,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20238,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20238,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20252,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20252,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20252,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20252,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20252,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20252,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20252,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20252,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20252,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20252,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20252,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20252,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20252,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20252,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20252,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20252,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20252,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20252,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20252,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20252,], ["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",20238,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20252,], ["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",20238,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20252,], ["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",20238,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20252,], ["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",20238,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20252,], ["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",20238,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20252,], ["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,], @@ -74,18 +74,18 @@ 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","",20238,], -["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20238,], -["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20238,], -["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20238,], -["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20238,], -["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20238,], +["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20252,], +["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20252,], +["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20252,], +["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20252,], +["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20252,], +["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20252,], ["features.messages.impl.attachments.preview_AttachmentsView_6_en","",0,], -["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20238,], +["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20252,], ["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",20238,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20252,], ["features.knockrequests.impl.banner_AvatarRowRtl_Day_0_en","features.knockrequests.impl.banner_AvatarRowRtl_Night_0_en",0,], ["features.knockrequests.impl.banner_AvatarRowRtl_Day_1_en","features.knockrequests.impl.banner_AvatarRowRtl_Night_1_en",0,], ["features.knockrequests.impl.banner_AvatarRowRtl_Day_2_en","features.knockrequests.impl.banner_AvatarRowRtl_Night_2_en",0,], @@ -193,13 +193,13 @@ export const screenshots = [ ["libraries.designsystem.components_Badge_Day_0_en","libraries.designsystem.components_Badge_Night_0_en",0,], ["libraries.designsystem.components_BigCheckmark_Day_0_en","libraries.designsystem.components_BigCheckmark_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",20238,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20238,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20238,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20238,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20238,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20238,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20238,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20252,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20252,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20252,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20252,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20252,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20252,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20252,], ["libraries.designsystem.components_BloomInitials_Day_0_en","libraries.designsystem.components_BloomInitials_Night_0_en",0,], ["libraries.designsystem.components_BloomInitials_Day_1_en","libraries.designsystem.components_BloomInitials_Night_1_en",0,], ["libraries.designsystem.components_BloomInitials_Day_2_en","libraries.designsystem.components_BloomInitials_Night_2_en",0,], @@ -210,141 +210,141 @@ export const screenshots = [ ["libraries.designsystem.components_BloomInitials_Day_7_en","libraries.designsystem.components_BloomInitials_Night_7_en",0,], ["libraries.designsystem.components_Bloom_Day_0_en","libraries.designsystem.components_Bloom_Night_0_en",0,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportView_Day_0_en","features.rageshake.impl.bugreport_BugReportView_Night_0_en",20238,], -["features.rageshake.impl.bugreport_BugReportView_Day_1_en","features.rageshake.impl.bugreport_BugReportView_Night_1_en",20238,], -["features.rageshake.impl.bugreport_BugReportView_Day_2_en","features.rageshake.impl.bugreport_BugReportView_Night_2_en",20238,], -["features.rageshake.impl.bugreport_BugReportView_Day_3_en","features.rageshake.impl.bugreport_BugReportView_Night_3_en",20238,], -["features.rageshake.impl.bugreport_BugReportView_Day_4_en","features.rageshake.impl.bugreport_BugReportView_Night_4_en",20238,], +["features.rageshake.impl.bugreport_BugReportView_Day_0_en","features.rageshake.impl.bugreport_BugReportView_Night_0_en",20252,], +["features.rageshake.impl.bugreport_BugReportView_Day_1_en","features.rageshake.impl.bugreport_BugReportView_Night_1_en",20252,], +["features.rageshake.impl.bugreport_BugReportView_Day_2_en","features.rageshake.impl.bugreport_BugReportView_Night_2_en",20252,], +["features.rageshake.impl.bugreport_BugReportView_Day_3_en","features.rageshake.impl.bugreport_BugReportView_Night_3_en",20252,], +["features.rageshake.impl.bugreport_BugReportView_Day_4_en","features.rageshake.impl.bugreport_BugReportView_Night_4_en",20252,], ["libraries.designsystem.atomic.molecules_ButtonColumnMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonColumnMolecule_Night_0_en",0,], ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20238,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20238,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20252,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20252,], ["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_CallScreenPipView_Day_0_en","features.call.impl.ui_CallScreenPipView_Night_0_en",0,], ["features.call.impl.ui_CallScreenPipView_Day_1_en","features.call.impl.ui_CallScreenPipView_Night_1_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",20238,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20238,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20238,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20238,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20238,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_0_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_0_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_10_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_10_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_1_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_1_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_2_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_2_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_3_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_3_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_4_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_4_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_5_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_5_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_6_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_6_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_7_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_7_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_8_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_8_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_9_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_9_en",20238,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_0_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_0_en",20238,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_1_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_1_en",20238,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_2_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_2_en",20238,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_3_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_3_en",20238,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_4_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_4_en",20238,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_5_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_5_en",20238,], -["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_6_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_6_en",20238,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20252,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20252,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20252,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20252,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20252,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_0_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_0_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_10_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_10_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_1_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_1_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_2_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_2_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_3_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_3_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_4_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_4_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_5_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_5_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_6_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_6_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_7_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_7_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_8_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_8_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_9_en","features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_9_en",20252,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_0_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_0_en",20252,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_1_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_1_en",20252,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_2_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_2_en",20252,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_3_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_3_en",20252,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_4_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_4_en",20252,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_5_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_5_en",20252,], +["features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Day_6_en","features.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_Night_6_en",20252,], ["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",20238,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20238,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20238,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20252,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20252,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20252,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20238,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20252,], ["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",20238,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20238,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20238,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20238,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20238,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20238,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20238,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20252,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20252,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20252,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20252,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20252,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20252,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20252,], ["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",20238,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20238,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20238,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20252,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20252,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20252,], ["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,], ["libraries.designsystem.components.avatar_CompositeAvatar_Avatars_en","",0,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20238,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20238,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20238,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20238,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20238,], -["features.roomlist.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.roomlist.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20238,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20252,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20252,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20252,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20252,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20252,], +["features.roomlist.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.roomlist.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20252,], ["libraries.designsystem.components.dialogs_ConfirmationDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_ConfirmationDialog_Day_0_en","libraries.designsystem.components.dialogs_ConfirmationDialog_Night_0_en",0,], ["features.networkmonitor.api.ui_ConnectivityIndicatorView_Day_0_en","features.networkmonitor.api.ui_ConnectivityIndicatorView_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_CounterAtom_Day_0_en","libraries.designsystem.atomic.atoms_CounterAtom_Night_0_en",0,], -["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20238,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20238,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20238,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20238,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20238,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20238,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20238,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20238,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20238,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20238,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20238,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20238,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20238,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20238,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20238,], -["features.createroom.impl.root_CreateRoomRootView_Day_0_en","features.createroom.impl.root_CreateRoomRootView_Night_0_en",20238,], -["features.createroom.impl.root_CreateRoomRootView_Day_1_en","features.createroom.impl.root_CreateRoomRootView_Night_1_en",20238,], -["features.createroom.impl.root_CreateRoomRootView_Day_2_en","features.createroom.impl.root_CreateRoomRootView_Night_2_en",20238,], -["features.createroom.impl.root_CreateRoomRootView_Day_3_en","features.createroom.impl.root_CreateRoomRootView_Night_3_en",20238,], -["features.createroom.impl.root_CreateRoomRootView_Day_4_en","features.createroom.impl.root_CreateRoomRootView_Night_4_en",20238,], -["features.createroom.impl.root_CreateRoomRootView_Day_5_en","features.createroom.impl.root_CreateRoomRootView_Night_5_en",20238,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20238,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20238,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20238,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20238,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20238,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20252,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20252,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20252,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20252,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20252,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20252,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20252,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20252,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20252,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20252,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20252,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20252,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20252,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20252,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20252,], +["features.createroom.impl.root_CreateRoomRootView_Day_0_en","features.createroom.impl.root_CreateRoomRootView_Night_0_en",20252,], +["features.createroom.impl.root_CreateRoomRootView_Day_1_en","features.createroom.impl.root_CreateRoomRootView_Night_1_en",20252,], +["features.createroom.impl.root_CreateRoomRootView_Day_2_en","features.createroom.impl.root_CreateRoomRootView_Night_2_en",20252,], +["features.createroom.impl.root_CreateRoomRootView_Day_3_en","features.createroom.impl.root_CreateRoomRootView_Night_3_en",20252,], +["features.createroom.impl.root_CreateRoomRootView_Day_4_en","features.createroom.impl.root_CreateRoomRootView_Night_4_en",20252,], +["features.createroom.impl.root_CreateRoomRootView_Day_5_en","features.createroom.impl.root_CreateRoomRootView_Night_5_en",20252,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20252,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20252,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20252,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20252,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20252,], ["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","",20238,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20238,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20238,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20238,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20238,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20238,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20238,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20252,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20252,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20252,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20252,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20252,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20252,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20252,], ["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",20238,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20238,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20238,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20252,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20252,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20252,], ["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",20238,], -["features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Day_0_en","features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Night_0_en",20238,], -["features.roomlist.impl.components_DefaultRoomListTopBar_Day_0_en","features.roomlist.impl.components_DefaultRoomListTopBar_Night_0_en",20238,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20252,], +["features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Day_0_en","features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Night_0_en",20252,], +["features.roomlist.impl.components_DefaultRoomListTopBar_Day_0_en","features.roomlist.impl.components_DefaultRoomListTopBar_Night_0_en",20252,], ["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",20238,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20238,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20238,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20238,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20238,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20238,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20238,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20252,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20252,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20252,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20252,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20252,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20252,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20252,], ["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,], @@ -357,17 +357,17 @@ 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",20238,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20238,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20238,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20238,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20238,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en",20238,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en",20238,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en",20238,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en",20238,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en",20238,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20238,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20252,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20252,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20252,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20252,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20252,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en",20252,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en",20252,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en",20252,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en",20252,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en",20252,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20252,], ["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,], @@ -377,9 +377,9 @@ export const screenshots = [ ["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_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction_EmojiPicker_Night_0_en",0,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20238,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20238,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20238,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20252,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20252,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20252,], ["features.messages.impl.timeline.debug_EventDebugInfoView_Day_0_en","features.messages.impl.timeline.debug_EventDebugInfoView_Night_0_en",0,], ["libraries.featureflag.ui_FeatureListView_Day_0_en","libraries.featureflag.ui_FeatureListView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_FileItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_FileItemView_Night_0_en",0,], @@ -397,16 +397,16 @@ 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",20238,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20238,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20238,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20252,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20252,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20252,], ["features.messages.impl.timeline.components_FocusedEvent_Day_0_en","features.messages.impl.timeline.components_FocusedEvent_Night_0_en",0,], ["libraries.textcomposer.components_FormattingOption_Day_0_en","libraries.textcomposer.components_FormattingOption_Night_0_en",0,], ["features.messages.impl.forward_ForwardMessagesView_Day_0_en","features.messages.impl.forward_ForwardMessagesView_Night_0_en",0,], ["features.messages.impl.forward_ForwardMessagesView_Day_1_en","features.messages.impl.forward_ForwardMessagesView_Night_1_en",0,], ["features.messages.impl.forward_ForwardMessagesView_Day_2_en","features.messages.impl.forward_ForwardMessagesView_Night_2_en",0,], -["features.messages.impl.forward_ForwardMessagesView_Day_3_en","features.messages.impl.forward_ForwardMessagesView_Night_3_en",20238,], -["features.roomlist.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.roomlist.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20238,], +["features.messages.impl.forward_ForwardMessagesView_Day_3_en","features.messages.impl.forward_ForwardMessagesView_Night_3_en",20252,], +["features.roomlist.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.roomlist.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20252,], ["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,], @@ -420,8 +420,8 @@ export const screenshots = [ ["libraries.designsystem.atomic.molecules_IconTitlePlaceholdersRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_IconTitlePlaceholdersRowMolecule_Night_0_en",0,], ["libraries.designsystem.atomic.molecules_IconTitleSubtitleMolecule_Day_0_en","libraries.designsystem.atomic.molecules_IconTitleSubtitleMolecule_Night_0_en",0,], ["libraries.designsystem.theme.components_IconToggleButton_Toggles_en","",0,], -["appicon.enterprise_Icon_en","",0,], ["appicon.element_Icon_en","",0,], +["appicon.enterprise_Icon_en","",0,], ["libraries.designsystem.icons_IconsCompound_Day_0_en","libraries.designsystem.icons_IconsCompound_Night_0_en",0,], ["libraries.designsystem.icons_IconsCompound_Day_1_en","libraries.designsystem.icons_IconsCompound_Night_1_en",0,], ["libraries.designsystem.icons_IconsCompound_Day_2_en","libraries.designsystem.icons_IconsCompound_Night_2_en",0,], @@ -430,8 +430,8 @@ export const screenshots = [ ["libraries.designsystem.icons_IconsCompound_Day_5_en","libraries.designsystem.icons_IconsCompound_Night_5_en",0,], ["libraries.designsystem.icons_IconsOther_Day_0_en","libraries.designsystem.icons_IconsOther_Night_0_en",0,], ["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_0_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_0_en",0,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20238,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20238,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20252,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20252,], ["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,], @@ -439,84 +439,85 @@ 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",20238,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20252,], ["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",20238,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20252,], ["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",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20238,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20238,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20252,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20252,], ["features.networkmonitor.api.ui_Indicator_Day_0_en","features.networkmonitor.api.ui_Indicator_Night_0_en",0,], ["libraries.designsystem.atomic.molecules_InfoListItemMolecule_Day_0_en","libraries.designsystem.atomic.molecules_InfoListItemMolecule_Night_0_en",0,], ["libraries.designsystem.atomic.organisms_InfoListOrganism_Day_0_en","libraries.designsystem.atomic.organisms_InfoListOrganism_Night_0_en",0,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20238,], -["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20238,], -["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20238,], -["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20238,], -["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20238,], -["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20238,], -["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20238,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20255,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20252,], +["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20252,], +["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20252,], +["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20252,], +["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20252,], +["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20252,], +["features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20252,], ["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",20238,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20238,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20238,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20238,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20238,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20238,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20238,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20238,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20238,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20238,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20238,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20252,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20252,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20252,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20252,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20252,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20252,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20252,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20252,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20252,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20252,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], ["features.leaveroom.api_LeaveRoomView_Day_0_en","features.leaveroom.api_LeaveRoomView_Night_0_en",0,], -["features.leaveroom.api_LeaveRoomView_Day_1_en","features.leaveroom.api_LeaveRoomView_Night_1_en",20238,], -["features.leaveroom.api_LeaveRoomView_Day_2_en","features.leaveroom.api_LeaveRoomView_Night_2_en",20238,], -["features.leaveroom.api_LeaveRoomView_Day_3_en","features.leaveroom.api_LeaveRoomView_Night_3_en",20238,], -["features.leaveroom.api_LeaveRoomView_Day_4_en","features.leaveroom.api_LeaveRoomView_Night_4_en",20238,], -["features.leaveroom.api_LeaveRoomView_Day_5_en","features.leaveroom.api_LeaveRoomView_Night_5_en",20238,], -["features.leaveroom.api_LeaveRoomView_Day_6_en","features.leaveroom.api_LeaveRoomView_Night_6_en",20238,], +["features.leaveroom.api_LeaveRoomView_Day_1_en","features.leaveroom.api_LeaveRoomView_Night_1_en",20252,], +["features.leaveroom.api_LeaveRoomView_Day_2_en","features.leaveroom.api_LeaveRoomView_Night_2_en",20252,], +["features.leaveroom.api_LeaveRoomView_Day_3_en","features.leaveroom.api_LeaveRoomView_Night_3_en",20252,], +["features.leaveroom.api_LeaveRoomView_Day_4_en","features.leaveroom.api_LeaveRoomView_Night_4_en",20252,], +["features.leaveroom.api_LeaveRoomView_Day_5_en","features.leaveroom.api_LeaveRoomView_Night_5_en",20252,], +["features.leaveroom.api_LeaveRoomView_Day_6_en","features.leaveroom.api_LeaveRoomView_Night_6_en",20252,], ["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",20238,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20252,], ["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,], @@ -571,31 +572,31 @@ 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",20238,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20238,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20238,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20238,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20252,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20252,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20252,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20252,], ["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",20238,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20238,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20238,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20238,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20238,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20238,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20238,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20238,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20238,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20238,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20238,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20238,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20238,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20238,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20238,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20238,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20238,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20238,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20252,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20252,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20252,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20252,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20252,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20252,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20252,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20252,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20252,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20252,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20252,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20252,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20252,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20252,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20252,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20252,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20252,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20252,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20238,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20252,], ["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,], @@ -608,22 +609,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",20238,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20238,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20252,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20252,], ["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",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20238,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20238,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20252,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20252,], ["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,], @@ -631,14 +632,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","",20238,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20238,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20252,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20252,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20238,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20252,], ["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","",20238,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20252,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -650,14 +651,8 @@ 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",20238,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20252,], ["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_10_en","features.messages.impl.timeline.components_MessageEventBubble_Night_10_en",0,], -["features.messages.impl.timeline.components_MessageEventBubble_Day_11_en","features.messages.impl.timeline.components_MessageEventBubble_Night_11_en",0,], -["features.messages.impl.timeline.components_MessageEventBubble_Day_12_en","features.messages.impl.timeline.components_MessageEventBubble_Night_12_en",0,], -["features.messages.impl.timeline.components_MessageEventBubble_Day_13_en","features.messages.impl.timeline.components_MessageEventBubble_Night_13_en",0,], -["features.messages.impl.timeline.components_MessageEventBubble_Day_14_en","features.messages.impl.timeline.components_MessageEventBubble_Night_14_en",0,], -["features.messages.impl.timeline.components_MessageEventBubble_Day_15_en","features.messages.impl.timeline.components_MessageEventBubble_Night_15_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,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_3_en","features.messages.impl.timeline.components_MessageEventBubble_Night_3_en",0,], @@ -665,9 +660,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_MessageEventBubble_Day_8_en","features.messages.impl.timeline.components_MessageEventBubble_Night_8_en",0,], -["features.messages.impl.timeline.components_MessageEventBubble_Day_9_en","features.messages.impl.timeline.components_MessageEventBubble_Night_9_en",0,], -["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20238,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20252,], ["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,], @@ -675,25 +668,25 @@ 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.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20238,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20238,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20238,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20238,], -["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20238,], -["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20238,], -["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20238,], -["features.messages.impl_MessagesView_Day_13_en","features.messages.impl_MessagesView_Night_13_en",20238,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20238,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20238,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20238,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20238,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20238,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20238,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20238,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20238,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20238,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20252,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20252,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20252,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20252,], +["features.messages.impl_MessagesView_Day_10_en","features.messages.impl_MessagesView_Night_10_en",20252,], +["features.messages.impl_MessagesView_Day_11_en","features.messages.impl_MessagesView_Night_11_en",20252,], +["features.messages.impl_MessagesView_Day_12_en","features.messages.impl_MessagesView_Night_12_en",20252,], +["features.messages.impl_MessagesView_Day_13_en","features.messages.impl_MessagesView_Night_13_en",20252,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20252,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20252,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20252,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20252,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20252,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20252,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20252,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20252,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20252,], ["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",20238,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20252,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], @@ -702,45 +695,43 @@ export const screenshots = [ ["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,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20238,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20238,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20238,], -["libraries.oidc.impl.webview_OidcView_Day_0_en","libraries.oidc.impl.webview_OidcView_Night_0_en",0,], -["libraries.oidc.impl.webview_OidcView_Day_1_en","libraries.oidc.impl.webview_OidcView_Night_1_en",0,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20252,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20252,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20252,], ["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",20238,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20238,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20238,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20238,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20238,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20238,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20252,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20252,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20252,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20252,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20252,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20252,], ["libraries.designsystem.background_OnboardingBackground_Day_0_en","libraries.designsystem.background_OnboardingBackground_Night_0_en",0,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20238,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20252,], ["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",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20238,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20238,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20252,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20252,], ["libraries.designsystem.theme.components_OutlinedButtonLargeLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonLarge_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonMediumLowPadding_Buttons_en","",0,], @@ -754,65 +745,65 @@ export const screenshots = [ ["libraries.designsystem.components_PageTitleWithIconFull_Day_5_en","libraries.designsystem.components_PageTitleWithIconFull_Night_5_en",0,], ["libraries.designsystem.components_PageTitleWithIconFull_Day_6_en","libraries.designsystem.components_PageTitleWithIconFull_Night_6_en",0,], ["libraries.designsystem.components_PageTitleWithIconMinimal_Day_0_en","libraries.designsystem.components_PageTitleWithIconMinimal_Night_0_en",0,], -["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20238,], -["features.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_Day_0_en","features.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_Night_0_en",20238,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20238,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20238,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20238,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20238,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20252,], +["features.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_Day_0_en","features.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_Night_0_en",20252,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20252,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20252,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20252,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20252,], ["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",20238,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20238,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20238,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20252,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20252,], ["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",20238,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20238,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20238,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20238,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20238,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20238,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20238,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20238,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20238,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20238,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20238,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20238,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20238,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20238,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20252,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20252,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20252,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20252,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20252,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20252,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20252,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20252,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20252,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20252,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20252,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20252,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20252,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20252,], ["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",20238,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20238,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20238,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20238,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20238,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20252,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20252,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20252,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20252,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20252,], ["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",20238,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20238,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20238,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20238,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20238,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20238,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20238,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20238,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20238,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20238,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20238,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20252,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20252,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20252,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20252,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20252,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20252,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20252,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20252,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20252,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20252,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20252,], ["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,], @@ -826,218 +817,215 @@ export const screenshots = [ ["libraries.designsystem.components.preferences_PreferenceRow_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSlide_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en","",0,], -["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20238,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20238,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20238,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20238,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20252,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20252,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20252,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20252,], ["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","",20238,], -["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20238,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20238,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20238,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20238,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20238,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20238,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20238,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20238,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20238,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20238,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20238,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20238,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20238,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20238,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20238,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20238,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20238,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20238,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20238,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20238,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20238,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20238,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20238,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20238,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20238,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20252,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20252,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20252,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20252,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20252,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20252,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20252,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20252,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20252,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20252,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20252,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20252,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20252,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20252,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20252,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20252,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20252,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20252,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20252,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20252,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20252,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20252,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20252,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20252,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20252,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20252,], ["libraries.designsystem.theme.components_RadioButton_Toggles_en","",0,], -["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20238,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20238,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20252,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20252,], ["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",20238,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20238,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20238,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20238,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20238,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20238,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20238,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20252,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20252,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20252,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20252,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20252,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20252,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20252,], ["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",20238,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20238,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20238,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20238,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20238,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20238,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20238,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20238,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20238,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20238,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20238,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20238,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20238,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20238,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20238,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20238,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20238,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20252,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20252,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20252,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20252,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20252,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20252,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20252,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20252,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20252,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20252,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20252,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20252,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20252,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20252,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20252,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20252,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20252,], ["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",20238,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20238,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20238,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20238,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_0_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_0_en",20238,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_1_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_1_en",20238,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_2_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_2_en",20238,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_3_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_3_en",20238,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_4_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_4_en",20238,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_5_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_5_en",20238,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_6_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_6_en",20238,], -["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_7_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_7_en",20238,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20252,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20252,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20252,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20252,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_0_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_0_en",20252,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_1_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_1_en",20252,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_2_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_2_en",20252,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_3_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_3_en",20252,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_4_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_4_en",20252,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_5_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_5_en",20252,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_6_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_6_en",20252,], +["features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Day_7_en","features.roomdetails.impl.rolesandpermissions_RolesAndPermissionsView_Night_7_en",20252,], ["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",20238,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20238,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20238,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20238,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en",20238,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en",20238,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en",20238,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en",20238,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en",20238,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en",20238,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en",20238,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en",20238,], -["features.roomdetails.impl_RoomDetails_0_en","",20238,], -["features.roomdetails.impl_RoomDetails_10_en","",20238,], -["features.roomdetails.impl_RoomDetails_11_en","",20238,], -["features.roomdetails.impl_RoomDetails_12_en","",20238,], -["features.roomdetails.impl_RoomDetails_13_en","",20238,], -["features.roomdetails.impl_RoomDetails_14_en","",20238,], -["features.roomdetails.impl_RoomDetails_15_en","",20238,], -["features.roomdetails.impl_RoomDetails_16_en","",20238,], -["features.roomdetails.impl_RoomDetails_17_en","",20238,], -["features.roomdetails.impl_RoomDetails_18_en","",20238,], -["features.roomdetails.impl_RoomDetails_1_en","",20238,], -["features.roomdetails.impl_RoomDetails_2_en","",20238,], -["features.roomdetails.impl_RoomDetails_3_en","",20238,], -["features.roomdetails.impl_RoomDetails_4_en","",20238,], -["features.roomdetails.impl_RoomDetails_5_en","",20238,], -["features.roomdetails.impl_RoomDetails_6_en","",20238,], -["features.roomdetails.impl_RoomDetails_7_en","",20238,], -["features.roomdetails.impl_RoomDetails_8_en","",20238,], -["features.roomdetails.impl_RoomDetails_9_en","",20238,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20238,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20238,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20238,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20238,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20238,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20238,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20238,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_4_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_4_en",20238,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_5_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_5_en",20238,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_6_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_6_en",20238,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_7_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_7_en",20238,], -["features.roomlist.impl.components_RoomListContentView_Day_0_en","features.roomlist.impl.components_RoomListContentView_Night_0_en",20238,], -["features.roomlist.impl.components_RoomListContentView_Day_1_en","features.roomlist.impl.components_RoomListContentView_Night_1_en",20238,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20252,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20252,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20252,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20252,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en",20252,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en",20252,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en",20252,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en",20252,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en",20252,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en",20252,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en",20252,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en",20252,], +["features.roomdetails.impl_RoomDetails_0_en","",20252,], +["features.roomdetails.impl_RoomDetails_10_en","",20252,], +["features.roomdetails.impl_RoomDetails_11_en","",20252,], +["features.roomdetails.impl_RoomDetails_12_en","",20252,], +["features.roomdetails.impl_RoomDetails_13_en","",20252,], +["features.roomdetails.impl_RoomDetails_14_en","",20252,], +["features.roomdetails.impl_RoomDetails_15_en","",20252,], +["features.roomdetails.impl_RoomDetails_16_en","",20252,], +["features.roomdetails.impl_RoomDetails_17_en","",20252,], +["features.roomdetails.impl_RoomDetails_18_en","",20252,], +["features.roomdetails.impl_RoomDetails_1_en","",20252,], +["features.roomdetails.impl_RoomDetails_2_en","",20252,], +["features.roomdetails.impl_RoomDetails_3_en","",20252,], +["features.roomdetails.impl_RoomDetails_4_en","",20252,], +["features.roomdetails.impl_RoomDetails_5_en","",20252,], +["features.roomdetails.impl_RoomDetails_6_en","",20252,], +["features.roomdetails.impl_RoomDetails_7_en","",20252,], +["features.roomdetails.impl_RoomDetails_8_en","",20252,], +["features.roomdetails.impl_RoomDetails_9_en","",20252,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20252,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20252,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20252,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20252,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20252,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20252,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20252,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_4_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_4_en",20252,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_5_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_5_en",20252,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_6_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_6_en",20252,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_7_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_7_en",20252,], +["features.roomlist.impl.components_RoomListContentView_Day_0_en","features.roomlist.impl.components_RoomListContentView_Night_0_en",20252,], +["features.roomlist.impl.components_RoomListContentView_Day_1_en","features.roomlist.impl.components_RoomListContentView_Night_1_en",20252,], ["features.roomlist.impl.components_RoomListContentView_Day_2_en","features.roomlist.impl.components_RoomListContentView_Night_2_en",0,], -["features.roomlist.impl.components_RoomListContentView_Day_3_en","features.roomlist.impl.components_RoomListContentView_Night_3_en",20238,], -["features.roomlist.impl.components_RoomListContentView_Day_4_en","features.roomlist.impl.components_RoomListContentView_Night_4_en",20238,], -["features.roomlist.impl_RoomListDeclineInviteMenuContent_Day_0_en","features.roomlist.impl_RoomListDeclineInviteMenuContent_Night_0_en",20238,], -["features.roomlist.impl.filters_RoomListFiltersView_Day_0_en","features.roomlist.impl.filters_RoomListFiltersView_Night_0_en",20238,], -["features.roomlist.impl.filters_RoomListFiltersView_Day_1_en","features.roomlist.impl.filters_RoomListFiltersView_Night_1_en",20238,], -["features.roomlist.impl_RoomListModalBottomSheetContent_Day_0_en","features.roomlist.impl_RoomListModalBottomSheetContent_Night_0_en",20238,], -["features.roomlist.impl_RoomListModalBottomSheetContent_Day_1_en","features.roomlist.impl_RoomListModalBottomSheetContent_Night_1_en",20238,], -["features.roomlist.impl_RoomListModalBottomSheetContent_Day_2_en","features.roomlist.impl_RoomListModalBottomSheetContent_Night_2_en",20238,], +["features.roomlist.impl.components_RoomListContentView_Day_3_en","features.roomlist.impl.components_RoomListContentView_Night_3_en",20252,], +["features.roomlist.impl.components_RoomListContentView_Day_4_en","features.roomlist.impl.components_RoomListContentView_Night_4_en",20252,], +["features.roomlist.impl_RoomListDeclineInviteMenuContent_Day_0_en","features.roomlist.impl_RoomListDeclineInviteMenuContent_Night_0_en",20252,], +["features.roomlist.impl.filters_RoomListFiltersView_Day_0_en","features.roomlist.impl.filters_RoomListFiltersView_Night_0_en",20252,], +["features.roomlist.impl.filters_RoomListFiltersView_Day_1_en","features.roomlist.impl.filters_RoomListFiltersView_Night_1_en",20252,], +["features.roomlist.impl_RoomListModalBottomSheetContent_Day_0_en","features.roomlist.impl_RoomListModalBottomSheetContent_Night_0_en",20252,], +["features.roomlist.impl_RoomListModalBottomSheetContent_Day_1_en","features.roomlist.impl_RoomListModalBottomSheetContent_Night_1_en",20252,], +["features.roomlist.impl_RoomListModalBottomSheetContent_Day_2_en","features.roomlist.impl_RoomListModalBottomSheetContent_Night_2_en",20252,], ["features.roomlist.impl.search_RoomListSearchContent_Day_0_en","features.roomlist.impl.search_RoomListSearchContent_Night_0_en",0,], -["features.roomlist.impl.search_RoomListSearchContent_Day_1_en","features.roomlist.impl.search_RoomListSearchContent_Night_1_en",20238,], -["features.roomlist.impl_RoomListView_Day_0_en","features.roomlist.impl_RoomListView_Night_0_en",20238,], -["features.roomlist.impl_RoomListView_Day_10_en","features.roomlist.impl_RoomListView_Night_10_en",20238,], -["features.roomlist.impl_RoomListView_Day_1_en","features.roomlist.impl_RoomListView_Night_1_en",20238,], -["features.roomlist.impl_RoomListView_Day_2_en","features.roomlist.impl_RoomListView_Night_2_en",20238,], -["features.roomlist.impl_RoomListView_Day_3_en","features.roomlist.impl_RoomListView_Night_3_en",20238,], -["features.roomlist.impl_RoomListView_Day_4_en","features.roomlist.impl_RoomListView_Night_4_en",20238,], -["features.roomlist.impl_RoomListView_Day_5_en","features.roomlist.impl_RoomListView_Night_5_en",20238,], -["features.roomlist.impl_RoomListView_Day_6_en","features.roomlist.impl_RoomListView_Night_6_en",20238,], -["features.roomlist.impl_RoomListView_Day_7_en","features.roomlist.impl_RoomListView_Night_7_en",20238,], +["features.roomlist.impl.search_RoomListSearchContent_Day_1_en","features.roomlist.impl.search_RoomListSearchContent_Night_1_en",20252,], +["features.roomlist.impl_RoomListView_Day_0_en","features.roomlist.impl_RoomListView_Night_0_en",20252,], +["features.roomlist.impl_RoomListView_Day_10_en","features.roomlist.impl_RoomListView_Night_10_en",20252,], +["features.roomlist.impl_RoomListView_Day_1_en","features.roomlist.impl_RoomListView_Night_1_en",20252,], +["features.roomlist.impl_RoomListView_Day_2_en","features.roomlist.impl_RoomListView_Night_2_en",20252,], +["features.roomlist.impl_RoomListView_Day_3_en","features.roomlist.impl_RoomListView_Night_3_en",20252,], +["features.roomlist.impl_RoomListView_Day_4_en","features.roomlist.impl_RoomListView_Night_4_en",20252,], +["features.roomlist.impl_RoomListView_Day_5_en","features.roomlist.impl_RoomListView_Night_5_en",20252,], +["features.roomlist.impl_RoomListView_Day_6_en","features.roomlist.impl_RoomListView_Night_6_en",20252,], +["features.roomlist.impl_RoomListView_Day_7_en","features.roomlist.impl_RoomListView_Night_7_en",20252,], ["features.roomlist.impl_RoomListView_Day_8_en","features.roomlist.impl_RoomListView_Night_8_en",0,], ["features.roomlist.impl_RoomListView_Day_9_en","features.roomlist.impl_RoomListView_Night_9_en",0,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en",20238,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en",20238,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en",20238,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20238,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20238,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20238,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20238,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20238,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20238,], +["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en",20252,], +["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en",20252,], +["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en",20252,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20252,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20252,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20252,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20252,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20252,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20252,], ["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",0,], -["features.roomdetails.impl.members_RoomMemberListView_Day_7_en","features.roomdetails.impl.members_RoomMemberListView_Night_7_en",20238,], -["features.roomdetails.impl.members_RoomMemberListView_Day_8_en","features.roomdetails.impl.members_RoomMemberListView_Night_8_en",20238,], -["features.roomdetails.impl.members_RoomMemberListView_Day_9_en","features.roomdetails.impl.members_RoomMemberListView_Night_9_en",20238,], +["features.roomdetails.impl.members_RoomMemberListView_Day_7_en","features.roomdetails.impl.members_RoomMemberListView_Night_7_en",20252,], +["features.roomdetails.impl.members_RoomMemberListView_Day_8_en","features.roomdetails.impl.members_RoomMemberListView_Night_8_en",20252,], +["features.roomdetails.impl.members_RoomMemberListView_Day_9_en","features.roomdetails.impl.members_RoomMemberListView_Night_9_en",20252,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20252,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20252,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20252,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20252,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20252,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20252,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20252,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20252,], ["libraries.designsystem.atomic.molecules_RoomMembersCountMolecule_Day_0_en","libraries.designsystem.atomic.molecules_RoomMembersCountMolecule_Night_0_en",0,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_0_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_0_en",20238,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_10_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_10_en",0,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_1_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_1_en",20238,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_2_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_2_en",20238,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_3_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_3_en",20238,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_4_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_4_en",20238,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_5_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_5_en",20238,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_6_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_6_en",20238,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_7_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_7_en",0,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_8_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_8_en",20238,], -["features.roomdetails.impl.members.moderation_RoomMembersModerationView_Day_9_en","features.roomdetails.impl.members.moderation_RoomMembersModerationView_Night_9_en",20238,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20238,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20238,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20238,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20238,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20238,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20238,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20238,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20238,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20238,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20238,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20238,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20238,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20238,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20238,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20252,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20252,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20252,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20252,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20252,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20252,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20252,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20252,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20252,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20252,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20252,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20252,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20252,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20252,], ["features.roomlist.impl.components_RoomSummaryPlaceholderRow_Day_0_en","features.roomlist.impl.components_RoomSummaryPlaceholderRow_Night_0_en",0,], ["features.roomlist.impl.components_RoomSummaryRow_Day_0_en","features.roomlist.impl.components_RoomSummaryRow_Night_0_en",0,], ["features.roomlist.impl.components_RoomSummaryRow_Day_10_en","features.roomlist.impl.components_RoomSummaryRow_Night_10_en",0,], @@ -1060,12 +1048,12 @@ export const screenshots = [ ["features.roomlist.impl.components_RoomSummaryRow_Day_26_en","features.roomlist.impl.components_RoomSummaryRow_Night_26_en",0,], ["features.roomlist.impl.components_RoomSummaryRow_Day_27_en","features.roomlist.impl.components_RoomSummaryRow_Night_27_en",0,], ["features.roomlist.impl.components_RoomSummaryRow_Day_28_en","features.roomlist.impl.components_RoomSummaryRow_Night_28_en",0,], -["features.roomlist.impl.components_RoomSummaryRow_Day_29_en","features.roomlist.impl.components_RoomSummaryRow_Night_29_en",20238,], -["features.roomlist.impl.components_RoomSummaryRow_Day_2_en","features.roomlist.impl.components_RoomSummaryRow_Night_2_en",20238,], -["features.roomlist.impl.components_RoomSummaryRow_Day_30_en","features.roomlist.impl.components_RoomSummaryRow_Night_30_en",20238,], -["features.roomlist.impl.components_RoomSummaryRow_Day_31_en","features.roomlist.impl.components_RoomSummaryRow_Night_31_en",20238,], -["features.roomlist.impl.components_RoomSummaryRow_Day_32_en","features.roomlist.impl.components_RoomSummaryRow_Night_32_en",20238,], -["features.roomlist.impl.components_RoomSummaryRow_Day_33_en","features.roomlist.impl.components_RoomSummaryRow_Night_33_en",20238,], +["features.roomlist.impl.components_RoomSummaryRow_Day_29_en","features.roomlist.impl.components_RoomSummaryRow_Night_29_en",20252,], +["features.roomlist.impl.components_RoomSummaryRow_Day_2_en","features.roomlist.impl.components_RoomSummaryRow_Night_2_en",20252,], +["features.roomlist.impl.components_RoomSummaryRow_Day_30_en","features.roomlist.impl.components_RoomSummaryRow_Night_30_en",20252,], +["features.roomlist.impl.components_RoomSummaryRow_Day_31_en","features.roomlist.impl.components_RoomSummaryRow_Night_31_en",20252,], +["features.roomlist.impl.components_RoomSummaryRow_Day_32_en","features.roomlist.impl.components_RoomSummaryRow_Night_32_en",20252,], +["features.roomlist.impl.components_RoomSummaryRow_Day_33_en","features.roomlist.impl.components_RoomSummaryRow_Night_33_en",20252,], ["features.roomlist.impl.components_RoomSummaryRow_Day_3_en","features.roomlist.impl.components_RoomSummaryRow_Night_3_en",0,], ["features.roomlist.impl.components_RoomSummaryRow_Day_4_en","features.roomlist.impl.components_RoomSummaryRow_Night_4_en",0,], ["features.roomlist.impl.components_RoomSummaryRow_Day_5_en","features.roomlist.impl.components_RoomSummaryRow_Night_5_en",0,], @@ -1073,77 +1061,77 @@ export const screenshots = [ ["features.roomlist.impl.components_RoomSummaryRow_Day_7_en","features.roomlist.impl.components_RoomSummaryRow_Night_7_en",0,], ["features.roomlist.impl.components_RoomSummaryRow_Day_8_en","features.roomlist.impl.components_RoomSummaryRow_Night_8_en",0,], ["features.roomlist.impl.components_RoomSummaryRow_Day_9_en","features.roomlist.impl.components_RoomSummaryRow_Night_9_en",0,], -["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20238,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20238,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20238,], -["appicon.element_RoundIcon_en","",0,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20252,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20252,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20252,], ["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",20238,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20238,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20238,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20252,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20252,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20252,], ["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","",20238,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20252,], ["libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarInactive_Search_views_en","",0,], -["features.createroom.impl.components_SearchMultipleUsersResultItem_en","",20238,], -["features.createroom.impl.components_SearchSingleUserResultItem_en","",20238,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20238,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20238,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20238,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20238,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20238,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20238,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20238,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20238,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20238,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en","",20238,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en","",20238,], +["features.createroom.impl.components_SearchMultipleUsersResultItem_en","",20252,], +["features.createroom.impl.components_SearchSingleUserResultItem_en","",20252,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20252,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20252,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20252,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20252,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20252,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20252,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20252,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20252,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20252,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en","",20252,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en","",20252,], ["libraries.matrix.ui.components_SelectedRoom_Day_0_en","libraries.matrix.ui.components_SelectedRoom_Night_0_en",0,], ["libraries.matrix.ui.components_SelectedRoom_Day_1_en","libraries.matrix.ui.components_SelectedRoom_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedRoom_Day_2_en","libraries.matrix.ui.components_SelectedRoom_Night_2_en",0,], @@ -1151,11 +1139,11 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_0_en","libraries.matrix.ui.components_SelectedUser_Night_0_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",20238,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20238,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20238,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20238,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20238,], +["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20252,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20252,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20252,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20252,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20252,], ["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,], @@ -1165,27 +1153,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",20238,], -["features.roomlist.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.roomlist.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20238,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20238,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20238,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20238,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20238,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20238,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20238,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20252,], +["features.roomlist.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.roomlist.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20252,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20252,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20252,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20252,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20252,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20252,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20252,], ["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",20238,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20238,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20238,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20238,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20238,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20238,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20238,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20238,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20238,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20238,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20252,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20252,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20252,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20252,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20252,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20252,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20252,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20252,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20252,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20252,], ["libraries.designsystem.components.dialogs_SingleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_SingleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_SingleSelectionDialog_Night_0_en",0,], ["libraries.designsystem.components.list_SingleSelectionListItemCustomFormattert_Single_selection_List_item_-_custom_formatter_List_items_en","",0,], @@ -1194,7 +1182,7 @@ 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",20238,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20252,], ["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,], @@ -1203,60 +1191,60 @@ export const screenshots = [ ["libraries.designsystem.modifiers_SquareSizeModifierInsideSquare_en","",0,], ["libraries.designsystem.modifiers_SquareSizeModifierLargeHeight_en","",0,], ["libraries.designsystem.modifiers_SquareSizeModifierLargeWidth_en","",0,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20238,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20252,], ["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",20238,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20252,], ["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",20238,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20252,], ["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",20238,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20238,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20238,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20238,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20238,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20238,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20238,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20238,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20238,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20238,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20238,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20238,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20238,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20238,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20238,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20252,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20252,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20252,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20252,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20252,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20252,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20252,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20252,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20252,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20252,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20252,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20252,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20252,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20252,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20252,], ["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",20238,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20238,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20252,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20252,], ["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,], @@ -1268,14 +1256,14 @@ 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,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20238,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20238,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20238,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20252,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20252,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20252,], ["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",20238,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20238,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20252,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20252,], ["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,], @@ -1285,18 +1273,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",20238,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20252,], ["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",20238,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20238,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20252,], ["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,], @@ -1304,18 +1292,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",20238,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20238,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20252,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20252,], ["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",20238,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20238,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20238,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20252,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20252,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20252,], ["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",20238,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20238,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20252,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20252,], ["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,], @@ -1324,40 +1312,40 @@ 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",20238,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20252,], ["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",20238,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20252,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_9_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_9_en",0,], ["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","",20238,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20252,], ["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",20238,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20238,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20252,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20252,], ["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",20238,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20252,], ["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",20238,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20238,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20238,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20238,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20252,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20252,], ["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",20238,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20238,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20252,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20252,], ["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",20238,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20252,], ["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,], @@ -1366,8 +1354,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",20238,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20238,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20252,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20252,], ["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,], @@ -1382,8 +1370,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",20238,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20238,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20252,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20252,], ["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,], @@ -1406,73 +1394,73 @@ 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",20238,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20238,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20252,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20252,], ["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",20238,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20238,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20238,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20238,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20238,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20238,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20238,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20238,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20252,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20252,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20252,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20252,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20252,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20252,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20252,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20252,], ["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",20238,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20252,], ["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",20238,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20252,], ["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",20238,], +["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20252,], ["features.messages.impl.timeline_TimelineView_Day_9_en","features.messages.impl.timeline_TimelineView_Night_9_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",20238,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20238,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20238,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20238,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20238,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20238,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20238,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20238,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20252,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20252,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20252,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20252,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20252,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20252,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20252,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20252,], ["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",20238,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20238,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20238,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20238,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20238,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20238,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20252,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20252,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20252,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20252,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20252,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20252,], ["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","",20238,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20252,], ["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], ["libraries.designsystem.components.avatar_UserAvatarColors_Day_0_en","libraries.designsystem.components.avatar_UserAvatarColors_Night_0_en",0,], -["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20238,], -["features.createroom.impl.components_UserListView_Day_0_en","features.createroom.impl.components_UserListView_Night_0_en",20238,], -["features.createroom.impl.components_UserListView_Day_1_en","features.createroom.impl.components_UserListView_Night_1_en",20238,], -["features.createroom.impl.components_UserListView_Day_2_en","features.createroom.impl.components_UserListView_Night_2_en",20238,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20252,], +["features.createroom.impl.components_UserListView_Day_0_en","features.createroom.impl.components_UserListView_Night_0_en",20252,], +["features.createroom.impl.components_UserListView_Day_1_en","features.createroom.impl.components_UserListView_Night_1_en",20252,], +["features.createroom.impl.components_UserListView_Day_2_en","features.createroom.impl.components_UserListView_Night_2_en",20252,], ["features.createroom.impl.components_UserListView_Day_3_en","features.createroom.impl.components_UserListView_Night_3_en",0,], ["features.createroom.impl.components_UserListView_Day_4_en","features.createroom.impl.components_UserListView_Night_4_en",0,], ["features.createroom.impl.components_UserListView_Day_5_en","features.createroom.impl.components_UserListView_Night_5_en",0,], ["features.createroom.impl.components_UserListView_Day_6_en","features.createroom.impl.components_UserListView_Night_6_en",0,], -["features.createroom.impl.components_UserListView_Day_7_en","features.createroom.impl.components_UserListView_Night_7_en",20238,], +["features.createroom.impl.components_UserListView_Day_7_en","features.createroom.impl.components_UserListView_Night_7_en",20252,], ["features.createroom.impl.components_UserListView_Day_8_en","features.createroom.impl.components_UserListView_Night_8_en",0,], -["features.createroom.impl.components_UserListView_Day_9_en","features.createroom.impl.components_UserListView_Night_9_en",20238,], +["features.createroom.impl.components_UserListView_Day_9_en","features.createroom.impl.components_UserListView_Night_9_en",20252,], ["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",20238,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20238,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20238,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20238,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20238,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20238,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20238,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20238,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20238,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20238,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20238,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20238,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20252,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20252,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20252,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20252,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20252,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20252,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20252,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20252,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20252,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20252,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20252,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20252,], ["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,], @@ -1480,7 +1468,7 @@ export const screenshots = [ ["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",20238,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20252,], ["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,], @@ -1499,6 +1487,6 @@ export const screenshots = [ ["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,], -["features.ftue.impl.welcome_WelcomeView_Day_0_en","features.ftue.impl.welcome_WelcomeView_Night_0_en",20238,], +["features.ftue.impl.welcome_WelcomeView_Day_0_en","features.ftue.impl.welcome_WelcomeView_Night_0_en",20252,], ["libraries.designsystem.ruler_WithRulers_Day_0_en","libraries.designsystem.ruler_WithRulers_Night_0_en",0,], ]; diff --git a/services/toolbox/test/build.gradle.kts b/services/toolbox/test/build.gradle.kts index 9f3f9bfee3..8d2f2b8a2d 100644 --- a/services/toolbox/test/build.gradle.kts +++ b/services/toolbox/test/build.gradle.kts @@ -14,4 +14,5 @@ android { dependencies { api(projects.services.toolbox.api) + implementation(projects.tests.testutils) } diff --git a/services/toolbox/test/src/main/kotlin/io/element/android/services/toolbox/test/intent/FakeExternalIntentLauncher.kt b/services/toolbox/test/src/main/kotlin/io/element/android/services/toolbox/test/intent/FakeExternalIntentLauncher.kt index 721a6ebe1b..a8e9589b6d 100644 --- a/services/toolbox/test/src/main/kotlin/io/element/android/services/toolbox/test/intent/FakeExternalIntentLauncher.kt +++ b/services/toolbox/test/src/main/kotlin/io/element/android/services/toolbox/test/intent/FakeExternalIntentLauncher.kt @@ -9,9 +9,10 @@ package io.element.android.services.toolbox.test.intent import android.content.Intent import io.element.android.services.toolbox.api.intent.ExternalIntentLauncher +import io.element.android.tests.testutils.lambda.lambdaError class FakeExternalIntentLauncher( - var launchLambda: (Intent) -> Unit = {}, + var launchLambda: (Intent) -> Unit = { lambdaError() }, ) : ExternalIntentLauncher { override fun launch(intent: Intent) { launchLambda(intent) 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 440af51676..55371a960d 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 @@ -16,6 +16,7 @@ import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.hasText 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 import org.junit.rules.TestRule @@ -54,3 +55,8 @@ fun AndroidComposeTestRule.pressBackKey() { fun SemanticsNodeInteractionsProvider.pressTag(tag: String) { onNode(hasTestTag(tag)).performClick() } + +fun AndroidComposeTestRule.assertNoNodeWithText(@StringRes res: Int) { + val text = activity.getString(res) + onNodeWithText(text).assertDoesNotExist() +} diff --git a/tests/uitests/src/test/snapshots/images/features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en.png new file mode 100644 index 0000000000..d7e0c73390 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c2a698cd7518bc96296bcd4f9b0b51b7a09094a178bca84b853efc03b58c228 +size 25365 diff --git a/tests/uitests/src/test/snapshots/images/features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en.png new file mode 100644 index 0000000000..d5d6f55e1d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3302dd631da6a38d569425e4a827051c00d20ab5755c7787739bf7ff37441dfd +size 23622 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en.png index 052885e97e..8b6135c4fa 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19f6f6dcdf49e9ffd2fbb0ea81c3fe0374faf79cecccc812ea1e1d8c05578671 -size 22344 +oid sha256:8823f1cca4a240779ade39486854332689d114efe2d2213a9ab0720113c7f04b +size 22353 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en.png index 1e43118d49..226dc55779 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12266ee1fc3477aec0f47e731294ccd2f93ecf4a3a1fada6cf4cb8ba6f7430ac -size 22661 +oid sha256:49916050cd93d9b4aa4a90aa3ecd19bec6095e8b7cb472a3543867c0ce6f9ffa +size 22783 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en.png index 16e9f5cc43..829cf58db8 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:138be910fa88b2e59882b909f5d83824503d88676d23d327c1f4948121cbebe0 -size 14297 +oid sha256:f4494a2cf13d267a1051ea3fbe4476d2354b8c7827d1b93aabacf5bbe063dc3a +size 49269 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en.png index 5808ed69cf..8e03a6e18d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4b9ce5853af7f03ac91da6bb318bd4f033936279d211e87efff4ef6ec8794f51 -size 13988 +oid sha256:affff20aa09000132ffa8535a81d888263e9d530144c8b96e15d25c1873254c9 +size 54426 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_0_en.png index f498c22ffe..a76b26e9aa 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:74bf9b7af113c4299c1d9807ac017117b3967e2c6edb0c3f84dfb2e8aa5efc70 -size 5543 +oid sha256:b491cce2773778b379853898e495301778fc97bc31e045360b39a2b09f29f844 +size 5789 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_10_en.png deleted file mode 100644 index f60f6ad5b1..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_10_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:643d87a9c1f2befdb5407a88a7590fa8598807db995d10c8b9c6460910a61b2e -size 5594 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_11_en.png deleted file mode 100644 index 0b38c37c2a..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_11_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:27e390a8045e54f5042bf038bba1b24df23e160abd662519d16483323d638ac6 -size 5411 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_12_en.png deleted file mode 100644 index 1563e58f86..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_12_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9fc37060281ce74491304a8b64e10e1664a29c1fb0d590ec80ac2e8336610198 -size 5780 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_13_en.png deleted file mode 100644 index 183b92a6cb..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_13_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f179e72eede44c7a1add39698519b07649bb978dd63170405c57fed261bfa871 -size 5618 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_14_en.png deleted file mode 100644 index 41780cbc77..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_14_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d068727866699683382b9b2344d685246568dd4a1fa27a91bf73c3b7a4ef76af -size 5773 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_15_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_15_en.png deleted file mode 100644 index 89f4be732c..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_15_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d823b36a5eeb8e888a5351633d47f8fcc70713021d224d37f302711c189398ea -size 5605 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_1_en.png index 5bc122015d..65909d6d48 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e65e7d7fa6a9b781e67c28d160278988241e73107f721bbfb3298dcb317d167 -size 5377 +oid sha256:675122178c926902a7c6b92ca15b7652a3099de144b9f990c7ef8a495e41b148 +size 5833 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_2_en.png index 0ad5b2ae4f..67df9853a1 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6ffa4545e93d9ff24a32c94b4da23029b7316537c7328f4347f2a3de257c9df -size 5504 +oid sha256:6b5981fda0fd6d7016f77c4fe9955690f2d6dab5825f320f1795d3fd460ffa63 +size 6076 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_3_en.png index 748bf14d95..5b61d53e6d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69eb45afa5b3b408c4ad0a713f87df56e6574e23538ed33694f352502b8401c8 -size 5333 +oid sha256:a9b027e16bf586857cad161205b7ca0445932d00c1f6b630dc50126394233153 +size 6192 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_4_en.png index 1685d89c08..d5ef562f0e 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3ea0f61fd842467be5ca9804265c29243b329ed7852a55dc7447dc3140e6658 -size 5807 +oid sha256:3fe1e1da27262a08ed7c59d7c0951e72836b26ec554688f0426ac9a38f436d0f +size 5846 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_5_en.png index cbee49d65e..ef512ba6ed 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e37bc6f4a19e25c238f3fb6c6e919a41a1da3fde930b951b7a08b15b7ab97e1 -size 5666 +oid sha256:8022a0fc45eca8d244a4aa2ddaa25e50c1ff03ad380f39c4c4693b8cfc978148 +size 5902 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_6_en.png index 97a25a3169..e20b582e84 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b6b7b54481a82deeedbdb66ce90191a4894fe25244cc3c70fba571fac74544e5 -size 5899 +oid sha256:2e1a2505f900b21e0396bee6733b5ce9170fddd9c15038f121abbbe30ae95281 +size 6076 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_7_en.png index ca29f20049..f20043707f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cfd4525483b1be593b9ad6fb098ff7597c7300e6c5b50e2b8316941c4cdba405 -size 5704 +oid sha256:cb5c7bdb55eaa8b5cd532b3b1b60158a18c4f13f559b1b6040807696343b8775 +size 6096 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_8_en.png deleted file mode 100644 index 43a7044112..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_8_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7450b6d88936c9ea016d6bc39dd9bcd6efb61e28a3282d2f7808a178e8ecd355 -size 5545 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_9_en.png deleted file mode 100644 index b3d1b807ef..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Day_9_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d29074ffc73aa10e27b4cb89b65ea736d50952e060bcf312a04b417e7f253e9a -size 5387 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_0_en.png index c8aee9eda7..c58b83d0ef 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96f0584206f23483d1ad6831dbfaece6f7531edcc76bcdba11d7cd1aa57fca4e -size 5659 +oid sha256:c98e2c35da18aaa8f5fce58515e86f171cc4df8787d34ae3b1a9567d49c4137e +size 5924 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_10_en.png deleted file mode 100644 index b88bbac098..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_10_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:00f73509f6efad9f6f2ce54f3a9706b9ccb2720e9119a0c9ba7abf8eea3856f8 -size 5603 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_11_en.png deleted file mode 100644 index efee6943a9..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_11_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d1d1fc4bac417bcd906c813e3d0442b2d38593c9e9fdaf7d93aa6dc20ecb3c44 -size 5417 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_12_en.png deleted file mode 100644 index a695072c6f..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_12_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e7045956cb362717e97cb10573cccf7774c872664c9b2178e6e73195eaa9c76a -size 5980 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_13_en.png deleted file mode 100644 index f80ceab33b..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_13_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8e2728835c30759efc96ba5a7d93af9b692fe059ec2f09b879f4c045ab6b6a5e -size 5804 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_14_en.png deleted file mode 100644 index dfb8a91ae2..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_14_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2edea761c0bbd7f9d0d68f39eff5d69cf5dc9599a71c27ba2c5730d862c99692 -size 5801 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_15_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_15_en.png deleted file mode 100644 index c8963479ec..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_15_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a35938676790d0d69ea6688f3e5d1c0440684dd69ea2e97162e60fab8c250c26 -size 5636 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_1_en.png index 28315f21c1..b75dd051f0 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:22d7f35612dd607d238774b3dd23ff07f8a22b882b15386d6ebed94eb6db642d -size 5483 +oid sha256:d8ec24f4135061fbf08aebd29b4b7d8bf3f988bf3b0d28bf602410afcc4a80f4 +size 5815 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_2_en.png index 82ce25b7e4..373431a91f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d9dd8b04317b9c35c13ec156c94c275074e6779a6ed6505a44fbb73d384fd6e3 -size 5512 +oid sha256:d86a47bcce5e883f2b94b98258fa7c944532d96f0db518d3bba4365cfde530ed +size 6222 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_3_en.png index c2e484ad40..ffbd6b1195 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1cdb682c8952c3c0b687e391f412ac5a39c2dd6b8152c12ed161efa045fd97a5 -size 5344 +oid sha256:afff10df66307d03f037911b93d58396ab401e020cb74952a4ef76d8564a6cde +size 6167 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_4_en.png index 2e766a434d..80a74dbf26 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ea127648d6a70bffa2cba9a9b576c3625a06e82fcb2eae3adc8426d621309f1 -size 5892 +oid sha256:9e0d88f051140b6a31b3007b6ab92f9ba742f7c2de60dc3924a05834533e0e96 +size 5976 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_5_en.png index 531b18baaf..499fde9e32 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c3da8139ef0f63b421b5637cd6f89ea5a048bd7804018740d528dac4d2179db -size 5754 +oid sha256:44113dd74f49efb18cb98b363c8ff01323cdd8aada466560a8360205732e56d5 +size 5906 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_6_en.png index 702f44844b..5c5992d39f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:43a5225c0a3a6709fd220144469bb2f7961f4257816ed70c770093f1c2b5dc18 -size 5854 +oid sha256:f47934caa1ed08f3c3a9f70830367b7180f5a2e658d4b6c99f39e339f51dcddd +size 6235 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_7_en.png index 344b5be2f8..c77cfeda16 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29975b9dd1530aa42a10302c45045929ab81c87e970c70c432a4aacb1daf0bcf -size 5686 +oid sha256:a13158fb8eec57147ce15ca8ed29ca485986b99fe4f2801ab166bf6b90cc586d +size 6110 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_8_en.png deleted file mode 100644 index b2efbc710f..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_8_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cfdbc0d7f4d7ed694f91f3e8fb9cd02701e2d2db98373bba6361911983d6d225 -size 5674 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_9_en.png deleted file mode 100644 index a30a2e62c8..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageEventBubble_Night_9_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:956670b8fb12cc76126c8fd9bb79c877ebfa81ade6783a91b8f2147a434e23a0 -size 5502 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageShieldView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageShieldView_Day_0_en.png index b078dca532..aaeb39225f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageShieldView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageShieldView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c389d128a7f89f8351b31c6043e9b6870af2c71e5e6e7eefbf3c632e6209f8b -size 36218 +oid sha256:dc2234e1f00b0edbe3389464b1ccf375a034bb4f6daca6c80345c85dc2d4a267 +size 44822 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageShieldView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageShieldView_Night_0_en.png index 28871cc02f..9c06f766d9 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageShieldView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components_MessageShieldView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:260b0e20954785563d6abc1a66fbc8823efecf2c8125802fe13b30aa1ab21786 -size 35104 +oid sha256:caa64bc210b30027a5f0eb1ea8c20b3d170b37ee3e1ac8f535233b3209feefc7 +size 43436 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_14_en.png new file mode 100644 index 0000000000..38e26d3deb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_14_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45ead771fc133b1c992d090f35c93f0de4166b52966b818d8a401e75e5b63caf +size 62982 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_5_en.png index dbd685291f..5b6906e54a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62475d0e6b37cff42980135438faeccebe74bc110f517c12616351be8469c448 -size 55208 +oid sha256:4493799d889522a540435c10f0bf3642a438c38d6b219491afff4a72a169ce1c +size 58416 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_14_en.png new file mode 100644 index 0000000000..2b750a8c5c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_14_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5864ca4671dee1caef50d0444ffdeb0c7d2a5d9ed28ebc64937efbc469f6031a +size 65288 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_5_en.png index 012203b274..e58339319e 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4209f327f3a7cb3fbb0de25230604857e9d0e39b7ca0b2bec948656f08b2e08 -size 54804 +oid sha256:b44213fdccb6b194466d3daa7474b77378f96ab9b35559c0ba392dde49ecf175 +size 58055 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 4e7871b133..d3792f6a0a 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:60571dc08867db9ad2f6528e95cc65df0eb57b9840bf8e96e6e1fbd802ad3a26 -size 38778 +oid sha256:f3cc4924fbbb2fea5937bf481b1322da14e1d2c8ea2cf4351fd6d0d222357738 +size 41304 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 fcb6f77177..4e7871b133 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:69d9aaf46305802861df8be0341abd73068376893bfd7aef43d7b8f3251350dd -size 38735 +oid sha256:60571dc08867db9ad2f6528e95cc65df0eb57b9840bf8e96e6e1fbd802ad3a26 +size 38778 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 new file mode 100644 index 0000000000..fcb6f77177 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetailsDark_19_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69d9aaf46305802861df8be0341abd73068376893bfd7aef43d7b8f3251350dd +size 38735 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 e60ef55c42..c9734faef5 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:cabfc7c5bf6f9b612e933cad211b8261b236cd981488cfa081e0226940626339 -size 39499 +oid sha256:63c75fdca8960f015caaa11bbb970c6e7621e87afbe7761d23db875664c55cd1 +size 42360 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 2e3298b2ff..e60ef55c42 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:cf96db08ac0382185c34863b38603fe55eb3aab691fa3c42b6d73e4167ce8f82 -size 39383 +oid sha256:cabfc7c5bf6f9b612e933cad211b8261b236cd981488cfa081e0226940626339 +size 39499 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 new file mode 100644 index 0000000000..2e3298b2ff --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl_RoomDetails_19_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf96db08ac0382185c34863b38603fe55eb3aab691fa3c42b6d73e4167ce8f82 +size 39383 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_BatteryOptimizationBanner_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_BatteryOptimizationBanner_Day_0_en.png new file mode 100644 index 0000000000..6b81678de0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_BatteryOptimizationBanner_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef31a93af4f24ebada1e1436812c01d949e75d09f1259fabbe0d7a2a7eae3400 +size 26278 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_BatteryOptimizationBanner_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_BatteryOptimizationBanner_Night_0_en.png new file mode 100644 index 0000000000..6440604848 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_BatteryOptimizationBanner_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bf4b769592e06e707a727bae111a6ebf27ced4c272c4aaace3368049873182b +size 25324 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomSummaryRow_Day_34_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomSummaryRow_Day_34_en.png new file mode 100644 index 0000000000..dd6fcb47f4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomSummaryRow_Day_34_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26ec46ce726cb5a36accb280cc019a1a93d065bc6f6c74027d42efb4f7709f6a +size 14566 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomSummaryRow_Night_34_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomSummaryRow_Night_34_en.png new file mode 100644 index 0000000000..b66b1007fa --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomSummaryRow_Night_34_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc7cf18c82801dd7aea6383a0f17fdbba11e92f9e4cead38ac609d7a2238837f +size 14203 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_11_en.png new file mode 100644 index 0000000000..b7e1278591 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_11_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6041a7693307a30183606e7f8f2b605ba4c9bfb8c7ad5d8122837749813d6e2c +size 99928 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_11_en.png new file mode 100644 index 0000000000..6cafa75e88 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_11_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7563629f9df4012d7cc35b2805e1ac381ccdb171935b35cad0d1ea60186e3e7d +size 105496 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png new file mode 100644 index 0000000000..72b14d9cc3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_AvatarCluster_Avatars_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6afcae51ee69dcdb9dbf60c8f72e55b9b07e4feb72dfba0a40ffeebed6ab681 +size 25730 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_CompositeAvatar_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_CompositeAvatar_Avatars_en.png deleted file mode 100644 index d14745b783..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_CompositeAvatar_Avatars_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:374b810a6ef7011ec1270b7d4faddc8feacef10d167a5b2fc2c920d87f7d8e2c -size 27831 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TextAvatar_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TextAvatar_Avatars_en.png new file mode 100644 index 0000000000..c0cc7d6d18 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TextAvatar_Avatars_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0645d454bcaac9e38fe9b6400347ee0fc92a71ef531f72b9ec527f644e050862 +size 5488 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TombstonedRoomAvatar_Avatars_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TombstonedRoomAvatar_Avatars_en.png new file mode 100644 index 0000000000..c812b2a714 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.avatar_TombstonedRoomAvatar_Avatars_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50abd66f2c58d8cc18a96c73120a779882cd121049e473646518ff6841e25e30 +size 5106 diff --git a/tools/localazy/checkForbiddenTerms.py b/tools/localazy/checkForbiddenTerms.py index 5d04743529..2ebe582ba3 100755 --- a/tools/localazy/checkForbiddenTerms.py +++ b/tools/localazy/checkForbiddenTerms.py @@ -23,6 +23,7 @@ forbiddenTerms = { "screen_onboarding_welcome_title", # Contains "Element Call" "screen_incoming_call_subtitle_android", + "call_invalid_audio_device_bluetooth_devices_disabled", # Contains "Element X" "screen_room_timeline_legacy_call", ] diff --git a/tools/localazy/config.json b/tools/localazy/config.json index b299c39ef7..dbe8c4221a 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -165,13 +165,14 @@ "name" : ":features:roomlist:impl", "includeRegex" : [ "screen_roomlist_.*", + "screen\\.roomlist\\..*", "session_verification_banner_.*", "confirm_recovery_key_banner_.*", "banner\\.set_up_recovery\\..*", + "banner\\.battery_optimization\\..*", "full_screen_intent_banner_.*", "screen_migration_.*", - "screen_invites_.*", - "screen\\.join_room\\.knock_sent_title" + "screen_invites_.*" ] }, { @@ -210,6 +211,7 @@ "screen_room_message.*", "screen_room_retry.*", "screen_room_timeline.*", + "screen\\.room_timeline.*", "screen_room_typing.*" ] }, @@ -242,6 +244,12 @@ "screen_polls_history_.*" ] }, + { + "name" : ":features:poll:api", + "includeRegex" : [ + "a11y\\.polls\\..*" + ] + }, { "name" : ":features:securebackup:impl", "includeRegex" : [