Repository: thunderbird/thunderbird-android (language: kotlin)

Issue:
Fix account and folder selection
The exsiting drawer has a complex setup to communicate account and folder changes between itself, the MessageList, MessageFragment and different entry points (widgets, notifications). To simplify the communication flow we decided to introduce a separate view model to keep track of the currently active account and when needed selected folder. It should be bound to the lifecycle of the MessageList activity and exposed to the navigation drawer as single source of truth.


Discussion hints:
nan

Pull request: Add folder drawer state
The `FolderDrawerState` is introduced to help synchronizing account and folder selection between `FolderDrawer` and `MessageList`. Like with the legacy implementation the `MessageList` will control the the selection state. To support different lifecycles the `FolderDrawer` will only store the current account uuid and folder id and resolve the selection on the fly. This is not very quick, but avoids having to rewrite the `MessageList`.

Resolves #8142


Test command: ./gradlew :feature:navigation:drawer:testDebugUnitTest --tests "app.k9mail.feature.navigation.drawer.ui.DrawerViewKtTest" --tests "app.k9mail.feature.navigation.drawer.domain.usecase.SyncAccountTest" --tests "app.k9mail.feature.navigation.drawer.ui.DrawerStateTest" --tests "app.k9mail.feature.navigation.drawer.ui.DrawerViewModelTest" --tests "app.k9mail.feature.navigation.drawer.domain.usecase.SyncAllAccountsTest" --tests "app.k9mail.feature.navigation.drawer.domain.usecase.GetDrawerConfigTest"

Fix patch:
diff --git a/feature/navigation/drawer/src/debug/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContentPreview.kt b/feature/navigation/drawer/src/debug/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContentPreview.kt
index c853fb01ec5..9d1371d8282 100644
--- a/feature/navigation/drawer/src/debug/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContentPreview.kt
+++ b/feature/navigation/drawer/src/debug/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContentPreview.kt
@@ -15,7 +15,7 @@ internal fun DrawerContentPreview() {
         DrawerContent(
             state = DrawerContract.State(
                 accounts = persistentListOf(),
-                selectedAccount = null,
+                selectedAccountUuid = null,
                 folders = persistentListOf(),
             ),
             onEvent = {},
@@ -30,7 +30,7 @@ internal fun DrawerContentWithAccountPreview() {
         DrawerContent(
             state = DrawerContract.State(
                 accounts = persistentListOf(DISPLAY_ACCOUNT),
-                selectedAccount = DISPLAY_ACCOUNT,
+                selectedAccountUuid = DISPLAY_ACCOUNT.uuid,
                 folders = persistentListOf(),
             ),
             onEvent = {},
@@ -47,7 +47,7 @@ internal fun DrawerContentWithFoldersPreview() {
                 accounts = persistentListOf(
                     DISPLAY_ACCOUNT,
                 ),
-                selectedAccount = null,
+                selectedAccountUuid = null,
                 folders = persistentListOf(
                     UNIFIED_FOLDER,
                     DISPLAY_FOLDER,
@@ -67,12 +67,33 @@ internal fun DrawerContentWithSelectedFolderPreview() {
                 accounts = persistentListOf(
                     DISPLAY_ACCOUNT,
                 ),
-                selectedAccount = DISPLAY_ACCOUNT,
+                selectedAccountUuid = DISPLAY_ACCOUNT.uuid,
                 folders = persistentListOf(
                     UNIFIED_FOLDER,
                     DISPLAY_FOLDER,
                 ),
-                selectedFolder = DISPLAY_FOLDER,
+                selectedFolderId = DISPLAY_FOLDER.id,
+            ),
+            onEvent = {},
+        )
+    }
+}
+
+@Composable
+@Preview(showBackground = true)
+internal fun DrawerContentWithSelectedUnifiedFolderPreview() {
+    PreviewWithTheme {
+        DrawerContent(
+            state = DrawerContract.State(
+                accounts = persistentListOf(
+                    DISPLAY_ACCOUNT,
+                ),
+                selectedAccountUuid = DISPLAY_ACCOUNT.uuid,
+                folders = persistentListOf(
+                    UNIFIED_FOLDER,
+                    DISPLAY_FOLDER,
+                ),
+                selectedFolderId = UNIFIED_FOLDER.id,
             ),
             onEvent = {},
         )
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/FolderDrawer.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/FolderDrawer.kt
index c1fabae908f..178273edb99 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/FolderDrawer.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/FolderDrawer.kt
@@ -5,14 +5,24 @@ import androidx.appcompat.app.AppCompatActivity
 import androidx.compose.ui.platform.ComposeView
 import androidx.core.view.GravityCompat
 import androidx.drawerlayout.widget.DrawerLayout
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
 import app.k9mail.core.ui.theme.api.FeatureThemeProvider
+import app.k9mail.feature.navigation.drawer.domain.entity.DisplayUnifiedFolderType
+import app.k9mail.feature.navigation.drawer.domain.entity.createDisplayAccountFolderId
 import app.k9mail.feature.navigation.drawer.ui.DrawerView
 import app.k9mail.legacy.account.Account
 import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.update
 import org.koin.core.component.KoinComponent
 import org.koin.core.component.inject
 
+internal data class FolderDrawerState(
+    val selectedAccountUuid: String? = null,
+    val selectedFolderId: String? = null,
+)
+
 class FolderDrawer(
     override val parent: AppCompatActivity,
     private val openAccount: (account: Account) -> Unit,
@@ -30,6 +40,8 @@ class FolderDrawer(
     private val sliderView: MaterialDrawerSliderView = parent.findViewById(R.id.material_drawer_slider)
     private val swipeRefreshLayout: SwipeRefreshLayout = parent.findViewById(R.id.material_drawer_swipe_refresh)
 
+    private val drawerState = MutableStateFlow(FolderDrawerState())
+
     init {
         sliderView.visibility = View.GONE
         drawerView.visibility = View.VISIBLE
@@ -38,7 +50,10 @@ class FolderDrawer(
 
         drawerView.setContent {
             themeProvider.WithTheme {
+                val state = drawerState.collectAsStateWithLifecycle()
+
                 DrawerView(
+                    drawerState = state.value,
                     openAccount = openAccount,
                     openFolder = openFolder,
                     openUnifiedFolder = openUnifiedFolder,
@@ -54,23 +69,38 @@ class FolderDrawer(
         get() = drawer.isOpen
 
     override fun updateUserAccountsAndFolders(account: Account?) {
-        // TODO("Not yet implemented")
+        // no-op
     }
 
     override fun selectAccount(accountUuid: String) {
-        // TODO("Not yet implemented")
+        drawerState.update {
+            it.copy(selectedAccountUuid = accountUuid)
+        }
     }
 
-    override fun selectFolder(folderId: Long) {
-        // TODO("Not yet implemented")
+    override fun selectFolder(accountUuid: String, folderId: Long) {
+        drawerState.update {
+            it.copy(
+                selectedAccountUuid = accountUuid,
+                selectedFolderId = createDisplayAccountFolderId(accountUuid, folderId),
+            )
+        }
     }
 
     override fun selectUnifiedInbox() {
-        // TODO("Not yet implemented")
+        drawerState.update {
+            it.copy(
+                selectedFolderId = DisplayUnifiedFolderType.INBOX.id,
+            )
+        }
     }
 
     override fun deselect() {
-        // TODO("Not yet implemented")
+        drawerState.update {
+            it.copy(
+                selectedFolderId = null,
+            )
+        }
     }
 
     override fun open() {
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/LegacyDrawer.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/LegacyDrawer.kt
index 30456cc2212..dbda63dbfd3 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/LegacyDrawer.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/LegacyDrawer.kt
@@ -437,7 +437,7 @@ class LegacyDrawer(
         }
     }
 
-    override fun selectFolder(folderId: Long) {
+    override fun selectFolder(accountUuid: String, folderId: Long) {
         deselect()
         openedFolderId = folderId
         for (drawerId in userFolderDrawerIds) {
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawer.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawer.kt
index 84f20ab5d62..09d9cb68bd4 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawer.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawer.kt
@@ -7,11 +7,12 @@ interface NavigationDrawer {
     val parent: AppCompatActivity
     val isOpen: Boolean
 
+    // TODO: remove once LegacyDrawer is removed
     fun updateUserAccountsAndFolders(account: Account?)
 
     fun selectAccount(accountUuid: String)
 
-    fun selectFolder(folderId: Long)
+    fun selectFolder(accountUuid: String, folderId: Long)
 
     fun selectUnifiedInbox()
 
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawerModule.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawerModule.kt
index 35e8fd2bf0a..e4463ef4bdd 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawerModule.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawerModule.kt
@@ -40,6 +40,7 @@ val navigationDrawerModule: Module = module {
 
     single<UseCase.SyncAccount> {
         SyncAccount(
+            accountManager = get(),
             messagingController = get(),
         )
     }
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/DomainContract.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/DomainContract.kt
index f8ab0118074..4437c0b6877 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/DomainContract.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/DomainContract.kt
@@ -3,7 +3,6 @@ package app.k9mail.feature.navigation.drawer.domain
 import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfig
 import app.k9mail.feature.navigation.drawer.domain.entity.DisplayAccount
 import app.k9mail.feature.navigation.drawer.domain.entity.DisplayFolder
-import app.k9mail.legacy.account.Account
 import kotlinx.coroutines.flow.Flow
 
 internal interface DomainContract {
@@ -22,10 +21,10 @@ internal interface DomainContract {
         }
 
         /**
-         * Synchronize the given account.
+         * Synchronize the given account uuid.
          */
         fun interface SyncAccount {
-            operator fun invoke(account: Account): Flow<Result<Unit>>
+            operator fun invoke(accountUuid: String): Flow<Result<Unit>>
         }
 
         /**
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayAccount.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayAccount.kt
index 6ce613c6033..a1eea409b5c 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayAccount.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayAccount.kt
@@ -6,4 +6,6 @@ internal data class DisplayAccount(
     val account: Account,
     val unreadMessageCount: Int,
     val starredMessageCount: Int,
-)
+) {
+    val uuid: String = account.uuid
+}
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayAccountFolder.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayAccountFolder.kt
index a404d9922bd..0089861cc89 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayAccountFolder.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayAccountFolder.kt
@@ -9,5 +9,9 @@ internal data class DisplayAccountFolder(
     override val unreadMessageCount: Int,
     override val starredMessageCount: Int,
 ) : DisplayFolder {
-    override val id: String = accountUuid + folder.id
+    override val id: String = createDisplayAccountFolderId(accountUuid, folder.id)
+}
+
+fun createDisplayAccountFolderId(accountUuid: String, folderId: Long): String {
+    return "${accountUuid}_$folderId"
 }
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayUnifiedFolderType.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayUnifiedFolderType.kt
index ac09151fedf..13cda80b440 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayUnifiedFolderType.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/entity/DisplayUnifiedFolderType.kt
@@ -1,5 +1,12 @@
 package app.k9mail.feature.navigation.drawer.domain.entity
 
-internal enum class DisplayUnifiedFolderType {
-    INBOX,
+/**
+ * Represents a unified folder in the drawer.
+ *
+ * The id is unique for each unified folder type.
+ */
+internal enum class DisplayUnifiedFolderType(
+    val id: String,
+) {
+    INBOX("unified_inbox"),
 }
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAccount.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAccount.kt
index 90609176660..942cfc1a150 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAccount.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAccount.kt
@@ -3,6 +3,7 @@ package app.k9mail.feature.navigation.drawer.domain.usecase
 import android.content.Context
 import app.k9mail.feature.navigation.drawer.domain.DomainContract.UseCase
 import app.k9mail.legacy.account.Account
+import app.k9mail.legacy.account.AccountManager
 import app.k9mail.legacy.message.controller.MessagingControllerMailChecker
 import app.k9mail.legacy.message.controller.SimpleMessagingListener
 import kotlin.coroutines.CoroutineContext
@@ -13,10 +14,11 @@ import kotlinx.coroutines.flow.callbackFlow
 import kotlinx.coroutines.flow.flowOn
 
 internal class SyncAccount(
+    private val accountManager: AccountManager,
     private val messagingController: MessagingControllerMailChecker,
     private val coroutineContext: CoroutineContext = Dispatchers.IO,
 ) : UseCase.SyncAccount {
-    override fun invoke(account: Account): Flow<Result<Unit>> = callbackFlow {
+    override fun invoke(accountUuid: String): Flow<Result<Unit>> = callbackFlow {
         val listener = object : SimpleMessagingListener() {
             override fun checkMailFinished(context: Context?, account: Account?) {
                 trySend(Result.success(Unit))
@@ -24,6 +26,8 @@ internal class SyncAccount(
             }
         }
 
+        val account = accountManager.getAccount(accountUuid)
+
         messagingController.checkMail(
             account = account,
             ignoreLastCheckedTime = true,
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContent.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContent.kt
index 809214bb98a..a4f1016abb3 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContent.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContent.kt
@@ -27,11 +27,12 @@ internal fun DrawerContent(
             .fillMaxSize()
             .testTag("DrawerContent"),
     ) {
+        val selectedAccount = state.accounts.firstOrNull { it.uuid == state.selectedAccountUuid }
         Column {
-            state.selectedAccount?.let {
+            selectedAccount?.let {
                 AccountView(
-                    account = it,
-                    onClick = { onEvent(Event.OnAccountViewClick(it)) },
+                    account = selectedAccount,
+                    onClick = { onEvent(Event.OnAccountViewClick(selectedAccount)) },
                     showAvatar = state.showAccountSelector,
                 )
 
@@ -43,7 +44,7 @@ internal fun DrawerContent(
                 ) {
                     AccountList(
                         accounts = state.accounts,
-                        selectedAccount = state.selectedAccount,
+                        selectedAccount = selectedAccount,
                         onAccountClick = { onEvent(Event.OnAccountClick(it)) },
                         onSyncAllAccountsClick = { onEvent(Event.OnSyncAllAccounts) },
                         onSettingsClick = { onEvent(Event.OnSettingsClick) },
@@ -56,7 +57,7 @@ internal fun DrawerContent(
                 ) {
                     FolderList(
                         folders = state.folders,
-                        selectedFolder = state.selectedFolder,
+                        selectedFolder = state.folders.firstOrNull { it.id == state.selectedFolderId },
                         onFolderClick = { folder ->
                             onEvent(Event.OnFolderClick(folder))
                         },
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContract.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContract.kt
index 657e4d1d9c0..877d96c674e 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContract.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerContract.kt
@@ -20,14 +20,16 @@ internal interface DrawerContract {
             showStarredCount = false,
         ),
         val accounts: ImmutableList<DisplayAccount> = persistentListOf(),
-        val selectedAccount: DisplayAccount? = null,
+        val selectedAccountUuid: String? = null,
         val folders: ImmutableList<DisplayFolder> = persistentListOf(),
-        val selectedFolder: DisplayFolder? = null,
+        val selectedFolderId: String? = null,
         val showAccountSelector: Boolean = false,
         val isLoading: Boolean = false,
     )
 
     sealed interface Event {
+        data class SelectAccount(val accountUuid: String?) : Event
+        data class SelectFolder(val folderId: String?) : Event
         data class OnAccountClick(val account: DisplayAccount) : Event
         data class OnAccountViewClick(val account: DisplayAccount) : Event
         data class OnFolderClick(val folder: DisplayFolder) : Event
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerView.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerView.kt
index 33f493b0ffb..d620669b45f 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerView.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerView.kt
@@ -1,8 +1,10 @@
 package app.k9mail.feature.navigation.drawer.ui
 
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import app.k9mail.core.ui.compose.common.mvi.observe
 import app.k9mail.core.ui.compose.designsystem.molecule.PullToRefreshBox
+import app.k9mail.feature.navigation.drawer.FolderDrawerState
 import app.k9mail.feature.navigation.drawer.ui.DrawerContract.Effect
 import app.k9mail.feature.navigation.drawer.ui.DrawerContract.Event
 import app.k9mail.feature.navigation.drawer.ui.DrawerContract.ViewModel
@@ -11,6 +13,7 @@ import org.koin.androidx.compose.koinViewModel
 
 @Composable
 internal fun DrawerView(
+    drawerState: FolderDrawerState,
     openAccount: (account: Account) -> Unit,
     openFolder: (folderId: Long) -> Unit,
     openUnifiedFolder: () -> Unit,
@@ -30,6 +33,14 @@ internal fun DrawerView(
         }
     }
 
+    LaunchedEffect(drawerState.selectedAccountUuid) {
+        dispatch(Event.SelectAccount(drawerState.selectedAccountUuid))
+    }
+
+    LaunchedEffect(drawerState.selectedFolderId) {
+        dispatch(Event.SelectFolder(drawerState.selectedFolderId))
+    }
+
     PullToRefreshBox(
         isRefreshing = state.value.isLoading,
         onRefresh = { dispatch(Event.OnSyncAccount) },
diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewModel.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewModel.kt
index 8e659d7ec59..604efde32b2 100644
--- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewModel.kt
+++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewModel.kt
@@ -23,7 +23,7 @@ import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
 
-@Suppress("MagicNumber")
+@Suppress("MagicNumber", "TooManyFunctions")
 internal class DrawerViewModel(
     private val getDrawerConfig: UseCase.GetDrawerConfig,
     private val getDisplayAccounts: UseCase.GetDisplayAccounts,
@@ -61,13 +61,13 @@ internal class DrawerViewModel(
     }
 
     private fun updateAccounts(accounts: List<DisplayAccount>) {
-        val selectedAccount = accounts.find { it.account.uuid == state.value.selectedAccount?.account?.uuid }
+        val selectedAccount = accounts.find { it.uuid == state.value.selectedAccountUuid }
             ?: accounts.firstOrNull()
 
         updateState {
             it.copy(
                 accounts = accounts.toImmutableList(),
-                selectedAccount = selectedAccount,
+                selectedAccountUuid = selectedAccount?.uuid,
             )
         }
     }
@@ -75,8 +75,8 @@ internal class DrawerViewModel(
     @OptIn(ExperimentalCoroutinesApi::class)
     private suspend fun loadFolders() {
         state.map {
-            it.selectedAccount?.let { selectAccount ->
-                Pair(selectAccount.account.uuid, it.config.showUnifiedFolders)
+            it.selectedAccountUuid?.let { accountUuid ->
+                Pair(accountUuid, it.config.showUnifiedFolders)
             }
         }.filterNotNull()
             .distinctUntilChanged()
@@ -89,24 +89,27 @@ internal class DrawerViewModel(
 
     private fun updateFolders(displayFolders: List<DisplayFolder>) {
         val selectedFolder = displayFolders.find {
-            it.id == state.value.selectedFolder?.id
+            it.id == state.value.selectedFolderId
         } ?: displayFolders.firstOrNull()
 
         updateState {
             it.copy(
                 folders = displayFolders.toImmutableList(),
-                selectedFolder = selectedFolder,
+                selectedFolderId = selectedFolder?.id,
             )
         }
     }
 
     override fun event(event: Event) {
         when (event) {
-            is Event.OnAccountClick -> selectAccount(event.account)
-            is Event.OnFolderClick -> selectFolder(event.folder)
+            is Event.SelectAccount -> selectAccount(event.accountUuid)
+            is Event.SelectFolder -> selectFolder(event.folderId)
+
+            is Event.OnAccountClick -> openAccount(event.account)
+            is Event.OnFolderClick -> openFolder(event.folder)
             is Event.OnAccountViewClick -> {
-                selectAccount(
-                    state.value.accounts.nextOrFirst(event.account)!!,
+                openAccount(
+                    state.value.accounts.nextOrFirst(event.account),
                 )
             }
 
@@ -118,16 +121,26 @@ internal class DrawerViewModel(
         }
     }
 
-    private fun selectAccount(account: DisplayAccount) {
-        viewModelScope.launch {
-            updateState {
-                it.copy(
-                    selectedAccount = account,
-                )
-            }
+    private fun selectAccount(accountUuid: String?) {
+        updateState {
+            it.copy(
+                selectedAccountUuid = accountUuid,
+            )
         }
+    }
 
-        emitEffect(Effect.OpenAccount(account.account))
+    private fun selectFolder(folderId: String?) {
+        updateState {
+            it.copy(
+                selectedFolderId = folderId,
+            )
+        }
+    }
+
+    private fun openAccount(account: DisplayAccount?) {
+        if (account != null) {
+            emitEffect(Effect.OpenAccount(account.account))
+        }
     }
 
     private fun ImmutableList<DisplayAccount>.nextOrFirst(account: DisplayAccount): DisplayAccount? {
@@ -141,11 +154,7 @@ internal class DrawerViewModel(
         }
     }
 
-    private fun selectFolder(folder: DisplayFolder) {
-        updateState {
-            it.copy(selectedFolder = folder)
-        }
-
+    private fun openFolder(folder: DisplayFolder) {
         if (folder is DisplayAccountFolder) {
             emitEffect(Effect.OpenFolder(folder.folder.id))
         } else if (folder is DisplayUnifiedFolder) {
@@ -159,14 +168,14 @@ internal class DrawerViewModel(
     }
 
     private fun onSyncAccount() {
-        if (state.value.isLoading || state.value.selectedAccount == null) return
+        if (state.value.isLoading || state.value.selectedAccountUuid == null) return
 
         viewModelScope.launch {
             updateState {
                 it.copy(isLoading = true)
             }
 
-            state.value.selectedAccount?.account?.let { syncAccount(it).collect() }
+            state.value.selectedAccountUuid?.let { syncAccount(it).collect() }
 
             updateState {
                 it.copy(isLoading = false)
diff --git a/legacy/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt b/legacy/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt
index b611011469e..7726014fad7 100644
--- a/legacy/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt
+++ b/legacy/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt
@@ -1413,7 +1413,7 @@ open class MessageList :
         val drawer = navigationDrawer ?: return
         drawer.selectAccount(account!!.uuid)
         when {
-            singleFolderMode -> drawer.selectFolder(search!!.folderIds[0])
+            singleFolderMode -> drawer.selectFolder(search!!.accountUuids[0], search!!.folderIds[0])
             // Don't select any item in the drawer because the Unified Inbox is displayed, but not listed in the drawer
             search!!.id == SearchAccount.UNIFIED_INBOX && !K9.isShowUnifiedInbox -> drawer.deselect()
             search!!.id == SearchAccount.UNIFIED_INBOX -> drawer.selectUnifiedInbox()


Test patch:
diff --git a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/FakeAccountManager.kt b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/FakeAccountManager.kt
new file mode 100644
index 00000000000..23e4d3891b1
--- /dev/null
+++ b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/FakeAccountManager.kt
@@ -0,0 +1,49 @@
+package app.k9mail.feature.navigation.drawer.domain.usecase
+
+import app.k9mail.legacy.account.Account
+import app.k9mail.legacy.account.AccountManager
+import app.k9mail.legacy.account.AccountRemovedListener
+import app.k9mail.legacy.account.AccountsChangeListener
+import kotlinx.coroutines.flow.Flow
+
+internal class FakeAccountManager(
+    val recordedParameters: MutableList<String> = mutableListOf(),
+    private val accounts: List<Account> = emptyList(),
+) : AccountManager {
+    override fun getAccounts(): List<Account> {
+        TODO("Not yet implemented")
+    }
+
+    override fun getAccountsFlow(): Flow<List<Account>> {
+        TODO("Not yet implemented")
+    }
+
+    override fun getAccount(accountUuid: String): Account? {
+        recordedParameters.add(accountUuid)
+        return accounts.find { it.uuid == accountUuid }
+    }
+
+    override fun getAccountFlow(accountUuid: String): Flow<Account> {
+        TODO("Not yet implemented")
+    }
+
+    override fun addAccountRemovedListener(listener: AccountRemovedListener) {
+        TODO("Not yet implemented")
+    }
+
+    override fun moveAccount(account: Account, newPosition: Int) {
+        TODO("Not yet implemented")
+    }
+
+    override fun addOnAccountsChangeListener(accountsChangeListener: AccountsChangeListener) {
+        TODO("Not yet implemented")
+    }
+
+    override fun removeOnAccountsChangeListener(accountsChangeListener: AccountsChangeListener) {
+        TODO("Not yet implemented")
+    }
+
+    override fun saveAccount(account: Account) {
+        TODO("Not yet implemented")
+    }
+}
diff --git a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/FakeMessagingControllerMailChecker.kt b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/FakeMessagingControllerMailChecker.kt
index 487ff72ff25..d2330a3eb4c 100644
--- a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/FakeMessagingControllerMailChecker.kt
+++ b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/FakeMessagingControllerMailChecker.kt
@@ -5,6 +5,7 @@ import app.k9mail.legacy.message.controller.MessagingControllerMailChecker
 import app.k9mail.legacy.message.controller.MessagingListener
 
 internal class FakeMessagingControllerMailChecker(
+    val recordedParameters: MutableList<CheckMailParameters> = mutableListOf(),
     private val listenerExecutor: (MessagingListener?) -> Unit = {},
 ) : MessagingControllerMailChecker {
     override fun checkMail(
@@ -14,6 +15,15 @@ internal class FakeMessagingControllerMailChecker(
         notify: Boolean,
         listener: MessagingListener?,
     ) {
+        recordedParameters.add(CheckMailParameters(account, ignoreLastCheckedTime, useManualWakeLock, notify))
+
         listenerExecutor(listener)
     }
 }
+
+internal data class CheckMailParameters(
+    val account: Account?,
+    val ignoreLastCheckedTime: Boolean,
+    val useManualWakeLock: Boolean,
+    val notify: Boolean,
+)
diff --git a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/GetDrawerConfigTest.kt b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/GetDrawerConfigTest.kt
index adfdd5b4225..0f559529555 100644
--- a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/GetDrawerConfigTest.kt
+++ b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/GetDrawerConfigTest.kt
@@ -7,7 +7,7 @@ import kotlin.test.Test
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.test.runTest
 
-class GetDrawerConfigTest {
+internal class GetDrawerConfigTest {
 
     @Test
     fun `should get drawer config`() = runTest {
diff --git a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAccountTest.kt b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAccountTest.kt
index 526d09c66be..cc4b8d5b9c0 100644
--- a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAccountTest.kt
+++ b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAccountTest.kt
@@ -2,26 +2,44 @@ package app.k9mail.feature.navigation.drawer.domain.usecase
 
 import app.k9mail.feature.navigation.drawer.ui.FakeData
 import app.k9mail.legacy.message.controller.MessagingListener
+import assertk.assertThat
 import assertk.assertions.isEqualTo
 import kotlin.test.Test
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.test.runTest
 
-class SyncAccountTest {
+internal class SyncAccountTest {
 
     @Test
     fun `should sync mail with account`() = runTest {
         val listenerExecutor: (MessagingListener?) -> Unit = { listener ->
             listener?.checkMailFinished(null, null)
         }
+        val account = FakeData.ACCOUNT
+        val accountManager = FakeAccountManager(
+            accounts = listOf(account),
+        )
+        val messagingController = FakeMessagingControllerMailChecker(
+            listenerExecutor = listenerExecutor,
+        )
         val testSubject = SyncAccount(
-            messagingController = FakeMessagingControllerMailChecker(
-                listenerExecutor = listenerExecutor,
-            ),
+            accountManager = accountManager,
+            messagingController = messagingController,
         )
 
-        val result = testSubject(FakeData.ACCOUNT).first()
+        val result = testSubject(account.uuid).first()
 
-        assertk.assertThat(result.isSuccess).isEqualTo(true)
+        assertThat(result.isSuccess).isEqualTo(true)
+        assertThat(accountManager.recordedParameters).isEqualTo(listOf(account.uuid))
+        assertThat(messagingController.recordedParameters).isEqualTo(
+            listOf(
+                CheckMailParameters(
+                    account = account,
+                    ignoreLastCheckedTime = true,
+                    useManualWakeLock = true,
+                    notify = true,
+                ),
+            ),
+        )
     }
 }
diff --git a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAllAccountsTest.kt b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAllAccountsTest.kt
index 26849c0cfde..98086bfa2ce 100644
--- a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAllAccountsTest.kt
+++ b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SyncAllAccountsTest.kt
@@ -1,26 +1,38 @@
 package app.k9mail.feature.navigation.drawer.domain.usecase
 
 import app.k9mail.legacy.message.controller.MessagingListener
+import assertk.assertThat
 import assertk.assertions.isEqualTo
 import kotlin.test.Test
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.test.runTest
 
-class SyncAllAccountsTest {
+internal class SyncAllAccountsTest {
 
     @Test
     fun `should sync mail`() = runTest {
         val listenerExecutor: (MessagingListener?) -> Unit = { listener ->
             listener?.checkMailFinished(null, null)
         }
+        val messagingController = FakeMessagingControllerMailChecker(
+            listenerExecutor = listenerExecutor,
+        )
         val testSubject = SyncAllAccounts(
-            messagingController = FakeMessagingControllerMailChecker(
-                listenerExecutor = listenerExecutor,
-            ),
+            messagingController = messagingController,
         )
 
         val result = testSubject().first()
 
-        assertk.assertThat(result.isSuccess).isEqualTo(true)
+        assertThat(result.isSuccess).isEqualTo(true)
+        assertThat(messagingController.recordedParameters).isEqualTo(
+            listOf(
+                CheckMailParameters(
+                    account = null,
+                    ignoreLastCheckedTime = true,
+                    useManualWakeLock = true,
+                    notify = true,
+                ),
+            ),
+        )
     }
 }
diff --git a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerStateTest.kt b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerStateTest.kt
index a2ae8185131..243b6fc54b9 100644
--- a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerStateTest.kt
+++ b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerStateTest.kt
@@ -7,7 +7,7 @@ import assertk.assertions.isEqualTo
 import kotlinx.collections.immutable.persistentListOf
 import org.junit.Test
 
-class DrawerStateTest {
+internal class DrawerStateTest {
 
     @Test
     fun `should set default values`() {
@@ -20,9 +20,9 @@ class DrawerStateTest {
                     showStarredCount = false,
                 ),
                 accounts = persistentListOf(),
-                selectedAccount = null,
+                selectedAccountUuid = null,
                 folders = persistentListOf(),
-                selectedFolder = null,
+                selectedFolderId = null,
                 showAccountSelector = false,
                 isLoading = false,
             ),
diff --git a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewKtTest.kt b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewKtTest.kt
index 1f249cb837a..3137469ee47 100644
--- a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewKtTest.kt
+++ b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewKtTest.kt
@@ -2,17 +2,21 @@ package app.k9mail.feature.navigation.drawer.ui
 
 import androidx.compose.ui.test.onChildAt
 import androidx.compose.ui.test.printToString
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import app.k9mail.core.ui.compose.testing.ComposeTest
 import app.k9mail.core.ui.compose.testing.onNodeWithTag
 import app.k9mail.core.ui.compose.testing.setContentWithTheme
+import app.k9mail.feature.navigation.drawer.FolderDrawerState
 import app.k9mail.feature.navigation.drawer.ui.DrawerContract.Effect
+import app.k9mail.feature.navigation.drawer.ui.DrawerContract.Event
 import app.k9mail.feature.navigation.drawer.ui.DrawerContract.State
 import assertk.assertThat
 import assertk.assertions.isEqualTo
 import kotlin.test.Test
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runTest
 
-class DrawerViewKtTest : ComposeTest() {
+internal class DrawerViewKtTest : ComposeTest() {
 
     @Test
     fun `should delegate effects`() = runTest {
@@ -23,6 +27,7 @@ class DrawerViewKtTest : ComposeTest() {
 
         setContentWithTheme {
             DrawerView(
+                drawerState = FolderDrawerState(),
                 openAccount = { counter.openAccountCount++ },
                 openFolder = { counter.openFolderCount++ },
                 openUnifiedFolder = { counter.openUnifiedFolderCount++ },
@@ -56,6 +61,45 @@ class DrawerViewKtTest : ComposeTest() {
         viewModel.effect(Effect.CloseDrawer)
     }
 
+    @Test
+    fun `should register to drawer state and send events to view model`() = runTest {
+        val initialState = State()
+        val viewModel = FakeDrawerViewModel(initialState)
+        val initialDrawerState = FolderDrawerState()
+        val drawerStateFlow = MutableStateFlow(initialDrawerState)
+
+        setContentWithTheme {
+            val state = drawerStateFlow.collectAsStateWithLifecycle()
+
+            DrawerView(
+                drawerState = state.value,
+                openAccount = { },
+                openFolder = { },
+                openUnifiedFolder = { },
+                openManageFolders = { },
+                openSettings = { },
+                closeDrawer = { },
+                viewModel = viewModel,
+            )
+        }
+
+        drawerStateFlow.emit(initialDrawerState.copy(selectedAccountUuid = FakeData.ACCOUNT.uuid))
+
+        viewModel.events.contains(Event.SelectAccount(FakeData.ACCOUNT.uuid))
+
+        drawerStateFlow.emit(initialDrawerState.copy(selectedAccountUuid = null))
+
+        viewModel.events.contains(Event.SelectAccount(null))
+
+        drawerStateFlow.emit(initialDrawerState.copy(selectedFolderId = "1"))
+
+        viewModel.events.contains(Event.SelectFolder("1"))
+
+        drawerStateFlow.emit(initialDrawerState.copy(selectedFolderId = null))
+
+        viewModel.events.contains(Event.SelectFolder(null))
+    }
+
     @Test
     fun `pull refresh should listen to view model state`() = runTest {
         val initialState = State(
@@ -65,6 +109,7 @@ class DrawerViewKtTest : ComposeTest() {
 
         setContentWithTheme {
             DrawerView(
+                drawerState = FolderDrawerState(),
                 openAccount = {},
                 openFolder = {},
                 openUnifiedFolder = {},
diff --git a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewModelTest.kt b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewModelTest.kt
index 5a8b2290cde..6cdc88e543c 100644
--- a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewModelTest.kt
+++ b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/DrawerViewModelTest.kt
@@ -34,7 +34,7 @@ import kotlinx.coroutines.test.runTest
 import org.junit.Rule
 
 @OptIn(ExperimentalCoroutinesApi::class)
-class DrawerViewModelTest {
+internal class DrawerViewModelTest {
 
     @get:Rule
     val mainDispatcherRule = MainDispatcherRule()
@@ -64,7 +64,7 @@ class DrawerViewModelTest {
     fun `should change loading state when OnSyncAccount event is received`() = runTest {
         val initialState = State(
             accounts = listOf(DISPLAY_ACCOUNT).toImmutableList(),
-            selectedAccount = DISPLAY_ACCOUNT,
+            selectedAccountUuid = DISPLAY_ACCOUNT.uuid,
         )
         val testSubject = createTestSubject(
             initialState = initialState,
@@ -90,12 +90,13 @@ class DrawerViewModelTest {
 
     @Test
     fun `should skip loading when no account is selected and OnSyncAccount event is received`() = runTest {
-        val initialState = State(selectedAccount = null)
+        val initialState = State(selectedAccountUuid = null)
         var counter = 0
         val testSubject = createTestSubject(
             initialState = initialState,
             syncAccountFlow = flow {
                 delay(25)
+                counter++
                 emit(Result.success(Unit))
             },
         )
@@ -197,7 +198,7 @@ class DrawerViewModelTest {
 
         assertThat(testSubject.state.value.accounts.size).isEqualTo(displayAccounts.size)
         assertThat(testSubject.state.value.accounts).isEqualTo(displayAccounts)
-        assertThat(testSubject.state.value.selectedAccount).isEqualTo(displayAccounts.first())
+        assertThat(testSubject.state.value.selectedAccountUuid).isEqualTo(displayAccounts.first().uuid)
     }
 
     @Test
@@ -217,7 +218,7 @@ class DrawerViewModelTest {
 
         assertThat(testSubject.state.value.accounts.size).isEqualTo(newDisplayAccounts.size)
         assertThat(testSubject.state.value.accounts).isEqualTo(newDisplayAccounts)
-        assertThat(testSubject.state.value.selectedAccount).isEqualTo(newDisplayAccounts.first())
+        assertThat(testSubject.state.value.selectedAccountUuid).isEqualTo(newDisplayAccounts.first().uuid)
     }
 
     @Test
@@ -230,11 +231,11 @@ class DrawerViewModelTest {
         advanceUntilIdle()
 
         assertThat(testSubject.state.value.accounts.size).isEqualTo(0)
-        assertThat(testSubject.state.value.selectedAccount).isEqualTo(null)
+        assertThat(testSubject.state.value.selectedAccountUuid).isEqualTo(null)
     }
 
     @Test
-    fun `should set selected account when OnAccountClick event is received`() = runTest {
+    fun `should send OpenAccount effect when OnAccountClick event is received`() = runTest {
         val displayAccounts = createDisplayAccountList(3)
         val getDisplayAccountsFlow = MutableStateFlow(displayAccounts)
         val testSubject = createTestSubject(
@@ -244,7 +245,7 @@ class DrawerViewModelTest {
             testSubject,
             State(
                 accounts = displayAccounts.toImmutableList(),
-                selectedAccount = displayAccounts.first(),
+                selectedAccountUuid = displayAccounts.first().uuid,
             ),
         )
 
@@ -254,8 +255,6 @@ class DrawerViewModelTest {
 
         advanceUntilIdle()
 
-        assertThat(turbines.awaitStateItem().selectedAccount).isEqualTo(displayAccounts[1])
-
         turbines.assertThatAndEffectTurbineConsumed {
             isEqualTo(Effect.OpenAccount(displayAccounts[1].account))
         }
@@ -266,7 +265,7 @@ class DrawerViewModelTest {
         val displayAccounts = createDisplayAccountList(3)
         val getDisplayAccountsFlow = MutableStateFlow(displayAccounts)
         val displayFoldersMap = mapOf(
-            displayAccounts[0].account.uuid to createDisplayFolderList(3),
+            displayAccounts[0].uuid to createDisplayFolderList(3),
         )
         val displayFoldersFlow = MutableStateFlow(displayFoldersMap)
         val testSubject = createTestSubject(
@@ -276,7 +275,7 @@ class DrawerViewModelTest {
 
         advanceUntilIdle()
 
-        val displayFolders = displayFoldersMap[displayAccounts[0].account.uuid] ?: emptyList()
+        val displayFolders = displayFoldersMap[displayAccounts[0].uuid] ?: emptyList()
         assertThat(testSubject.state.value.folders.size).isEqualTo(displayFolders.size)
         assertThat(testSubject.state.value.folders).isEqualTo(displayFolders)
     }
@@ -286,9 +285,9 @@ class DrawerViewModelTest {
         val displayAccounts = createDisplayAccountList(3)
         val getDisplayAccountsFlow = MutableStateFlow(displayAccounts)
         val displayFoldersMap = mapOf(
-            displayAccounts[0].account.uuid to createDisplayFolderList(1),
-            displayAccounts[1].account.uuid to createDisplayFolderList(5),
-            displayAccounts[2].account.uuid to createDisplayFolderList(10),
+            displayAccounts[0].uuid to createDisplayFolderList(1),
+            displayAccounts[1].uuid to createDisplayFolderList(5),
+            displayAccounts[2].uuid to createDisplayFolderList(10),
         )
         val displayFoldersFlow = MutableStateFlow(displayFoldersMap)
         val testSubject = createTestSubject(
@@ -298,7 +297,7 @@ class DrawerViewModelTest {
 
         advanceUntilIdle()
 
-        testSubject.event(Event.OnAccountClick(displayAccounts[1]))
+        testSubject.event(Event.SelectAccount(displayAccounts[1].uuid))
 
         advanceUntilIdle()
 
@@ -308,7 +307,7 @@ class DrawerViewModelTest {
     }
 
     @Test
-    fun `should set selected folder and emit OpenFolder when OnFolderClick event is received`() = runTest {
+    fun `should emit OpenFolder effect when OnFolderClick event is received`() = runTest {
         val displayAccounts = createDisplayAccountList(3)
         val getDisplayAccountsFlow = MutableStateFlow(displayAccounts)
         val displayFoldersMap = mapOf(
@@ -317,9 +316,9 @@ class DrawerViewModelTest {
         val displayFoldersFlow = MutableStateFlow(displayFoldersMap)
         val initialState = State(
             accounts = displayAccounts.toImmutableList(),
-            selectedAccount = displayAccounts[0],
+            selectedAccountUuid = displayAccounts[0].uuid,
             folders = displayFoldersMap[displayAccounts[0].account.uuid]!!.toImmutableList(),
-            selectedFolder = displayFoldersMap[displayAccounts[0].account.uuid]!![0],
+            selectedFolderId = displayFoldersMap[displayAccounts[0].account.uuid]!![0].id,
         )
         val testSubject = createTestSubject(
             displayAccountsFlow = getDisplayAccountsFlow,
@@ -332,8 +331,6 @@ class DrawerViewModelTest {
         val displayFolders = displayFoldersMap[displayAccounts[0].account.uuid] ?: emptyList()
         testSubject.event(Event.OnFolderClick(displayFolders[1]))
 
-        assertThat(turbines.awaitStateItem().selectedFolder).isEqualTo(displayFolders[1])
-
         assertThat(turbines.awaitEffectItem()).isEqualTo(Effect.OpenFolder(displayFolders[1].folder.id))
 
         turbines.assertThatAndEffectTurbineConsumed {
@@ -342,7 +339,7 @@ class DrawerViewModelTest {
     }
 
     @Test
-    fun `should set selected folder emit OpenUnifiedFolder when OnFolderClick event for unified folder is received`() =
+    fun `should emit OpenUnifiedFolder when OnFolderClick event for unified folder is received`() =
         runTest {
             val displayAccounts = createDisplayAccountList(1)
             val getDisplayAccountsFlow = MutableStateFlow(displayAccounts)
@@ -353,9 +350,9 @@ class DrawerViewModelTest {
             val displayFoldersFlow = MutableStateFlow(displayFoldersMap)
             val initialState = State(
                 accounts = displayAccounts.toImmutableList(),
-                selectedAccount = displayAccounts[0],
+                selectedAccountUuid = displayAccounts[0].account.uuid,
                 folders = displayFoldersMap[displayAccounts[0].account.uuid]!!.toImmutableList(),
-                selectedFolder = displayFoldersMap[displayAccounts[0].account.uuid]!![0],
+                selectedFolderId = displayFoldersMap[displayAccounts[0].account.uuid]!![0].id,
             )
             val testSubject = createTestSubject(
                 displayAccountsFlow = getDisplayAccountsFlow,
@@ -368,8 +365,6 @@ class DrawerViewModelTest {
             val displayFolders = displayFoldersMap[displayAccounts[0].account.uuid] ?: emptyList()
             testSubject.event(Event.OnFolderClick(displayFolders[1]))
 
-            assertThat(turbines.awaitStateItem().selectedFolder).isEqualTo(displayFolders[1])
-
             assertThat(turbines.awaitEffectItem()).isEqualTo(Effect.OpenUnifiedFolder)
 
             turbines.assertThatAndEffectTurbineConsumed {
diff --git a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/FakeDrawerViewModel.kt b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/FakeDrawerViewModel.kt
index 0eaa6573ffc..173ab838d5b 100644
--- a/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/FakeDrawerViewModel.kt
+++ b/feature/navigation/drawer/src/test/kotlin/app/k9mail/feature/navigation/drawer/ui/FakeDrawerViewModel.kt
@@ -6,6 +6,6 @@ import app.k9mail.feature.navigation.drawer.ui.DrawerContract.Event
 import app.k9mail.feature.navigation.drawer.ui.DrawerContract.State
 import app.k9mail.feature.navigation.drawer.ui.DrawerContract.ViewModel
 
-class FakeDrawerViewModel(
+internal class FakeDrawerViewModel(
     initialState: State = State(),
 ) : BaseFakeViewModel<State, Event, Effect>(initialState), ViewModel