Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions mobile/src/main/java/es/hegocre/scorecounter/ScoreViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package es.hegocre.scorecounter

import android.app.Application
import android.content.Context
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.toMutableStateList
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
Expand All @@ -26,15 +27,26 @@ class ScoreViewModel(application: Application) : AndroidViewModel(application) {
val scores: List<Score>
get() = _scores

private val _startingScore = mutableIntStateOf(_preferencesManager.getInt("starting_score", 0))
val startingScore: Int
get() = _startingScore.intValue

private suspend fun saveScore() {
withContext(Dispatchers.IO) {
val scoresString = Json.encodeToString(_scores.toList())
_preferencesManager.edit { putString("scores", scoresString) }
}
}

fun add() {
_scores.add(Score())
suspend fun setStartingScore(startingScore: Int) {
_startingScore.intValue = startingScore
withContext(Dispatchers.IO) {
_preferencesManager.edit { putInt("starting_score", startingScore) }
}
}

fun add(startingScore: Int = 0) {
_scores.add(Score(score = startingScore))
viewModelScope.launch {
saveScore()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Configuration
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -15,6 +17,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Close
Expand All @@ -36,6 +39,7 @@ import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
Expand All @@ -46,7 +50,9 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
Expand All @@ -55,13 +61,17 @@ import es.hegocre.scorecounter.ScoreViewModel
import es.hegocre.scorecounter.model.Score
import es.hegocre.scorecounter.ui.theme.ScoreCounterTheme
import androidx.core.content.edit
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

@SuppressLint("ConfigurationScreenWidthHeight")
@Composable
fun ScoreList(
scoreViewModel: ScoreViewModel
) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()

val scores = scoreViewModel.scores
val scoresNum by remember {
Expand All @@ -74,13 +84,41 @@ fun ScoreList(
.getBoolean("isFirstLaunch", true)
)
}
var showSetStartingScoreDialog by remember { mutableStateOf(false) }

ScoreCounterTheme {
val configuration = LocalConfiguration.current

Scaffold(
floatingActionButton = {
FloatingActionButton(onClick = { scoreViewModel.add() }) {
val interactionSource = remember { MutableInteractionSource() }

val viewConfiguration = LocalViewConfiguration.current

LaunchedEffect(interactionSource) {
var isLongClick = false

interactionSource.interactions.collectLatest { interaction ->
when (interaction) {
is PressInteraction.Press -> {
isLongClick = false
delay(viewConfiguration.longPressTimeoutMillis)
isLongClick = true
showSetStartingScoreDialog = true
}

is PressInteraction.Release -> {
if (isLongClick.not()) {
scoreViewModel.add(scoreViewModel.startingScore)
}

}

}
}
}

FloatingActionButton(onClick = { }, interactionSource = interactionSource) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "Add Score"
Expand Down Expand Up @@ -150,8 +188,6 @@ fun ScoreList(
}
}



if (showTutorialDialog) {
context.getSharedPreferences("preferences", Context.MODE_PRIVATE)
.edit { putBoolean("isFirstLaunch", false) }
Expand All @@ -167,6 +203,20 @@ fun ScoreList(
text = { Text(text = stringResource(id = R.string.dialog_tutorial_message)) }
)
}

if (showSetStartingScoreDialog) {
InputStartingScoreDialog(
currentStartingScore = scoreViewModel.startingScore,
onSetStartingScore = {
coroutineScope.launch {
scoreViewModel.setStartingScore(it.toIntOrNull() ?: 0)
}
},
onDismissRequest = {
showSetStartingScoreDialog = false
}
)
}
}
}

Expand Down Expand Up @@ -299,6 +349,70 @@ fun InputPlayerNameDialog(
}
}

LaunchedEffect(key1 = Unit) {
requester.requestFocus()
}
}

@Composable
fun InputStartingScoreDialog(
currentStartingScore: Int,
onSetStartingScore: (String) -> Unit,
onDismissRequest: (() -> Unit)? = null
) {
val requester = FocusRequester()

val (startingScore, setStartingScore) = remember { mutableStateOf(currentStartingScore.toString()) }

Dialog(
onDismissRequest = { onDismissRequest?.invoke() },
) {
Surface(
color = MaterialTheme.colorScheme.surface,
contentColor = contentColorFor(backgroundColor = MaterialTheme.colorScheme.surface),
shape = MaterialTheme.shapes.extraLarge,
tonalElevation = 6.dp,
) {
Column(modifier = Modifier.padding(all = 24.dp)) {
Text(
text = stringResource(id = R.string.starting_score),
style = MaterialTheme.typography.headlineSmall,
modifier = Modifier.padding(bottom = 16.dp)
)

OutlinedTextField(
modifier = Modifier
.padding(bottom = 16.dp, top = 8.dp)
.focusRequester(requester),
value = startingScore,
onValueChange = { if (it.isBlank() || it.toIntOrNull() != null) setStartingScore(it) },
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
singleLine = true,
maxLines = 1,
label = { Text(text = stringResource(id = R.string.starting_score)) },
placeholder = { Text(text = currentStartingScore.toString()) }
)


TextButton(
onClick = {
if (startingScore.isBlank()) {
onSetStartingScore(currentStartingScore.toString())
} else if (startingScore.toIntOrNull() != null) {
onSetStartingScore(startingScore)
}
onDismissRequest?.invoke()
},
modifier = Modifier
.align(Alignment.End)
.padding(horizontal = 0.dp)
) {
Text(text = stringResource(android.R.string.ok))
}
}
}
}

LaunchedEffect(key1 = Unit) {
requester.requestFocus()
}
Expand Down
3 changes: 2 additions & 1 deletion mobile/src/main/res/values-ca/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
<resources>
<string name="app_name">Marcador de puntuació</string>
<string name="dialog_tutorial_title">Com utilitzar</string>
<string name="dialog_tutorial_message">Per canviar el marcador, premi a la part superior per incrementar-lo, la part inferior per reduir-lo, o mantingui premut per restablir-lo.</string>
<string name="dialog_tutorial_message">Per canviar el marcador, premi a la part superior per incrementar-lo, la part inferior per reduir-lo, o mantingui premut per restablir-lo. Per canviar la puntuació inicial, mantingui premut el botó +.</string>
<string name="player_name">Nom del jugador</string>
<string name="player">Jugador</string>
<string name="starting_score">Puntuació inicial</string>
</resources>
3 changes: 2 additions & 1 deletion mobile/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
<resources>
<string name="app_name">Marcador de puntuación</string>
<string name="dialog_tutorial_title">Como utililizar</string>
<string name="dialog_tutorial_message">Para cambiar el marcador, pulse en la parte superior para incrementarlo, la parte inferior para reducirlo, o mantenga pulsado para restablecerlo.</string>
<string name="dialog_tutorial_message">Para cambiar el marcador, pulse en la parte superior para incrementarlo, la parte inferior para reducirlo, o mantenga pulsado para restablecerlo. Para cambiar la puntuación inicial, mantenga pulsado el botón +.</string>
<string name="player_name">Nombre del jugador</string>
<string name="player">Jugador</string>
<string name="starting_score">Puntuación inicial</string>
</resources>
3 changes: 2 additions & 1 deletion mobile/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<resources>
<string name="app_name">Score Counter</string>
<string name="dialog_tutorial_title">How to use</string>
<string name="dialog_tutorial_message">To change a score, press on its upper part to increment it, on its lower part to decrement it, or long press to reset it.</string>
<string name="dialog_tutorial_message">To change a score, press on its upper part to increment it, on its lower part to decrement it, or long press to reset it. Change the starting score by long pressing the + button.</string>
<string name="player_name">Player name</string>
<string name="player">Player</string>
<string name="starting_score">Starting score</string>
</resources>