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() }.apply()
} }
fun updateTheme(theme: String) { fun updateTheme(theme: Int) {
encryptedPreferences().edit().apply { encryptedPreferences().edit().apply {
putString(PrefKeys.THEME, theme) putInt(PrefKeys.THEME, theme)
}.apply() }.apply()
} }
fun getTheme(): String { fun getTheme(): Int {
var theme = "System"
encryptedPreferences().apply { encryptedPreferences().apply {
theme = getString(PrefKeys.THEME, "System") ?: "System" return getInt(PrefKeys.THEME, 0)
} }
return theme
} }
fun getPreferredLanguage(): String { fun getPreferredLanguage(): String {
@@ -85,19 +85,31 @@ class Account(
val saveable: AccountLiveData = AccountLiveData(this) val saveable: AccountLiveData = AccountLiveData(this)
var userProfileCache: User? = null var userProfileCache: User? = null
fun updateAutomaticallyStartPlayback(
fun updateGlobalSettings(
automaticallyShowImages: Boolean?,
automaticallyStartPlayback: Boolean?, automaticallyStartPlayback: Boolean?,
automaticallyShowUrlPreview: Boolean?
) { ) {
settings.automaticallyStartPlayback = automaticallyStartPlayback settings.automaticallyStartPlayback = automaticallyStartPlayback
settings.automaticallyShowImages = automaticallyShowImages live.invalidateData()
saveable.invalidateData()
}
fun updateAutomaticallyShowUrlPreview(
automaticallyShowUrlPreview: Boolean?,
) {
settings.automaticallyShowUrlPreview = automaticallyShowUrlPreview settings.automaticallyShowUrlPreview = automaticallyShowUrlPreview
live.invalidateData() live.invalidateData()
saveable.invalidateData() saveable.invalidateData()
} }
fun updateAutomaticallyShowImages(
automaticallyShowImages: Boolean?,
) {
settings.automaticallyShowImages = automaticallyShowImages
live.invalidateData()
saveable.invalidateData()
}
fun updateOptOutOptions(warnReports: Boolean, filterSpam: Boolean) { fun updateOptOutOptions(warnReports: Boolean, filterSpam: Boolean) {
warnAboutPostsWithReports = warnReports warnAboutPostsWithReports = warnReports
filterSpamFromStrangers = filterSpam filterSpamFromStrangers = filterSpam
@@ -5,10 +5,10 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
class ThemeViewModel : ViewModel() { class ThemeViewModel : ViewModel() {
private val _theme = MutableLiveData("System") private val _theme = MutableLiveData(0)
val theme: LiveData<String> = _theme val theme: LiveData<Int> = _theme
fun onChange(newValue: String) { fun onChange(newValue: Int) {
_theme.value = newValue _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 userFollows: LiveData<UserState> = account.userProfile().live().follows.map { it }
val userRelays: LiveData<UserState> = account.userProfile().live().relays.map { it } val userRelays: LiveData<UserState> = account.userProfile().live().relays.map { it }
fun changeTheme(newValue: String) { fun changeTheme(newValue: Int) {
themeViewModel.onChange(newValue) themeViewModel.onChange(newValue)
} }
fun currentTheme(): String { fun currentTheme(): Int {
return themeViewModel.theme.value ?: "System" return themeViewModel.theme.value ?: 0
} }
fun updateGlobalSettings( fun updateAutomaticallyStartPlayback(
automaticallyShowImages: Boolean?,
automaticallyStartPlayback: Boolean?, 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 { fun isWriteable(): Boolean {
@@ -2,15 +2,15 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn
import android.content.Context import android.content.Context
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.DropdownMenuItem import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.ExposedDropdownMenuBox import androidx.compose.material.ExposedDropdownMenuBox
@@ -34,9 +34,10 @@ import androidx.compose.ui.unit.sp
import androidx.core.os.LocaleListCompat import androidx.core.os.LocaleListCompat
import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.StdPadding
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParser
@@ -89,7 +90,7 @@ fun SettingsScreen(
nav: (String) -> Unit nav: (String) -> Unit
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val selectedItens = arrayOf("Always", "Wifi-only", "Never") val selectedItens = persistentListOf("Always", "Wifi-only", "Never")
val settings = accountViewModel.account.settings val settings = accountViewModel.account.settings
val index = if (settings.automaticallyShowImages == null) { 0 } else { val index = if (settings.automaticallyShowImages == null) { 0 } else {
if (settings.automaticallyShowImages == true) 1 else 2 if (settings.automaticallyShowImages == true) 1 else 2
@@ -97,33 +98,18 @@ fun SettingsScreen(
val videoIndex = if (settings.automaticallyStartPlayback == null) { 0 } else { val videoIndex = if (settings.automaticallyStartPlayback == null) { 0 } else {
if (settings.automaticallyShowImages == true) 1 else 2 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 { val linkIndex = if (settings.automaticallyShowUrlPreview == null) { 0 } else {
if (settings.automaticallyShowUrlPreview == true) 1 else 2 if (settings.automaticallyShowUrlPreview == true) 1 else 2
} }
val selectedLinkItem = remember {
mutableStateOf(selectedItens[linkIndex])
}
val themeItens = arrayOf("System", "Light", "Dark") val themeItens = persistentListOf("System", "Light", "Dark")
val themeIndex = themeItens.indexOf(accountViewModel.currentTheme()) val themeIndex = accountViewModel.currentTheme()
val selectedTheme = remember {
mutableStateOf(themeItens[themeIndex])
}
val context = LocalContext.current val context = LocalContext.current
val languageEntries = context.getLangPreferenceDropdownEntries() val languageEntries = context.getLangPreferenceDropdownEntries()
val languageList = languageEntries.keys.toTypedArray() val languageList = languageEntries.keys.toImmutableList()
val languageIndex = getLanguageIndex(languageEntries) val languageIndex = getLanguageIndex(languageEntries)
val selectedLanguage = remember {
mutableStateOf(languageList[languageIndex])
}
Column( Column(
StdPadding StdPadding
@@ -132,72 +118,125 @@ fun SettingsScreen(
) { ) {
Section("Application preferences") 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( Row(
Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically,
Arrangement.Center modifier = Modifier.fillMaxWidth()
) { ) {
Button( TextSpinner(
onClick = { label = "Language",
val automaticallyShowImages = when (selectedItens.indexOf(selectedItem.value)) { placeholder = languageList[languageIndex],
1 -> true options = languageList,
2 -> false onSelect = {
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)
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.updateGlobalSettings(automaticallyShowImages, automaticallyStartPlayback, automaticallyShowUrlPreview) val locale = languageEntries[languageList[it]]
accountViewModel.account.settings.preferredLanguage = locale
LocalPreferences.saveToEncryptedStorage(accountViewModel.account) LocalPreferences.saveToEncryptedStorage(accountViewModel.account)
LocalPreferences.updateTheme(selectedTheme.value) val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(languageEntries[languageList[it]])
ServiceManager.pause()
ServiceManager.start(context)
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(languageEntries[selectedLanguage.value])
AppCompatDelegate.setApplicationLocales(appLocale) AppCompatDelegate.setApplicationLocales(appLocale)
} }
} },
) { modifier = Modifier
Text(text = "Save") .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) { fun AmethystTheme(themeViewModel: ThemeViewModel, content: @Composable () -> Unit) {
val theme = themeViewModel.theme.observeAsState() val theme = themeViewModel.theme.observeAsState()
val darkTheme = when (theme.value) { val darkTheme = when (theme.value) {
"Dark" -> true 2 -> true
"Light" -> false 1 -> false
else -> if (isSystemInDarkTheme()) true else false else -> isSystemInDarkTheme()
} }
val colors = if (darkTheme) DarkColorPalette else LightColorPalette val colors = if (darkTheme) DarkColorPalette else LightColorPalette