add settings to change theme
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
+12
-3
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user