Style game history. Add functionality to delete and open game from history.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-01-21 13:04:45 +01:00
parent 63f213bc75
commit 6d0192df18
7 changed files with 112 additions and 39 deletions

View File

@@ -15,6 +15,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
@@ -114,7 +115,7 @@ class MainActivity : BaseActivity() {
NavigationAction { scope.launch { drawerState.open() } } NavigationAction { scope.launch { drawerState.open() } }
} }
composable("history") { composable("history") {
HistoryList(historyViewModel) HistoryList(historyViewModel) { navController.navigate("counter") }
mainViewModel.topBarActions = emptyList() mainViewModel.topBarActions = emptyList()
mainViewModel.topBarIcon = Icons.Outlined.ArrowBack mainViewModel.topBarIcon = Icons.Outlined.ArrowBack
mainViewModel.topBarTitle = stringResource(R.string.menu_history) mainViewModel.topBarTitle = stringResource(R.string.menu_history)

View File

@@ -16,4 +16,7 @@ interface DaoBase<T> {
@Delete @Delete
fun delete(entity: T) fun delete(entity: T)
@Delete
fun delete(entity: List<T>)
} }

View File

@@ -2,6 +2,7 @@ package me.zobrist.tichucounter.repository
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import me.zobrist.tichucounter.data.Game import me.zobrist.tichucounter.data.Game
@@ -50,7 +51,7 @@ class GameRepository @Inject constructor(
} }
} }
private suspend fun setActive(id: Long) { suspend fun setActive(id: Long) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
gameDao.setActive(id) gameDao.setActive(id)
gameDao.setOthersInactive(id) gameDao.setOthersInactive(id)
@@ -85,4 +86,17 @@ class GameRepository @Inject constructor(
gameDao.update(active) gameDao.update(active)
} }
} }
suspend fun deleteGame(uid: Long) {
withContext(Dispatchers.IO) {
try {
gameDao.getGameById(uid).take(1).collect() {
gameDao.delete(it)
val rounds = roundDao.getAllForGame(it.uid)
roundDao.delete(rounds)
}
} catch (_: NullPointerException) {
}
}
}
} }

View File

@@ -1,77 +1,109 @@
package me.zobrist.tichucounter.ui.history package me.zobrist.tichucounter.ui.history
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Card import androidx.compose.material.icons.Icons
import androidx.compose.material3.MaterialTheme import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material3.Text import androidx.compose.material.icons.outlined.DeleteForever
import androidx.compose.material.icons.outlined.OpenInFull
import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
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.data.GameAndScore import me.zobrist.tichucounter.data.GameAndScore
import java.text.DateFormat import java.text.DateFormat
import java.util.* import java.util.*
@Composable @Composable
fun HistoryList(viewModel: HistoryViewModel) { fun HistoryList(viewModel: HistoryViewModel, navigateToCalculator: () -> Unit) {
HistoryList(viewModel.gameAndHistory) HistoryList(viewModel.gameAndHistory,
{
viewModel.activateGame(it)
navigateToCalculator()
},
{viewModel.deleteGame(it)})
} }
@Composable @Composable
fun HistoryList(games: List<GameAndScore>) { fun HistoryList(games: List<GameAndScore>,
onOpenClicked: (GameId: Long) -> Unit,
onDeleteClicked: (GameId: Long) -> Unit) {
Row {
LazyColumn { LazyColumn {
items(games) { items(games) {
HistoryListItem(it) HistoryListItem(it, onOpenClicked, onDeleteClicked)
}
} }
} }
} }
@Composable @Composable
fun HistoryListItem(game: GameAndScore) { fun HistoryListItem(
game: GameAndScore,
onOpenClicked: (GameId: Long) -> Unit,
onDeleteClicked: (GameId: Long) -> Unit) {
val format = val format =
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault()) DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault())
val cardColor = if(game.active)
{
CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.secondaryContainer)
} else
{
CardDefaults.cardColors()
}
Card( Card(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(all = 4.dp), .padding(all = 4.dp),
colors = cardColor
) { ) {
Column( Row(
Modifier Modifier
.padding(all = 12.dp), .padding(all = 12.dp)){
) { Column(Modifier.weight(4f)){
Row {
Text( Text(
text = game.nameA, text = game.nameA + " vs " + game.nameB,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.headlineSmall style = MaterialTheme.typography.headlineSmall
) )
Text( Text(
text = game.scoreA.toString(), text = game.scoreA.toString() + " : " + game.scoreB.toString(),
style = MaterialTheme.typography.headlineSmall style = MaterialTheme.typography.bodyLarge
) )
} Spacer(modifier = Modifier.padding(5.dp))
Row {
Text( Text(
text = game.nameB, text = stringResource(R.string.created, format.format(game.created)),
style = MaterialTheme.typography.headlineSmall
)
Text(
text = game.scoreB.toString(),
style = MaterialTheme.typography.headlineSmall
)
}
Row {
Text(
text = format.format(game.modified),
style = MaterialTheme.typography.labelSmall style = MaterialTheme.typography.labelSmall
) )
Text(
text = stringResource(R.string.modified, format.format(game.modified)),
style = MaterialTheme.typography.labelSmall
)
}
Column(
Modifier
.wrapContentSize()
.width(70.dp)){
ElevatedButton(
onClick = { onDeleteClicked(game.gameId) }, enabled = !game.active ) {
Icon(Icons.Outlined.Delete, null)
}
ElevatedButton(onClick = { onOpenClicked(game.gameId) }, enabled = !game.active) {
Icon(Icons.Outlined.OpenInFull, null)
}
} }
} }
} }
@@ -83,9 +115,9 @@ private fun HistoryListPreview() {
val tempData = listOf( val tempData = listOf(
GameAndScore(false, "abc", "def", Date(), Date(), 1, 10, 50), GameAndScore(false, "abc", "def", Date(), Date(), 1, 10, 50),
GameAndScore(true, "ADTH", "dogfg", Date(), Date(), 2, 20, 60), GameAndScore(true, "ADTH", "dogfg", Date(), Date(), 2, 20, 60),
GameAndScore(false, "TeamA3", "TeamB3", Date(), Date(), 3, 30, 70), GameAndScore(false, "TeamA3 langer Name", "TeamB3", Date(), Date(), 3, 30, 70),
GameAndScore(false, "TeamA4", "TeamB4", Date(), Date(), 4, 40, 80), GameAndScore(false, "TeamA4", "TeamB4", Date(), Date(), 4, 40, 80),
GameAndScore(false, "TeamA5", "TeamB5", Date(), Date(), 5, 50, 90) GameAndScore(false, "TeamA5", "TeamB5", Date(), Date(), 5, 50, 90)
) )
HistoryList(tempData) HistoryList(tempData, {}) {}
} }

View File

@@ -9,12 +9,14 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.zobrist.tichucounter.data.GameAndScore import me.zobrist.tichucounter.data.GameAndScore
import me.zobrist.tichucounter.data.GameDao import me.zobrist.tichucounter.data.GameDao
import me.zobrist.tichucounter.repository.GameRepository
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class HistoryViewModel @Inject constructor( class HistoryViewModel @Inject constructor(
private val gameDao: GameDao private val gameDao: GameDao,
private val gameRepository: GameRepository
) : ViewModel() { ) : ViewModel() {
var gameAndHistory by mutableStateOf(emptyList<GameAndScore>()) var gameAndHistory by mutableStateOf(emptyList<GameAndScore>())
@@ -27,4 +29,19 @@ class HistoryViewModel @Inject constructor(
} }
} }
} }
fun deleteGame(gameId: Long)
{
viewModelScope.launch {
gameRepository.deleteGame(gameId)
}
}
fun activateGame(gameId: Long)
{
viewModelScope.launch {
gameRepository.setActive(gameId)
}
}
} }

View File

@@ -13,5 +13,8 @@
<string name="on">Ein</string> <string name="on">Ein</string>
<string name="off">Aus</string> <string name="off">Aus</string>
<string name="newGame">Neues Spiel</string> <string name="newGame">Neues Spiel</string>
<string name="created">"Erstellt: %s "</string>
<string name="modified">Bearbeitet: %s</string>
<string name="delete_all">Alle löschen</string>
</resources> </resources>

View File

@@ -16,4 +16,7 @@
<string name="on">On</string> <string name="on">On</string>
<string name="off">Off</string> <string name="off">Off</string>
<string name="newGame">New Game</string> <string name="newGame">New Game</string>
<string name="created">Created: %s</string>
<string name="modified">Modified: %s</string>
<string name="delete_all">Delete all</string>
</resources> </resources>