Add alerts for winning and draw.
This commit is contained in:
@@ -40,7 +40,6 @@ import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import com.google.android.play.core.review.ReviewManager
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -230,7 +229,7 @@ class MainActivity : AppCompatActivity(), ISystemSettingsChangeListener {
|
||||
mainViewModel.activeGameHasRounds,
|
||||
{ expanded = true }
|
||||
) {
|
||||
val newGameTranslated = stringResource(R.string.newGame)
|
||||
val newGameTranslated = stringResource(R.string.new_game)
|
||||
DropDownMenu(
|
||||
listOf(newGameTranslated),
|
||||
"",
|
||||
|
||||
@@ -2,21 +2,11 @@ package me.zobrist.tichucounter.domain
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.play.core.review.ReviewManagerFactory
|
||||
import com.google.android.play.core.review.testing.FakeReviewManager
|
||||
import dagger.hilt.android.internal.Contexts
|
||||
import dagger.hilt.android.qualifiers.ActivityContext
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.android.scopes.ActivityScoped
|
||||
import dagger.hilt.android.scopes.FragmentScoped
|
||||
import dagger.hilt.android.scopes.ViewScoped
|
||||
import java.time.Duration
|
||||
import java.time.Period
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
class ReviewService @Inject constructor(@ActivityContext private val appContext: Context) {
|
||||
|
||||
@@ -43,10 +33,8 @@ class ReviewService @Inject constructor(@ActivityContext private val appContext:
|
||||
fun request() {
|
||||
requestCalled += 1
|
||||
|
||||
if(requestCalled >= 3)
|
||||
{
|
||||
if(nextReviewedDate.time < System.currentTimeMillis())
|
||||
{
|
||||
if (requestCalled >= 3) {
|
||||
if (nextReviewedDate.time < System.currentTimeMillis()) {
|
||||
requestCalled = 0
|
||||
nextReviewedDate = Date(System.currentTimeMillis() + THREE_MONTHS)
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.content.Context
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
||||
@@ -7,10 +7,8 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.scopes.ActivityScoped
|
||||
import kotlinx.coroutines.launch
|
||||
import me.zobrist.tichucounter.data.entity.Round
|
||||
import me.zobrist.tichucounter.domain.ReviewService
|
||||
import me.zobrist.tichucounter.repository.GameRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
@@ -3,7 +3,13 @@ package me.zobrist.tichucounter.ui.counter
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.EmojiEvents
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -12,7 +18,9 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import me.zobrist.tichucounter.R
|
||||
import me.zobrist.tichucounter.data.entity.Round
|
||||
import me.zobrist.tichucounter.ui.AppTheme
|
||||
|
||||
@@ -23,6 +31,18 @@ fun Counter(viewModel: ICounterViewModel = PreviewViewModel()) {
|
||||
var orientation by remember { mutableStateOf(Configuration.ORIENTATION_PORTRAIT) }
|
||||
orientation = LocalConfiguration.current.orientation
|
||||
|
||||
if (viewModel.showVictoryDialog) {
|
||||
GameVictoryDialog(
|
||||
viewModel.totalScoreA,
|
||||
viewModel.totalScoreB,
|
||||
viewModel.teamNameA,
|
||||
viewModel.teamNameB,
|
||||
{ viewModel.victoryDialogExecuted(false) })
|
||||
{
|
||||
viewModel.victoryDialogExecuted(true)
|
||||
}
|
||||
}
|
||||
|
||||
Surface {
|
||||
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
Landscape(viewModel)
|
||||
@@ -102,6 +122,54 @@ fun CounterViewPreview() {
|
||||
}
|
||||
}
|
||||
|
||||
@Preview()
|
||||
@Composable
|
||||
fun GameVictoryDialog(
|
||||
pointsA: Int = 2000,
|
||||
pointsB: Int = 50,
|
||||
nameA: String = "nameA",
|
||||
nameB: String = "nameB",
|
||||
onDismiss: () -> Unit = {},
|
||||
onNewGame: () -> Unit = {},
|
||||
) {
|
||||
|
||||
val winner = if (pointsA > pointsB) {
|
||||
nameA
|
||||
} else {
|
||||
nameB
|
||||
}
|
||||
|
||||
val message = if (pointsA == pointsB) {
|
||||
stringResource(R.string.draw_message, winner, 100)
|
||||
} else {
|
||||
stringResource(R.string.victory_message)
|
||||
}
|
||||
|
||||
val title = if (pointsA == pointsB) {
|
||||
stringResource(R.string.draw_title)
|
||||
} else {
|
||||
stringResource(R.string.victory_title, winner)
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDismiss() },
|
||||
dismissButton = {
|
||||
TextButton({ onDismiss() }) {
|
||||
Text(stringResource(R.string.continue_play))
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton({ onNewGame() }) {
|
||||
Text(stringResource(R.string.new_game))
|
||||
}
|
||||
},
|
||||
icon = { Icon(Icons.Outlined.EmojiEvents, null) },
|
||||
title = { Text(title) },
|
||||
text = { Text(message) }
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
internal class PreviewViewModel : ICounterViewModel {
|
||||
override var roundScoreList: List<Round> =
|
||||
listOf(Round(1, 10, 90), Round(1, 50, 50), Round(1, 70, 30))
|
||||
@@ -123,7 +191,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 var showVictoryDialog: Boolean = false
|
||||
|
||||
override fun focusLastInput() {
|
||||
}
|
||||
@@ -156,6 +224,9 @@ internal class PreviewViewModel : ICounterViewModel {
|
||||
override fun updateNameB(value: String) {
|
||||
}
|
||||
|
||||
override fun victoryDialogExecuted(result: Boolean) {
|
||||
}
|
||||
|
||||
override fun updateFocusStateA(state: Boolean) {
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,10 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import me.zobrist.tichucounter.data.entity.Game
|
||||
import me.zobrist.tichucounter.data.entity.Round
|
||||
import me.zobrist.tichucounter.domain.IGameSettingsChangeListener
|
||||
import me.zobrist.tichucounter.domain.SettingsAdapter
|
||||
import me.zobrist.tichucounter.domain.Tichu
|
||||
import me.zobrist.tichucounter.domain.digitCount
|
||||
import me.zobrist.tichucounter.domain.getTotalPoints
|
||||
@@ -59,15 +61,17 @@ interface ICounterViewModel : IKeyBoardViewModel {
|
||||
val teamNameB: String
|
||||
val teamNameSuggestionsA: List<String>
|
||||
val teamNameSuggestionsB: List<String>
|
||||
val victoryPoints: Int
|
||||
val showVictoryDialog: Boolean
|
||||
|
||||
fun updateNameA(value: String)
|
||||
fun updateNameB(value: String)
|
||||
fun victoryDialogExecuted(result: Boolean)
|
||||
}
|
||||
|
||||
@HiltViewModel
|
||||
class CounterViewModel @Inject constructor(
|
||||
private val gameRepository: GameRepository
|
||||
private val gameRepository: GameRepository,
|
||||
private val settings: SettingsAdapter
|
||||
) :
|
||||
ViewModel(), ICounterViewModel, IGameSettingsChangeListener {
|
||||
|
||||
@@ -115,8 +119,7 @@ class CounterViewModel @Inject constructor(
|
||||
|
||||
override var teamNameSuggestionsB by mutableStateOf(listOf<String>())
|
||||
private set
|
||||
|
||||
override var victoryPoints by mutableStateOf(0)
|
||||
override var showVictoryDialog by mutableStateOf(false)
|
||||
private set
|
||||
|
||||
override var activeValue: String
|
||||
@@ -160,11 +163,14 @@ class CounterViewModel @Inject constructor(
|
||||
|
||||
private var distinctTeamNames = listOf<String>()
|
||||
|
||||
private var victoryDialogShown = false
|
||||
|
||||
private var lastGame: Game? = null
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
gameRepository.getActiveGameFlow().collect {
|
||||
if (it != null) {
|
||||
|
||||
val score = it.getTotalPoints()
|
||||
|
||||
roundScoreList = it.rounds
|
||||
@@ -176,12 +182,16 @@ class CounterViewModel @Inject constructor(
|
||||
|
||||
buildTeamNameSuggestions()
|
||||
|
||||
if (totalScoreA >= victoryPoints || totalScoreB >= victoryPoints) {
|
||||
if (totalScoreA == totalScoreB) {
|
||||
|
||||
}
|
||||
if (it.game.uid != lastGame?.uid) {
|
||||
victoryDialogShown = false
|
||||
lastGame = it.game
|
||||
}
|
||||
|
||||
if (!victoryDialogShown) {
|
||||
if (totalScoreA >= settings.victoryPoints || totalScoreB >= settings.victoryPoints) {
|
||||
showVictoryDialog = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,6 +203,12 @@ class CounterViewModel @Inject constructor(
|
||||
buildTeamNameSuggestions()
|
||||
}
|
||||
}
|
||||
|
||||
settings.registerOnChangeListener(this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
settings.unregisterOnChangeListener(this)
|
||||
}
|
||||
|
||||
override fun focusLastInput() {
|
||||
@@ -301,6 +317,17 @@ class CounterViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun victoryDialogExecuted(result: Boolean) {
|
||||
showVictoryDialog = false
|
||||
victoryDialogShown = true
|
||||
|
||||
if (result) {
|
||||
viewModelScope.launch {
|
||||
gameRepository.newGame()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateFocusStateA(state: Boolean) {
|
||||
isAFocused = state
|
||||
if (state) {
|
||||
@@ -341,10 +368,6 @@ class CounterViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVictoryPointsChanged(victoryPoints: Int) {
|
||||
this.victoryPoints = victoryPoints
|
||||
}
|
||||
|
||||
private fun deleteLastDigitActive() {
|
||||
if (activeValue != "") {
|
||||
activeValue = activeValue.dropLast(1)
|
||||
@@ -378,4 +401,8 @@ class CounterViewModel @Inject constructor(
|
||||
|
||||
return filtered.sorted().sortedBy { it.length }.take(10)
|
||||
}
|
||||
|
||||
override fun onVictoryPointsChanged(victoryPoints: Int) {
|
||||
victoryDialogShown = false
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
<string name="menu_settings">Einstellungen</string>
|
||||
<string name="on">Ein</string>
|
||||
<string name="off">Aus</string>
|
||||
<string name="newGame">Neues Spiel</string>
|
||||
<string name="new_game">Neues Spiel</string>
|
||||
<string name="delete_inactive_title">Verlauf löschen</string>
|
||||
<string name="delete_inactive_text">Wirklich den gesamten Verlauf löschen? Diese Aktion kann nicht rückgängig gemacht werden.</string>
|
||||
<string name="cancel">Abbrechen</string>
|
||||
@@ -32,4 +32,8 @@
|
||||
<string name="display">Anzeige</string>
|
||||
<string name="game">Spiel</string>
|
||||
<string name="victory_points">Siegespunkte</string>
|
||||
<string name="victory_title">%1$s hat gewonnen</string>
|
||||
<string name="draw_message">Sieht aus, als ob ihr ein neues Spiel starten solltet, um das endgültig zu klären.</string>
|
||||
<string name="draw_title">Unentschieden</string>
|
||||
<string name="victory_message">Herzliche Gratulation! Wie wäre es mit einer Revanche?</string>
|
||||
</resources>
|
||||
@@ -15,7 +15,7 @@
|
||||
<string name="menu_settings">Settings</string>
|
||||
<string name="on">On</string>
|
||||
<string name="off">Off</string>
|
||||
<string name="newGame">New Game</string>
|
||||
<string name="new_game">New Game</string>
|
||||
<string name="delete_inactive_title">Delete history</string>
|
||||
<string name="delete_inactive_text">You really want to delete the history? This action can\'t be undone.</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
@@ -28,7 +28,7 @@
|
||||
<string name="menu_about">About</string>
|
||||
<string name="contact_us">Contact us</string>
|
||||
<string name="play_store" translatable="false">Play Store</string>
|
||||
<string name="continue_play">Continue</string>
|
||||
<string name="continue_play">Continue game</string>
|
||||
<string name="delete_success">Game deleted.</string>
|
||||
<string name="undo_question">UNDO</string>
|
||||
<string name="activated_success">Game activated.</string>
|
||||
@@ -36,4 +36,8 @@
|
||||
<string name="display">Display</string>
|
||||
<string name="game">Game</string>
|
||||
<string name="victory_points">Victory points</string>
|
||||
<string name="victory_title">%1$s won the game</string>
|
||||
<string name="draw_message">Looks like you should start a new game to settle this for good.</string>
|
||||
<string name="draw_title">Draw</string>
|
||||
<string name="victory_message">Congratulations! How about a rematch?</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user