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