commit 6ca22829a6910fcfebe112ff5cf26e9276ba0313
parent e78429ba09926890c135682fbb7100b1bd017ab1
Author: Iván Ávalos <avalos@disroot.org>
Date: Wed, 29 Apr 2026 22:45:23 +0200
[wallet] re-add tx delete confirm dialog
Diffstat:
3 files changed, 59 insertions(+), 30 deletions(-)
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailScreen.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailScreen.kt
@@ -504,7 +504,7 @@ private fun handleTransactionAction(
}
when (action) {
- TransactionAction.Delete -> transactionManager.deleteTransaction(tx.transactionId) { onNavigateBack() }
+ TransactionAction.Delete -> transactionManager.deleteTransaction(tx.transactionId, onError).invokeOnCompletion { onNavigateBack() }
TransactionAction.Retry -> transactionManager.retryTransaction(tx.transactionId, onError)
TransactionAction.Abort -> transactionManager.abortTransaction(tx.transactionId, { onNavigateBack() }, onError)
TransactionAction.Fail -> transactionManager.failTransaction(tx.transactionId, onError)
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt
@@ -96,37 +96,36 @@ class TransactionManager(
}
}
- @UiThread
fun loadTransactions(
scopeInfo: ScopeInfo? = null,
searchQuery: String? = null,
stateFilter: TransactionStateFilter? = null,
) {
Log.d(TAG, "loadTransactions($scopeInfo, $searchQuery, $stateFilter)")
- val s = scopeInfo ?: run {
- MutableStateFlow(TransactionsResult.None)
- return
- }
+ val scopes = scopeInfo?.let { listOf(it) } ?: mTransactions.keys.toList()
+ if (scopes.isEmpty()) return
- // initialize key with empty state flow
- if (mTransactions[s] == null) {
- mTransactions[s] = MutableStateFlow(TransactionsResult.None)
- }
-
- scope.launch {
- // return cached transactions if available
- if(searchQuery == null) allTransactions[s]?.let { txs ->
- mTransactions[s]?.value = TransactionsResult.Success(txs)
+ scopes.forEach { s ->
+ // initialize key with empty state flow
+ if (mTransactions[s] == null) {
+ mTransactions[s] = MutableStateFlow(TransactionsResult.None)
}
- // ...then fetch new ones
- val res = getTransactions(s, searchQuery, filterByState = stateFilter)
- if (res is TransactionsResult.Success) {
- allTransactions[s] = res.transactions
- }
+ scope.launch {
+ // return cached transactions if available
+ if (searchQuery == null) allTransactions[s]?.let { txs ->
+ mTransactions[s]?.value = TransactionsResult.Success(txs)
+ }
+
+ // ...then fetch new ones
+ val res = getTransactions(s, searchQuery, filterByState = stateFilter)
+ if (res is TransactionsResult.Success) {
+ allTransactions[s] = res.transactions
+ }
- // ...and then emit them when available
- mTransactions[s]?.value = res
+ // ...and then emit them when available
+ mTransactions[s]?.value = res
+ }
}
}
@@ -275,15 +274,17 @@ class TransactionManager(
}
}
- fun deleteTransactions(transactionIds: List<String>, onError: (it: TalerErrorInfo) -> Unit) {
- allTransactions.values.flatten().filter { transaction ->
- transaction.transactionId in transactionIds
- }.forEach { toBeDeletedTx ->
- if (Delete in toBeDeletedTx.txActions) {
- deleteTransaction(toBeDeletedTx.transactionId) {
+ fun deleteTransactions(transactionIds: List<String>, onError: (it: TalerErrorInfo) -> Unit) =
+ scope.launch {
+ allTransactions.values.flatten().filter { transaction ->
+ transaction.transactionId in transactionIds && Delete in transaction.txActions
+ }.forEach { toBeDeletedTx ->
+ api.request<Unit>("deleteTransaction") {
+ put("transactionId", toBeDeletedTx.transactionId)
+ }.onError {
onError(it)
}
}
+ loadTransactions()
}
- }
}
\ No newline at end of file
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt
@@ -119,6 +119,28 @@ fun TransitionsComposable(
@Composable
fun TransitionComposable(t: TransactionAction, onClick: (t: TransactionAction) -> Unit) {
+ var showConfirmDialog by remember { mutableStateOf(false) }
+ if (showConfirmDialog) {
+ AlertDialog(
+ onDismissRequest = { showConfirmDialog = false },
+ title = { Text(stringResource(R.string.transactions_delete_dialog_title)) },
+ text = { Text(stringResource(R.string.transactions_delete_dialog_message)) },
+ confirmButton = {
+ TextButton(onClick = {
+ showConfirmDialog = false
+ onClick(t)
+ }) {
+ Text(stringResource(R.string.transactions_delete))
+ }
+ },
+ dismissButton = {
+ TextButton(onClick = { showConfirmDialog = false }) {
+ Text(stringResource(R.string.cancel))
+ }
+ }
+ )
+ }
+
Button(
modifier = Modifier.padding(16.dp),
colors = ButtonDefaults.buttonColors(
@@ -131,7 +153,13 @@ fun TransitionComposable(t: TransactionAction, onClick: (t: TransactionAction) -
Suspend -> MaterialTheme.colorScheme.primary
}
),
- onClick = { onClick(t) },
+ onClick = {
+ if (t == Delete) {
+ showConfirmDialog = true
+ } else {
+ onClick(t)
+ }
+ },
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(