diff options
author | Torsten Grote <t@grobox.de> | 2022-08-17 15:40:16 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2022-08-17 15:40:16 -0300 |
commit | d1163e31e904ac59d0739169257a8e3fdc7986a7 (patch) | |
tree | 44dfc439444d0ed5e004147c79b3dcf6ff0b5efb /wallet/src | |
parent | 326b1bdf62a687aa40d32994c14c792fcbf113fc (diff) | |
download | taler-android-d1163e31e904ac59d0739169257a8e3fdc7986a7.tar.gz taler-android-d1163e31e904ac59d0739169257a8e3fdc7986a7.tar.bz2 taler-android-d1163e31e904ac59d0739169257a8e3fdc7986a7.zip |
[wallet] Add ability to cancel/delete transactions
Diffstat (limited to 'wallet/src')
10 files changed, 131 insertions, 37 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt index 128ca04..f21818f 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt @@ -23,8 +23,11 @@ import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import android.widget.TextView +import androidx.annotation.StringRes +import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.navigation.fragment.findNavController import net.taler.common.Amount import net.taler.common.startActivitySafe import net.taler.wallet.MainViewModel @@ -67,7 +70,7 @@ abstract class TransactionDetailFragment : Fragment() { feeView: TextView, info: TransactionInfo, raw: Amount, - fee: Amount + fee: Amount, ) { orderAmountView.text = raw.toString() feeView.text = getString(R.string.amount_negative, fee.toString()) @@ -85,4 +88,30 @@ abstract class TransactionDetailFragment : Fragment() { orderIdView.text = getString(R.string.transaction_order_id, info.orderId) } + @StringRes + protected open val deleteDialogTitle = R.string.transactions_delete + @StringRes + protected open val deleteDialogMessage = R.string.transactions_delete_dialog_message + @StringRes + protected open val deleteDialogButton = R.string.transactions_delete + + protected fun onDeleteButtonClicked(t: Transaction) { + AlertDialog.Builder(requireContext(), R.style.DialogTheme) + .setTitle(deleteDialogTitle) + .setMessage(deleteDialogMessage) + .setPositiveButton(R.string.cancel) { dialog, _ -> + dialog.cancel() + } + .setNegativeButton(deleteDialogButton) { dialog, _ -> + deleteTransaction(t) + dialog.dismiss() + } + .show() + } + + private fun deleteTransaction(t: Transaction) { + transactionManager.deleteTransaction(t.transactionId) + findNavController().popBackStack() + } + } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt index ea257a8..d1020e2 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt @@ -25,7 +25,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import net.taler.wallet.TAG import net.taler.wallet.backend.WalletBackendApi -import java.util.HashMap import java.util.LinkedList sealed class TransactionsResult { @@ -96,7 +95,14 @@ class TransactionManager( }.onError { Log.e(TAG, "Error deleteTransaction $it") }.onSuccess { - // no op + // re-load transactions as our list is stale otherwise + loadTransactions() + } + } + + fun deleteTransactions(transactionIds: List<String>) { + transactionIds.forEach { id -> + deleteTransaction(id) } } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt index 84c5c77..e2e4f9f 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt @@ -30,8 +30,8 @@ class TransactionPaymentFragment : TransactionDetailFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { + savedInstanceState: Bundle?, + ): View { ui = FragmentTransactionPaymentBinding.inflate(inflater, container, false) return ui.root } @@ -51,6 +51,9 @@ class TransactionPaymentFragment : TransactionDetailFragment() { t.amountRaw, fee ) + ui.deleteButton.setOnClickListener { + onDeleteButtonClicked(t) + } } } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt index 717dd33..d44db43 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt @@ -33,8 +33,8 @@ class TransactionRefreshFragment : TransactionDetailFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { + savedInstanceState: Bundle?, + ): View { ui = FragmentTransactionWithdrawalBinding.inflate(inflater, container, false) return ui.root } @@ -50,7 +50,10 @@ class TransactionRefreshFragment : TransactionDetailFragment() { ui.chosenAmountView.visibility = GONE val fee = t.amountEffective ui.feeView.text = getString(R.string.amount_negative, fee.toString()) - ui. exchangeView.text = cleanExchange(t.exchangeBaseUrl) + ui.exchangeView.text = cleanExchange(t.exchangeBaseUrl) + ui.deleteButton.setOnClickListener { + onDeleteButtonClicked(t) + } } } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt index 6628d6c..5e6eef4 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt @@ -32,8 +32,8 @@ class TransactionRefundFragment : TransactionDetailFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { + savedInstanceState: Bundle?, + ): View { ui = FragmentTransactionPaymentBinding.inflate(inflater, container, false) return ui.root } @@ -56,6 +56,9 @@ class TransactionRefundFragment : TransactionDetailFragment() { t.amountRaw, fee ) + ui.deleteButton.setOnClickListener { + onDeleteButtonClicked(t) + } } } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt index a11f8ba..ff8d272 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt @@ -31,6 +31,8 @@ import net.taler.wallet.MainViewModel import net.taler.wallet.R import net.taler.wallet.cleanExchange import net.taler.wallet.databinding.FragmentTransactionWithdrawalBinding +import net.taler.wallet.transactions.WithdrawalDetails.ManualTransfer +import net.taler.wallet.transactions.WithdrawalDetails.TalerBankIntegrationApi import net.taler.wallet.withdraw.createManualTransferRequired class TransactionWithdrawalFragment : TransactionDetailFragment() { @@ -54,33 +56,55 @@ class TransactionWithdrawalFragment : TransactionDetailFragment() { ui.effectiveAmountLabel.text = getString(R.string.withdraw_total) ui.effectiveAmountView.text = t.amountEffective.toString() - if (t.pending && t.withdrawalDetails is WithdrawalDetails.TalerBankIntegrationApi && - !t.confirmed && t.withdrawalDetails.bankConfirmationUrl != null - ) { - val i = Intent(ACTION_VIEW).apply { - data = Uri.parse(t.withdrawalDetails.bankConfirmationUrl) - } - ui.confirmWithdrawalButton.setOnClickListener { startActivitySafe(i) } - } else if (t.pending && !t.confirmed && t.withdrawalDetails is WithdrawalDetails.ManualTransfer) { - ui.confirmWithdrawalButton.setText(R.string.withdraw_manual_ready_details_intro) - ui.confirmWithdrawalButton.setOnClickListener { - val status = createManualTransferRequired( - amount = t.amountRaw, - exchangeBaseUrl = t.exchangeBaseUrl, - // TODO what if there's more than one or no URI? - uriStr = t.withdrawalDetails.exchangePaytoUris[0], - transactionId = t.transactionId, - ) - withdrawManager.viewManualWithdrawal(status) - findNavController().navigate(R.id.action_nav_transactions_detail_withdrawal_to_nav_exchange_manual_withdrawal_success) - } - } else ui.confirmWithdrawalButton.visibility = View.GONE + setupConfirmWithdrawalButton(t) ui.chosenAmountLabel.text = getString(R.string.amount_chosen) ui.chosenAmountView.text = getString(R.string.amount_positive, t.amountRaw.toString()) val fee = t.amountRaw - t.amountEffective ui.feeView.text = getString(R.string.amount_negative, fee.toString()) ui.exchangeView.text = cleanExchange(t.exchangeBaseUrl) + if (t.pending) { + ui.deleteButton.setIconResource(R.drawable.ic_cancel) + ui.deleteButton.setText(R.string.cancel) + } + ui.deleteButton.setOnClickListener { + onDeleteButtonClicked(t) + } + } + + override val deleteDialogTitle: Int + get() = if (transaction?.pending == true) R.string.cancel else super.deleteDialogTitle + override val deleteDialogMessage: Int + get() = if (transaction?.pending == true) R.string.transactions_cancel_dialog_message + else super.deleteDialogMessage + override val deleteDialogButton: Int + get() = if (transaction?.pending == true) R.string.ok else super.deleteDialogButton + + private fun setupConfirmWithdrawalButton(t: TransactionWithdrawal) { + if (t.pending && !t.confirmed) { + if (t.withdrawalDetails is TalerBankIntegrationApi && + t.withdrawalDetails.bankConfirmationUrl != null + ) { + val i = Intent(ACTION_VIEW).apply { + data = Uri.parse(t.withdrawalDetails.bankConfirmationUrl) + } + ui.confirmWithdrawalButton.setOnClickListener { startActivitySafe(i) } + } else if (t.withdrawalDetails is ManualTransfer) { + ui.confirmWithdrawalButton.setText(R.string.withdraw_manual_ready_details_intro) + ui.confirmWithdrawalButton.setOnClickListener { + val status = createManualTransferRequired( + amount = t.amountRaw, + exchangeBaseUrl = t.exchangeBaseUrl, + // TODO what if there's more than one or no URI? + uriStr = t.withdrawalDetails.exchangePaytoUris[0], + transactionId = t.transactionId, + ) + withdrawManager.viewManualWithdrawal(status) + findNavController().navigate( + R.id.action_nav_transactions_detail_withdrawal_to_nav_exchange_manual_withdrawal_success) + } + } else ui.confirmWithdrawalButton.visibility = View.GONE + } else ui.confirmWithdrawalButton.visibility = View.GONE } } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt index ff2574f..fddaaec 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt @@ -25,8 +25,6 @@ import android.view.MenuItem import android.view.View import android.view.View.INVISIBLE import android.view.ViewGroup -import android.widget.Toast -import android.widget.Toast.LENGTH_LONG import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView.OnQueryTextListener import androidx.fragment.app.Fragment @@ -211,8 +209,9 @@ class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode. override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { when (item.itemId) { R.id.transaction_delete -> { - val s = "Not yet implemented. Pester Florian! ;)" - Toast.makeText(requireContext(), s, LENGTH_LONG).show() + tracker?.selection?.toList()?.let { transactionIds -> + transactionManager.deleteTransactions(transactionIds) + } mode.finish() } R.id.transaction_select_all -> transactionAdapter.selectAll() diff --git a/wallet/src/main/res/layout/fragment_transaction_payment.xml b/wallet/src/main/res/layout/fragment_transaction_payment.xml index 20ba161..32aa6ed 100644 --- a/wallet/src/main/res/layout/fragment_transaction_payment.xml +++ b/wallet/src/main/res/layout/fragment_transaction_payment.xml @@ -116,11 +116,23 @@ style="@style/TransactionLabel" android:layout_marginBottom="16dp" android:text="@string/transaction_order_id" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@+id/deleteButton" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/orderSummaryView" /> + <com.google.android.material.button.MaterialButton + android:id="@+id/deleteButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/transactions_delete" + app:backgroundTint="@color/red" + app:icon="@drawable/ic_delete" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/orderIdView" /> + </androidx.constraintlayout.widget.ConstraintLayout> </ScrollView> diff --git a/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml b/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml index 8fe3247..78d1667 100644 --- a/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml +++ b/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml @@ -117,12 +117,24 @@ <TextView android:id="@+id/exchangeView" style="@style/TransactionContent" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@+id/deleteButton" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/exchangeLabel" tools:text="exchange.demo.taler.net" /> + <com.google.android.material.button.MaterialButton + android:id="@+id/deleteButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/transactions_delete" + app:backgroundTint="@color/red" + app:icon="@drawable/ic_delete" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/exchangeView" /> + </androidx.constraintlayout.widget.ConstraintLayout> </ScrollView> diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml index efaa7dd..d1a0c78 100644 --- a/wallet/src/main/res/values/strings.xml +++ b/wallet/src/main/res/values/strings.xml @@ -77,6 +77,9 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card <string name="transactions_detail_title_balance">Balance: %s</string> <string name="transactions_delete">Delete</string> <string name="transactions_select_all">Select All</string> + <string name="transactions_delete_dialog_title">Delete Transaction</string> + <string name="transactions_delete_dialog_message">Are you sure you want to remove this transaction from your wallet?</string> + <string name="transactions_cancel_dialog_message">Are you sure you want to cancel this withdrawal? Funds still in transit might get lost.</string> <!-- Transactions --> <string name="transaction_paid">Paid</string> |