Compare commits
1 Commits
main
...
feature/#3
| Author | SHA1 | Date | |
|---|---|---|---|
| d1b4ab1e8c |
@@ -37,7 +37,7 @@ import me.zobrist.tichucounter.ui.settings.SettingsViewModel
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : AppCompatActivity(), ISettingsChangeListener {
|
class MainActivity : AppCompatActivity(), ISystemSettingsChangeListener {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var settingsAdapter: SettingsAdapter
|
lateinit var settingsAdapter: SettingsAdapter
|
||||||
|
|||||||
@@ -16,17 +16,26 @@ enum class Language(val value: LocaleListCompat) {
|
|||||||
|
|
||||||
enum class KeepScreenOn(val value: Boolean) { ON(true), OFF(false) }
|
enum class KeepScreenOn(val value: Boolean) { ON(true), OFF(false) }
|
||||||
|
|
||||||
interface ISettingsChangeListener {
|
enum class CounterListView { BY_ROUND, CONTINUOUS }
|
||||||
|
|
||||||
|
|
||||||
|
interface ISystemSettingsChangeListener {
|
||||||
fun onLanguageChanged(language: Language)
|
fun onLanguageChanged(language: Language)
|
||||||
fun onThemeChanged(theme: Theme)
|
fun onThemeChanged(theme: Theme)
|
||||||
fun onScreenOnChanged(keepOn: KeepScreenOn)
|
fun onScreenOnChanged(keepOn: KeepScreenOn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IDisplaySettingsChangeListener {
|
||||||
|
fun onCounterListViewChanged(listView: CounterListView)
|
||||||
|
}
|
||||||
|
|
||||||
@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>()
|
private var systemListenerList = mutableListOf<ISystemSettingsChangeListener>()
|
||||||
|
private var displayListenerList = mutableListOf<IDisplaySettingsChangeListener>()
|
||||||
|
|
||||||
|
|
||||||
var language: Language
|
var language: Language
|
||||||
private set
|
private set
|
||||||
@@ -37,6 +46,9 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
|
|||||||
var keepScreenOn: KeepScreenOn
|
var keepScreenOn: KeepScreenOn
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var counterListView: CounterListView
|
||||||
|
private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
language = try {
|
language = try {
|
||||||
enumValueOf(sharedPreferences.getString(Language::class.simpleName, null)!!)
|
enumValueOf(sharedPreferences.getString(Language::class.simpleName, null)!!)
|
||||||
@@ -55,19 +67,37 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
|
|||||||
} catch (_: java.lang.Exception) {
|
} catch (_: java.lang.Exception) {
|
||||||
KeepScreenOn.OFF
|
KeepScreenOn.OFF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
counterListView = try {
|
||||||
|
enumValueOf(sharedPreferences.getString(CounterListView::class.simpleName, null)!!)
|
||||||
|
} catch (_: java.lang.Exception) {
|
||||||
|
CounterListView.BY_ROUND
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerOnChangeListener(listener: ISettingsChangeListener) {
|
fun registerOnChangeListener(listener: ISystemSettingsChangeListener) {
|
||||||
listenerList.add(listener)
|
systemListenerList.add(listener)
|
||||||
|
|
||||||
listener.onThemeChanged(theme)
|
listener.onThemeChanged(theme)
|
||||||
listener.onLanguageChanged(language)
|
listener.onLanguageChanged(language)
|
||||||
listener.onScreenOnChanged(keepScreenOn)
|
listener.onScreenOnChanged(keepScreenOn)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unregisterOnChangeListener(listener: ISettingsChangeListener?) {
|
fun registerOnChangeListener(listener: IDisplaySettingsChangeListener) {
|
||||||
|
displayListenerList.add(listener)
|
||||||
|
|
||||||
|
listener.onCounterListViewChanged(counterListView)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterOnChangeListener(listener: ISystemSettingsChangeListener?) {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listenerList.remove(listener)
|
systemListenerList.remove(listener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterOnChangeListener(listener: IDisplaySettingsChangeListener?) {
|
||||||
|
if (listener != null) {
|
||||||
|
displayListenerList.remove(listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +119,12 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
|
|||||||
notifyListeners(setting)
|
notifyListeners(setting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setCounterViewList(setting: CounterListView) {
|
||||||
|
this.counterListView = setting
|
||||||
|
updatePreference(CounterListView::class.simpleName, setting.name)
|
||||||
|
notifyListeners(setting)
|
||||||
|
}
|
||||||
|
|
||||||
private fun updatePreference(name: String?, value: String) {
|
private fun updatePreference(name: String?, value: String) {
|
||||||
val editor = sharedPreferences.edit()
|
val editor = sharedPreferences.edit()
|
||||||
editor.putString(name, value)
|
editor.putString(name, value)
|
||||||
@@ -96,21 +132,27 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun notifyListeners(language: Language) {
|
private fun notifyListeners(language: Language) {
|
||||||
listenerList.forEach {
|
systemListenerList.forEach {
|
||||||
it.onLanguageChanged(language)
|
it.onLanguageChanged(language)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun notifyListeners(theme: Theme) {
|
private fun notifyListeners(theme: Theme) {
|
||||||
listenerList.forEach {
|
systemListenerList.forEach {
|
||||||
it.onThemeChanged(theme)
|
it.onThemeChanged(theme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun notifyListeners(keepScreenOn: KeepScreenOn) {
|
private fun notifyListeners(keepScreenOn: KeepScreenOn) {
|
||||||
listenerList.forEach {
|
systemListenerList.forEach {
|
||||||
it.onScreenOnChanged(keepScreenOn)
|
it.onScreenOnChanged(keepScreenOn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun notifyListeners(counterListView: CounterListView) {
|
||||||
|
displayListenerList.forEach {
|
||||||
|
it.onCounterListViewChanged(counterListView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -52,6 +52,7 @@ fun Landscape(viewModel: ICounterViewModel) {
|
|||||||
|
|
||||||
RoundListView(
|
RoundListView(
|
||||||
viewModel.roundScoreList,
|
viewModel.roundScoreList,
|
||||||
|
viewModel.sumUpScores,
|
||||||
Modifier.weight(1f)
|
Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -83,6 +84,7 @@ fun Portrait(viewModel: ICounterViewModel) {
|
|||||||
|
|
||||||
RoundListView(
|
RoundListView(
|
||||||
viewModel.roundScoreList,
|
viewModel.roundScoreList,
|
||||||
|
viewModel.sumUpScores,
|
||||||
Modifier.weight(1f)
|
Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,6 +111,7 @@ internal class PreviewViewModel : ICounterViewModel {
|
|||||||
override var totalScoreB: Int = 750
|
override var totalScoreB: Int = 750
|
||||||
override var teamNameA: String = "Team A"
|
override var teamNameA: String = "Team A"
|
||||||
override var teamNameB: String = "Team B"
|
override var teamNameB: String = "Team B"
|
||||||
|
override val sumUpScores: Boolean = false
|
||||||
override var currentScoreA: String = ""
|
override var currentScoreA: String = ""
|
||||||
override var currentScoreB: String = "45"
|
override var currentScoreB: String = "45"
|
||||||
override var isValidRound: Boolean = false
|
override var isValidRound: Boolean = false
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import me.zobrist.tichucounter.data.entity.Round
|
import me.zobrist.tichucounter.data.entity.Round
|
||||||
import me.zobrist.tichucounter.domain.Tichu
|
import me.zobrist.tichucounter.domain.*
|
||||||
import me.zobrist.tichucounter.domain.digitCount
|
|
||||||
import me.zobrist.tichucounter.domain.getTotalPoints
|
|
||||||
import me.zobrist.tichucounter.repository.GameRepository
|
import me.zobrist.tichucounter.repository.GameRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -53,6 +51,7 @@ interface ICounterViewModel : IKeyBoardViewModel {
|
|||||||
val roundScoreList: List<Round>
|
val roundScoreList: List<Round>
|
||||||
val totalScoreA: Int
|
val totalScoreA: Int
|
||||||
val totalScoreB: Int
|
val totalScoreB: Int
|
||||||
|
val sumUpScores: Boolean
|
||||||
val teamNameA: String
|
val teamNameA: String
|
||||||
val teamNameB: String
|
val teamNameB: String
|
||||||
val teamNameSuggestionsA: List<String>
|
val teamNameSuggestionsA: List<String>
|
||||||
@@ -64,9 +63,10 @@ interface ICounterViewModel : IKeyBoardViewModel {
|
|||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class CounterViewModel @Inject constructor(
|
class CounterViewModel @Inject constructor(
|
||||||
private val gameRepository: GameRepository
|
private val gameRepository: GameRepository,
|
||||||
|
private val settingsAdapter: SettingsAdapter
|
||||||
) :
|
) :
|
||||||
ViewModel(), ICounterViewModel {
|
ViewModel(), ICounterViewModel, IDisplaySettingsChangeListener {
|
||||||
|
|
||||||
override var roundScoreList by mutableStateOf(emptyList<Round>())
|
override var roundScoreList by mutableStateOf(emptyList<Round>())
|
||||||
private set
|
private set
|
||||||
@@ -80,6 +80,9 @@ class CounterViewModel @Inject constructor(
|
|||||||
override var teamNameA by mutableStateOf("")
|
override var teamNameA by mutableStateOf("")
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
override var sumUpScores by mutableStateOf(false)
|
||||||
|
private set
|
||||||
|
|
||||||
override var teamNameB by mutableStateOf("")
|
override var teamNameB by mutableStateOf("")
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@@ -181,6 +184,12 @@ class CounterViewModel @Inject constructor(
|
|||||||
buildTeamNameSuggestions()
|
buildTeamNameSuggestions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settingsAdapter.registerOnChangeListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCleared() {
|
||||||
|
settingsAdapter.unregisterOnChangeListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun focusLastInput() {
|
override fun focusLastInput() {
|
||||||
@@ -362,4 +371,8 @@ class CounterViewModel @Inject constructor(
|
|||||||
|
|
||||||
return filtered.sorted().sortedBy { it.length }.take(10)
|
return filtered.sorted().sortedBy { it.length }.take(10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCounterListViewChanged(listView: CounterListView) {
|
||||||
|
sumUpScores = listView == CounterListView.CONTINUOUS
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -21,13 +21,22 @@ import me.zobrist.tichucounter.data.entity.Round
|
|||||||
import me.zobrist.tichucounter.ui.AppTheme
|
import me.zobrist.tichucounter.ui.AppTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RoundListView(rounds: List<Round>, modifier: Modifier) {
|
fun RoundListView(rounds: List<Round>, sumUpRounds: Boolean = false, modifier: Modifier) {
|
||||||
val lazyListState = rememberLazyListState()
|
val lazyListState = rememberLazyListState()
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
var sumA = 0
|
||||||
|
var sumB = 0
|
||||||
|
|
||||||
LazyColumn(state = lazyListState, modifier = modifier) {
|
LazyColumn(state = lazyListState, modifier = modifier) {
|
||||||
itemsIndexed(rounds) { index, item ->
|
itemsIndexed(rounds) { index, item ->
|
||||||
RoundListItem(item, index)
|
if (sumUpRounds) {
|
||||||
|
sumA += item.scoreA
|
||||||
|
sumB += item.scoreB
|
||||||
|
RoundListItem(sumA, sumB, index)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
RoundListItem(item.scoreA, item.scoreB, index)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@@ -37,14 +46,14 @@ fun RoundListView(rounds: List<Round>, modifier: Modifier) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RoundListItem(round: Round, index: Int) {
|
private fun RoundListItem(scoreA: Int, scoreB: Int, index: Int) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(all = 4.dp)
|
.padding(all = 4.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = round.scoreA.toString(),
|
text = scoreA.toString(),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
modifier = Modifier.weight(5f),
|
modifier = Modifier.weight(5f),
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
@@ -56,7 +65,7 @@ private fun RoundListItem(round: Round, index: Int) {
|
|||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = round.scoreB.toString(),
|
text = scoreB.toString(),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
modifier = Modifier.weight(5f),
|
modifier = Modifier.weight(5f),
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
@@ -78,7 +87,7 @@ fun RoundListViewPreview() {
|
|||||||
|
|
||||||
AppTheme {
|
AppTheme {
|
||||||
Surface {
|
Surface {
|
||||||
RoundListView(rounds, Modifier)
|
RoundListView(rounds, true, Modifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import me.zobrist.tichucounter.R
|
import me.zobrist.tichucounter.R
|
||||||
|
import me.zobrist.tichucounter.domain.CounterListView
|
||||||
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.Theme
|
import me.zobrist.tichucounter.domain.Theme
|
||||||
@@ -44,6 +45,11 @@ val themeMap = mapOf(
|
|||||||
Theme.LIGHT to R.string.light
|
Theme.LIGHT to R.string.light
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val counterListViewMap = mapOf(
|
||||||
|
CounterListView.BY_ROUND to R.string.by_round,
|
||||||
|
CounterListView.CONTINUOUS to R.string.continuous,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsView(viewModel: SettingsViewModel) {
|
fun SettingsView(viewModel: SettingsViewModel) {
|
||||||
@@ -51,9 +57,11 @@ fun SettingsView(viewModel: SettingsViewModel) {
|
|||||||
viewModel.screenOn.value,
|
viewModel.screenOn.value,
|
||||||
viewModel.language,
|
viewModel.language,
|
||||||
viewModel.theme,
|
viewModel.theme,
|
||||||
|
viewModel.counterListView,
|
||||||
{ viewModel.updateScreenOn(it) },
|
{ viewModel.updateScreenOn(it) },
|
||||||
{ viewModel.updateLanguage(it) },
|
{ viewModel.updateLanguage(it) },
|
||||||
{ viewModel.updateTheme(it) })
|
{ viewModel.updateTheme(it) },
|
||||||
|
{ viewModel.updateCounterListView(it) })
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -61,9 +69,11 @@ fun SettingsView(
|
|||||||
valueScreenOn: Boolean = true,
|
valueScreenOn: Boolean = true,
|
||||||
valueLanguage: Language = Language.ENGLISH,
|
valueLanguage: Language = Language.ENGLISH,
|
||||||
valueTheme: Theme = Theme.DARK,
|
valueTheme: Theme = Theme.DARK,
|
||||||
|
valueCounterListView: CounterListView = CounterListView.BY_ROUND,
|
||||||
updateScreenOn: (KeepScreenOn) -> Unit = {},
|
updateScreenOn: (KeepScreenOn) -> Unit = {},
|
||||||
updateLanguage: (Language) -> Unit = {},
|
updateLanguage: (Language) -> Unit = {},
|
||||||
updateTheme: (Theme) -> Unit = {}
|
updateTheme: (Theme) -> Unit = {},
|
||||||
|
updateCounterListView: (CounterListView) -> Unit = {}
|
||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
BooleanSetting(
|
BooleanSetting(
|
||||||
@@ -82,6 +92,14 @@ fun SettingsView(
|
|||||||
themeMap,
|
themeMap,
|
||||||
valueTheme,
|
valueTheme,
|
||||||
) { updateTheme(it) }
|
) { updateTheme(it) }
|
||||||
|
|
||||||
|
StringSetting(
|
||||||
|
stringResource(R.string.counter_mode),
|
||||||
|
counterListViewMap,
|
||||||
|
valueCounterListView,
|
||||||
|
) { updateCounterListView(it) }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import me.zobrist.tichucounter.domain.KeepScreenOn
|
import me.zobrist.tichucounter.domain.*
|
||||||
import me.zobrist.tichucounter.domain.Language
|
|
||||||
import me.zobrist.tichucounter.domain.SettingsAdapter
|
|
||||||
import me.zobrist.tichucounter.domain.Theme
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@@ -24,6 +21,9 @@ class SettingsViewModel @Inject constructor(private val settings: SettingsAdapte
|
|||||||
var screenOn by mutableStateOf(settings.keepScreenOn)
|
var screenOn by mutableStateOf(settings.keepScreenOn)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var counterListView by mutableStateOf(settings.counterListView)
|
||||||
|
private set
|
||||||
|
|
||||||
fun updateLanguage(language: Language) {
|
fun updateLanguage(language: Language) {
|
||||||
settings.setLanguage(language)
|
settings.setLanguage(language)
|
||||||
this.language = settings.language
|
this.language = settings.language
|
||||||
@@ -39,4 +39,9 @@ class SettingsViewModel @Inject constructor(private val settings: SettingsAdapte
|
|||||||
screenOn = settings.keepScreenOn
|
screenOn = settings.keepScreenOn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateCounterListView(value: CounterListView) {
|
||||||
|
settings.setCounterViewList(value)
|
||||||
|
counterListView = settings.counterListView
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -26,6 +26,9 @@
|
|||||||
<string name="inactive">Old Games</string>
|
<string name="inactive">Old Games</string>
|
||||||
<string name="menu_counter">Counter</string>
|
<string name="menu_counter">Counter</string>
|
||||||
<string name="menu_about">About</string>
|
<string name="menu_about">About</string>
|
||||||
|
<string name="by_round">Display Single Round</string>
|
||||||
|
<string name="continuous">Sum up rounds</string>
|
||||||
|
<string name="counter_mode">Counter Mode</string>
|
||||||
<string name="contact_us">Contact us</string>
|
<string name="contact_us">Contact us</string>
|
||||||
<string name="play_store" translatable="false">Play Store</string>
|
<string name="play_store" translatable="false">Play Store</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user