refactor settings to use TextSpinner and save settings when selecting an option
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-7
@@ -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 {
|
||||||
|
|||||||
+121
-82
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user