Skip to content

Commit

Permalink
Fixes New menu forgets its "Hide accounts" setting
Browse files Browse the repository at this point in the history
  • Loading branch information
shamim-emon committed Jan 17, 2025
1 parent fb561e3 commit 4ac65b3
Show file tree
Hide file tree
Showing 22 changed files with 190 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -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<DrawerConfig>
}

fun interface DrawerConfigWriter {
fun writeDrawerConfig(drawerConfig: DrawerConfig)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -18,6 +19,11 @@ val navigationDrawerModule: Module = module {
configProver = get(),
)
}
single<UseCase.SaveDrawerConfig> {
SaveDrawerConfig(
drawerConfigWriter = get(),
)
}

single<UseCase.GetDisplayAccounts> {
GetDisplayAccounts(
Expand Down Expand Up @@ -50,6 +56,7 @@ val navigationDrawerModule: Module = module {
viewModel {
DrawerViewModel(
getDrawerConfig = get(),
saveDrawerConfig = get(),
getDisplayAccounts = get(),
getDisplayFoldersForAccount = get(),
syncAccount = get(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ internal interface DomainContract {
operator fun invoke(): Flow<DrawerConfig>
}

fun interface SaveDrawerConfig {
operator fun invoke(drawerConfig: DrawerConfig): Flow<Unit>
}

fun interface GetDisplayAccounts {
operator fun invoke(): Flow<List<DisplayAccount>>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DrawerConfig> {
// TODO This needs to be updated when the config changes
return flow {
emit(configProver.loadDrawerConfig())
}
return configProver.loadDrawerConfigFlow()
}
}
Original file line number Diff line number Diff line change
@@ -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<Unit> {
return flow {
emit(drawerConfigWriter.writeDrawerConfig(drawerConfig))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -76,7 +76,7 @@ internal fun DrawerContent(
SettingList(
onAccountSelectorClick = { onEvent(Event.OnAccountSelectorClick) },
onManageFoldersClick = { onEvent(Event.OnManageFoldersClick) },
showAccountSelector = state.showAccountSelector,
showAccountSelector = state.config.showAccountSelector,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ internal interface DrawerContract {
val config: DrawerConfig = DrawerConfig(
showUnifiedFolders = false,
showStarredCount = false,
showAccountSelector = true,
),
val accounts: ImmutableList<DisplayAccount> = persistentListOf(),
val selectedAccountId: String? = null,
val folders: ImmutableList<DisplayFolder> = persistentListOf(),
val selectedFolderId: String? = null,
val showAccountSelector: Boolean = true,
val isLoading: Boolean = false,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ 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,
Expand Down Expand Up @@ -113,7 +114,19 @@ internal class DrawerViewModel(
)
}

Event.OnAccountSelectorClick -> updateState { it.copy(showAccountSelector = it.showAccountSelector.not()) }
Event.OnAccountSelectorClick -> {
viewModelScope.launch {
saveDrawerConfig.invoke(
state.value.config.copy(showAccountSelector = state.value.config.showAccountSelector.not()),
).collect {
updateState {
it.copy(
config = it.config.copy(showAccountSelector = it.config.showAccountSelector.not()),
)
}
}
}
}
Event.OnManageFoldersClick -> emitEffect(Effect.OpenManageFolders)
Event.OnSettingsClick -> emitEffect(Effect.OpenSettings)
Event.OnSyncAccount -> onSyncAccount()
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,14 +363,16 @@ internal class DrawerViewModelTest {
fun `should change state when OnAccountSelectorClick event is received`() = runMviTest {
val testSubject = createTestSubject()
val turbines = turbinesWithInitialStateCheck(testSubject, State())
val drawerConfigWithAccountSelectorEnabled = createDrawerConfig(showAccountSelector = true)
val drawerConfigWithAccountSelectorDisabled = createDrawerConfig(showAccountSelector = false)

testSubject.event(Event.OnAccountSelectorClick)

assertThat(turbines.awaitStateItem()).isEqualTo(State(showAccountSelector = false))
assertThat(turbines.awaitStateItem()).isEqualTo(State(config = drawerConfigWithAccountSelectorDisabled))

testSubject.event(Event.OnAccountSelectorClick)

assertThat(turbines.awaitStateItem()).isEqualTo(State(showAccountSelector = true))
assertThat(turbines.awaitStateItem()).isEqualTo(State(config = drawerConfigWithAccountSelectorEnabled))
}

@Test
Expand Down Expand Up @@ -414,16 +416,19 @@ internal class DrawerViewModelTest {
},
syncAccount = { syncAccountFlow },
syncAllAccounts = { syncAllAccounts },
saveDrawerConfig = { flow { emit(Unit) } },
)
}

private fun createDrawerConfig(
showUnifiedInbox: Boolean = false,
showStarredCount: Boolean = false,
showAccountSelector: Boolean = true,
): DrawerConfig {
return DrawerConfig(
showUnifiedFolders = showUnifiedInbox,
showStarredCount = showStarredCount,
showAccountSelector = showAccountSelector,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ val featureLauncherModule = module {
}

single<NavigationDrawerExternalContract.DrawerConfigLoader> {
NavigationDrawerConfigLoader()
NavigationDrawerConfigLoader(get())
}

single<NavigationDrawerExternalContract.DrawerConfigWriter> {
NavigationDrawerConfigWriter(get())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 app.k9mail.legacy.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<DrawerConfig> {
return drawerConfigManager.getDrawerConfigFlow()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.fsck.k9.feature

import app.k9mail.feature.navigation.drawer.NavigationDrawerExternalContract
import app.k9mail.legacy.preferences.DrawerConfigManager

class NavigationDrawerConfigWriter(
private val drawerConfigManager: DrawerConfigManager,
) : NavigationDrawerExternalContract.DrawerConfigWriter {
override fun writeDrawerConfig(drawerConfig: NavigationDrawerExternalContract.DrawerConfig) {
drawerConfigManager.save(drawerConfig)
}
}
1 change: 1 addition & 0 deletions legacy/core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions legacy/core/src/main/java/com/fsck/k9/K9.kt
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ object K9 : KoinComponent {
@JvmStatic
var isShowUnifiedInbox = false

@JvmStatic
var isShowAccountSelector = true

@JvmStatic
var isShowStarredCount = false

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.fsck.k9.preferences

import app.k9mail.legacy.account.AccountManager
import app.k9mail.legacy.preferences.DrawerConfigManager
import app.k9mail.legacy.preferences.GeneralSettingsManager
import com.fsck.k9.Preferences
import org.koin.core.qualifier.named
Expand All @@ -26,6 +27,12 @@ val preferencesModule = module {
coroutineScope = get(named("AppCoroutineScope")),
)
} bind GeneralSettingsManager::class
single {
RealDrawerConfigManager(
preferences = get(),
coroutineScope = get(named("AppCoroutineScope")),
)
} bind DrawerConfigManager::class

factory { SettingsFileParser() }

Expand Down
Loading

0 comments on commit 4ac65b3

Please sign in to comment.