Update view with victory points setting.
Add victory points to settings adapter.
This commit is contained in:
@@ -45,7 +45,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import me.zobrist.tichucounter.domain.DrawerItem
|
||||
import me.zobrist.tichucounter.domain.ISettingsChangeListener
|
||||
import me.zobrist.tichucounter.domain.ISystemSettingsChangeListener
|
||||
import me.zobrist.tichucounter.domain.KeepScreenOn
|
||||
import me.zobrist.tichucounter.domain.Language
|
||||
import me.zobrist.tichucounter.domain.ReviewService
|
||||
@@ -70,7 +70,7 @@ import me.zobrist.tichucounter.ui.settings.SettingsViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : AppCompatActivity(), ISettingsChangeListener {
|
||||
class MainActivity : AppCompatActivity(), ISystemSettingsChangeListener {
|
||||
|
||||
@Inject
|
||||
lateinit var settingsAdapter: SettingsAdapter
|
||||
@@ -192,7 +192,6 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener {
|
||||
|
||||
var topBarState by remember { mutableStateOf(TopBarState()) }
|
||||
var snackbarHostState by remember { mutableStateOf(SnackbarHostState()) }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Scaffold(
|
||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||
@@ -211,7 +210,7 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener {
|
||||
startDestination = Route.COUNTER.name,
|
||||
modifier = Modifier.padding(paddings)
|
||||
) {
|
||||
composable(Route.COUNTER.name) {
|
||||
this.composable(Route.COUNTER.name.toString()) {
|
||||
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
@@ -231,15 +230,16 @@ class MainActivity : AppCompatActivity(), ISettingsChangeListener {
|
||||
mainViewModel.activeGameHasRounds,
|
||||
{ expanded = true }
|
||||
) {
|
||||
val newGameTranslated = stringResource(R.string.newGame)
|
||||
DropDownMenu(
|
||||
mapOf("new" to R.string.newGame),
|
||||
listOf(newGameTranslated),
|
||||
"",
|
||||
expanded,
|
||||
) {
|
||||
expanded = false
|
||||
it?.let {
|
||||
when (it) {
|
||||
"new" -> mainViewModel.newGame()
|
||||
newGameTranslated -> mainViewModel.newGame()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,19 @@ enum class Language(val value: LocaleListCompat) {
|
||||
|
||||
enum class KeepScreenOn(val value: Boolean) { ON(true), OFF(false) }
|
||||
|
||||
interface ISettingsChangeListener {
|
||||
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) {
|
||||
|
||||
@@ -37,9 +44,9 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
|
||||
|
||||
var keepScreenOn: KeepScreenOn
|
||||
private set
|
||||
var reviewDialogShownDate: Date
|
||||
get() = Date(sharedPreferences.getLong("reviewDialogShownDate", 0))
|
||||
set(value) = updatePreference("reviewDialogShownDate", value.time)
|
||||
|
||||
var victoryPoints: Int
|
||||
private set
|
||||
|
||||
init {
|
||||
language = try {
|
||||
@@ -59,14 +66,22 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
|
||||
} catch (_: java.lang.Exception) {
|
||||
KeepScreenOn.OFF
|
||||
}
|
||||
|
||||
victoryPoints = sharedPreferences.getInt(VictoryPoints::class.simpleName, 1000)
|
||||
}
|
||||
|
||||
fun registerOnChangeListener(listener: ISettingsChangeListener) {
|
||||
listenerList.add(listener)
|
||||
|
||||
listener.onThemeChanged(theme)
|
||||
listener.onLanguageChanged(language)
|
||||
listener.onScreenOnChanged(keepScreenOn)
|
||||
if (listener is ISystemSettingsChangeListener) {
|
||||
listener.onThemeChanged(theme)
|
||||
listener.onLanguageChanged(language)
|
||||
listener.onScreenOnChanged(keepScreenOn)
|
||||
}
|
||||
|
||||
if (listener is IGameSettingsChangeListener) {
|
||||
listener.onVictoryPointsChanged(victoryPoints)
|
||||
}
|
||||
}
|
||||
|
||||
fun unregisterOnChangeListener(listener: ISettingsChangeListener?) {
|
||||
@@ -93,6 +108,12 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
|
||||
notifyListeners(setting)
|
||||
}
|
||||
|
||||
fun setVictoryPoints(setting: Int) {
|
||||
this.victoryPoints = setting
|
||||
updatePreference(VictoryPoints::class.simpleName, setting)
|
||||
notifyListeners(setting)
|
||||
}
|
||||
|
||||
private fun updatePreference(name: String?, value: String) {
|
||||
val editor = sharedPreferences.edit()
|
||||
editor.putString(name, value)
|
||||
@@ -105,22 +126,33 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
|
||||
editor.apply()
|
||||
}
|
||||
|
||||
private fun updatePreference(name: String?, value: Int) {
|
||||
val editor = sharedPreferences.edit()
|
||||
editor.putInt(name, value)
|
||||
editor.apply()
|
||||
}
|
||||
|
||||
private fun notifyListeners(language: Language) {
|
||||
listenerList.forEach {
|
||||
listenerList.filterIsInstance<ISystemSettingsChangeListener>().forEach {
|
||||
it.onLanguageChanged(language)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyListeners(theme: Theme) {
|
||||
listenerList.forEach {
|
||||
listenerList.filterIsInstance<ISystemSettingsChangeListener>().forEach {
|
||||
it.onThemeChanged(theme)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyListeners(keepScreenOn: KeepScreenOn) {
|
||||
listenerList.forEach {
|
||||
it.onScreenOnChanged(keepScreenOn)
|
||||
private fun notifyListeners(victoryPoints: VictoryPoints) {
|
||||
listenerList.filterIsInstance<IGameSettingsChangeListener>().forEach {
|
||||
it.onVictoryPointsChanged(victoryPoints)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyListeners(keepScreenOn: KeepScreenOn) {
|
||||
listenerList.filterIsInstance<ISystemSettingsChangeListener>().forEach {
|
||||
it.onScreenOnChanged(keepScreenOn)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,25 +7,29 @@ import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
||||
@Composable
|
||||
fun <T> DropDownMenu(map: Map<T, Int>, selected: T, expanded: Boolean, onSelected: (T?) -> Unit) {
|
||||
fun <T> DropDownMenu(
|
||||
list: Collection<T>,
|
||||
selected: T,
|
||||
expanded: Boolean,
|
||||
onSelected: (T?) -> Unit
|
||||
) {
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { onSelected(null) }
|
||||
) {
|
||||
map.forEach {
|
||||
list.forEach {
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
onSelected(it.key)
|
||||
onSelected(it)
|
||||
},
|
||||
trailingIcon = {
|
||||
if (it.key == selected) {
|
||||
if (it == selected) {
|
||||
Icon(Icons.Outlined.Check, null)
|
||||
}
|
||||
},
|
||||
text = { Text(stringResource(it.value)) },
|
||||
text = { Text(it.toString()) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ internal class PreviewViewModel : ICounterViewModel {
|
||||
listOf("TeamA", "asdffd", "TeamB", "really really long Team Name that is way too long")
|
||||
override val teamNameSuggestionsB: List<String> =
|
||||
listOf("TeamA", "asdffd", "TeamB", "really really long Team Name that is way too long")
|
||||
override val victoryPoints: Int = 1000
|
||||
|
||||
override fun focusLastInput() {
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import me.zobrist.tichucounter.data.entity.Round
|
||||
import me.zobrist.tichucounter.domain.IGameSettingsChangeListener
|
||||
import me.zobrist.tichucounter.domain.Tichu
|
||||
import me.zobrist.tichucounter.domain.digitCount
|
||||
import me.zobrist.tichucounter.domain.getTotalPoints
|
||||
@@ -58,6 +59,7 @@ interface ICounterViewModel : IKeyBoardViewModel {
|
||||
val teamNameB: String
|
||||
val teamNameSuggestionsA: List<String>
|
||||
val teamNameSuggestionsB: List<String>
|
||||
val victoryPoints: Int
|
||||
|
||||
fun updateNameA(value: String)
|
||||
fun updateNameB(value: String)
|
||||
@@ -67,7 +69,7 @@ interface ICounterViewModel : IKeyBoardViewModel {
|
||||
class CounterViewModel @Inject constructor(
|
||||
private val gameRepository: GameRepository
|
||||
) :
|
||||
ViewModel(), ICounterViewModel {
|
||||
ViewModel(), ICounterViewModel, IGameSettingsChangeListener {
|
||||
|
||||
override var roundScoreList by mutableStateOf(emptyList<Round>())
|
||||
private set
|
||||
@@ -114,6 +116,9 @@ class CounterViewModel @Inject constructor(
|
||||
override var teamNameSuggestionsB by mutableStateOf(listOf<String>())
|
||||
private set
|
||||
|
||||
override var victoryPoints by mutableStateOf(0)
|
||||
private set
|
||||
|
||||
override var activeValue: String
|
||||
get() {
|
||||
return if (isBFocused) {
|
||||
@@ -171,6 +176,12 @@ class CounterViewModel @Inject constructor(
|
||||
|
||||
buildTeamNameSuggestions()
|
||||
|
||||
if (totalScoreA >= victoryPoints || totalScoreB >= victoryPoints) {
|
||||
if (totalScoreA == totalScoreB) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -330,6 +341,10 @@ class CounterViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVictoryPointsChanged(victoryPoints: Int) {
|
||||
this.victoryPoints = victoryPoints
|
||||
}
|
||||
|
||||
private fun deleteLastDigitActive() {
|
||||
if (activeValue != "") {
|
||||
activeValue = activeValue.dropLast(1)
|
||||
|
||||
@@ -44,6 +44,7 @@ val themeMap = mapOf(
|
||||
Theme.LIGHT to R.string.light
|
||||
)
|
||||
|
||||
val victoryPointsList = listOf(500, 1000, 1500, 2000)
|
||||
|
||||
@Composable
|
||||
fun SettingsView(viewModel: SettingsViewModel) {
|
||||
@@ -51,9 +52,11 @@ fun SettingsView(viewModel: SettingsViewModel) {
|
||||
viewModel.screenOn.value,
|
||||
viewModel.language,
|
||||
viewModel.theme,
|
||||
viewModel.victoryPoints,
|
||||
{ viewModel.updateScreenOn(it) },
|
||||
{ viewModel.updateLanguage(it) },
|
||||
{ viewModel.updateTheme(it) })
|
||||
{ viewModel.updateTheme(it) },
|
||||
{ viewModel.updateVictoryPoints(it) })
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -61,11 +64,22 @@ fun SettingsView(
|
||||
valueScreenOn: Boolean = true,
|
||||
valueLanguage: Language = Language.ENGLISH,
|
||||
valueTheme: Theme = Theme.DARK,
|
||||
valueVictoryPoints: Int = 1000,
|
||||
updateScreenOn: (KeepScreenOn) -> Unit = {},
|
||||
updateLanguage: (Language) -> Unit = {},
|
||||
updateTheme: (Theme) -> Unit = {}
|
||||
updateTheme: (Theme) -> Unit = {},
|
||||
updateVictoryPoints: (Int) -> Unit = {}
|
||||
) {
|
||||
Column {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(20.dp)
|
||||
) {
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.display),
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
|
||||
BooleanSetting(
|
||||
stringResource(R.string.keep_screen_on),
|
||||
valueScreenOn
|
||||
@@ -82,6 +96,18 @@ fun SettingsView(
|
||||
themeMap,
|
||||
valueTheme,
|
||||
) { updateTheme(it) }
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.game),
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
|
||||
|
||||
ListSetting(
|
||||
stringResource(R.string.victory_points),
|
||||
victoryPointsList,
|
||||
valueVictoryPoints
|
||||
) { updateVictoryPoints(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +116,7 @@ fun BooleanSetting(name: String, value: Boolean, updateValue: (Boolean) -> Unit)
|
||||
|
||||
Row(
|
||||
Modifier
|
||||
.padding(20.dp)
|
||||
.padding(bottom = 15.dp, top = 5.dp)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Column(Modifier.weight(5f)) {
|
||||
@@ -119,21 +145,32 @@ fun BooleanSetting(name: String, value: Boolean, updateValue: (Boolean) -> Unit)
|
||||
@Composable
|
||||
fun <T> StringSetting(name: String, map: Map<T, Int>, selected: T, onSelected: (T) -> Unit) {
|
||||
|
||||
val translated = map.map { it.key to stringResource(it.value) }.toMap()
|
||||
val getValue = map.map { stringResource(it.value) to it.key }.toMap()
|
||||
|
||||
ListSetting(
|
||||
name,
|
||||
translated.values,
|
||||
translated[selected]
|
||||
) { getValue[it]?.let { it1 -> onSelected(it1) } }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> ListSetting(name: String, list: Collection<T>, selected: T, onSelected: (T) -> Unit) {
|
||||
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(20.dp)
|
||||
.padding(bottom = 15.dp, top = 5.dp)
|
||||
.clickable { expanded = true }) {
|
||||
Column(Modifier.weight(5f)) {
|
||||
Text(name, style = MaterialTheme.typography.bodyLarge, overflow = TextOverflow.Ellipsis)
|
||||
map[selected]?.let {
|
||||
Text(
|
||||
stringResource(it),
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
}
|
||||
Text(
|
||||
selected.toString(),
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
}
|
||||
|
||||
Column(Modifier.weight(1f)) {
|
||||
@@ -142,15 +179,15 @@ fun <T> StringSetting(name: String, map: Map<T, Int>, selected: T, onSelected: (
|
||||
contentDescription = null,
|
||||
modifier = Modifier.align(End)
|
||||
)
|
||||
}
|
||||
|
||||
DropDownMenu(
|
||||
map,
|
||||
selected,
|
||||
expanded,
|
||||
) {
|
||||
expanded = false
|
||||
it?.let { onSelected(it) }
|
||||
DropDownMenu(
|
||||
list,
|
||||
selected,
|
||||
expanded,
|
||||
) {
|
||||
expanded = false
|
||||
it?.let { onSelected(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,20 +204,3 @@ fun SettingsViewPreview() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(name = "Light Mode")
|
||||
@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
|
||||
@Composable
|
||||
fun StringSettingPreview() {
|
||||
|
||||
AppTheme {
|
||||
Surface {
|
||||
DropDownMenu(
|
||||
themeMap,
|
||||
Theme.LIGHT,
|
||||
true,
|
||||
) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@ class SettingsViewModel @Inject constructor(private val settings: SettingsAdapte
|
||||
var screenOn by mutableStateOf(settings.keepScreenOn)
|
||||
private set
|
||||
|
||||
var victoryPoints by mutableStateOf(settings.victoryPoints)
|
||||
private set
|
||||
|
||||
fun updateLanguage(language: Language) {
|
||||
settings.setLanguage(language)
|
||||
this.language = settings.language
|
||||
@@ -39,4 +42,8 @@ class SettingsViewModel @Inject constructor(private val settings: SettingsAdapte
|
||||
screenOn = settings.keepScreenOn
|
||||
}
|
||||
|
||||
fun updateVictoryPoints(value: Int) {
|
||||
settings.setVictoryPoints(value)
|
||||
victoryPoints = settings.victoryPoints
|
||||
}
|
||||
}
|
||||
@@ -29,5 +29,7 @@
|
||||
<string name="undo_question">RÜCKGÄNGIG</string>
|
||||
<string name="activated_success">Spiel aktiviert.</string>
|
||||
<string name="to_calculator_question">WEITERSPIELEN</string>
|
||||
|
||||
<string name="display">Anzeige</string>
|
||||
<string name="game">Spiel</string>
|
||||
<string name="victory_points">Siegespunkte</string>
|
||||
</resources>
|
||||
@@ -33,4 +33,7 @@
|
||||
<string name="undo_question">UNDO</string>
|
||||
<string name="activated_success">Game activated.</string>
|
||||
<string name="to_calculator_question">CONTINUE PLAYING</string>
|
||||
<string name="display">Display</string>
|
||||
<string name="game">Game</string>
|
||||
<string name="victory_points">Victory points</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user