Add persistence for isImageLoadingEnabled appearance setting (#612)

This commit is contained in:
Oleg Semenenko 2024-01-15 10:26:43 -06:00 committed by Álison Fernandes
parent 561aabc528
commit 80084ff0fb
9 changed files with 92 additions and 7 deletions

View file

@ -8,6 +8,12 @@ import kotlinx.coroutines.flow.Flow
* Primary access point for general settings-related disk information.
*/
interface SettingsDiskSource {
/**
* The currently persisted setting for getting login item icons (or `null` if not set).
*/
var isIconLoadingDisabled: Boolean?
/**
* The currently persisted app language (or `null` if not set).
*/

View file

@ -13,6 +13,7 @@ private const val APP_LANGUAGE_KEY = "$BASE_KEY:appLocale"
private const val PULL_TO_REFRESH_KEY = "$BASE_KEY:syncOnRefresh"
private const val VAULT_TIMEOUT_ACTION_KEY = "$BASE_KEY:vaultTimeoutAction"
private const val VAULT_TIME_IN_MINUTES_KEY = "$BASE_KEY:vaultTimeout"
private const val DISABLE_ICON_LOADING_KEY = "$BASE_KEY:disableFavicon"
/**
* Primary implementation of [SettingsDiskSource].
@ -43,6 +44,15 @@ class SettingsDiskSourceImpl(
)
}
override var isIconLoadingDisabled: Boolean?
get() = getBoolean(key = DISABLE_ICON_LOADING_KEY)
set(value) {
putBoolean(
key = DISABLE_ICON_LOADING_KEY,
value = value,
)
}
override fun clearData(userId: String) {
storeVaultTimeoutInMinutes(userId = userId, vaultTimeoutInMinutes = null)
storeVaultTimeoutAction(userId = userId, vaultTimeoutAction = null)

View file

@ -14,6 +14,11 @@ interface SettingsRepository {
*/
var appLanguage: AppLanguage
/**
* Is icon loading for login items disabled.
*/
var isIconLoadingDisabled: Boolean
/**
* The [VaultTimeout] for the current user.
*/

View file

@ -31,6 +31,12 @@ class SettingsRepositoryImpl(
settingsDiskSource.appLanguage = value
}
override var isIconLoadingDisabled: Boolean
get() = settingsDiskSource.isIconLoadingDisabled ?: false
set(value) {
settingsDiskSource.isIconLoadingDisabled = value
}
override var vaultTimeout: VaultTimeout
get() = activeUserId
?.let {

View file

@ -28,7 +28,7 @@ class AppearanceViewModel @Inject constructor(
initialState = savedStateHandle[KEY_STATE]
?: AppearanceState(
language = settingsRepository.appLanguage,
showWebsiteIcons = false,
showWebsiteIcons = !settingsRepository.isIconLoadingDisabled,
theme = AppearanceState.Theme.DEFAULT,
),
) {
@ -54,8 +54,12 @@ class AppearanceViewModel @Inject constructor(
}
private fun handleShowWebsiteIconsToggled(action: AppearanceAction.ShowWebsiteIconsToggle) {
// TODO: BIT-541 add website icon support
mutableStateFlow.update { it.copy(showWebsiteIcons = action.showWebsiteIcons) }
mutableStateFlow.update {
it.copy(showWebsiteIcons = action.showWebsiteIcons)
}
// Negate the boolean to properly update the settings repository
settingsRepository.isIconLoadingDisabled = !action.showWebsiteIcons
}
private fun handleThemeChanged(action: AppearanceAction.ThemeChange) {

View file

@ -76,6 +76,36 @@ class SettingsDiskSourceTest {
assertNull(settingsDiskSource.getVaultTimeoutAction(userId = userId))
}
@Test
fun `isIconLoadingDisabled should pull from and update SharedPreferences`() {
val isIconLoadingDisabled = "bwPreferencesStorage:disableFavicon"
val expected = false
// Assert that the default value in disk source is null
assertNull(settingsDiskSource.isIconLoadingDisabled)
// Updating the shared preferences should update disk source.
fakeSharedPreferences
.edit()
.putBoolean(
isIconLoadingDisabled,
expected,
)
.apply()
assertEquals(
expected,
settingsDiskSource.isIconLoadingDisabled,
)
// Updating the disk source updates the shared preferences
settingsDiskSource.isIconLoadingDisabled = true
assertTrue(
fakeSharedPreferences.getBoolean(
isIconLoadingDisabled, false,
),
)
}
@Test
fun `getVaultTimeoutInMinutes when values are present should pull from SharedPreferences`() {
val vaultTimeoutBaseKey = "bwPreferencesStorage:vaultTimeout"

View file

@ -29,6 +29,8 @@ class FakeSettingsDiskSource : SettingsDiskSource {
override var appLanguage: AppLanguage? = null
override var isIconLoadingDisabled: Boolean? = null
override fun clearData(userId: String) {
storedVaultTimeoutActions.remove(userId)
storedVaultTimeoutInMinutes.remove(userId)

View file

@ -112,6 +112,19 @@ class SettingsRepositoryTest {
)
}
@Test
fun `isIconLoadingDisabled should pull from and update SettingsDiskSource`() {
assertFalse(settingsRepository.isIconLoadingDisabled)
// Updates to the disk source change the repository value.
fakeSettingsDiskSource.isIconLoadingDisabled = true
assertTrue(settingsRepository.isIconLoadingDisabled)
// Updates to the repository change the disk source value
settingsRepository.isIconLoadingDisabled = false
assertFalse(fakeSettingsDiskSource.isIconLoadingDisabled!!)
}
@Test
fun `vaultTimeout should pull from and update SettingsDiskSource for the current user`() {
every { authDiskSource.userState?.activeUserId } returns null

View file

@ -23,6 +23,8 @@ class AppearanceViewModelTest : BaseViewModelTest() {
private val mockSettingsRepository = mockk<SettingsRepository> {
every { appLanguage } returns AppLanguage.DEFAULT
every { appLanguage = AppLanguage.ENGLISH } just runs
every { isIconLoadingDisabled } returns false
every { isIconLoadingDisabled = true } just runs
}
@BeforeEach
@ -85,18 +87,25 @@ class AppearanceViewModelTest : BaseViewModelTest() {
}
@Test
fun `on ShowWebsiteIconsToggle should update value in state`() = runTest {
fun `on ShowWebsiteIconsToggle should update state and store the value`() = runTest {
val viewModel = createViewModel()
viewModel.stateFlow.test {
assertEquals(
DEFAULT_STATE,
awaitItem(),
)
viewModel.trySendAction(AppearanceAction.ShowWebsiteIconsToggle(true))
viewModel.trySendAction(AppearanceAction.ShowWebsiteIconsToggle(false))
assertEquals(
DEFAULT_STATE.copy(showWebsiteIcons = true),
DEFAULT_STATE.copy(showWebsiteIcons = false),
awaitItem(),
)
// Since we negate the boolean in the ViewModel it should be true
verify {
mockSettingsRepository.isIconLoadingDisabled = true
}
}
}
@ -129,7 +138,7 @@ class AppearanceViewModelTest : BaseViewModelTest() {
companion object {
private val DEFAULT_STATE = AppearanceState(
language = AppLanguage.DEFAULT,
showWebsiteIcons = false,
showWebsiteIcons = true,
theme = AppearanceState.Theme.DEFAULT,
)
}