aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2022-08-17 15:40:16 -0300
committerTorsten Grote <t@grobox.de>2022-08-17 15:40:16 -0300
commitd1163e31e904ac59d0739169257a8e3fdc7986a7 (patch)
tree44dfc439444d0ed5e004147c79b3dcf6ff0b5efb
parent326b1bdf62a687aa40d32994c14c792fcbf113fc (diff)
downloadtaler-android-d1163e31e904ac59d0739169257a8e3fdc7986a7.tar.gz
taler-android-d1163e31e904ac59d0739169257a8e3fdc7986a7.tar.bz2
taler-android-d1163e31e904ac59d0739169257a8e3fdc7986a7.zip
[wallet] Add ability to cancel/delete transactions
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt31
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt10
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt7
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt9
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt7
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt66
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt7
-rw-r--r--wallet/src/main/res/layout/fragment_transaction_payment.xml14
-rw-r--r--wallet/src/main/res/layout/fragment_transaction_withdrawal.xml14
-rw-r--r--wallet/src/main/res/values/strings.xml3
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>