diff --git a/changelog.d/2310.misc b/changelog.d/2310.misc new file mode 100644 index 0000000000..b5106ad927 --- /dev/null +++ b/changelog.d/2310.misc @@ -0,0 +1 @@ +Move migration screen to within the room list diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt index 5840671b6f..983e0c8db2 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/FtueFlowNode.kt @@ -33,7 +33,6 @@ import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode import io.element.android.features.analytics.api.AnalyticsEntryPoint import io.element.android.features.ftue.api.FtueEntryPoint -import io.element.android.features.ftue.impl.migration.MigrationScreenNode import io.element.android.features.ftue.impl.notifications.NotificationsOptInNode import io.element.android.features.ftue.impl.state.DefaultFtueState import io.element.android.features.ftue.impl.state.FtueStep @@ -74,9 +73,6 @@ class FtueFlowNode @AssistedInject constructor( @Parcelize data object Placeholder : NavTarget - @Parcelize - data object MigrationScreen : NavTarget - @Parcelize data object WelcomeScreen : NavTarget @@ -114,14 +110,6 @@ class FtueFlowNode @AssistedInject constructor( NavTarget.Placeholder -> { createNode(buildContext) } - NavTarget.MigrationScreen -> { - val callback = object : MigrationScreenNode.Callback { - override fun onMigrationFinished() { - lifecycleScope.launch { moveToNextStep() } - } - } - createNode(buildContext, listOf(callback)) - } NavTarget.WelcomeScreen -> { val callback = object : WelcomeNode.Callback { override fun onContinueClicked() { @@ -158,9 +146,6 @@ class FtueFlowNode @AssistedInject constructor( private fun moveToNextStep() { when (ftueState.getNextStep()) { - FtueStep.MigrationScreen -> { - backstack.newRoot(NavTarget.MigrationScreen) - } FtueStep.WelcomeScreen -> { backstack.newRoot(NavTarget.WelcomeScreen) } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenNode.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenNode.kt deleted file mode 100644 index 7c4257c422..0000000000 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenNode.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.ftue.impl.migration - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.bumble.appyx.core.modality.BuildContext -import com.bumble.appyx.core.node.Node -import com.bumble.appyx.core.plugin.Plugin -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import io.element.android.anvilannotations.ContributesNode -import io.element.android.libraries.di.SessionScope - -@ContributesNode(SessionScope::class) -class MigrationScreenNode @AssistedInject constructor( - @Assisted buildContext: BuildContext, - @Assisted plugins: List, - private val presenter: MigrationScreenPresenter, -) : Node(buildContext, plugins = plugins) { - interface Callback : Plugin { - fun onMigrationFinished() - } - - private fun onMigrationFinished() { - plugins.filterIsInstance().forEach { it.onMigrationFinished() } - } - - @Composable - override fun View(modifier: Modifier) { - val state = presenter.present() - MigrationScreenView( - state, - onMigrationFinished = ::onMigrationFinished, - modifier = modifier - ) - } -} diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt index 212919a691..ce7a769187 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/state/DefaultFtueState.kt @@ -21,11 +21,9 @@ import android.os.Build import androidx.annotation.VisibleForTesting import com.squareup.anvil.annotations.ContributesBinding import io.element.android.features.ftue.api.state.FtueState -import io.element.android.features.ftue.impl.migration.MigrationScreenStore import io.element.android.features.ftue.impl.welcome.state.WelcomeScreenState import io.element.android.features.lockscreen.api.LockScreenService import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.permissions.api.PermissionStateProvider import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider @@ -43,17 +41,14 @@ class DefaultFtueState @Inject constructor( coroutineScope: CoroutineScope, private val analyticsService: AnalyticsService, private val welcomeScreenState: WelcomeScreenState, - private val migrationScreenStore: MigrationScreenStore, private val permissionStateProvider: PermissionStateProvider, private val lockScreenService: LockScreenService, - private val matrixClient: MatrixClient, ) : FtueState { override val shouldDisplayFlow = MutableStateFlow(isAnyStepIncomplete()) override suspend fun reset() { welcomeScreenState.reset() analyticsService.reset() - migrationScreenStore.reset() if (sdkVersionProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) { permissionStateProvider.resetPermission(Manifest.permission.POST_NOTIFICATIONS) } @@ -67,12 +62,7 @@ class DefaultFtueState @Inject constructor( fun getNextStep(currentStep: FtueStep? = null): FtueStep? = when (currentStep) { - null -> if (shouldDisplayMigrationScreen()) { - FtueStep.MigrationScreen - } else { - getNextStep(FtueStep.MigrationScreen) - } - FtueStep.MigrationScreen -> if (shouldDisplayWelcomeScreen()) { + null -> if (shouldDisplayWelcomeScreen()) { FtueStep.WelcomeScreen } else { getNextStep(FtueStep.WelcomeScreen) @@ -97,7 +87,6 @@ class DefaultFtueState @Inject constructor( private fun isAnyStepIncomplete(): Boolean { return listOf( - { shouldDisplayMigrationScreen() }, { shouldDisplayWelcomeScreen() }, { shouldAskNotificationPermissions() }, { needsAnalyticsOptIn() }, @@ -105,10 +94,6 @@ class DefaultFtueState @Inject constructor( ).any { it() } } - private fun shouldDisplayMigrationScreen(): Boolean { - return migrationScreenStore.isMigrationScreenNeeded(matrixClient.sessionId) - } - private fun needsAnalyticsOptIn(): Boolean { // We need this function to not be suspend, so we need to load the value through runBlocking return runBlocking { analyticsService.didAskUserConsent().first().not() } @@ -147,7 +132,6 @@ class DefaultFtueState @Inject constructor( } sealed interface FtueStep { - data object MigrationScreen : FtueStep data object WelcomeScreen : FtueStep data object NotificationsOptIn : FtueStep data object AnalyticsOptIn : FtueStep diff --git a/features/ftue/impl/src/main/res/values-be/translations.xml b/features/ftue/impl/src/main/res/values-be/translations.xml index 3d785bbbdc..413bad9132 100644 --- a/features/ftue/impl/src/main/res/values-be/translations.xml +++ b/features/ftue/impl/src/main/res/values-be/translations.xml @@ -1,7 +1,5 @@ - "Гэта аднаразовы працэс, дзякуем за чаканне." - "Налада ўліковага запісу." "Вы можаце змяніць налады пазней." "Дазвольце апавяшчэнні і ніколі не прапускайце іх" "Званкі, апытанні, пошук і многае іншае будзе дададзена пазней у гэтым годзе." diff --git a/features/ftue/impl/src/main/res/values-cs/translations.xml b/features/ftue/impl/src/main/res/values-cs/translations.xml index 9363c704ad..bc262cf2b4 100644 --- a/features/ftue/impl/src/main/res/values-cs/translations.xml +++ b/features/ftue/impl/src/main/res/values-cs/translations.xml @@ -1,7 +1,5 @@ - "Jedná se o jednorázový proces, prosíme o strpení." - "Nastavení vašeho účtu" "Nastavení můžete později změnit." "Povolte oznámení a nezmeškejte žádnou zprávu" "Hovory, hlasování, vyhledávání a další budou přidány koncem tohoto roku." diff --git a/features/ftue/impl/src/main/res/values-de/translations.xml b/features/ftue/impl/src/main/res/values-de/translations.xml index d2a71e98e5..151500adda 100644 --- a/features/ftue/impl/src/main/res/values-de/translations.xml +++ b/features/ftue/impl/src/main/res/values-de/translations.xml @@ -1,7 +1,5 @@ - "Dies ist ein einmaliger Vorgang, danke fürs Warten." - "Dein Konto wird eingerichtet." "Du kannst deine Einstellungen später ändern." "Erlaube Benachrichtigungen und verpasse keine Nachricht" "Anrufe, Umfragen, Suchfunktionen und mehr werden im Laufe des Jahres hinzugefügt." 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 b5bac7f6a1..6a3224c531 100644 --- a/features/ftue/impl/src/main/res/values-es/translations.xml +++ b/features/ftue/impl/src/main/res/values-es/translations.xml @@ -1,7 +1,5 @@ - "Este proceso solo se hace una vez, gracias por esperar." - "Configura tu cuenta" "Puedes cambiar la configuración más tarde." "Activa las notificaciones y nunca te pierdas un mensaje" "Las llamadas, las encuestas, la búsqueda y más se agregarán más adelante este año." diff --git a/features/ftue/impl/src/main/res/values-fr/translations.xml b/features/ftue/impl/src/main/res/values-fr/translations.xml index 864a887f20..15a66c2323 100644 --- a/features/ftue/impl/src/main/res/values-fr/translations.xml +++ b/features/ftue/impl/src/main/res/values-fr/translations.xml @@ -1,8 +1,6 @@ - "Il s’agit d’une opération ponctuelle, merci d’attendre quelques instants." - "Configuration de votre compte." - "Vous pourrez modifier vos paramètres ultérieurement." + "Vous pourrez modifier vos paramètres ultérieurement." "Autorisez les notifications et ne manquez aucun message" "Les appels, les sondages, les recherches et plus encore seront ajoutés plus tard cette année." "L’historique des messages pour les salons chiffrés ne sera pas disponible dans cette mise à jour." diff --git a/features/ftue/impl/src/main/res/values-hu/translations.xml b/features/ftue/impl/src/main/res/values-hu/translations.xml index 6585aaf4a8..30ec7ab478 100644 --- a/features/ftue/impl/src/main/res/values-hu/translations.xml +++ b/features/ftue/impl/src/main/res/values-hu/translations.xml @@ -1,8 +1,6 @@ - "Ez egy egyszeri folyamat, köszönjük a türelmét." - "A fiók beállítása." - "A beállításokat később is módosíthatja." + "A beállításokat később is módosíthatja." "Értesítések engedélyezése, hogy soha ne maradjon le egyetlen üzenetről sem" "A hívások, szavazások, keresések és egyebek az év további részében kerülnek hozzáadásra." "A titkosított szobák üzenetelőzményei nem lesznek elérhetők ebben a frissítésben." diff --git a/features/ftue/impl/src/main/res/values-in/translations.xml b/features/ftue/impl/src/main/res/values-in/translations.xml index 126ce6376b..c4caa3d31c 100644 --- a/features/ftue/impl/src/main/res/values-in/translations.xml +++ b/features/ftue/impl/src/main/res/values-in/translations.xml @@ -1,8 +1,6 @@ - "Ini adalah proses satu kali, terima kasih telah menunggu." - "Menyiapkan akun Anda." - "Anda dapat mengubah pengaturan Anda nanti." + "Anda dapat mengubah pengaturan Anda nanti." "Izinkan pemberitahuan dan jangan pernah melewatkan pesan" "Panggilan, pemungutan suara, pencarian, dan lainnya akan ditambahkan di tahun ini." "Riwayat pesan untuk ruangan terenkripsi tidak akan tersedia dalam pembaruan ini." diff --git a/features/ftue/impl/src/main/res/values-it/translations.xml b/features/ftue/impl/src/main/res/values-it/translations.xml index 69013ebdb8..b4bb889c93 100644 --- a/features/ftue/impl/src/main/res/values-it/translations.xml +++ b/features/ftue/impl/src/main/res/values-it/translations.xml @@ -1,8 +1,6 @@ - "Si tratta di una procedura che si effettua una sola volta, grazie per l\'attesa." - "Configurazione del tuo account." - "Potrai modificare le tue impostazioni in seguito." + "Potrai modificare le tue impostazioni in seguito." "Consenti le notifiche e non perdere mai un messaggio" "Chiamate, sondaggi, ricerche e altro ancora saranno aggiunti nel corso dell\'anno." "La cronologia dei messaggi per le stanze crittografate non è ancora disponibile." diff --git a/features/ftue/impl/src/main/res/values-ro/translations.xml b/features/ftue/impl/src/main/res/values-ro/translations.xml index f932256318..a1b7ca15f1 100644 --- a/features/ftue/impl/src/main/res/values-ro/translations.xml +++ b/features/ftue/impl/src/main/res/values-ro/translations.xml @@ -1,8 +1,6 @@ - "Acesta este un proces care se desfășoară o singură dată, vă mulțumim pentru așteptare." - "Contul dumneavoastră se configurează" - "Apelurile, sondajele, căutare și multe altele vor fi adăugate în cursul acestui an." + "Apelurile, sondajele, căutare și multe altele vor fi adăugate în cursul acestui an." "Istoricul mesajelor pentru camerele criptate nu va fi disponibil în această actualizare." "Ne-ar plăcea să auzim de la dumneavoastră, spuneți-ne ce părere aveți prin intermediul paginii de setări." "Să începem!" diff --git a/features/ftue/impl/src/main/res/values-ru/translations.xml b/features/ftue/impl/src/main/res/values-ru/translations.xml index ab225b5d0f..685b72ded1 100644 --- a/features/ftue/impl/src/main/res/values-ru/translations.xml +++ b/features/ftue/impl/src/main/res/values-ru/translations.xml @@ -1,8 +1,6 @@ - "Это одноразовый процесс, спасибо, что подождали." - "Настройка учетной записи." - "Вы можете изменить настройки позже." + "Вы можете изменить настройки позже." "Разрешите уведомления и никогда не пропустите сообщение" "Звонки, опросы, поиск и многое другое будут добавлены позже в этом году." "История сообщений для зашифрованных комнат в этом обновлении будет недоступна." diff --git a/features/ftue/impl/src/main/res/values-sk/translations.xml b/features/ftue/impl/src/main/res/values-sk/translations.xml index c7eb1f83be..e5e6654164 100644 --- a/features/ftue/impl/src/main/res/values-sk/translations.xml +++ b/features/ftue/impl/src/main/res/values-sk/translations.xml @@ -1,8 +1,6 @@ - "Ide o jednorazový proces, ďakujeme za trpezlivosť." - "Nastavenie vášho účtu." - "Svoje nastavenia môžete neskôr zmeniť." + "Svoje nastavenia môžete neskôr zmeniť." "Povoľte oznámenia a nikdy nezmeškajte žiadnu správu" "Hovory, ankety, vyhľadávanie a ďalšie funkcie pribudnú neskôr v tomto roku." "História správ pre zašifrované miestnosti nebude v tejto aktualizácii k dispozícii." diff --git a/features/ftue/impl/src/main/res/values-zh-rTW/translations.xml b/features/ftue/impl/src/main/res/values-zh-rTW/translations.xml index 1edd145776..0edb4ec4f1 100644 --- a/features/ftue/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/ftue/impl/src/main/res/values-zh-rTW/translations.xml @@ -1,8 +1,6 @@ - "這是一次性的程序,感謝您耐心等候。" - "正在設定您的帳號。" - "通話、投票、搜尋等更多功能將在今年登場。" + "通話、投票、搜尋等更多功能將在今年登場。" "在這次的更新,您無法查看聊天室內被加密的歷史訊息。" "我們很樂意聽取您的意見,請到設定頁面告訴我們您的想法。" "開始吧!" diff --git a/features/ftue/impl/src/main/res/values/localazy.xml b/features/ftue/impl/src/main/res/values/localazy.xml index f89cc622f6..3e8c86b761 100644 --- a/features/ftue/impl/src/main/res/values/localazy.xml +++ b/features/ftue/impl/src/main/res/values/localazy.xml @@ -1,7 +1,5 @@ - "This is a one time process, thanks for waiting." - "Setting up your account." "You can change your settings later." "Allow notifications and never miss a message" "Calls, polls, search and more will be added later this year." diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt index 44df35ca05..834aaa5c1f 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt +++ b/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/DefaultFtueStateTests.kt @@ -18,16 +18,11 @@ package io.element.android.features.ftue.impl import android.os.Build import com.google.common.truth.Truth.assertThat -import io.element.android.features.ftue.impl.migration.InMemoryMigrationScreenStore -import io.element.android.features.ftue.impl.migration.MigrationScreenStore import io.element.android.features.ftue.impl.state.DefaultFtueState import io.element.android.features.ftue.impl.state.FtueStep import io.element.android.features.ftue.impl.welcome.state.FakeWelcomeState import io.element.android.features.lockscreen.api.LockScreenService import io.element.android.features.lockscreen.test.FakeLockScreenService -import io.element.android.libraries.matrix.api.MatrixClient -import io.element.android.libraries.matrix.test.A_SESSION_ID -import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.permissions.impl.FakePermissionStateProvider import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService @@ -54,7 +49,6 @@ class DefaultFtueStateTests { fun `given all checks being true, should display flow is false`() = runTest { val welcomeState = FakeWelcomeState() val analyticsService = FakeAnalyticsService() - val migrationScreenStore = InMemoryMigrationScreenStore() val permissionStateProvider = FakePermissionStateProvider(permissionGranted = true) val lockScreenService = FakeLockScreenService() val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) @@ -63,14 +57,12 @@ class DefaultFtueStateTests { coroutineScope = coroutineScope, welcomeState = welcomeState, analyticsService = analyticsService, - migrationScreenStore = migrationScreenStore, permissionStateProvider = permissionStateProvider, lockScreenService = lockScreenService, ) welcomeState.setWelcomeScreenShown() analyticsService.setDidAskUserConsent() - migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) permissionStateProvider.setPermissionGranted() lockScreenService.setIsPinSetup(true) state.updateState() @@ -85,7 +77,6 @@ class DefaultFtueStateTests { fun `traverse flow`() = runTest { val welcomeState = FakeWelcomeState() val analyticsService = FakeAnalyticsService() - val migrationScreenStore = InMemoryMigrationScreenStore() val permissionStateProvider = FakePermissionStateProvider(permissionGranted = false) val lockScreenService = FakeLockScreenService() val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) @@ -94,29 +85,24 @@ class DefaultFtueStateTests { coroutineScope = coroutineScope, welcomeState = welcomeState, analyticsService = analyticsService, - migrationScreenStore = migrationScreenStore, permissionStateProvider = permissionStateProvider, lockScreenService = lockScreenService, ) val steps = mutableListOf() - // First step, migration screen - steps.add(state.getNextStep(steps.lastOrNull())) - migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) - - // Second step, welcome screen + // First step, welcome screen steps.add(state.getNextStep(steps.lastOrNull())) welcomeState.setWelcomeScreenShown() - // Third step, notifications opt in + // Second step, notifications opt in steps.add(state.getNextStep(steps.lastOrNull())) permissionStateProvider.setPermissionGranted() - // Fourth step, entering PIN code + // Third step, entering PIN code steps.add(state.getNextStep(steps.lastOrNull())) lockScreenService.setIsPinSetup(true) - // Fifth step, analytics opt in + // Fourth step, analytics opt in steps.add(state.getNextStep(steps.lastOrNull())) analyticsService.setDidAskUserConsent() @@ -124,7 +110,6 @@ class DefaultFtueStateTests { steps.add(state.getNextStep(steps.lastOrNull())) assertThat(steps).containsExactly( - FtueStep.MigrationScreen, FtueStep.WelcomeScreen, FtueStep.NotificationsOptIn, FtueStep.LockscreenSetup, @@ -141,19 +126,16 @@ class DefaultFtueStateTests { fun `if a check for a step is true, start from the next one`() = runTest { val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) val analyticsService = FakeAnalyticsService() - val migrationScreenStore = InMemoryMigrationScreenStore() val permissionStateProvider = FakePermissionStateProvider(permissionGranted = false) val lockScreenService = FakeLockScreenService() val state = createState( coroutineScope = coroutineScope, analyticsService = analyticsService, - migrationScreenStore = migrationScreenStore, permissionStateProvider = permissionStateProvider, lockScreenService = lockScreenService, ) - // Skip first 4 steps - migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) + // Skip first 3 steps state.setWelcomeScreenShown() permissionStateProvider.setPermissionGranted() lockScreenService.setIsPinSetup(true) @@ -171,18 +153,15 @@ class DefaultFtueStateTests { fun `if version is older than 13 we don't display the notification opt in screen`() = runTest { val coroutineScope = CoroutineScope(coroutineContext + SupervisorJob()) val analyticsService = FakeAnalyticsService() - val migrationScreenStore = InMemoryMigrationScreenStore() val lockScreenService = FakeLockScreenService() val state = createState( sdkIntVersion = Build.VERSION_CODES.M, coroutineScope = coroutineScope, analyticsService = analyticsService, - migrationScreenStore = migrationScreenStore, lockScreenService = lockScreenService, ) - migrationScreenStore.setMigrationScreenShown(A_SESSION_ID) assertThat(state.getNextStep()).isEqualTo(FtueStep.WelcomeScreen) state.setWelcomeScreenShown() lockScreenService.setIsPinSetup(true) @@ -200,9 +179,7 @@ class DefaultFtueStateTests { coroutineScope: CoroutineScope, welcomeState: FakeWelcomeState = FakeWelcomeState(), analyticsService: AnalyticsService = FakeAnalyticsService(), - migrationScreenStore: MigrationScreenStore = InMemoryMigrationScreenStore(), permissionStateProvider: FakePermissionStateProvider = FakePermissionStateProvider(permissionGranted = false), - matrixClient: MatrixClient = FakeMatrixClient(), lockScreenService: LockScreenService = FakeLockScreenService(), // First version where notification permission is required sdkIntVersion: Int = Build.VERSION_CODES.TIRAMISU, @@ -211,9 +188,7 @@ class DefaultFtueStateTests { coroutineScope = coroutineScope, analyticsService = analyticsService, welcomeScreenState = welcomeState, - migrationScreenStore = migrationScreenStore, permissionStateProvider = permissionStateProvider, lockScreenService = lockScreenService, - matrixClient = matrixClient, ) } diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListView.kt index e8a3bddc43..ed6d8b1825 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListView.kt @@ -25,11 +25,11 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle +import io.element.android.compound.theme.ElementTheme import io.element.android.features.login.impl.R import io.element.android.features.login.impl.error.isWaitListError import io.element.android.features.login.impl.error.loginError @@ -123,7 +123,7 @@ private fun OverallContent( ) { Box(modifier = modifier.fillMaxSize()) { if (state.loginAction !is AsyncData.Success) { - CompositionLocalProvider(LocalContentColor provides Color.Black) { + CompositionLocalProvider(LocalContentColor provides ElementTheme.colors.textOnSolidPrimary) { TextButton( text = stringResource(CommonStrings.action_cancel), onClick = onCancelClicked, diff --git a/features/preferences/impl/build.gradle.kts b/features/preferences/impl/build.gradle.kts index e6a605f5e4..ee0658ddc6 100644 --- a/features/preferences/impl/build.gradle.kts +++ b/features/preferences/impl/build.gradle.kts @@ -55,6 +55,7 @@ dependencies { implementation(projects.features.analytics.api) implementation(projects.features.ftue.api) implementation(projects.features.logout.api) + implementation(projects.features.roomlist.api) implementation(projects.services.analytics.api) implementation(projects.services.toolbox.api) implementation(libs.datetime) 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 07ca0716e9..2d590b90c1 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 @@ -24,6 +24,7 @@ import coil.annotation.ExperimentalCoilApi import com.squareup.anvil.annotations.ContributesBinding import io.element.android.features.ftue.api.state.FtueState import io.element.android.features.preferences.impl.DefaultCacheService +import io.element.android.features.roomlist.api.migration.MigrationScreenStore import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.SessionScope @@ -45,6 +46,7 @@ class DefaultClearCacheUseCase @Inject constructor( private val defaultCacheIndexProvider: DefaultCacheService, private val okHttpClient: Provider, private val ftueState: FtueState, + private val migrationScreenStore: MigrationScreenStore, ) : ClearCacheUseCase { override suspend fun invoke() = withContext(coroutineDispatchers.io) { // Clear Matrix cache @@ -60,6 +62,8 @@ class DefaultClearCacheUseCase @Inject constructor( context.cacheDir.deleteRecursively() // Clear some settings ftueState.reset() + // Clear migration screen store + migrationScreenStore.reset() // Ensure the app is restarted defaultCacheIndexProvider.onClearedCache(matrixClient.sessionId) } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenStore.kt b/features/roomlist/api/src/main/kotlin/io/element/android/features/roomlist/api/migration/MigrationScreenStore.kt similarity index 93% rename from features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenStore.kt rename to features/roomlist/api/src/main/kotlin/io/element/android/features/roomlist/api/migration/MigrationScreenStore.kt index 42eeab673a..6e20b1ad4a 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenStore.kt +++ b/features/roomlist/api/src/main/kotlin/io/element/android/features/roomlist/api/migration/MigrationScreenStore.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.ftue.impl.migration +package io.element.android.features.roomlist.api.migration import io.element.android.libraries.matrix.api.core.SessionId 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 421cdb0c62..f25ebcec20 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 @@ -33,6 +33,7 @@ import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.roomlist.impl.datasource.InviteStateDataSource import io.element.android.features.roomlist.impl.datasource.RoomListDataSource +import io.element.android.features.roomlist.impl.migration.MigrationScreenPresenter import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher @@ -63,6 +64,7 @@ class RoomListPresenter @Inject constructor( private val encryptionService: EncryptionService, private val featureFlagService: FeatureFlagService, private val indicatorService: IndicatorService, + private val migrationScreenPresenter: MigrationScreenPresenter, ) : Presenter { @Composable override fun present(): RoomListState { @@ -82,6 +84,8 @@ class RoomListPresenter @Inject constructor( initialLoad(matrixUser) } + val isMigrating = migrationScreenPresenter.present().isMigrating + // Session verification status (unknown, not verified, verified) val canVerifySession by sessionVerificationService.canVerifySessionFlow.collectAsState(initial = false) var verificationPromptDismissed by rememberSaveable { mutableStateOf(false) } @@ -148,6 +152,7 @@ class RoomListPresenter @Inject constructor( displaySearchResults = displaySearchResults, contextMenu = contextMenu, leaveRoomState = leaveRoomState, + displayMigrationStatus = isMigrating, eventSink = ::handleEvents ) } 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 b1180aecb3..13ba030720 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 @@ -40,6 +40,7 @@ data class RoomListState( val displaySearchResults: Boolean, val contextMenu: ContextMenu, val leaveRoomState: LeaveRoomState, + val displayMigrationStatus: Boolean, val eventSink: (RoomListEvents) -> Unit, ) { sealed interface ContextMenu { 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 55cbcf925b..7fda3a180a 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 @@ -53,6 +53,7 @@ open class RoomListStateProvider : PreviewParameterProvider { aRoomListState().copy(displayRecoveryKeyPrompt = true), aRoomListState().copy(roomList = AsyncData.Success(persistentListOf())), aRoomListState().copy(roomList = AsyncData.Loading(prevData = RoomListRoomSummaryFactory.createFakeList())), + aRoomListState().copy(matrixUser = null, displayMigrationStatus = true), ) } @@ -70,6 +71,7 @@ internal fun aRoomListState() = RoomListState( displaySearchResults = false, contextMenu = RoomListState.ContextMenu.Hidden, leaveRoomState = aLeaveRoomState(), + displayMigrationStatus = false, eventSink = {} ) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt index ac55e6a0f4..3d084e15c4 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt @@ -54,6 +54,7 @@ import io.element.android.features.roomlist.impl.components.RequestVerificationH import io.element.android.features.roomlist.impl.components.RoomListMenuAction import io.element.android.features.roomlist.impl.components.RoomListTopBar import io.element.android.features.roomlist.impl.components.RoomSummaryRow +import io.element.android.features.roomlist.impl.migration.MigrationScreenView import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.roomlist.impl.search.RoomListSearchResultView import io.element.android.libraries.architecture.AsyncData @@ -212,6 +213,7 @@ private fun RoomListContent( onMenuActionClicked = onMenuActionClicked, onOpenSettings = onOpenSettings, scrollBehavior = scrollBehavior, + displayMenuItems = !state.displayMigrationStatus, ) }, content = { padding -> @@ -270,18 +272,22 @@ private fun RoomListContent( } } } + + MigrationScreenView(isMigrating = state.displayMigrationStatus) }, floatingActionButton = { - FloatingActionButton( - // FIXME align on Design system theme - containerColor = MaterialTheme.colorScheme.primary, - onClick = onCreateRoomClicked - ) { - Icon( - // Note cannot use Icons.Outlined.EditSquare, it does not exist :/ - resourceId = CommonDrawables.ic_new_message, - contentDescription = stringResource(id = R.string.screen_roomlist_a11y_create_message) - ) + if (!state.displayMigrationStatus) { + FloatingActionButton( + // FIXME align on Design system theme + containerColor = MaterialTheme.colorScheme.primary, + onClick = onCreateRoomClicked + ) { + Icon( + // Note cannot use Icons.Outlined.EditSquare, it does not exist :/ + resourceId = CommonDrawables.ic_new_message, + contentDescription = stringResource(id = R.string.screen_roomlist_a11y_create_message) + ) + } } }, snackbarHost = { SnackbarHost(snackbarHostState) }, diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt index 91b1dc4384..731e195744 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt @@ -21,8 +21,10 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.TopAppBarDefaults @@ -68,6 +70,7 @@ import io.element.android.libraries.designsystem.theme.components.HorizontalDivi import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.MediumTopAppBar +import io.element.android.libraries.designsystem.theme.components.Surface import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser @@ -89,6 +92,7 @@ fun RoomListTopBar( onMenuActionClicked: (RoomListMenuAction) -> Unit, onOpenSettings: () -> Unit, scrollBehavior: TopAppBarScrollBehavior, + displayMenuItems: Boolean, modifier: Modifier = Modifier, ) { fun closeFilter() { @@ -108,6 +112,7 @@ fun RoomListTopBar( onSearchClicked = onToggleSearch, onMenuActionClicked = onMenuActionClicked, scrollBehavior = scrollBehavior, + displayMenuItems = displayMenuItems, modifier = modifier, ) } @@ -122,6 +127,7 @@ private fun DefaultRoomListTopBar( onOpenSettings: () -> Unit, onSearchClicked: () -> Unit, onMenuActionClicked: (RoomListMenuAction) -> Unit, + displayMenuItems: Boolean, modifier: Modifier = Modifier, ) { // We need this to manually clip the top app bar in preview mode @@ -195,79 +201,89 @@ private fun DefaultRoomListTopBar( Text(text = stringResource(id = R.string.screen_roomlist_main_space_title)) }, navigationIcon = { - avatarData?.let { - IconButton( - modifier = Modifier.testTag(TestTags.homeScreenSettings), - onClick = onOpenSettings - ) { + IconButton( + modifier = Modifier.testTag(TestTags.homeScreenSettings), + onClick = onOpenSettings + ) { + if (avatarData != null) { Avatar( - avatarData = it, + avatarData = avatarData!!, contentDescription = stringResource(CommonStrings.common_settings), ) - if (showAvatarIndicator) { - RedIndicatorAtom( - modifier = Modifier - .padding(4.5.dp) - .align(Alignment.TopEnd) - ) - } + } else { + // Placeholder avatar until the avatarData is available + Surface( + modifier = Modifier.size(AvatarSize.CurrentUserTopBar.dp), + shape = CircleShape, + color = ElementTheme.colors.iconSecondary, + content = {} + ) + } + if (showAvatarIndicator) { + RedIndicatorAtom( + modifier = Modifier + .padding(4.5.dp) + .align(Alignment.TopEnd) + ) } } }, actions = { - IconButton( - onClick = onSearchClicked, - ) { - Icon( - imageVector = CompoundIcons.Search, - contentDescription = stringResource(CommonStrings.action_search), - ) - } - if (RoomListConfig.HAS_DROP_DOWN_MENU) { - var showMenu by remember { mutableStateOf(false) } + if (displayMenuItems) { IconButton( - onClick = { showMenu = !showMenu } + onClick = onSearchClicked, ) { Icon( - imageVector = CompoundIcons.OverflowVertical, - contentDescription = null, + imageVector = CompoundIcons.Search, + contentDescription = stringResource(CommonStrings.action_search), ) } - DropdownMenu( - expanded = showMenu, - onDismissRequest = { showMenu = false } - ) { - if (RoomListConfig.SHOW_INVITE_MENU_ITEM) { - DropdownMenuItem( - onClick = { - showMenu = false - onMenuActionClicked(RoomListMenuAction.InviteFriends) - }, - text = { Text(stringResource(id = CommonStrings.action_invite)) }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.ShareAndroid, - tint = ElementTheme.materialColors.secondary, - contentDescription = null, - ) - } + if (RoomListConfig.HAS_DROP_DOWN_MENU) { + var showMenu by remember { mutableStateOf(false) } + IconButton( + onClick = { showMenu = !showMenu } + ) { + Icon( + imageVector = CompoundIcons.OverflowVertical, + contentDescription = null, ) } - if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM) { - DropdownMenuItem( - onClick = { - showMenu = false - onMenuActionClicked(RoomListMenuAction.ReportBug) - }, - text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.ChatProblem, - tint = ElementTheme.materialColors.secondary, - contentDescription = null, - ) - } - ) + DropdownMenu( + expanded = showMenu, + onDismissRequest = { showMenu = false } + ) { + if (RoomListConfig.SHOW_INVITE_MENU_ITEM) { + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClicked(RoomListMenuAction.InviteFriends) + }, + text = { Text(stringResource(id = CommonStrings.action_invite)) }, + leadingIcon = { + Icon( + imageVector = CompoundIcons.ShareAndroid, + tint = ElementTheme.materialColors.secondary, + contentDescription = null, + ) + } + ) + } + if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM) { + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClicked(RoomListMenuAction.ReportBug) + }, + text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) }, + leadingIcon = { + Icon( + imageVector = CompoundIcons.ChatProblem, + tint = ElementTheme.materialColors.secondary, + contentDescription = null, + ) + } + ) + } } } } @@ -299,6 +315,7 @@ internal fun DefaultRoomListTopBarPreview() = ElementPreview { scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()), onOpenSettings = {}, onSearchClicked = {}, + displayMenuItems = true, onMenuActionClicked = {}, ) } @@ -314,6 +331,7 @@ internal fun DefaultRoomListTopBarWithIndicatorPreview() = ElementPreview { scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()), onOpenSettings = {}, onSearchClicked = {}, + displayMenuItems = true, onMenuActionClicked = {}, ) } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenter.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenPresenter.kt similarity index 73% rename from features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenter.kt rename to features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenPresenter.kt index 6507130383..4886eca7bb 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenter.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenPresenter.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 New Vector Ltd + * Copyright (c) 2024 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,16 @@ * limitations under the License. */ -package io.element.android.features.ftue.impl.migration +package io.element.android.features.roomlist.impl.migration import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import io.element.android.features.roomlist.api.migration.MigrationScreenStore import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.roomlist.RoomListService @@ -32,13 +36,15 @@ class MigrationScreenPresenter @Inject constructor( @Composable override fun present(): MigrationScreenState { val roomListState by matrixClient.roomListService.state.collectAsState() + var needsMigration by remember { mutableStateOf(migrationScreenStore.isMigrationScreenNeeded(matrixClient.sessionId)) } if (roomListState == RoomListService.State.Running) { LaunchedEffect(Unit) { + needsMigration = false migrationScreenStore.setMigrationScreenShown(matrixClient.sessionId) } } return MigrationScreenState( - isMigrating = roomListState != RoomListService.State.Running + isMigrating = needsMigration && roomListState != RoomListService.State.Running ) } } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenState.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenState.kt similarity index 91% rename from features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenState.kt rename to features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenState.kt index fa718990e4..884c706da5 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenState.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenState.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.ftue.impl.migration +package io.element.android.features.roomlist.impl.migration data class MigrationScreenState( val isMigrating: Boolean diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenView.kt similarity index 54% rename from features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenView.kt rename to features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenView.kt index 54a1b541be..b7627f1ce0 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenView.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 New Vector Ltd + * Copyright (c) 2024 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,45 +14,43 @@ * limitations under the License. */ -package io.element.android.features.ftue.impl.migration +package io.element.android.features.roomlist.impl.migration +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.tween import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.res.stringResource -import io.element.android.features.ftue.impl.R +import io.element.android.features.roomlist.impl.R import io.element.android.libraries.designsystem.atomic.pages.SunsetPage import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @Composable fun MigrationScreenView( - migrationState: MigrationScreenState, - onMigrationFinished: () -> Unit, + isMigrating: Boolean, modifier: Modifier = Modifier, ) { - if (migrationState.isMigrating.not()) { - val latestOnMigrationFinished by rememberUpdatedState(onMigrationFinished) - LaunchedEffect(Unit) { - latestOnMigrationFinished() - } - } - SunsetPage( - modifier = modifier, - isLoading = true, - title = stringResource(id = R.string.screen_migration_title), - subtitle = stringResource(id = R.string.screen_migration_message), - overallContent = {} + val displayMigrationStatusFadeProgress by animateFloatAsState( + targetValue = if (isMigrating) 1f else 0f, + animationSpec = tween(durationMillis = 200), + label = "Migration view fade" ) + if (displayMigrationStatusFadeProgress > 0f) { + SunsetPage( + modifier = modifier.alpha(displayMigrationStatusFadeProgress), + isLoading = true, + title = stringResource(id = R.string.screen_migration_title), + subtitle = stringResource(id = R.string.screen_migration_message), + overallContent = {} + ) + } } -@PreviewsDayNight @Composable +@PreviewsDayNight internal fun MigrationViewPreview() = ElementPreview { - MigrationScreenView( - migrationState = MigrationScreenState(isMigrating = true), - onMigrationFinished = {} - ) + MigrationScreenView(isMigrating = true) } diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/SharedPrefsMigrationScreenStore.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/SharedPrefsMigrationScreenStore.kt similarity index 92% rename from features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/SharedPrefsMigrationScreenStore.kt rename to features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/SharedPrefsMigrationScreenStore.kt index 8ece45c08c..62121fd282 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/migration/SharedPrefsMigrationScreenStore.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/migration/SharedPrefsMigrationScreenStore.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 New Vector Ltd + * Copyright (c) 2024 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,11 +14,12 @@ * limitations under the License. */ -package io.element.android.features.ftue.impl.migration +package io.element.android.features.roomlist.impl.migration import android.content.SharedPreferences import androidx.core.content.edit import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.features.roomlist.api.migration.MigrationScreenStore import io.element.android.libraries.androidutils.hash.hash import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.DefaultPreferences diff --git a/features/roomlist/impl/src/main/res/values/localazy.xml b/features/roomlist/impl/src/main/res/values/localazy.xml index 7f0c4cce9c..d9980835f4 100644 --- a/features/roomlist/impl/src/main/res/values/localazy.xml +++ b/features/roomlist/impl/src/main/res/values/localazy.xml @@ -2,6 +2,8 @@ "Your chat backup is currently out of sync. You need to confirm your recovery key to maintain access to your chat backup." "Confirm your recovery key" + "This is a one time process, thanks for waiting." + "Setting up your account." "Create a new conversation or room" "Get started by messaging someone." "No chats yet." diff --git a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt index 09d6f12e0c..10730f0c90 100644 --- a/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/RoomListPresenterTests.kt @@ -29,6 +29,8 @@ import io.element.android.features.roomlist.impl.datasource.FakeInviteDataSource import io.element.android.features.roomlist.impl.datasource.InviteStateDataSource import io.element.android.features.roomlist.impl.datasource.RoomListDataSource import io.element.android.features.roomlist.impl.datasource.RoomListRoomSummaryFactory +import io.element.android.features.roomlist.impl.migration.InMemoryMigrationScreenStore +import io.element.android.features.roomlist.impl.migration.MigrationScreenPresenter import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.libraries.dateformatter.api.LastMessageTimestampFormatter import io.element.android.libraries.dateformatter.test.FakeLastMessageTimestampFormatter @@ -44,12 +46,14 @@ import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.encryption.BackupState import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.room.RoomNotificationMode +import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME +import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_NAME import io.element.android.libraries.matrix.test.FakeMatrixClient @@ -396,6 +400,36 @@ class RoomListPresenterTests { } } + @Test + fun `present - change in migration presenter state modifies isMigrating`() = runTest { + val client = FakeMatrixClient(sessionId = A_SESSION_ID) + val migrationStore = InMemoryMigrationScreenStore() + val migrationScreenPresenter = MigrationScreenPresenter(client, migrationStore) + val scope = CoroutineScope(coroutineContext + SupervisorJob()) + val presenter = createRoomListPresenter( + client = client, + coroutineScope = scope, + migrationScreenPresenter = migrationScreenPresenter, + ) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + // The migration screen is shown if the migration screen has not been shown before + assertThat(initialState.displayMigrationStatus).isTrue() + skipItems(2) + + // Set migration as done and set the room list service as running to trigger a refresh of the presenter value + (client.roomListService as FakeRoomListService).postState(RoomListService.State.Running) + migrationStore.setMigrationScreenShown(A_SESSION_ID) + + // The migration screen is not shown anymore + assertThat(awaitItem().displayMigrationStatus).isFalse() + cancelAndIgnoreRemainingEvents() + scope.cancel() + } + } + private fun TestScope.createRoomListPresenter( client: MatrixClient = FakeMatrixClient(), sessionVerificationService: SessionVerificationService = FakeSessionVerificationService(), @@ -409,6 +443,10 @@ class RoomListPresenterTests { roomLastMessageFormatter: RoomLastMessageFormatter = FakeRoomLastMessageFormatter(), encryptionService: EncryptionService = FakeEncryptionService(), coroutineScope: CoroutineScope, + migrationScreenPresenter: MigrationScreenPresenter = MigrationScreenPresenter( + matrixClient = client, + migrationScreenStore = InMemoryMigrationScreenStore(), + ) ) = RoomListPresenter( client = client, sessionVerificationService = sessionVerificationService, @@ -433,6 +471,7 @@ class RoomListPresenterTests { encryptionService = encryptionService, featureFlagService = FakeFeatureFlagService(mapOf(FeatureFlags.SecureStorage.key to true)), ), + migrationScreenPresenter = migrationScreenPresenter, ) } diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/InMemoryMigrationScreenStore.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/migration/InMemoryMigrationScreenStore.kt similarity index 86% rename from features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/InMemoryMigrationScreenStore.kt rename to features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/migration/InMemoryMigrationScreenStore.kt index a77a4d001a..79d0b7c628 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/InMemoryMigrationScreenStore.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/migration/InMemoryMigrationScreenStore.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 New Vector Ltd + * Copyright (c) 2024 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,8 +14,9 @@ * limitations under the License. */ -package io.element.android.features.ftue.impl.migration +package io.element.android.features.roomlist.impl.migration +import io.element.android.features.roomlist.api.migration.MigrationScreenStore import io.element.android.libraries.matrix.api.core.SessionId class InMemoryMigrationScreenStore : MigrationScreenStore { diff --git a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenterTest.kt b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenPresenterTest.kt similarity index 92% rename from features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenterTest.kt rename to features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenPresenterTest.kt index 44dcba6e00..2ddcaed566 100644 --- a/features/ftue/impl/src/test/kotlin/io/element/android/features/ftue/impl/migration/MigrationScreenPresenterTest.kt +++ b/features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/migration/MigrationScreenPresenterTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 New Vector Ltd + * Copyright (c) 2024 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,13 @@ * limitations under the License. */ -package io.element.android.features.ftue.impl.migration +package io.element.android.features.roomlist.impl.migration import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.features.roomlist.api.migration.MigrationScreenStore import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.test.A_SESSION_ID @@ -61,6 +62,7 @@ class MigrationScreenPresenterTest { val nextState = awaitItem() assertThat(nextState.isMigrating).isFalse() assertThat(migrationScreenStore.isMigrationScreenNeeded(A_SESSION_ID)).isFalse() + cancelAndIgnoreRemainingEvents() } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/SunsetPage.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/SunsetPage.kt index 476545befc..2bc4290c67 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/SunsetPage.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/SunsetPage.kt @@ -37,8 +37,10 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import io.element.android.compound.annotations.CoreColorToken import io.element.android.compound.theme.ElementTheme -import io.element.android.compound.theme.ForcedDarkElementTheme +import io.element.android.compound.tokens.generated.internal.DarkColorTokens +import io.element.android.compound.tokens.generated.internal.LightColorTokens import io.element.android.libraries.designsystem.R import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -54,7 +56,11 @@ fun SunsetPage( modifier: Modifier = Modifier, overallContent: @Composable () -> Unit, ) { - ForcedDarkElementTheme(lightStatusBar = true) { + ElementTheme( + // Always use the opposite value of the current theme + darkTheme = ElementTheme.isLightTheme, + applySystemBarsUpdate = false, + ) { Box( modifier = modifier.fillMaxSize() ) { @@ -107,21 +113,34 @@ fun SunsetPage( } } +@OptIn(CoreColorToken::class) @Composable private fun SunsetBackground( modifier: Modifier = Modifier, ) { Column(modifier = modifier.fillMaxSize()) { + // The top background colors are the opposite of the current theme ones + val topBackgroundColor = if (ElementTheme.isLightTheme) { + DarkColorTokens.colorThemeBg + } else { + LightColorTokens.colorThemeBg + } + // The bottom background colors follow the current theme + val bottomBackgroundColor = if (ElementTheme.isLightTheme) { + LightColorTokens.colorThemeBg + } else { + // The dark background color doesn't 100% match the image, so we use a custom color + Color(0xFF121418) + } Box( modifier = Modifier .fillMaxWidth() .weight(0.3f) - .background(Color.White) + .background(topBackgroundColor) ) Image( - modifier = Modifier - .fillMaxWidth(), - painter = painterResource(id = R.drawable.light_dark), + modifier = Modifier.fillMaxWidth(), + painter = painterResource(id = R.drawable.bg_migration), contentScale = ContentScale.Crop, contentDescription = null, ) @@ -129,7 +148,7 @@ private fun SunsetBackground( modifier = Modifier .fillMaxWidth() .weight(0.7f) - .background(Color(0xFF121418)) + .background(bottomBackgroundColor) ) } } 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 5742438641..bb3373b397 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 @@ -23,7 +23,6 @@ import android.os.Build import android.text.TextPaint import androidx.annotation.FloatRange import androidx.compose.foundation.Image -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.consumeWindowInsets @@ -136,13 +135,13 @@ object BloomDefaults { @Composable fun defaultLayers() = persistentListOf( // Bottom layer - if (isSystemInDarkTheme()) { - BloomLayer(0.5f, BlendMode.Exclusion) - } else { + if (ElementTheme.isLightTheme) { BloomLayer(0.2f, BlendMode.Hardlight) + } else { + BloomLayer(0.5f, BlendMode.Exclusion) }, // Top layer - BloomLayer(if (isSystemInDarkTheme()) 0.2f else 0.8f, BlendMode.Color), + BloomLayer(if (ElementTheme.isLightTheme) 0.8f else 0.2f, BlendMode.Color), ) } diff --git a/libraries/designsystem/src/main/res/drawable-night/bg_migration.png b/libraries/designsystem/src/main/res/drawable-night/bg_migration.png new file mode 100644 index 0000000000..41cba4f4ba Binary files /dev/null and b/libraries/designsystem/src/main/res/drawable-night/bg_migration.png differ diff --git a/libraries/designsystem/src/main/res/drawable/light_dark.png b/libraries/designsystem/src/main/res/drawable/bg_migration.png similarity index 100% rename from libraries/designsystem/src/main/res/drawable/light_dark.png rename to libraries/designsystem/src/main/res/drawable/bg_migration.png diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt index 286a80d71d..f87119293d 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt @@ -28,6 +28,8 @@ import io.element.android.features.roomlist.impl.RoomListView import io.element.android.features.roomlist.impl.datasource.DefaultInviteStateDataSource import io.element.android.features.roomlist.impl.datasource.RoomListDataSource import io.element.android.features.roomlist.impl.datasource.RoomListRoomSummaryFactory +import io.element.android.features.roomlist.impl.migration.MigrationScreenPresenter +import io.element.android.features.roomlist.impl.migration.SharedPrefsMigrationScreenStore import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.dateformatter.impl.DateFormatters import io.element.android.libraries.dateformatter.impl.DefaultLastMessageTimestampFormatter @@ -103,6 +105,10 @@ class RoomListScreen( featureFlagService = featureFlagService, ), featureFlagService = featureFlagService, + migrationScreenPresenter = MigrationScreenPresenter( + matrixClient = matrixClient, + migrationScreenStore = SharedPrefsMigrationScreenStore(context.getSharedPreferences("migration", Context.MODE_PRIVATE)) + ) ) @Composable diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.migration_MigrationView_null_MigrationView-Night-0_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.migration_MigrationView_null_MigrationView-Night-0_2_null,NEXUS_5,1.0,en].png deleted file mode 100644 index 99a9e03973..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.migration_MigrationView_null_MigrationView-Night-0_2_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4c9d9aa75b2b01e9b0106377fbcd88a92fb8b4d6a34323b18264fed8f9a48cab -size 133347 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_NotificationsOptInView_null_NotificationsOptInView-Day-1_2_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_NotificationsOptInView_null_NotificationsOptInView-Day-0_1_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_NotificationsOptInView_null_NotificationsOptInView-Day-1_2_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_NotificationsOptInView_null_NotificationsOptInView-Day-0_1_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_NotificationsOptInView_null_NotificationsOptInView-Night-1_3_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_NotificationsOptInView_null_NotificationsOptInView-Night-0_2_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_NotificationsOptInView_null_NotificationsOptInView-Night-1_3_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.notifications_NotificationsOptInView_null_NotificationsOptInView-Night-0_2_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_WelcomeView_null_WelcomeView-Day-2_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_WelcomeView_null_WelcomeView-Day-1_2_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_WelcomeView_null_WelcomeView-Day-2_3_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_WelcomeView_null_WelcomeView-Day-1_2_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_WelcomeView_null_WelcomeView-Night-2_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_WelcomeView_null_WelcomeView-Night-1_3_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_WelcomeView_null_WelcomeView-Night-2_4_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.welcome_WelcomeView_null_WelcomeView-Night-1_3_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_0,NEXUS_5,1.0,en].png index 412475009c..54f60964f3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce7cb3f4a50912cd7aa96340ff850d438a26e5efc331173c658448fdbecc7b65 -size 145047 +oid sha256:9db077d2e2981e9b3d431312b171741505e22816fa4b2bb3699f6ae4e00b48e9 +size 145160 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_1,NEXUS_5,1.0,en].png index f89a48fbdf..e9fdb0d176 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b06c44fcc0afee1a398dbddeb18253f25002c3c8e77929d049edd878b3927e8a -size 145776 +oid sha256:de09324bd0a41e25eff91ae77d5d88d96289a379ecf24e626fa9ea09a5acd43b +size 145928 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_2,NEXUS_5,1.0,en].png index f24b59907d..c5b8dcbb18 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:30a12c0e23d30c5841fef2f705af3fc4ea691ff06425d84a5c33f34809b78d8c -size 65492 +oid sha256:54f47ca8a687adf5528e5ff8ddd87d901d2aa1280e6252ec962c176d6a207237 +size 65584 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_3,NEXUS_5,1.0,en].png index 412475009c..54f60964f3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Day-8_9_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce7cb3f4a50912cd7aa96340ff850d438a26e5efc331173c658448fdbecc7b65 -size 145047 +oid sha256:9db077d2e2981e9b3d431312b171741505e22816fa4b2bb3699f6ae4e00b48e9 +size 145160 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_0,NEXUS_5,1.0,en].png index 412475009c..5bdbb9dbff 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce7cb3f4a50912cd7aa96340ff850d438a26e5efc331173c658448fdbecc7b65 -size 145047 +oid sha256:5d5c0f2cf39d75b09a8cc1f4ffbd65912cab79ce5881ed5da5fdadeb9f57cb00 +size 170070 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_1,NEXUS_5,1.0,en].png index f89a48fbdf..91a55dee0f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b06c44fcc0afee1a398dbddeb18253f25002c3c8e77929d049edd878b3927e8a -size 145776 +oid sha256:c23b11ebcc1e73255714b07cee27c4583a9923112cdf0eda60983925d8074bb7 +size 170640 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_2,NEXUS_5,1.0,en].png index f6aaba2f2d..17bd0f8204 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6687f1be6e8abab9ae846152cc4edeb5fe1becda4ec9bcf64c255ded9dc937a -size 63857 +oid sha256:026200b29fb2599e1f04ae19ab75cfed41a8c4aff5b0ef0086a6948244733830 +size 67437 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_3,NEXUS_5,1.0,en].png index 412475009c..5bdbb9dbff 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce7cb3f4a50912cd7aa96340ff850d438a26e5efc331173c658448fdbecc7b65 -size 145047 +oid sha256:5d5c0f2cf39d75b09a8cc1f4ffbd65912cab79ce5881ed5da5fdadeb9f57cb00 +size 170070 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_4,NEXUS_5,1.0,en].png index 220fb6de61..9b7088595f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.login.impl.screens.waitlistscreen_WaitListView_null_WaitListView-Night-8_10_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ddf3e62bd00f179fbeed4e432bd9a7a21321e83dd1d5192e3dc213fcfbc8c372 -size 128199 +oid sha256:97aa5dbc8ddcd05a44ae56771a13085096f11b2469c1a7edb3281e242d86ad21 +size 150264 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.migration_MigrationView_null_MigrationView-Day-0_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.migration_MigrationView_null_MigrationView-Day-10_11_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.ftue.impl.migration_MigrationView_null_MigrationView-Day-0_1_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.migration_MigrationView_null_MigrationView-Day-10_11_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.migration_MigrationView_null_MigrationView-Night-10_12_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.migration_MigrationView_null_MigrationView-Night-10_12_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..46a349cbce --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.migration_MigrationView_null_MigrationView-Night-10_12_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fea824bf7f4c74c827fa3c1fa892b9beeb9d11e0863fc9e5c104c725236c7d10 +size 156506 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_RoomListSearchResultContent_null_RoomListSearchResultContent-Day-10_11_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_RoomListSearchResultContent_null_RoomListSearchResultContent-Day-11_12_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_RoomListSearchResultContent_null_RoomListSearchResultContent-Day-10_11_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_RoomListSearchResultContent_null_RoomListSearchResultContent-Day-11_12_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_RoomListSearchResultContent_null_RoomListSearchResultContent-Night-10_12_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_RoomListSearchResultContent_null_RoomListSearchResultContent-Night-11_13_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_RoomListSearchResultContent_null_RoomListSearchResultContent-Night-10_12_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl.search_RoomListSearchResultContent_null_RoomListSearchResultContent-Night-11_13_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_RoomListView_null_RoomListView-Day-3_4_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_RoomListView_null_RoomListView-Day-3_4_null_12,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..f901e915e5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_RoomListView_null_RoomListView-Day-3_4_null_12,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64c4eb481f40871925405ae317cb80927caf31cb552a8aa9549bfb5658ca91e4 +size 137589 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_RoomListView_null_RoomListView-Night-3_5_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_RoomListView_null_RoomListView-Night-3_5_null_12,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..56f7f133f3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomlist.impl_RoomListView_null_RoomListView-Night-3_5_null_12,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7bf47b0a25c455b108d7b3585a42849f03c6652af73a175fe2147cb1ad62a66 +size 161125 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.pages_SunsetPage_null_SunsetPage-Night_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.pages_SunsetPage_null_SunsetPage-Night_1_null,NEXUS_5,1.0,en].png index 9a5371804e..a6b5cfab9b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.pages_SunsetPage_null_SunsetPage-Night_1_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.pages_SunsetPage_null_SunsetPage-Night_1_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:50ca2afda159bdd7f57e78b04fbe3c022a9aeee1b68f72cf4d4269b3e503f0e5 -size 127335 +oid sha256:d56b02025c9de6cca3aaa3e4cc5cd82b222790c4efa0013f957307c13e45ee40 +size 151229 diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 1bf1e9071b..2416876fa4 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -106,7 +106,8 @@ "includeRegex" : [ "screen_roomlist_.*", "session_verification_banner_.*", - "confirm_recovery_key_banner_.*" + "confirm_recovery_key_banner_.*", + "screen_migration_.*" ] }, { @@ -154,7 +155,6 @@ "name" : ":features:ftue:impl", "includeRegex" : [ "screen_welcome_.*", - "screen_migration_.*", "screen_notification_optin_.*" ] },