Style game history. Add functionality to delete and open game from history.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -16,4 +16,7 @@ interface DaoBase<T> {
|
|||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
fun delete(entity: T)
|
fun delete(entity: T)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun delete(entity: List<T>)
|
||||||
}
|
}
|
||||||
@@ -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) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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, {}) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
Reference in New Issue
Block a user