From 6e89e69fb6ac0787d40e373946696b619e38168b Mon Sep 17 00:00:00 2001 From: greenart7c3 <115044884+greenart7c3@users.noreply.github.com> Date: Fri, 7 Jul 2023 13:02:39 -0300 Subject: [PATCH] refactor settings to use TextSpinner and save settings when selecting an option --- .../amethyst/LocalPreferences.kt | 10 +- .../vitorpamplona/amethyst/model/Account.kt | 22 +- .../amethyst/ui/screen/ThemeViewModel.kt | 6 +- .../ui/screen/loggedIn/AccountViewModel.kt | 24 ++- .../ui/screen/loggedIn/SettingsScreen.kt | 203 +++++++++++------- .../vitorpamplona/amethyst/ui/theme/Theme.kt | 6 +- 6 files changed, 165 insertions(+), 106 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index 2a6929735..3ea15b1a8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -265,18 +265,16 @@ object LocalPreferences { }.apply() } - fun updateTheme(theme: String) { + fun updateTheme(theme: Int) { encryptedPreferences().edit().apply { - putString(PrefKeys.THEME, theme) + putInt(PrefKeys.THEME, theme) }.apply() } - fun getTheme(): String { - var theme = "System" + fun getTheme(): Int { encryptedPreferences().apply { - theme = getString(PrefKeys.THEME, "System") ?: "System" + return getInt(PrefKeys.THEME, 0) } - return theme } fun getPreferredLanguage(): String { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index cefa8bf11..9adf54c5f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -85,19 +85,31 @@ class Account( val saveable: AccountLiveData = AccountLiveData(this) var userProfileCache: User? = null - - fun updateGlobalSettings( - automaticallyShowImages: Boolean?, + fun updateAutomaticallyStartPlayback( automaticallyStartPlayback: Boolean?, - automaticallyShowUrlPreview: Boolean? ) { settings.automaticallyStartPlayback = automaticallyStartPlayback - settings.automaticallyShowImages = automaticallyShowImages + live.invalidateData() + saveable.invalidateData() + } + + fun updateAutomaticallyShowUrlPreview( + automaticallyShowUrlPreview: Boolean?, + ) { settings.automaticallyShowUrlPreview = automaticallyShowUrlPreview live.invalidateData() saveable.invalidateData() } + fun updateAutomaticallyShowImages( + automaticallyShowImages: Boolean?, + ) { + settings.automaticallyShowImages = automaticallyShowImages + live.invalidateData() + saveable.invalidateData() + } + + fun updateOptOutOptions(warnReports: Boolean, filterSpam: Boolean) { warnAboutPostsWithReports = warnReports filterSpamFromStrangers = filterSpam diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThemeViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThemeViewModel.kt index c64cca42d..661d8672d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThemeViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThemeViewModel.kt @@ -5,10 +5,10 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel class ThemeViewModel : ViewModel() { - private val _theme = MutableLiveData("System") - val theme: LiveData = _theme + private val _theme = MutableLiveData(0) + val theme: LiveData = _theme - fun onChange(newValue: String) { + fun onChange(newValue: Int) { _theme.value = newValue } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 003f7c926..ab743e3d2 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -41,20 +41,30 @@ class AccountViewModel(val account: Account, private val themeViewModel: ThemeVi val userFollows: LiveData = account.userProfile().live().follows.map { it } val userRelays: LiveData = account.userProfile().live().relays.map { it } - fun changeTheme(newValue: String) { + fun changeTheme(newValue: Int) { themeViewModel.onChange(newValue) } - fun currentTheme(): String { - return themeViewModel.theme.value ?: "System" + fun currentTheme(): Int { + return themeViewModel.theme.value ?: 0 } - fun updateGlobalSettings( - automaticallyShowImages: Boolean?, + fun updateAutomaticallyStartPlayback( automaticallyStartPlayback: Boolean?, - automaticallyShowUrlPreview: Boolean? ) { - account.updateGlobalSettings(automaticallyShowImages, automaticallyStartPlayback, automaticallyShowUrlPreview) + account.updateAutomaticallyStartPlayback(automaticallyStartPlayback) + } + + fun updateAutomaticallyShowUrlPreview( + automaticallyShowUrlPreview: Boolean?, + ) { + account.updateAutomaticallyShowUrlPreview(automaticallyShowUrlPreview) + } + + fun updateAutomaticallyShowImages( + automaticallyShowImages: Boolean?, + ) { + account.updateAutomaticallyShowImages(automaticallyShowImages) } fun isWriteable(): Boolean { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt index 29a34963a..a26087ebe 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt @@ -2,15 +2,15 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn import android.content.Context import androidx.appcompat.app.AppCompatDelegate -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material.Button import androidx.compose.material.DropdownMenuItem import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExposedDropdownMenuBox @@ -34,9 +34,10 @@ import androidx.compose.ui.unit.sp import androidx.core.os.LocaleListCompat import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.StdPadding +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.xmlpull.v1.XmlPullParser @@ -89,7 +90,7 @@ fun SettingsScreen( nav: (String) -> Unit ) { val scope = rememberCoroutineScope() - val selectedItens = arrayOf("Always", "Wifi-only", "Never") + val selectedItens = persistentListOf("Always", "Wifi-only", "Never") val settings = accountViewModel.account.settings val index = if (settings.automaticallyShowImages == null) { 0 } else { if (settings.automaticallyShowImages == true) 1 else 2 @@ -97,33 +98,18 @@ fun SettingsScreen( val videoIndex = if (settings.automaticallyStartPlayback == null) { 0 } else { if (settings.automaticallyShowImages == true) 1 else 2 } - val selectedItem = remember { - mutableStateOf(selectedItens[index]) - } - val selectedVideoItem = remember { - mutableStateOf(selectedItens[videoIndex]) - } val linkIndex = if (settings.automaticallyShowUrlPreview == null) { 0 } else { if (settings.automaticallyShowUrlPreview == true) 1 else 2 } - val selectedLinkItem = remember { - mutableStateOf(selectedItens[linkIndex]) - } - val themeItens = arrayOf("System", "Light", "Dark") - val themeIndex = themeItens.indexOf(accountViewModel.currentTheme()) - val selectedTheme = remember { - mutableStateOf(themeItens[themeIndex]) - } + val themeItens = persistentListOf("System", "Light", "Dark") + val themeIndex = accountViewModel.currentTheme() val context = LocalContext.current val languageEntries = context.getLangPreferenceDropdownEntries() - val languageList = languageEntries.keys.toTypedArray() + val languageList = languageEntries.keys.toImmutableList() val languageIndex = getLanguageIndex(languageEntries) - val selectedLanguage = remember { - mutableStateOf(languageList[languageIndex]) - } Column( StdPadding @@ -132,72 +118,125 @@ fun SettingsScreen( ) { Section("Application preferences") - DropDownSettings( - selectedItem = selectedLanguage, - listItems = languageList, - title = "Language" - ) - - DropDownSettings( - selectedItem = selectedTheme, - listItems = themeItens, - title = "Theme" - ) - - DropDownSettings( - selectedItem = selectedItem, - listItems = selectedItens, - title = "Automatically load images/gifs" - ) - - DropDownSettings( - selectedItem = selectedVideoItem, - listItems = selectedItens, - title = "Automatically play videos" - ) - - DropDownSettings( - selectedItem = selectedLinkItem, - listItems = selectedItens, - title = "Automatically show url preview" - ) - Row( - Modifier.fillMaxWidth(), - Arrangement.Center + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() ) { - Button( - onClick = { - val automaticallyShowImages = when (selectedItens.indexOf(selectedItem.value)) { - 1 -> true - 2 -> false - else -> null - } - val automaticallyStartPlayback = when (selectedItens.indexOf(selectedVideoItem.value)) { - 1 -> true - 2 -> false - else -> null - } - val automaticallyShowUrlPreview = when (selectedItens.indexOf(selectedLinkItem.value)) { - 1 -> true - 2 -> false - else -> null - } - accountViewModel.changeTheme(selectedTheme.value) - + TextSpinner( + label = "Language", + placeholder = languageList[languageIndex], + options = languageList, + onSelect = { scope.launch(Dispatchers.IO) { - accountViewModel.updateGlobalSettings(automaticallyShowImages, automaticallyStartPlayback, automaticallyShowUrlPreview) + val locale = languageEntries[languageList[it]] + accountViewModel.account.settings.preferredLanguage = locale LocalPreferences.saveToEncryptedStorage(accountViewModel.account) - LocalPreferences.updateTheme(selectedTheme.value) - ServiceManager.pause() - ServiceManager.start(context) - val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(languageEntries[selectedLanguage.value]) + val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(languageEntries[languageList[it]]) AppCompatDelegate.setApplicationLocales(appLocale) } - } - ) { - Text(text = "Save") - } + }, + modifier = Modifier + .windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)) + .weight(1f) + ) + } + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + TextSpinner( + label = "Theme", + placeholder = themeItens[themeIndex], + options = themeItens, + onSelect = { + accountViewModel.changeTheme(it) + scope.launch(Dispatchers.IO) { + LocalPreferences.updateTheme(it) + } + }, + modifier = Modifier + .windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)) + .weight(1f) + ) + } + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + TextSpinner( + label = "Automatically load images/gifs", + placeholder = selectedItens[index], + options = selectedItens, + onSelect = { + val automaticallyShowImages = when (it) { + 1 -> true + 2 -> false + else -> null + } + + scope.launch(Dispatchers.IO) { + accountViewModel.updateAutomaticallyShowImages(automaticallyShowImages) + LocalPreferences.saveToEncryptedStorage(accountViewModel.account) + } + }, + modifier = Modifier + .windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)) + .weight(1f) + ) + } + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + TextSpinner( + label = "Automatically play videos", + placeholder = selectedItens[videoIndex], + options = selectedItens, + onSelect = { + val automaticallyStartPlayback = when (it) { + 1 -> true + 2 -> false + else -> null + } + + scope.launch(Dispatchers.IO) { + accountViewModel.updateAutomaticallyStartPlayback(automaticallyStartPlayback) + LocalPreferences.saveToEncryptedStorage(accountViewModel.account) + } + }, + modifier = Modifier + .windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)) + .weight(1f) + ) + } + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + TextSpinner( + label = "Automatically show url preview", + placeholder = selectedItens[linkIndex], + options = selectedItens, + onSelect = { + val automaticallyShowUrlPreview = when (it) { + 1 -> true + 2 -> false + else -> null + } + + scope.launch(Dispatchers.IO) { + accountViewModel.updateAutomaticallyStartPlayback(automaticallyShowUrlPreview) + LocalPreferences.saveToEncryptedStorage(accountViewModel.account) + } + }, + modifier = Modifier + .windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)) + .weight(1f) + ) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt index a1966e8a6..cb4f37191 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt @@ -309,9 +309,9 @@ val Colors.innerPostModifier: Modifier fun AmethystTheme(themeViewModel: ThemeViewModel, content: @Composable () -> Unit) { val theme = themeViewModel.theme.observeAsState() val darkTheme = when (theme.value) { - "Dark" -> true - "Light" -> false - else -> if (isSystemInDarkTheme()) true else false + 2 -> true + 1 -> false + else -> isSystemInDarkTheme() } val colors = if (darkTheme) DarkColorPalette else LightColorPalette