taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

commit 10f01495670d5cd88e2f3e4582bb59d2c96bf0eb
parent 3087f4bf6bf2260e443ea28fd44308b99736d369
Author: Iván Ávalos <avalos@disroot.org>
Date:   Thu, 20 Jun 2024 09:11:42 -0600

[wallet] hide errors in pending transactions when offline

bug 0008912

Diffstat:
Mwallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt | 44+++++++++++++++++++++++++++++++++-----------
Mwallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt | 14+++++++++++++-
Mwallet/src/main/res/values/strings.xml | 1+
3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt @@ -17,6 +17,7 @@ package net.taler.wallet.transactions import android.content.Context +import android.util.Log import android.view.LayoutInflater import android.view.MotionEvent import android.view.View @@ -36,19 +37,23 @@ import net.taler.common.CurrencySpecification import net.taler.common.exhaustive import net.taler.common.toRelativeTime import net.taler.wallet.R +import net.taler.wallet.TAG import net.taler.wallet.getThemeColor import net.taler.wallet.transactions.TransactionAdapter.TransactionViewHolder import net.taler.wallet.transactions.TransactionMajorState.Aborted +import net.taler.wallet.transactions.TransactionMajorState.Aborting import net.taler.wallet.transactions.TransactionMajorState.Failed import net.taler.wallet.transactions.TransactionMajorState.Pending import net.taler.wallet.transactions.TransactionMinorState.BankConfirmTransfer import net.taler.wallet.transactions.TransactionMinorState.KycRequired + internal class TransactionAdapter( private val listener: OnTransactionClickListener, ) : Adapter<TransactionViewHolder>() { private var transactions: List<Transaction> = ArrayList() + private var networkAvailable: Boolean = true private var currencySpec: CurrencySpecification? = null lateinit var tracker: SelectionTracker<String> @@ -76,8 +81,9 @@ internal class TransactionAdapter( this.notifyDataSetChanged() } - fun update(updatedTransactions: List<Transaction>) { - this.transactions = updatedTransactions + fun update(updatedTransactions: List<Transaction>? = null, networkAvailable: Boolean? = null) { + updatedTransactions?.let { this.transactions = it } + networkAvailable?.let { this.networkAvailable = it } this.notifyDataSetChanged() } @@ -123,14 +129,6 @@ internal class TransactionAdapter( private fun bindExtraInfo(transaction: Transaction) { when { - // Goes first so it always shows errors when present - transaction.error != null -> { - extraInfoView.text = - context.getString(R.string.payment_error, transaction.error!!.userFacingMsg) - extraInfoView.setTextColor(red) - extraInfoView.visibility = VISIBLE - } - transaction.txState.major == Aborted -> { extraInfoView.setText(R.string.payment_aborted) extraInfoView.setTextColor(red) @@ -143,18 +141,30 @@ internal class TransactionAdapter( extraInfoView.visibility = VISIBLE } + transaction.txState.major == Aborting -> { + extraInfoView.setText(R.string.payment_aborting) + extraInfoView.setTextColor(red) + extraInfoView.visibility = VISIBLE + } + transaction.txState.major == Pending -> when (transaction.txState.minor) { BankConfirmTransfer -> { extraInfoView.setText(R.string.withdraw_waiting_confirm) extraInfoView.setTextColor(amountColor) extraInfoView.visibility = VISIBLE } + KycRequired -> { extraInfoView.setText(R.string.transaction_action_kyc) extraInfoView.setTextColor(amountColor) extraInfoView.visibility = VISIBLE } - else -> extraInfoView.visibility = GONE + + else -> { + extraInfoView.setText(R.string.transaction_pending) + extraInfoView.setTextColor(extraInfoColor) + extraInfoView.visibility = VISIBLE + } } transaction is TransactionWithdrawal && !transaction.confirmed -> { @@ -189,6 +199,18 @@ internal class TransactionAdapter( else -> extraInfoView.visibility = GONE } + + // If network is available and the transaction is in a pending state, + // show error message, otherwise it might just be a network error. + // https://bugs.gnunet.org/view.php?id=8912 + if (transaction.error != null + && (transaction.txState.major !in listOf(Pending, Aborting) || networkAvailable) + ) { + extraInfoView.text = + context.getString(R.string.payment_error, transaction.error!!.userFacingMsg) + extraInfoView.setTextColor(red) + extraInfoView.visibility = VISIBLE + } } private fun bindAmount(transaction: Transaction) { diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt @@ -59,6 +59,7 @@ class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode. private val model: MainViewModel by activityViewModels() private val transactionManager by lazy { model.transactionManager } private val balanceManager by lazy { model.balanceManager } + private val networkManager by lazy { model.networkManager } private lateinit var ui: FragmentTransactionsBinding private val transactionAdapter by lazy { TransactionAdapter(this) } @@ -122,21 +123,31 @@ class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode. transactionAdapter.setCurrencySpec(balance.available.spec) } } + transactionManager.progress.observe(viewLifecycleOwner) { show -> if (show) ui.progressBar.fadeIn() else ui.progressBar.fadeOut() } + transactionManager.transactions.observe(viewLifecycleOwner) { result -> onTransactionsResult(result) } + + networkManager.networkStatus.observe(viewLifecycleOwner) { state -> + transactionAdapter.update(networkAvailable = state) + } + ui.actionsBar.sendButton.setOnClickListener { findNavController().navigate(R.id.sendFunds) } + ui.actionsBar.receiveButton.setOnClickListener { findNavController().navigate(R.id.action_global_receiveFunds) } + ui.mainFab.setOnClickListener { model.scanCode() } + ui.mainFab.setOnLongClickListener { findNavController().navigate(R.id.action_nav_transactions_to_nav_uri_input) true @@ -205,8 +216,9 @@ class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode. ui.emptyState.fadeIn() ui.list.fadeOut() } else { + val state = networkManager.networkStatus.value ?: true ui.emptyState.fadeOut() - transactionAdapter.update(result.transactions) + transactionAdapter.update(result.transactions, state) ui.list.fadeIn() } } diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml @@ -164,6 +164,7 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card <!-- Payments --> <string name="payment_aborted">Aborted</string> + <string name="payment_aborting">Aborting</string> <string name="payment_already_paid">You\'ve already paid for this purchase.</string> <string name="payment_balance_insufficient">Balance insufficient!</string> <string name="payment_button_confirm">Confirm Payment</string>