Repository: element-hq/element-x-android (language: kotlin)

Issue:
Move migration screen to within the room list
The current migration screen blocks the user from accessing the rest of the app, especially bug reporting and logs. This is a problem when setting up custom backend stacks.
We have agreed with product to move it from a modal to a state of the room list similar to what has been done on iOS here https://github.com/element-hq/element-x-ios/pull/2389


Discussion hints:
nan

Pull request: Move migration screen to within the room list
<!-- Please read [CONTRIBUTING.md](https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md) before submitting your pull request -->
 
## Type of change

- [ ] Feature
- [ ] Bugfix
- [ ] Technical
- [x] Other : screen redesign.

## Content

- Moves the `migration` package contents from `:features:ftue` to `:features:messages:impl`.
- Adds light variant of the migration screen.
- Updates compound version to `v0.0.4` to fix status bar tinting issues.
- Displays the migration screen inside the room list one, allowing the user to send bug reports if needed, while preventing some other actions such as searching or creating a new room.

## Motivation and context

Closes #2310.

## Screenshots / GIFs

Inside the PR. There are also changes to the wait list screen since it reuses the same `SunsetPage` component, but I believe this is the desired behaviour.

Here's also a video with the current behaviour:

https://github.com/element-hq/element-x-android/assets/480955/29405a9f-66ca-46c0-86c8-3b7cf635a407

## Tests

<!-- Explain how you tested your development -->

- Remove all data from the EX app.
- Sign in again.
- Go through the FTUE screens quickly.
- With some luck, you'll still be able to see the migration screen and interact with the empty avatar icon now to open the settings.
- The migration screen should only appear once.

## Tested devices

- [x] Physical
- [ ] Emulator
- OS version(s): 14

## Checklist

<!-- Depending on the Pull Request content, it can be acceptable if some of the following checkboxes stay unchecked. -->

- [ ] Changes have been tested on an Android device or Android emulator with API 23
- [x] UI change has been tested on both light and dark themes
- [ ] Accessibility has been taken into account. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#accessibility
- [x] Pull request is based on the develop branch
- [x] Pull request includes a new file under ./changelog.d. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#changelog
- [x] Pull request includes screenshots or videos if containing UI changes
- [ ] Pull request includes a [sign off](https://matrix-org.github.io/synapse/latest/development/contributing_guide.html#sign-off)
- [x] You've made a self review of your PR


Test command: ./gradlew :features:roomlist:impl:testDebugUnitTest --tests "io.element.android.features.roomlist.impl.migration.InMemoryMigrationScreenStore" --tests "io.element.android.features.roomlist.impl.RoomListPresenterTests" :features:ftue:impl:testDebugUnitTest --tests "io.element.android.features.ftue.impl.DefaultFtueStateTests"

Fix patch:
diff --git a/changelog.d/2310.misc b/changelog.d/2310.misc
new file mode 100644
index 00000000000..b5106ad9273
--- /dev/null
+++ b/changelog.d/2310.misc
@@ -0,0 +1,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 5840671b6fb..983e0c8db2e 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<PlaceholderNode>(buildContext)
             }
-            NavTarget.MigrationScreen -> {
-                val callback = object : MigrationScreenNode.Callback {
-                    override fun onMigrationFinished() {
-                        lifecycleScope.launch { moveToNextStep() }
-                    }
-                }
-                createNode<MigrationScreenNode>(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 7c4257c4220..00000000000
--- 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<Plugin>,
-    private val presenter: MigrationScreenPresenter,
-) : Node(buildContext, plugins = plugins) {
-    interface Callback : Plugin {
-        fun onMigrationFinished()
-    }
-
-    private fun onMigrationFinished() {
-        plugins.filterIsInstance<Callback>().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 212919a691f..ce7a769187f 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 3d785bbbdce..413bad91322 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Гэта аднаразовы працэс, дзякуем за чаканне."</string>
-  <string name="screen_migration_title">"Налада ўліковага запісу."</string>
   <string name="screen_notification_optin_subtitle">"Вы можаце змяніць налады пазней."</string>
   <string name="screen_notification_optin_title">"Дазвольце апавяшчэнні і ніколі не прапускайце іх"</string>
   <string name="screen_welcome_bullet_1">"Званкі, апытанні, пошук і многае іншае будзе дададзена пазней у гэтым годзе."</string>
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 9363c704adb..bc262cf2b46 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Jedná se o jednorázový proces, prosíme o strpení."</string>
-  <string name="screen_migration_title">"Nastavení vašeho účtu"</string>
   <string name="screen_notification_optin_subtitle">"Nastavení můžete později změnit."</string>
   <string name="screen_notification_optin_title">"Povolte oznámení a nezmeškejte žádnou zprávu"</string>
   <string name="screen_welcome_bullet_1">"Hovory, hlasování, vyhledávání a další budou přidány koncem tohoto roku."</string>
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 d2a71e98e54..151500addad 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Dies ist ein einmaliger Vorgang, danke fürs Warten."</string>
-  <string name="screen_migration_title">"Dein Konto wird eingerichtet."</string>
   <string name="screen_notification_optin_subtitle">"Du kannst deine Einstellungen später ändern."</string>
   <string name="screen_notification_optin_title">"Erlaube Benachrichtigungen und verpasse keine Nachricht"</string>
   <string name="screen_welcome_bullet_1">"Anrufe, Umfragen, Suchfunktionen und mehr werden im Laufe des Jahres hinzugefügt."</string>
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 b5bac7f6a15..6a3224c5313 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Este proceso solo se hace una vez, gracias por esperar."</string>
-  <string name="screen_migration_title">"Configura tu cuenta"</string>
   <string name="screen_notification_optin_subtitle">"Puedes cambiar la configuración más tarde."</string>
   <string name="screen_notification_optin_title">"Activa las notificaciones y nunca te pierdas un mensaje"</string>
   <string name="screen_welcome_bullet_1">"Las llamadas, las encuestas, la búsqueda y más se agregarán más adelante este año."</string>
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 864a887f20f..15a66c23230 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Il s’agit d’une opération ponctuelle, merci d’attendre quelques instants."</string>
-  <string name="screen_migration_title">"Configuration de votre compte."</string>
-  <string name="screen_notification_optin_subtitle">"Vous pourrez modifier vos paramètres ultérieurement."</string>
+    <string name="screen_notification_optin_subtitle">"Vous pourrez modifier vos paramètres ultérieurement."</string>
   <string name="screen_notification_optin_title">"Autorisez les notifications et ne manquez aucun message"</string>
   <string name="screen_welcome_bullet_1">"Les appels, les sondages, les recherches et plus encore seront ajoutés plus tard cette année."</string>
   <string name="screen_welcome_bullet_2">"L’historique des messages pour les salons chiffrés ne sera pas disponible dans cette mise à jour."</string>
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 6585aaf4a8c..30ec7ab478f 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Ez egy egyszeri folyamat, köszönjük a türelmét."</string>
-  <string name="screen_migration_title">"A fiók beállítása."</string>
-  <string name="screen_notification_optin_subtitle">"A beállításokat később is módosíthatja."</string>
+    <string name="screen_notification_optin_subtitle">"A beállításokat később is módosíthatja."</string>
   <string name="screen_notification_optin_title">"Értesítések engedélyezése, hogy soha ne maradjon le egyetlen üzenetről sem"</string>
   <string name="screen_welcome_bullet_1">"A hívások, szavazások, keresések és egyebek az év további részében kerülnek hozzáadásra."</string>
   <string name="screen_welcome_bullet_2">"A titkosított szobák üzenetelőzményei nem lesznek elérhetők ebben a frissítésben."</string>
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 126ce6376b3..c4caa3d31ca 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Ini adalah proses satu kali, terima kasih telah menunggu."</string>
-  <string name="screen_migration_title">"Menyiapkan akun Anda."</string>
-  <string name="screen_notification_optin_subtitle">"Anda dapat mengubah pengaturan Anda nanti."</string>
+    <string name="screen_notification_optin_subtitle">"Anda dapat mengubah pengaturan Anda nanti."</string>
   <string name="screen_notification_optin_title">"Izinkan pemberitahuan dan jangan pernah melewatkan pesan"</string>
   <string name="screen_welcome_bullet_1">"Panggilan, pemungutan suara, pencarian, dan lainnya akan ditambahkan di tahun ini."</string>
   <string name="screen_welcome_bullet_2">"Riwayat pesan untuk ruangan terenkripsi tidak akan tersedia dalam pembaruan ini."</string>
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 69013ebdb8b..b4bb889c93b 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Si tratta di una procedura che si effettua una sola volta, grazie per l\'attesa."</string>
-  <string name="screen_migration_title">"Configurazione del tuo account."</string>
-  <string name="screen_notification_optin_subtitle">"Potrai modificare le tue impostazioni in seguito."</string>
+    <string name="screen_notification_optin_subtitle">"Potrai modificare le tue impostazioni in seguito."</string>
   <string name="screen_notification_optin_title">"Consenti le notifiche e non perdere mai un messaggio"</string>
   <string name="screen_welcome_bullet_1">"Chiamate, sondaggi, ricerche e altro ancora saranno aggiunti nel corso dell\'anno."</string>
   <string name="screen_welcome_bullet_2">"La cronologia dei messaggi per le stanze crittografate non è ancora disponibile."</string>
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 f9322563180..a1b7ca15f1c 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Acesta este un proces care se desfășoară o singură dată, vă mulțumim pentru așteptare."</string>
-  <string name="screen_migration_title">"Contul dumneavoastră se configurează"</string>
-  <string name="screen_welcome_bullet_1">"Apelurile, sondajele, căutare și multe altele vor fi adăugate în cursul acestui an."</string>
+    <string name="screen_welcome_bullet_1">"Apelurile, sondajele, căutare și multe altele vor fi adăugate în cursul acestui an."</string>
   <string name="screen_welcome_bullet_2">"Istoricul mesajelor pentru camerele criptate nu va fi disponibil în această actualizare."</string>
   <string name="screen_welcome_bullet_3">"Ne-ar plăcea să auzim de la dumneavoastră, spuneți-ne ce părere aveți prin intermediul paginii de setări."</string>
   <string name="screen_welcome_button">"Să începem!"</string>
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 ab225b5d0fc..685b72ded18 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Это одноразовый процесс, спасибо, что подождали."</string>
-  <string name="screen_migration_title">"Настройка учетной записи."</string>
-  <string name="screen_notification_optin_subtitle">"Вы можете изменить настройки позже."</string>
+    <string name="screen_notification_optin_subtitle">"Вы можете изменить настройки позже."</string>
   <string name="screen_notification_optin_title">"Разрешите уведомления и никогда не пропустите сообщение"</string>
   <string name="screen_welcome_bullet_1">"Звонки, опросы, поиск и многое другое будут добавлены позже в этом году."</string>
   <string name="screen_welcome_bullet_2">"История сообщений для зашифрованных комнат в этом обновлении будет недоступна."</string>
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 c7eb1f83be0..e5e66541646 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"Ide o jednorazový proces, ďakujeme za trpezlivosť."</string>
-  <string name="screen_migration_title">"Nastavenie vášho účtu."</string>
-  <string name="screen_notification_optin_subtitle">"Svoje nastavenia môžete neskôr zmeniť."</string>
+    <string name="screen_notification_optin_subtitle">"Svoje nastavenia môžete neskôr zmeniť."</string>
   <string name="screen_notification_optin_title">"Povoľte oznámenia a nikdy nezmeškajte žiadnu správu"</string>
   <string name="screen_welcome_bullet_1">"Hovory, ankety, vyhľadávanie a ďalšie funkcie pribudnú neskôr v tomto roku."</string>
   <string name="screen_welcome_bullet_2">"História správ pre zašifrované miestnosti nebude v tejto aktualizácii k dispozícii."</string>
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 1edd1457760..0edb4ec4f18 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"這是一次性的程序，感謝您耐心等候。"</string>
-  <string name="screen_migration_title">"正在設定您的帳號。"</string>
-  <string name="screen_welcome_bullet_1">"通話、投票、搜尋等更多功能將在今年登場。"</string>
+    <string name="screen_welcome_bullet_1">"通話、投票、搜尋等更多功能將在今年登場。"</string>
   <string name="screen_welcome_bullet_2">"在這次的更新，您無法查看聊天室內被加密的歷史訊息。"</string>
   <string name="screen_welcome_bullet_3">"我們很樂意聽取您的意見，請到設定頁面告訴我們您的想法。"</string>
   <string name="screen_welcome_button">"開始吧！"</string>
diff --git a/features/ftue/impl/src/main/res/values/localazy.xml b/features/ftue/impl/src/main/res/values/localazy.xml
index f89cc622f64..3e8c86b7614 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 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="screen_migration_message">"This is a one time process, thanks for waiting."</string>
-  <string name="screen_migration_title">"Setting up your account."</string>
   <string name="screen_notification_optin_subtitle">"You can change your settings later."</string>
   <string name="screen_notification_optin_title">"Allow notifications and never miss a message"</string>
   <string name="screen_welcome_bullet_1">"Calls, polls, search and more will be added later this year."</string>
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 e8a3bddc431..ed6d8b18253 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 e6a605f5e44..ee0658ddc67 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 07ca0716e9a..2d590b90c17 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<OkHttpClient>,
     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 42eeab673a7..6e20b1ad4ab 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 421cdb0c62d..f25ebcec20e 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<RoomListState> {
     @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 b1180aecb3c..13ba030720f 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 55cbcf925bd..7fda3a180ab 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<RoomListState> {
             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 ace8b9ce605..0814ed10373 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
@@ -218,6 +219,7 @@ private fun RoomListContent(
                 onMenuActionClicked = onMenuActionClicked,
                 onOpenSettings = onOpenSettings,
                 scrollBehavior = scrollBehavior,
+                displayMenuItems = !state.displayMigrationStatus,
             )
         },
         content = { padding ->
@@ -276,18 +278,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 e6aae4da6eb..183e45a5c13 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.designsystem.utils.LogCompositions
 import io.element.android.libraries.matrix.api.core.UserId
@@ -90,6 +93,7 @@ fun RoomListTopBar(
     onMenuActionClicked: (RoomListMenuAction) -> Unit,
     onOpenSettings: () -> Unit,
     scrollBehavior: TopAppBarScrollBehavior,
+    displayMenuItems: Boolean,
     modifier: Modifier = Modifier,
 ) {
     LogCompositions(
@@ -114,6 +118,7 @@ fun RoomListTopBar(
         onSearchClicked = onToggleSearch,
         onMenuActionClicked = onMenuActionClicked,
         scrollBehavior = scrollBehavior,
+        displayMenuItems = displayMenuItems,
         modifier = modifier,
     )
 }
@@ -128,6 +133,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
@@ -201,79 +207,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,
+                                            )
+                                        }
+                                    )
+                                }
                             }
                         }
                     }
@@ -305,6 +321,7 @@ internal fun DefaultRoomListTopBarPreview() = ElementPreview {
         scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()),
         onOpenSettings = {},
         onSearchClicked = {},
+        displayMenuItems = true,
         onMenuActionClicked = {},
     )
 }
@@ -320,6 +337,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 65071303837..4886eca7bbf 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 fa718990e49..884c706da59 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 54a1b541be1..b7627f1ce0f 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 8ece45c08cd..62121fd2828 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 7f0c4cce9c5..d9980835f4c 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 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string name="confirm_recovery_key_banner_message">"Your chat backup is currently out of sync. You need to confirm your recovery key to maintain access to your chat backup."</string>
   <string name="confirm_recovery_key_banner_title">"Confirm your recovery key"</string>
+  <string name="screen_migration_message">"This is a one time process, thanks for waiting."</string>
+  <string name="screen_migration_title">"Setting up your account."</string>
   <string name="screen_roomlist_a11y_create_message">"Create a new conversation or room"</string>
   <string name="screen_roomlist_empty_message">"Get started by messaging someone."</string>
   <string name="screen_roomlist_empty_title">"No chats yet."</string>
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 78f5e72ad15..c42bf83c4a8 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -142,7 +142,7 @@ coil = { module = "io.coil-kt:coil", version.ref = "coil" }
 coil_compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
 coil_gif = { module = "io.coil-kt:coil-gif", version.ref = "coil" }
 coil_test = { module = "io.coil-kt:coil-test", version.ref = "coil" }
-compound = { module = "io.element.android:compound-android", version = "0.0.3" }
+compound = { module = "io.element.android:compound-android", version = "0.0.4" }
 datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" }
 serialization_json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization_json" }
 kotlinx_collections_immutable = "org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7"
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 476545befc1..2bc4290c670 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 5742438641b..bb3373b3971 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 00000000000..41cba4f4ba9
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 286a80d71d2..f87119293d2 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/tools/localazy/config.json b/tools/localazy/config.json
index 1bf1e9071b8..2416876fa44 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_.*"
       ]
     },


Test patch:
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 44df35ca052..834aaa5c1f4 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<FtueStep?>()
 
-        // 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/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 09d6f12e0c8..10730f0c901 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 a77a4d001af..79d0b7c6280 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 44dcba6e003..2ddcaed5669 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/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 99a9e03973e..00000000000
--- 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 412475009cc..54f60964f3b 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 f89a48fbdf8..e9fdb0d1762 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 f24b59907d9..c5b8dcbb18c 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 412475009cc..54f60964f3b 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 412475009cc..5bdbb9dbff3 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 f89a48fbdf8..91a55dee0fc 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 f6aaba2f2df..17bd0f82047 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 412475009cc..5bdbb9dbff3 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 220fb6de61a..9b7088595fc 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 00000000000..46a349cbce0
--- /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 00000000000..f901e915e5e
--- /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 00000000000..56f7f133f33
--- /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 9a5371804eb..a6b5cfab9b8 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