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 563d4a1bc00..302a9bab80a 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 @@ -8,6 +8,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme import app.k9mail.core.ui.compose.designsystem.atom.Surface +import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfig import app.k9mail.feature.navigation.drawer.ui.FakeData.DISPLAY_ACCOUNT import app.k9mail.feature.navigation.drawer.ui.FakeData.DISPLAY_FOLDER import app.k9mail.feature.navigation.drawer.ui.FakeData.UNIFIED_FOLDER @@ -121,7 +122,11 @@ internal fun DrawerContentSingleAccountPreview() { selectedAccountId = DISPLAY_ACCOUNT.id, folders = displayFolders, selectedFolderId = displayFolders[0].id, - showAccountSelector = false, + config = DrawerConfig( + showUnifiedFolders = false, + showStarredCount = false, + showAccountSelector = false, + ), ), onEvent = {}, ) @@ -142,7 +147,11 @@ internal fun DrawerContentSingleAccountWithAccountSelectionPreview() { selectedAccountId = DISPLAY_ACCOUNT.id, folders = displayFolders, selectedFolderId = displayFolders[0].id, - showAccountSelector = true, + config = DrawerConfig( + showUnifiedFolders = false, + showStarredCount = false, + showAccountSelector = true, + ), ), onEvent = {}, ) @@ -162,7 +171,11 @@ internal fun DrawerContentMultipleAccountsAccountPreview() { selectedAccountId = accountList[0].id, folders = displayFolders, selectedFolderId = UNIFIED_FOLDER.id, - showAccountSelector = false, + config = DrawerConfig( + showUnifiedFolders = false, + showStarredCount = false, + showAccountSelector = false, + ), ), onEvent = {}, ) @@ -181,7 +194,11 @@ internal fun DrawerContentMultipleAccountsWithAccountSelectionPreview() { selectedAccountId = accountList[1].id, folders = createDisplayFolderList(hasUnifiedFolder = true), selectedFolderId = UNIFIED_FOLDER.id, - showAccountSelector = true, + config = DrawerConfig( + showUnifiedFolders = false, + showStarredCount = false, + showAccountSelector = true, + ), ), onEvent = {}, ) @@ -200,7 +217,11 @@ internal fun DrawerContentMultipleAccountsWithDifferentAccountSelectionPreview() selectedAccountId = accountList[2].id, folders = createDisplayFolderList(hasUnifiedFolder = true), selectedFolderId = UNIFIED_FOLDER.id, - showAccountSelector = true, + config = DrawerConfig( + showUnifiedFolders = false, + showStarredCount = false, + showAccountSelector = true, + ), ), onEvent = {}, ) @@ -224,7 +245,11 @@ internal fun DrawerContentSmallScreenPreview() { selectedAccountId = accountList[2].id, folders = createDisplayFolderList(hasUnifiedFolder = true), selectedFolderId = UNIFIED_FOLDER.id, - showAccountSelector = true, + config = DrawerConfig( + showUnifiedFolders = false, + showStarredCount = false, + showAccountSelector = true, + ), ), onEvent = {}, ) @@ -249,7 +274,11 @@ internal fun DrawerContentVerySmallScreenPreview() { selectedAccountId = accountList[2].id, folders = createDisplayFolderList(hasUnifiedFolder = true), selectedFolderId = UNIFIED_FOLDER.id, - showAccountSelector = true, + config = DrawerConfig( + showUnifiedFolders = false, + showStarredCount = false, + showAccountSelector = true, + ), ), onEvent = {}, ) diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawerExternalContract.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawerExternalContract.kt index a0365968237..6f34262b0ef 100644 --- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawerExternalContract.kt +++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/NavigationDrawerExternalContract.kt @@ -1,13 +1,20 @@ package app.k9mail.feature.navigation.drawer +import kotlinx.coroutines.flow.Flow + interface NavigationDrawerExternalContract { data class DrawerConfig( val showUnifiedFolders: Boolean, val showStarredCount: Boolean, + val showAccountSelector: Boolean, ) fun interface DrawerConfigLoader { - fun loadDrawerConfig(): DrawerConfig + fun loadDrawerConfigFlow(): Flow + } + + fun interface DrawerConfigWriter { + fun writeDrawerConfig(drawerConfig: DrawerConfig) } } 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 aa63cc325d4..b12697dd367 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 @@ -4,6 +4,7 @@ import app.k9mail.feature.navigation.drawer.domain.DomainContract.UseCase import app.k9mail.feature.navigation.drawer.domain.usecase.GetDisplayAccounts import app.k9mail.feature.navigation.drawer.domain.usecase.GetDisplayFoldersForAccount import app.k9mail.feature.navigation.drawer.domain.usecase.GetDrawerConfig +import app.k9mail.feature.navigation.drawer.domain.usecase.SaveDrawerConfig import app.k9mail.feature.navigation.drawer.domain.usecase.SyncAccount import app.k9mail.feature.navigation.drawer.domain.usecase.SyncAllAccounts import app.k9mail.feature.navigation.drawer.ui.DrawerViewModel @@ -18,6 +19,11 @@ val navigationDrawerModule: Module = module { configProver = get(), ) } + single { + SaveDrawerConfig( + drawerConfigWriter = get(), + ) + } single { GetDisplayAccounts( @@ -50,6 +56,7 @@ val navigationDrawerModule: Module = module { viewModel { DrawerViewModel( getDrawerConfig = get(), + saveDrawerConfig = get(), getDisplayAccounts = get(), getDisplayFoldersForAccount = get(), syncAccount = 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 211b1456ac5..f0164ac9e2d 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 @@ -12,6 +12,10 @@ internal interface DomainContract { operator fun invoke(): Flow } + fun interface SaveDrawerConfig { + operator fun invoke(drawerConfig: DrawerConfig): Flow + } + fun interface GetDisplayAccounts { operator fun invoke(): Flow> } diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/GetDrawerConfig.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/GetDrawerConfig.kt index d4d1672e124..30f24ac9d78 100644 --- a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/GetDrawerConfig.kt +++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/GetDrawerConfig.kt @@ -4,15 +4,11 @@ import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.Dra import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfigLoader import app.k9mail.feature.navigation.drawer.domain.DomainContract.UseCase import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow internal class GetDrawerConfig( private val configProver: DrawerConfigLoader, ) : UseCase.GetDrawerConfig { override operator fun invoke(): Flow { - // TODO This needs to be updated when the config changes - return flow { - emit(configProver.loadDrawerConfig()) - } + return configProver.loadDrawerConfigFlow() } } diff --git a/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SaveDrawerConfig.kt b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SaveDrawerConfig.kt new file mode 100644 index 00000000000..651a32c1ad5 --- /dev/null +++ b/feature/navigation/drawer/src/main/kotlin/app/k9mail/feature/navigation/drawer/domain/usecase/SaveDrawerConfig.kt @@ -0,0 +1,17 @@ +package app.k9mail.feature.navigation.drawer.domain.usecase + +import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract +import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfigWriter +import app.k9mail.feature.navigation.drawer.domain.DomainContract.UseCase +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow + +internal class SaveDrawerConfig( + private val drawerConfigWriter: DrawerConfigWriter, +) : UseCase.SaveDrawerConfig { + override fun invoke(drawerConfig: NavigationDrawerExternalContract.DrawerConfig): Flow { + return flow { + emit(drawerConfigWriter.writeDrawerConfig(drawerConfig)) + } + } +} 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 0666bf41542..c2e37e7a5ca 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 @@ -41,14 +41,14 @@ internal fun DrawerContent( AccountView( account = selectedAccount, onClick = { onEvent(Event.OnAccountViewClick(selectedAccount)) }, - showAvatar = state.showAccountSelector, + showAvatar = state.config.showAccountSelector, ) DividerHorizontal() } Row { AnimatedVisibility( - visible = state.showAccountSelector, + visible = state.config.showAccountSelector, ) { AccountList( accounts = state.accounts, @@ -76,7 +76,7 @@ internal fun DrawerContent( SettingList( onAccountSelectorClick = { onEvent(Event.OnAccountSelectorClick) }, onManageFoldersClick = { onEvent(Event.OnManageFoldersClick) }, - showAccountSelector = state.showAccountSelector, + showAccountSelector = state.config.showAccountSelector, ) } } 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 f3a9023af41..3dd1554c438 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 @@ -17,12 +17,12 @@ internal interface DrawerContract { val config: DrawerConfig = DrawerConfig( showUnifiedFolders = false, showStarredCount = false, + showAccountSelector = true, ), val accounts: ImmutableList = persistentListOf(), val selectedAccountId: String? = null, val folders: ImmutableList = persistentListOf(), val selectedFolderId: String? = null, - val showAccountSelector: Boolean = true, val isLoading: Boolean = false, ) 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 b38e10f43d2..ba49d366a1f 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 @@ -20,12 +20,14 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @Suppress("MagicNumber", "TooManyFunctions") internal class DrawerViewModel( private val getDrawerConfig: UseCase.GetDrawerConfig, + private val saveDrawerConfig: UseCase.SaveDrawerConfig, private val getDisplayAccounts: UseCase.GetDisplayAccounts, private val getDisplayFoldersForAccount: UseCase.GetDisplayFoldersForAccount, private val syncAccount: UseCase.SyncAccount, @@ -113,7 +115,11 @@ internal class DrawerViewModel( ) } - Event.OnAccountSelectorClick -> updateState { it.copy(showAccountSelector = it.showAccountSelector.not()) } + Event.OnAccountSelectorClick -> { + saveDrawerConfig( + state.value.config.copy(showAccountSelector = state.value.config.showAccountSelector.not()), + ).launchIn(viewModelScope) + } Event.OnManageFoldersClick -> emitEffect(Effect.OpenManageFolders) Event.OnSettingsClick -> emitEffect(Effect.OpenSettings) Event.OnSyncAccount -> onSyncAccount() 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 0f559529555..363467ba42f 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 @@ -1,32 +1,32 @@ package app.k9mail.feature.navigation.drawer.domain.usecase import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfig +import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfigLoader import assertk.assertThat import assertk.assertions.isEqualTo import kotlin.test.Test import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest +import org.mockito.Mockito.mock +import org.mockito.kotlin.whenever internal class GetDrawerConfigTest { @Test fun `should get drawer config`() = runTest { + val configProver: DrawerConfigLoader = mock() val drawerConfig = DrawerConfig( showUnifiedFolders = true, showStarredCount = true, + showAccountSelector = true, ) - val testSubject = GetDrawerConfig( - configProver = { drawerConfig }, - ) + val testSubject = GetDrawerConfig(configProver = configProver) + whenever(configProver.loadDrawerConfigFlow()).thenReturn(flowOf(drawerConfig)) val result = testSubject().first() - assertThat(result).isEqualTo( - DrawerConfig( - showUnifiedFolders = true, - showStarredCount = true, - ), - ) + assertThat(result).isEqualTo(drawerConfig) } } 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 6197de8bd04..6b2ffb80c75 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 @@ -18,12 +18,12 @@ internal class DrawerStateTest { config = DrawerConfig( showUnifiedFolders = false, showStarredCount = false, + showAccountSelector = true, ), accounts = persistentListOf(), selectedAccountId = null, folders = persistentListOf(), selectedFolderId = null, - showAccountSelector = true, isLoading = false, ), ) 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 f1ee11e19f2..944ff911945 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 @@ -8,6 +8,7 @@ import app.k9mail.core.ui.compose.testing.mvi.assertThatAndEffectTurbineConsumed import app.k9mail.core.ui.compose.testing.mvi.runMviTest import app.k9mail.core.ui.compose.testing.mvi.turbinesWithInitialStateCheck import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfig +import app.k9mail.feature.navigation.drawer.domain.DomainContract.UseCase import app.k9mail.feature.navigation.drawer.domain.entity.DisplayAccount import app.k9mail.feature.navigation.drawer.domain.entity.DisplayAccountFolder import app.k9mail.feature.navigation.drawer.domain.entity.DisplayFolder @@ -26,10 +27,17 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import org.junit.Rule +import org.mockito.Mockito.mock +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.kotlin.any +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.whenever @OptIn(ExperimentalCoroutinesApi::class) internal class DrawerViewModelTest { @@ -359,18 +367,54 @@ internal class DrawerViewModelTest { } } + @Suppress("MaxLineLength") @Test - fun `should change state when OnAccountSelectorClick event is received`() = runMviTest { - val testSubject = createTestSubject() - val turbines = turbinesWithInitialStateCheck(testSubject, State()) + fun `when initial state has drawerConfigWithAccountSelectorDisabled saveDrawerConfig should receive drawerConfigWithAccountSelectorEnabled when OnAccountSelectorClick event is received`() = runTest { + val drawerConfigWithAccountSelectorEnabled = createDrawerConfig(showAccountSelector = true) + val drawerConfigWithAccountSelectorDisabled = createDrawerConfig(showAccountSelector = false) - testSubject.event(Event.OnAccountSelectorClick) + val saveDrawerConfig: UseCase.SaveDrawerConfig = mock() + whenever( + saveDrawerConfig.invoke(any()), + ).thenReturn(flowOf(Unit)) - assertThat(turbines.awaitStateItem()).isEqualTo(State(showAccountSelector = false)) + val testSubject = createTestSubject( + initialState = State(config = drawerConfigWithAccountSelectorDisabled), + saveDrawerConfig = saveDrawerConfig, + drawerConfigFlow = flowOf(drawerConfigWithAccountSelectorDisabled), + ) + + val captor = argumentCaptor() testSubject.event(Event.OnAccountSelectorClick) + advanceUntilIdle() + verify(saveDrawerConfig, times(1)).invoke(captor.capture()) + assertThat(captor.firstValue).isEqualTo(drawerConfigWithAccountSelectorEnabled) + } - assertThat(turbines.awaitStateItem()).isEqualTo(State(showAccountSelector = true)) + @Suppress("MaxLineLength") + @Test + fun `when initial state has drawerConfigWithAccountSelectorEnabled saveDrawerConfig should receive drawerConfigWithAccountSelectorDisabled when OnAccountSelectorClick event is received`() = runTest { + val drawerConfigWithAccountSelectorEnabled = createDrawerConfig(showAccountSelector = true) + val drawerConfigWithAccountSelectorDisabled = createDrawerConfig(showAccountSelector = false) + + val saveDrawerConfig: UseCase.SaveDrawerConfig = mock() + whenever( + saveDrawerConfig.invoke(any()), + ).thenReturn(flowOf(Unit)) + + val testSubject = createTestSubject( + initialState = State(config = drawerConfigWithAccountSelectorEnabled), + saveDrawerConfig = saveDrawerConfig, + drawerConfigFlow = flowOf(drawerConfigWithAccountSelectorEnabled), + ) + + val captor = argumentCaptor() + + testSubject.event(Event.OnAccountSelectorClick) + advanceUntilIdle() + verify(saveDrawerConfig, times(1)).invoke(captor.capture()) + assertThat(captor.firstValue).isEqualTo(drawerConfigWithAccountSelectorDisabled) } @Test @@ -404,6 +448,7 @@ internal class DrawerViewModelTest { displayFoldersFlow: Flow>> = flow { emit(emptyMap()) }, syncAccountFlow: Flow> = flow { emit(Result.success(Unit)) }, syncAllAccounts: Flow> = flow { emit(Result.success(Unit)) }, + saveDrawerConfig: UseCase.SaveDrawerConfig = mock(), ): DrawerViewModel { return DrawerViewModel( initialState = initialState, @@ -414,16 +459,19 @@ internal class DrawerViewModelTest { }, syncAccount = { syncAccountFlow }, syncAllAccounts = { syncAllAccounts }, + saveDrawerConfig = saveDrawerConfig, ) } private fun createDrawerConfig( showUnifiedInbox: Boolean = false, showStarredCount: Boolean = false, + showAccountSelector: Boolean = true, ): DrawerConfig { return DrawerConfig( showUnifiedFolders = showUnifiedInbox, showStarredCount = showStarredCount, + showAccountSelector = showAccountSelector, ) } diff --git a/legacy/common/src/main/java/com/fsck/k9/feature/FeatureModule.kt b/legacy/common/src/main/java/com/fsck/k9/feature/FeatureModule.kt index a27eb4efa30..5c8bd0de3f1 100644 --- a/legacy/common/src/main/java/com/fsck/k9/feature/FeatureModule.kt +++ b/legacy/common/src/main/java/com/fsck/k9/feature/FeatureModule.kt @@ -13,6 +13,10 @@ val featureLauncherModule = module { } single { - NavigationDrawerConfigLoader() + NavigationDrawerConfigLoader(get()) + } + + single { + NavigationDrawerConfigWriter(get()) } } diff --git a/legacy/common/src/main/java/com/fsck/k9/feature/NavigationDrawerConfigLoader.kt b/legacy/common/src/main/java/com/fsck/k9/feature/NavigationDrawerConfigLoader.kt index ae8c1ed708e..f8f5251c392 100644 --- a/legacy/common/src/main/java/com/fsck/k9/feature/NavigationDrawerConfigLoader.kt +++ b/legacy/common/src/main/java/com/fsck/k9/feature/NavigationDrawerConfigLoader.kt @@ -2,13 +2,11 @@ package com.fsck.k9.feature import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfig import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfigLoader -import com.fsck.k9.K9 +import com.fsck.k9.preferences.DrawerConfigManager +import kotlinx.coroutines.flow.Flow -class NavigationDrawerConfigLoader : DrawerConfigLoader { - override fun loadDrawerConfig(): DrawerConfig { - return DrawerConfig( - showUnifiedFolders = K9.isShowUnifiedInbox, - showStarredCount = K9.isShowStarredCount, - ) +class NavigationDrawerConfigLoader(private val drawerConfigManager: DrawerConfigManager) : DrawerConfigLoader { + override fun loadDrawerConfigFlow(): Flow { + return drawerConfigManager.getConfigFlow() } } diff --git a/legacy/common/src/main/java/com/fsck/k9/feature/NavigationDrawerConfigWriter.kt b/legacy/common/src/main/java/com/fsck/k9/feature/NavigationDrawerConfigWriter.kt new file mode 100644 index 00000000000..0ff44dd935e --- /dev/null +++ b/legacy/common/src/main/java/com/fsck/k9/feature/NavigationDrawerConfigWriter.kt @@ -0,0 +1,13 @@ +package com.fsck.k9.feature + +import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract +import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfig +import com.fsck.k9.preferences.DrawerConfigManager + +class NavigationDrawerConfigWriter( + private val drawerConfigManager: DrawerConfigManager, +) : NavigationDrawerExternalContract.DrawerConfigWriter { + override fun writeDrawerConfig(drawerConfig: DrawerConfig) { + drawerConfigManager.save(drawerConfig) + } +} diff --git a/legacy/core/build.gradle.kts b/legacy/core/build.gradle.kts index b94dcd6cdb5..47c17bffa91 100644 --- a/legacy/core/build.gradle.kts +++ b/legacy/core/build.gradle.kts @@ -36,6 +36,7 @@ dependencies { implementation(libs.timber) implementation(libs.mime4j.core) implementation(libs.mime4j.dom) + implementation(projects.feature.navigation.drawer) testApi(projects.core.testing) testApi(projects.core.android.testing) diff --git a/legacy/core/src/main/java/com/fsck/k9/K9.kt b/legacy/core/src/main/java/com/fsck/k9/K9.kt index 8e3d7c5077a..263df7f648f 100644 --- a/legacy/core/src/main/java/com/fsck/k9/K9.kt +++ b/legacy/core/src/main/java/com/fsck/k9/K9.kt @@ -200,6 +200,9 @@ object K9 : KoinComponent { @JvmStatic var isShowUnifiedInbox = false + @JvmStatic + var isShowAccountSelector = true + @JvmStatic var isShowStarredCount = false @@ -329,6 +332,7 @@ object K9 : KoinComponent { isShowAnimations = storage.getBoolean("animations", true) isUseVolumeKeysForNavigation = storage.getBoolean("useVolumeKeysForNavigation", false) isShowUnifiedInbox = storage.getBoolean("showUnifiedInbox", false) + isShowAccountSelector = storage.getBoolean("showAccountSelector", true) isShowStarredCount = storage.getBoolean("showStarredCount", false) isMessageListSenderAboveSubject = storage.getBoolean("messageListSenderAboveSubject", false) isShowMessageListStars = storage.getBoolean("messageListStars", true) @@ -424,6 +428,7 @@ object K9 : KoinComponent { editor.putEnum("messageListDensity", messageListDensity) editor.putBoolean("messageListSenderAboveSubject", isMessageListSenderAboveSubject) editor.putBoolean("showUnifiedInbox", isShowUnifiedInbox) + editor.putBoolean("showAccountSelector", isShowAccountSelector) editor.putBoolean("showStarredCount", isShowStarredCount) editor.putBoolean("messageListStars", isShowMessageListStars) editor.putInt("messageListPreviewLines", messageListPreviewLines) diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/DrawerConfigManager.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/DrawerConfigManager.kt new file mode 100644 index 00000000000..91b5fed6878 --- /dev/null +++ b/legacy/core/src/main/java/com/fsck/k9/preferences/DrawerConfigManager.kt @@ -0,0 +1,6 @@ +package com.fsck.k9.preferences + +import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfig +import app.k9mail.legacy.preferences.ConfigManager + +interface DrawerConfigManager : ConfigManager diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java b/legacy/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java index 4dd24a637e2..96928500a23 100644 --- a/legacy/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java +++ b/legacy/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java @@ -174,6 +174,9 @@ class GeneralSettingsDescriptions { new V(69, new BooleanSetting(true)), new V(101, new BooleanSetting(false)) )); + s.put("isShowAccountSelector", Settings.versions( + new V(102, new BooleanSetting(true)) + )); s.put("sortTypeEnum", Settings.versions( new V(10, new EnumSetting<>(SortType.class, Account.DEFAULT_SORT_TYPE)) )); diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt index e63e197748f..41de59f552c 100644 --- a/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt +++ b/legacy/core/src/main/java/com/fsck/k9/preferences/KoinModule.kt @@ -26,6 +26,12 @@ val preferencesModule = module { coroutineScope = get(named("AppCoroutineScope")), ) } bind GeneralSettingsManager::class + single { + RealDrawerConfigManager( + preferences = get(), + coroutineScope = get(named("AppCoroutineScope")), + ) + } bind DrawerConfigManager::class factory { SettingsFileParser() } diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/RealDrawerConfigManager.kt b/legacy/core/src/main/java/com/fsck/k9/preferences/RealDrawerConfigManager.kt new file mode 100644 index 00000000000..33f18e336df --- /dev/null +++ b/legacy/core/src/main/java/com/fsck/k9/preferences/RealDrawerConfigManager.kt @@ -0,0 +1,65 @@ +package com.fsck.k9.preferences + +import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract.DrawerConfig +import com.fsck.k9.K9 +import com.fsck.k9.Preferences +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.launch + +internal class RealDrawerConfigManager( + private val preferences: Preferences, + private val coroutineScope: CoroutineScope, +) : DrawerConfigManager { + private val drawerConfigFlow = MutableSharedFlow(replay = 1) + private var drawerConfig: DrawerConfig? = null + + override fun save(config: DrawerConfig) { + saveDrawerConfig(config) + updateDrawerConfigFlow(config) + } + + private fun loadDrawerConfig(): DrawerConfig { + val drawerConfig = DrawerConfig( + showAccountSelector = K9.isShowAccountSelector, + showStarredCount = K9.isShowStarredCount, + showUnifiedFolders = K9.isShowUnifiedInbox, + ) + + updateDrawerConfigFlow(drawerConfig) + + return drawerConfig + } + + private fun updateDrawerConfigFlow(config: DrawerConfig) { + coroutineScope.launch { + drawerConfigFlow.emit(config) + } + } + + @Synchronized + override fun getConfig(): DrawerConfig { + return drawerConfig ?: loadDrawerConfig().also { drawerConfig = it } + } + + override fun getConfigFlow(): Flow { + getConfig() + return drawerConfigFlow.distinctUntilChanged() + } + + @Synchronized + private fun saveDrawerConfig(config: DrawerConfig) { + val editor = preferences.createStorageEditor() + K9.save(editor) + writeDrawerConfig(editor, config) + editor.commit() + } + + private fun writeDrawerConfig(editor: StorageEditor, config: DrawerConfig) { + editor.putBoolean("showAccountSelector", config.showAccountSelector) + editor.putBoolean("showUnifiedInbox", config.showUnifiedFolders) + editor.putBoolean("showStarredCount", config.showStarredCount) + } +} diff --git a/legacy/core/src/main/java/com/fsck/k9/preferences/Settings.java b/legacy/core/src/main/java/com/fsck/k9/preferences/Settings.java index 43c5495c7f5..cd7aede6621 100644 --- a/legacy/core/src/main/java/com/fsck/k9/preferences/Settings.java +++ b/legacy/core/src/main/java/com/fsck/k9/preferences/Settings.java @@ -33,7 +33,7 @@ class Settings { * * @see SettingsExporter */ - public static final int VERSION = 101; + public static final int VERSION = 102; static Map validate(int version, Map>> settings, Map importedSettings, boolean useDefaultValues) { diff --git a/legacy/preferences/src/main/java/app/k9mail/legacy/preferences/ConfigManager.kt b/legacy/preferences/src/main/java/app/k9mail/legacy/preferences/ConfigManager.kt new file mode 100644 index 00000000000..370ef629eb7 --- /dev/null +++ b/legacy/preferences/src/main/java/app/k9mail/legacy/preferences/ConfigManager.kt @@ -0,0 +1,9 @@ +package app.k9mail.legacy.preferences + +import kotlinx.coroutines.flow.Flow + +interface ConfigManager { + fun save(config: T) + fun getConfig(): T + fun getConfigFlow(): Flow +}