refactor settings to use TextSpinner and save settings when selecting an option

This commit is contained in:
greenart7c3
2023-07-07 13:02:39 -03:00
parent 1e6ee67932
commit 6e89e69fb6
6 changed files with 165 additions and 106 deletions
@@ -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 {
@@ -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
@@ -5,10 +5,10 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class ThemeViewModel : ViewModel() {
private val _theme = MutableLiveData("System")
val theme: LiveData<String> = _theme
private val _theme = MutableLiveData(0)
val theme: LiveData<Int> = _theme
fun onChange(newValue: String) {
fun onChange(newValue: Int) {
_theme.value = newValue
}
}
@@ -41,20 +41,30 @@ class AccountViewModel(val account: Account, private val themeViewModel: ThemeVi
val userFollows: LiveData<UserState> = account.userProfile().live().follows.map { it }
val userRelays: LiveData<UserState> = 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 {
@@ -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)
)
}
}
}
@@ -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