Add setting and a button to change between modes.
All checks were successful
Build Android / build (push) Successful in 9m0s

This commit is contained in:
2023-07-04 23:23:39 +02:00
parent 6fe4e1f790
commit ac615560ae
6 changed files with 154 additions and 26 deletions

View File

@@ -8,7 +8,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.outlined.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
@@ -37,7 +36,7 @@ import me.zobrist.tichucounter.ui.settings.SettingsViewModel
import javax.inject.Inject
@AndroidEntryPoint
class MainActivity : AppCompatActivity(), ISettingsChangeListener {
class MainActivity : AppCompatActivity(), ISystemSettingsListener {
@Inject
lateinit var settingsAdapter: SettingsAdapter

View File

@@ -14,19 +14,26 @@ enum class Language(val value: LocaleListCompat) {
GERMAN(LocaleListCompat.forLanguageTags("de"))
}
enum class CounterMode{ LIST, GRAPH }
enum class KeepScreenOn(val value: Boolean) { ON(true), OFF(false) }
interface ISettingsChangeListener {
interface ISystemSettingsListener {
fun onLanguageChanged(language: Language)
fun onThemeChanged(theme: Theme)
fun onScreenOnChanged(keepOn: KeepScreenOn)
}
interface IDisplaySettingsListener {
fun onCounterModeChanged(counterMode: CounterMode)
}
@Singleton
class SettingsAdapter @Inject constructor(@ApplicationContext private val context: Context) {
private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
private var listenerList = mutableListOf<ISettingsChangeListener>()
private var systemSettingsListeners = mutableListOf<ISystemSettingsListener>()
private var displaySettingsListeners = mutableListOf<IDisplaySettingsListener>()
var language: Language
private set
@@ -37,37 +44,57 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
var keepScreenOn: KeepScreenOn
private set
var counterMode: CounterMode
private set
init {
language = try {
enumValueOf(sharedPreferences.getString(Language::class.simpleName, null)!!)
} catch (_: NullPointerException) {
} catch (_: Exception) {
Language.DEFAULT
}
theme = try {
enumValueOf(sharedPreferences.getString(Theme::class.simpleName, null)!!)
} catch (_: java.lang.Exception) {
} catch (_: Exception) {
Theme.DEFAULT
}
keepScreenOn = try {
enumValueOf(sharedPreferences.getString(KeepScreenOn::class.simpleName, null)!!)
} catch (_: java.lang.Exception) {
} catch (_: Exception) {
KeepScreenOn.OFF
}
counterMode = try {
enumValueOf(sharedPreferences.getString(CounterMode::class.simpleName, null)!!)
} catch (_: Exception) {
CounterMode.LIST
}
}
fun registerOnChangeListener(listener: ISettingsChangeListener) {
listenerList.add(listener)
fun registerOnChangeListener(listener: IDisplaySettingsListener) {
displaySettingsListeners.add(listener)
listener.onCounterModeChanged(counterMode)
}
fun unregisterOnChangeListener(listener: IDisplaySettingsListener?) {
if (listener != null) {
displaySettingsListeners.remove(listener)
}
}
fun registerOnChangeListener(listener: ISystemSettingsListener) {
systemSettingsListeners.add(listener)
listener.onThemeChanged(theme)
listener.onLanguageChanged(language)
listener.onScreenOnChanged(keepScreenOn)
}
fun unregisterOnChangeListener(listener: ISettingsChangeListener?) {
fun unregisterOnChangeListener(listener: ISystemSettingsListener?) {
if (listener != null) {
listenerList.remove(listener)
systemSettingsListeners.remove(listener)
}
}
@@ -89,6 +116,12 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
notifyListeners(setting)
}
fun setCounterMode(counterMode: CounterMode) {
this.counterMode = counterMode
updatePreference(CounterMode::class.simpleName, counterMode.name)
notifyListeners(counterMode)
}
private fun updatePreference(name: String?, value: String) {
val editor = sharedPreferences.edit()
editor.putString(name, value)
@@ -96,21 +129,27 @@ class SettingsAdapter @Inject constructor(@ApplicationContext private val contex
}
private fun notifyListeners(language: Language) {
listenerList.forEach {
systemSettingsListeners.forEach {
it.onLanguageChanged(language)
}
}
private fun notifyListeners(theme: Theme) {
listenerList.forEach {
systemSettingsListeners.forEach {
it.onThemeChanged(theme)
}
}
private fun notifyListeners(keepScreenOn: KeepScreenOn) {
listenerList.forEach {
systemSettingsListeners.forEach {
it.onScreenOnChanged(keepScreenOn)
}
}
private fun notifyListeners(counterMode: CounterMode) {
displaySettingsListeners.forEach {
it.onCounterModeChanged(counterMode)
}
}
}

View File

@@ -1,19 +1,37 @@
package me.zobrist.tichucounter.ui.counter
import android.content.res.Configuration
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material.icons.outlined.Keyboard
import androidx.compose.material.icons.outlined.ShowChart
import androidx.compose.material.icons.outlined.TableChart
import androidx.compose.material.icons.outlined.TableRows
import androidx.compose.material.icons.outlined.TableView
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.FloatingActionButtonElevation
import androidx.compose.material3.Icon
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import me.zobrist.tichucounter.data.entity.Round
import me.zobrist.tichucounter.domain.CounterMode
import me.zobrist.tichucounter.ui.AppTheme
@@ -50,10 +68,12 @@ fun Landscape(viewModel: ICounterViewModel) {
viewModel.totalScoreB
)
RoundGraphView(
viewModel.roundScoreList,
Modifier.weight(1f)
)
RoundView(
Modifier.weight(1f),
viewModel.counterMode,
viewModel.roundScoreList)
{ viewModel.changeCounterMode() }
}
if (!viewModel.keyboardHidden) {
Column(Modifier.weight(1f)) {
@@ -81,10 +101,11 @@ fun Portrait(viewModel: ICounterViewModel) {
viewModel.totalScoreB
)
RoundGraphView(
viewModel.roundScoreList,
Modifier.weight(1f)
)
RoundView(
Modifier.weight(1f),
viewModel.counterMode,
viewModel.roundScoreList)
{ viewModel.changeCounterMode() }
if (!viewModel.keyboardHidden) {
KeyBoardView(viewModel = viewModel)
@@ -92,6 +113,41 @@ fun Portrait(viewModel: ICounterViewModel) {
}
}
@Composable
private fun RoundView(modifier: Modifier = Modifier,
counterMode: CounterMode,
rounds: List<Round>,
changeCounterMode: () -> Unit) {
Box(modifier) {
if(counterMode == CounterMode.LIST)
{
RoundListView(
rounds,
Modifier.fillMaxHeight()
)
}
else
{
RoundGraphView(
rounds,
Modifier.fillMaxHeight()
)
}
FloatingActionButton(
modifier = Modifier.align(Alignment.BottomStart).padding(15.dp),
onClick = { changeCounterMode() }) {
Icon(getIcon(counterMode), null)
}
}
}
private fun getIcon(counterMode: CounterMode): ImageVector {
return when(counterMode)
{
CounterMode.LIST -> Icons.Outlined.ShowChart
CounterMode.GRAPH -> Icons.Outlined.TableRows
}
}
@Preview(name = "Light Mode")
@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
@@ -123,6 +179,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 counterMode: CounterMode = CounterMode.GRAPH
override fun focusLastInput() {
}
@@ -155,6 +212,9 @@ internal class PreviewViewModel : ICounterViewModel {
override fun updateNameB(value: String) {
}
override fun changeCounterMode() {
}
override fun updateFocusStateA(state: Boolean) {
}

View File

@@ -11,6 +11,9 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import me.zobrist.tichucounter.data.entity.Round
import me.zobrist.tichucounter.domain.CounterMode
import me.zobrist.tichucounter.domain.IDisplaySettingsListener
import me.zobrist.tichucounter.domain.SettingsAdapter
import me.zobrist.tichucounter.domain.Tichu
import me.zobrist.tichucounter.domain.digitCount
import me.zobrist.tichucounter.domain.getTotalPoints
@@ -57,16 +60,19 @@ interface ICounterViewModel : IKeyBoardViewModel {
val teamNameB: String
val teamNameSuggestionsA: List<String>
val teamNameSuggestionsB: List<String>
val counterMode: CounterMode
fun updateNameA(value: String)
fun updateNameB(value: String)
fun changeCounterMode()
}
@HiltViewModel
class CounterViewModel @Inject constructor(
private val gameRepository: GameRepository
private val gameRepository: GameRepository,
private val settingsAdapter: SettingsAdapter
) :
ViewModel(), ICounterViewModel {
ViewModel(), ICounterViewModel, IDisplaySettingsListener {
override var roundScoreList by mutableStateOf(emptyList<Round>())
private set
@@ -113,6 +119,17 @@ class CounterViewModel @Inject constructor(
override var teamNameSuggestionsB by mutableStateOf(listOf<String>())
private set
override var counterMode by mutableStateOf(CounterMode.LIST)
private set
init {
settingsAdapter.registerOnChangeListener(this)
}
override fun onCleared() {
settingsAdapter.unregisterOnChangeListener(this)
}
override var activeValue: String
get() {
return if (isBFocused) {
@@ -289,6 +306,15 @@ class CounterViewModel @Inject constructor(
}
}
override fun changeCounterMode() {
val nextMode = when(settingsAdapter.counterMode)
{
CounterMode.LIST -> CounterMode.GRAPH
CounterMode.GRAPH -> CounterMode.LIST
}
settingsAdapter.setCounterMode(nextMode)
}
override fun updateFocusStateA(state: Boolean) {
isAFocused = state
if (state) {
@@ -362,4 +388,8 @@ class CounterViewModel @Inject constructor(
return filtered.sorted().sortedBy { it.length }.take(10)
}
override fun onCounterModeChanged(counterMode: CounterMode) {
this.counterMode = counterMode
}
}

View File

@@ -40,7 +40,7 @@ import kotlin.math.roundToInt
@Composable
fun RoundGraphView(rounds: List<Round>, modifier: Modifier) {
fun RoundGraphView(rounds: List<Round>, modifier: Modifier = Modifier) {
val points = getPoints(rounds)

View File

@@ -21,7 +21,7 @@ import me.zobrist.tichucounter.data.entity.Round
import me.zobrist.tichucounter.ui.AppTheme
@Composable
fun RoundListView(rounds: List<Round>, modifier: Modifier) {
fun RoundListView(rounds: List<Round>, modifier: Modifier = Modifier) {
val lazyListState = rememberLazyListState()
val scope = rememberCoroutineScope()