add settings to change theme

This commit is contained in:
greenart7c3
2023-07-05 11:30:18 -03:00
parent fee6f19d5e
commit 33cc261b62
7 changed files with 78 additions and 13 deletions
@@ -70,6 +70,7 @@ private object PrefKeys {
const val LAST_READ_PER_ROUTE = "last_read_route_per_route"
const val AUTOMATICALLY_SHOW_IMAGES = "automatically_show_images"
const val AUTOMATICALLY_START_PLAYBACK = "automatically_start_playback"
const val THEME = "theme"
val LAST_READ: (String) -> String = { route -> "last_read_route_$route" }
}
@@ -256,6 +257,20 @@ object LocalPreferences {
}.apply()
}
fun updateTheme(theme: String) {
encryptedPreferences().edit().apply {
putString(PrefKeys.THEME, theme)
}.apply()
}
fun getTheme(): String {
var theme = "System"
encryptedPreferences().apply {
theme = getString(PrefKeys.THEME, "System") ?: "System"
}
return theme
}
fun loadFromEncryptedStorage(): Account? {
val acc = loadFromEncryptedStorage(currentAccount())
acc?.registerObservers()
@@ -33,6 +33,7 @@ import com.vitorpamplona.amethyst.ui.navigation.debugState
import com.vitorpamplona.amethyst.ui.note.Nip47
import com.vitorpamplona.amethyst.ui.screen.AccountScreen
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
import com.vitorpamplona.amethyst.ui.screen.ThemeViewModel
import com.vitorpamplona.amethyst.ui.theme.AmethystTheme
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
@@ -50,16 +51,18 @@ class MainActivity : FragmentActivity() {
val startingPage = uriToRoute(uri)
LocalPreferences.migrateSingleUserPrefs()
val themeViewModel = ThemeViewModel()
themeViewModel.onChange(LocalPreferences.getTheme())
setContent {
AmethystTheme {
AmethystTheme(themeViewModel) {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
val accountStateViewModel: AccountStateViewModel = viewModel {
AccountStateViewModel(this@MainActivity)
}
AccountScreen(accountStateViewModel, startingPage)
AccountScreen(accountStateViewModel, themeViewModel, startingPage)
}
}
}
@@ -12,7 +12,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.MainScreen
import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginPage
@Composable
fun AccountScreen(accountStateViewModel: AccountStateViewModel, startingPage: String?) {
fun AccountScreen(accountStateViewModel: AccountStateViewModel, themeViewModel: ThemeViewModel, startingPage: String?) {
val accountState by accountStateViewModel.accountContent.collectAsState()
Column() {
@@ -24,7 +24,7 @@ fun AccountScreen(accountStateViewModel: AccountStateViewModel, startingPage: St
is AccountState.LoggedIn -> {
val accountViewModel: AccountViewModel = viewModel(
key = state.account.userProfile().pubkeyHex,
factory = AccountViewModel.Factory(state.account)
factory = AccountViewModel.Factory(state.account, themeViewModel)
)
MainScreen(accountViewModel, accountStateViewModel, startingPage)
@@ -32,7 +32,7 @@ fun AccountScreen(accountStateViewModel: AccountStateViewModel, startingPage: St
is AccountState.LoggedInViewOnly -> {
val accountViewModel: AccountViewModel = viewModel(
key = state.account.userProfile().pubkeyHex,
factory = AccountViewModel.Factory(state.account)
factory = AccountViewModel.Factory(state.account, themeViewModel)
)
MainScreen(accountViewModel, accountStateViewModel, startingPage)
@@ -0,0 +1,14 @@
package com.vitorpamplona.amethyst.ui.screen
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class ThemeViewModel : ViewModel() {
private val _theme = MutableLiveData("System")
val theme: LiveData<String> = _theme
fun onChange(newValue: String) {
_theme.value = newValue
}
}
@@ -22,6 +22,7 @@ import com.vitorpamplona.amethyst.service.model.Event
import com.vitorpamplona.amethyst.service.model.LnZapEvent
import com.vitorpamplona.amethyst.service.model.PayInvoiceErrorResponse
import com.vitorpamplona.amethyst.service.model.ReportEvent
import com.vitorpamplona.amethyst.ui.screen.ThemeViewModel
import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toImmutableSet
@@ -32,7 +33,7 @@ import java.math.BigDecimal
import java.util.Locale
@Stable
class AccountViewModel(val account: Account) : ViewModel() {
class AccountViewModel(val account: Account, private val themeViewModel: ThemeViewModel) : ViewModel() {
val accountLiveData: LiveData<AccountState> = account.live.map { it }
val accountLanguagesLiveData: LiveData<AccountState> = account.liveLanguages.map { it }
val accountLastReadLiveData: LiveData<AccountState> = account.liveLastRead.map { it }
@@ -40,6 +41,14 @@ class AccountViewModel(val account: Account) : ViewModel() {
val userFollows: LiveData<UserState> = account.userProfile().live().follows.map { it }
val userRelays: LiveData<UserState> = account.userProfile().live().relays.map { it }
fun changeTheme(newValue: String) {
themeViewModel.onChange(newValue)
}
fun currentTheme(): String {
return themeViewModel.theme.value ?: "System"
}
fun updateGlobalSettings(automaticallyShowImages: Boolean?, automaticallyStartPlayback: Boolean?) {
account.updateGlobalSettings(automaticallyShowImages, automaticallyStartPlayback)
}
@@ -303,9 +312,9 @@ class AccountViewModel(val account: Account) : ViewModel() {
}
}
class Factory(val account: Account) : ViewModelProvider.Factory {
class Factory(val account: Account, private val themeViewModel: ThemeViewModel) : ViewModelProvider.Factory {
override fun <AccountViewModel : ViewModel> create(modelClass: Class<AccountViewModel>): AccountViewModel {
return AccountViewModel(account) as AccountViewModel
return AccountViewModel(account, themeViewModel) as AccountViewModel
}
}
}
@@ -51,6 +51,13 @@ fun SettingsScreen(
val selectedVideoItem = remember {
mutableStateOf(selectedItens[videoIndex])
}
val themeItens = arrayOf("System", "Light", "Dark")
val themeIndex = themeItens.indexOf(accountViewModel.currentTheme())
val selectedTheme = remember {
mutableStateOf(themeItens[themeIndex])
}
val context = LocalContext.current
Column(
StdPadding,
@@ -60,6 +67,17 @@ fun SettingsScreen(
Section("Application preferences")
Text(
"Theme",
fontWeight = FontWeight.Bold
)
DropDownSettings(
selectedItem = selectedTheme,
listItems = themeItens,
title = "Theme"
)
Text(
"Media",
fontWeight = FontWeight.Bold
@@ -95,9 +113,11 @@ fun SettingsScreen(
2 -> false
else -> null
}
accountViewModel.changeTheme(selectedTheme.value)
scope.launch(Dispatchers.IO) {
accountViewModel.updateGlobalSettings(automaticallyShowImages, automaticallyStartPlayback)
LocalPreferences.saveToEncryptedStorage(accountViewModel.account)
LocalPreferences.updateTheme(selectedTheme.value)
ServiceManager.pause()
ServiceManager.start(context)
}
@@ -14,6 +14,7 @@ import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
@@ -27,6 +28,7 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import com.halilibo.richtext.ui.RichTextStyle
import com.halilibo.richtext.ui.resolveDefaults
import com.vitorpamplona.amethyst.ui.screen.ThemeViewModel
private val DarkColorPalette = darkColors(
primary = Purple200,
@@ -304,12 +306,14 @@ val Colors.innerPostModifier: Modifier
get() = if (isLight) LightInnerPostBorderModifier else DarkInnerPostBorderModifier
@Composable
fun AmethystTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
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
}
val colors = if (darkTheme) DarkColorPalette else LightColorPalette
MaterialTheme(
colors = colors,