Settings as state flow.
This commit is contained in:
@@ -34,6 +34,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
@@ -44,7 +45,6 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import me.zobrist.tichucounter.domain.DrawerItem
|
||||
import me.zobrist.tichucounter.domain.ISystemSettingsChangeListener
|
||||
import me.zobrist.tichucounter.domain.KeepScreenOn
|
||||
import me.zobrist.tichucounter.domain.Language
|
||||
import me.zobrist.tichucounter.domain.ReviewService
|
||||
@@ -69,7 +69,7 @@ import me.zobrist.tichucounter.ui.settings.SettingsViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : AppCompatActivity(), ISystemSettingsChangeListener {
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
@Inject
|
||||
lateinit var settingsAdapter: SettingsAdapter
|
||||
@@ -86,7 +86,26 @@ class MainActivity : AppCompatActivity(), ISystemSettingsChangeListener {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
settingsAdapter.registerOnChangeListener(this)
|
||||
changeTheme(settingsAdapter.theme.value)
|
||||
setKeepScreenOn(settingsAdapter.keepScreenOn.value)
|
||||
changeLanguage(settingsAdapter.language.value)
|
||||
|
||||
|
||||
lifecycleScope.launch {
|
||||
settingsAdapter.theme.collect {
|
||||
changeTheme(it)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
settingsAdapter.keepScreenOn.collect {
|
||||
setKeepScreenOn(it)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
settingsAdapter.language.collect {
|
||||
changeLanguage(it)
|
||||
}
|
||||
}
|
||||
|
||||
mainViewModel.onNewGame = {
|
||||
reviewService.request()
|
||||
@@ -101,16 +120,11 @@ class MainActivity : AppCompatActivity(), ISystemSettingsChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
settingsAdapter.unregisterOnChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onLanguageChanged(language: Language) {
|
||||
private fun changeLanguage(language: Language) {
|
||||
AppCompatDelegate.setApplicationLocales(language.value)
|
||||
}
|
||||
|
||||
override fun onThemeChanged(theme: Theme) {
|
||||
private fun changeTheme(theme: Theme) {
|
||||
val themeValue = when (theme) {
|
||||
Theme.LIGHT -> AppCompatDelegate.MODE_NIGHT_NO
|
||||
Theme.DARK -> AppCompatDelegate.MODE_NIGHT_YES
|
||||
@@ -119,7 +133,7 @@ class MainActivity : AppCompatActivity(), ISystemSettingsChangeListener {
|
||||
AppCompatDelegate.setDefaultNightMode(themeValue)
|
||||
}
|
||||
|
||||
override fun onScreenOnChanged(keepOn: KeepScreenOn) {
|
||||
private fun setKeepScreenOn(keepOn: KeepScreenOn) {
|
||||
if (keepOn.value) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
} else {
|
||||
|
||||
@@ -4,6 +4,10 @@ import android.content.Context
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@@ -18,99 +22,64 @@ enum class KeepScreenOn(val value: Boolean) { ON(true), OFF(false) }
|
||||
|
||||
typealias VictoryPoints = Int
|
||||
|
||||
interface ISettingsChangeListener
|
||||
interface ISystemSettingsChangeListener : ISettingsChangeListener {
|
||||
fun onLanguageChanged(language: Language)
|
||||
fun onThemeChanged(theme: Theme)
|
||||
fun onScreenOnChanged(keepOn: KeepScreenOn)
|
||||
}
|
||||
|
||||
interface IGameSettingsChangeListener : ISettingsChangeListener {
|
||||
fun onVictoryPointsChanged(victoryPoints: Int)
|
||||
}
|
||||
|
||||
@Singleton
|
||||
class SettingsAdapter @Inject constructor(@ApplicationContext private val context: Context) {
|
||||
|
||||
private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
private var listenerList = mutableListOf<ISettingsChangeListener>()
|
||||
|
||||
var language: Language
|
||||
private set
|
||||
val language = MutableStateFlow(Language.DEFAULT)
|
||||
|
||||
var theme: Theme
|
||||
private set
|
||||
val theme = MutableStateFlow(Theme.DEFAULT)
|
||||
|
||||
var keepScreenOn: KeepScreenOn
|
||||
private set
|
||||
val keepScreenOn = MutableStateFlow(KeepScreenOn.OFF)
|
||||
|
||||
var victoryPoints: Int
|
||||
private set
|
||||
val victoryPoints = MutableStateFlow(0)
|
||||
|
||||
init {
|
||||
language = try {
|
||||
language.value = try {
|
||||
enumValueOf(sharedPreferences.getString(Language::class.simpleName, null)!!)
|
||||
} catch (_: NullPointerException) {
|
||||
Language.DEFAULT
|
||||
}
|
||||
|
||||
theme = try {
|
||||
theme.value = try {
|
||||
enumValueOf(sharedPreferences.getString(Theme::class.simpleName, null)!!)
|
||||
} catch (_: java.lang.Exception) {
|
||||
Theme.DEFAULT
|
||||
}
|
||||
|
||||
keepScreenOn = try {
|
||||
keepScreenOn.value = try {
|
||||
enumValueOf(sharedPreferences.getString(KeepScreenOn::class.simpleName, null)!!)
|
||||
} catch (_: java.lang.Exception) {
|
||||
KeepScreenOn.OFF
|
||||
}
|
||||
|
||||
victoryPoints = sharedPreferences.getInt(VictoryPoints::class.simpleName, 1000)
|
||||
}
|
||||
victoryPoints.value = sharedPreferences.getInt(VictoryPoints::class.simpleName, 1000)
|
||||
|
||||
fun registerOnChangeListener(listener: ISettingsChangeListener) {
|
||||
listenerList.add(listener)
|
||||
|
||||
if (listener is ISystemSettingsChangeListener) {
|
||||
listener.onThemeChanged(theme)
|
||||
listener.onLanguageChanged(language)
|
||||
listener.onScreenOnChanged(keepScreenOn)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
language.collect {
|
||||
updatePreference(Language::class.simpleName, it.name)
|
||||
}
|
||||
}
|
||||
|
||||
if (listener is IGameSettingsChangeListener) {
|
||||
listener.onVictoryPointsChanged(victoryPoints)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
theme.collect {
|
||||
updatePreference(Theme::class.simpleName, it.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun unregisterOnChangeListener(listener: ISettingsChangeListener?) {
|
||||
if (listener != null) {
|
||||
listenerList.remove(listener)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
keepScreenOn.collect {
|
||||
updatePreference(KeepScreenOn::class.simpleName, it.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setLanguage(language: Language) {
|
||||
this.language = language
|
||||
updatePreference(Language::class.simpleName, language.name)
|
||||
notifyListeners(language)
|
||||
}
|
||||
|
||||
fun setTheme(theme: Theme) {
|
||||
this.theme = theme
|
||||
updatePreference(Theme::class.simpleName, theme.name)
|
||||
notifyListeners(theme)
|
||||
}
|
||||
|
||||
fun setKeepScreenOn(setting: KeepScreenOn) {
|
||||
this.keepScreenOn = setting
|
||||
updatePreference(KeepScreenOn::class.simpleName, setting.name)
|
||||
notifyListeners(setting)
|
||||
}
|
||||
|
||||
fun setVictoryPoints(setting: Int) {
|
||||
this.victoryPoints = setting
|
||||
updatePreference(VictoryPoints::class.simpleName, setting)
|
||||
notifyListeners(setting)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
victoryPoints.collect {
|
||||
updatePreference(VictoryPoints::class.simpleName, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePreference(name: String?, value: String) {
|
||||
@@ -130,28 +99,4 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
|
||||
editor.putInt(name, value)
|
||||
editor.apply()
|
||||
}
|
||||
|
||||
private fun notifyListeners(language: Language) {
|
||||
listenerList.filterIsInstance<ISystemSettingsChangeListener>().forEach {
|
||||
it.onLanguageChanged(language)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyListeners(theme: Theme) {
|
||||
listenerList.filterIsInstance<ISystemSettingsChangeListener>().forEach {
|
||||
it.onThemeChanged(theme)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyListeners(victoryPoints: VictoryPoints) {
|
||||
listenerList.filterIsInstance<IGameSettingsChangeListener>().forEach {
|
||||
it.onVictoryPointsChanged(victoryPoints)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyListeners(keepScreenOn: KeepScreenOn) {
|
||||
listenerList.filterIsInstance<ISystemSettingsChangeListener>().forEach {
|
||||
it.onScreenOnChanged(keepScreenOn)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import me.zobrist.tichucounter.data.entity.Game
|
||||
import me.zobrist.tichucounter.data.entity.Round
|
||||
import me.zobrist.tichucounter.domain.IGameSettingsChangeListener
|
||||
import me.zobrist.tichucounter.domain.SettingsAdapter
|
||||
import me.zobrist.tichucounter.domain.Tichu
|
||||
import me.zobrist.tichucounter.domain.digitCount
|
||||
@@ -73,7 +72,7 @@ class CounterViewModel @Inject constructor(
|
||||
private val gameRepository: GameRepository,
|
||||
private val settings: SettingsAdapter
|
||||
) :
|
||||
ViewModel(), ICounterViewModel, IGameSettingsChangeListener {
|
||||
ViewModel(), ICounterViewModel {
|
||||
|
||||
override var roundScoreList by mutableStateOf(emptyList<Round>())
|
||||
private set
|
||||
@@ -188,7 +187,7 @@ class CounterViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
if (!victoryDialogShown) {
|
||||
if (totalScoreA >= settings.victoryPoints || totalScoreB >= settings.victoryPoints) {
|
||||
if (totalScoreA >= settings.victoryPoints.value || totalScoreB >= settings.victoryPoints.value) {
|
||||
showVictoryDialog = true
|
||||
}
|
||||
}
|
||||
@@ -202,13 +201,11 @@ class CounterViewModel @Inject constructor(
|
||||
|
||||
buildTeamNameSuggestions()
|
||||
}
|
||||
|
||||
settings.victoryPoints.collect {
|
||||
victoryDialogShown = false
|
||||
}
|
||||
}
|
||||
|
||||
settings.registerOnChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
settings.unregisterOnChangeListener(this)
|
||||
}
|
||||
|
||||
override fun focusLastInput() {
|
||||
@@ -401,8 +398,4 @@ class CounterViewModel @Inject constructor(
|
||||
|
||||
return filtered.sorted().sortedBy { it.length }.take(10)
|
||||
}
|
||||
|
||||
override fun onVictoryPointsChanged(victoryPoints: Int) {
|
||||
victoryDialogShown = false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.zobrist.tichucounter.ui.settings
|
||||
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
@@ -15,35 +16,35 @@ import javax.inject.Inject
|
||||
class SettingsViewModel @Inject constructor(private val settings: SettingsAdapter) : ViewModel() {
|
||||
|
||||
|
||||
var language by mutableStateOf(settings.language)
|
||||
var language by mutableStateOf(settings.language.value)
|
||||
private set
|
||||
|
||||
var theme by mutableStateOf(settings.theme)
|
||||
var theme by mutableStateOf(settings.theme.value)
|
||||
private set
|
||||
|
||||
var screenOn by mutableStateOf(settings.keepScreenOn)
|
||||
var screenOn by mutableStateOf(settings.keepScreenOn.value)
|
||||
private set
|
||||
|
||||
var victoryPoints by mutableStateOf(settings.victoryPoints)
|
||||
var victoryPoints by mutableIntStateOf(settings.victoryPoints.value)
|
||||
private set
|
||||
|
||||
fun updateLanguage(language: Language) {
|
||||
settings.setLanguage(language)
|
||||
this.language = settings.language
|
||||
settings.language.value = language
|
||||
this.language = language
|
||||
}
|
||||
|
||||
fun updateTheme(theme: Theme) {
|
||||
settings.setTheme(theme)
|
||||
this.theme = settings.theme
|
||||
settings.theme.value = theme
|
||||
this.theme = theme
|
||||
}
|
||||
|
||||
fun updateScreenOn(value: KeepScreenOn) {
|
||||
settings.setKeepScreenOn(value)
|
||||
screenOn = settings.keepScreenOn
|
||||
settings.keepScreenOn.value = value
|
||||
screenOn = value
|
||||
}
|
||||
|
||||
fun updateVictoryPoints(value: Int) {
|
||||
settings.setVictoryPoints(value)
|
||||
victoryPoints = settings.victoryPoints
|
||||
settings.victoryPoints.value = value
|
||||
victoryPoints = value
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user