From ad0236556e29d5cd8546e0ea42a49c3067cba5f3 Mon Sep 17 00:00:00 2001 From: Fabian Zobrist Date: Sat, 21 Jan 2023 15:48:07 +0100 Subject: [PATCH] Add delete all history with confirm dialog. --- .../me/zobrist/tichucounter/MainActivity.kt | 20 +++++- .../me/zobrist/tichucounter/data/RoundDao.kt | 3 + .../tichucounter/repository/GameRepository.kt | 17 +++++ .../zobrist/tichucounter/ui/MainViewModel.kt | 6 ++ .../tichucounter/ui/counter/KeyboardView.kt | 7 +- .../tichucounter/ui/counter/TeamNamesView.kt | 3 +- .../tichucounter/ui/history/HistoryView.kt | 68 ++++++++++++++----- .../ui/history/HistoryViewModel.kt | 6 +- app/src/main/res/values-de/strings.xml | 5 +- app/src/main/res/values/strings.xml | 5 +- 10 files changed, 110 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt b/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt index 3642c49..17a092b 100644 --- a/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt +++ b/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt @@ -15,7 +15,6 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController @@ -115,8 +114,23 @@ class MainActivity : BaseActivity() { NavigationAction { scope.launch { drawerState.open() } } } composable("history") { - HistoryList(historyViewModel) { navController.navigate("counter") } - mainViewModel.topBarActions = emptyList() + + var openDialog by remember { mutableStateOf(false) } + + HistoryList(historyViewModel, openDialog, { deleteAll -> + if (deleteAll) { + mainViewModel.deleteAllInactiveGames() + } + openDialog = false + }) { navController.navigate("counter") } + mainViewModel.topBarActions = listOf( + TopBarAction( + Icons.Outlined.DeleteForever, + true + ) { + openDialog = true + } + ) mainViewModel.topBarIcon = Icons.Outlined.ArrowBack mainViewModel.topBarTitle = stringResource(R.string.menu_history) mainViewModel.topBarNavigationAction = diff --git a/app/src/main/java/me/zobrist/tichucounter/data/RoundDao.kt b/app/src/main/java/me/zobrist/tichucounter/data/RoundDao.kt index f6edf71..4063e76 100644 --- a/app/src/main/java/me/zobrist/tichucounter/data/RoundDao.kt +++ b/app/src/main/java/me/zobrist/tichucounter/data/RoundDao.kt @@ -6,6 +6,9 @@ import kotlinx.coroutines.flow.Flow @Dao interface RoundDao : DaoBase { + @Query("SELECT * FROM round") + fun getAll(): List + @Query("SELECT * FROM round WHERE gameId is :gameId") fun getAllForGame(gameId: Long?): List diff --git a/app/src/main/java/me/zobrist/tichucounter/repository/GameRepository.kt b/app/src/main/java/me/zobrist/tichucounter/repository/GameRepository.kt index 4473bb6..8ae41f6 100644 --- a/app/src/main/java/me/zobrist/tichucounter/repository/GameRepository.kt +++ b/app/src/main/java/me/zobrist/tichucounter/repository/GameRepository.kt @@ -99,4 +99,21 @@ class GameRepository @Inject constructor( } } } + + suspend fun deleteAllInactive() { + withContext(Dispatchers.IO) { + try { + gameDao.getAll().take(1).collect() { games -> + + val activeId = games.first { it.active }.uid + val gamesToDelete = games.filter { !it.active } + val roundsToDelete = roundDao.getAll().filter { it.gameId != activeId } + + gameDao.delete(gamesToDelete) + roundDao.delete(roundsToDelete) + } + } catch (_: NullPointerException) { + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/MainViewModel.kt b/app/src/main/java/me/zobrist/tichucounter/ui/MainViewModel.kt index 7a6cf61..cc08b6b 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/MainViewModel.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/MainViewModel.kt @@ -83,4 +83,10 @@ class MainViewModel @Inject constructor( gameRepository.newGame() } } + + fun deleteAllInactiveGames() { + viewModelScope.launch { + gameRepository.deleteAllInactive() + } + } } \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/counter/KeyboardView.kt b/app/src/main/java/me/zobrist/tichucounter/ui/counter/KeyboardView.kt index 15b7d25..28340c0 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/counter/KeyboardView.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/counter/KeyboardView.kt @@ -170,10 +170,9 @@ fun KeyboardTextButton(text: String, onClicked: () -> Unit) { val screenWidth = configuration.screenWidthDp.dp - val style = if(screenWidth < 350.dp) - { - MaterialTheme.typography.labelSmall - }else { + val style = if (screenWidth < 350.dp) { + MaterialTheme.typography.labelSmall + } else { MaterialTheme.typography.labelLarge } diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/counter/TeamNamesView.kt b/app/src/main/java/me/zobrist/tichucounter/ui/counter/TeamNamesView.kt index f042200..596c861 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/counter/TeamNamesView.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/counter/TeamNamesView.kt @@ -21,7 +21,8 @@ fun TeamNamesView( ) { val color = TextFieldDefaults.textFieldColors( - containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)) + containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp) + ) Row { TextField( diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/history/HistoryView.kt b/app/src/main/java/me/zobrist/tichucounter/ui/history/HistoryView.kt index 0b4788d..26bdd03 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/history/HistoryView.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/history/HistoryView.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Delete -import androidx.compose.material.icons.outlined.DeleteForever import androidx.compose.material.icons.outlined.OpenInFull import androidx.compose.material3.* import androidx.compose.runtime.Composable @@ -22,19 +21,54 @@ import java.util.* @Composable -fun HistoryList(viewModel: HistoryViewModel, navigateToCalculator: () -> Unit) { +fun HistoryList( + viewModel: HistoryViewModel, + showDeleteDialog: Boolean, + onDialogExecuted: (Boolean) -> Unit, + navigateToCalculator: () -> Unit +) { + + DeleteConfirmDialog(showDeleteDialog, onDialogExecuted) + HistoryList(viewModel.gameAndHistory, { viewModel.activateGame(it) navigateToCalculator() }, - {viewModel.deleteGame(it)}) + { viewModel.deleteGame(it) }) +} + +@Preview +@Composable +fun DeleteConfirmDialog(show: Boolean = true, onExecuted: (Boolean) -> Unit = {}) { + if (show) { + + AlertDialog( + onDismissRequest = { onExecuted(false) }, + dismissButton = { + TextButton({ onExecuted(false) }) + { + Text(stringResource(R.string.cancel)) + } + }, + confirmButton = { + TextButton({ onExecuted(true) }) + { + Text(stringResource(R.string.ok)) + } + }, + title = { Text(stringResource(R.string.delete_inactive_title)) }, + text = { Text(stringResource(R.string.delete_inactive_text)) }, + ) + } } @Composable -fun HistoryList(games: List, - onOpenClicked: (GameId: Long) -> Unit, - onDeleteClicked: (GameId: Long) -> Unit) { +fun HistoryList( + games: List, + onOpenClicked: (GameId: Long) -> Unit, + onDeleteClicked: (GameId: Long) -> Unit +) { Row { LazyColumn { items(games) { @@ -48,20 +82,19 @@ fun HistoryList(games: List, fun HistoryListItem( game: GameAndScore, onOpenClicked: (GameId: Long) -> Unit, - onDeleteClicked: (GameId: Long) -> Unit) { + onDeleteClicked: (GameId: Long) -> Unit +) { val format = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault()) - val cardColor = if(game.active) - { + val cardColor = if (game.active) { CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.secondaryContainer) - } else - { + } else { CardDefaults.cardColors() } - + Card( modifier = Modifier .fillMaxWidth() @@ -70,8 +103,9 @@ fun HistoryListItem( ) { Row( Modifier - .padding(all = 12.dp)){ - Column(Modifier.weight(4f)){ + .padding(all = 12.dp) + ) { + Column(Modifier.weight(4f)) { Text( text = game.nameA + " vs " + game.nameB, maxLines = 1, @@ -91,13 +125,15 @@ fun HistoryListItem( Column( Modifier .wrapContentSize() - .width(70.dp)){ + .width(70.dp) + ) { ElevatedButton(onClick = { onOpenClicked(game.gameId) }, enabled = true) { Icon(Icons.Outlined.OpenInFull, null) } ElevatedButton( - onClick = { onDeleteClicked(game.gameId) }, enabled = !game.active ) { + onClick = { onDeleteClicked(game.gameId) }, enabled = !game.active + ) { Icon(Icons.Outlined.Delete, null) } } diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/history/HistoryViewModel.kt b/app/src/main/java/me/zobrist/tichucounter/ui/history/HistoryViewModel.kt index bb28bf5..affda48 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/history/HistoryViewModel.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/history/HistoryViewModel.kt @@ -30,15 +30,13 @@ class HistoryViewModel @Inject constructor( } } - fun deleteGame(gameId: Long) - { + fun deleteGame(gameId: Long) { viewModelScope.launch { gameRepository.deleteGame(gameId) } } - fun activateGame(gameId: Long) - { + fun activateGame(gameId: Long) { viewModelScope.launch { gameRepository.setActive(gameId) } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d0f4fbd..05711ba 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -15,6 +15,9 @@ Neues Spiel "Erstellt: %s " Bearbeitet: %s - Alle löschen + Verlauf löschen + Wirklich den gesamten Verlauf löschen? Diese Aktion kann nicht rückgängig gemacht werden. + Abbrechen + Ok \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e092648..f8b7bbc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -18,5 +18,8 @@ New Game Created: %s Modified: %s - Delete all + Delete history + You really want to delete the the history? This action can\'t be undone. + Cancel + Ok \ No newline at end of file