summaryrefslogtreecommitdiff
path: root/wallet
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2024-01-30 18:55:55 -0600
committerTorsten Grote <t@grobox.de>2024-02-02 15:56:57 -0300
commitf004af7b746a436e7317d5c27f8f261bd7a407f0 (patch)
treef9b4ad5b3fa40d4e53d5dd640439f3ae6bc02de8 /wallet
parent636b11b195cd250b96e7de4bea5fa32fc374d2a2 (diff)
downloadtaler-android-f004af7b746a436e7317d5c27f8f261bd7a407f0.tar.gz
taler-android-f004af7b746a436e7317d5c27f8f261bd7a407f0.tar.bz2
taler-android-f004af7b746a436e7317d5c27f8f261bd7a407f0.zip
[wallet] Redirect to details view after payment, deprecate proposalId, and remove pending op actions
bug 0008297
Diffstat (limited to 'wallet')
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt71
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PaymentResponses.kt19
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt35
-rw-r--r--wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt35
-rw-r--r--wallet/src/main/res/layout/list_item_pending_operation.xml6
-rw-r--r--wallet/src/main/res/navigation/nav_graph.xml4
7 files changed, 81 insertions, 91 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt
index 815f463..e2a8a64 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt
@@ -149,7 +149,7 @@ fun PayTemplateAlreadyPaidPreview() {
PayTemplateComposable(
defaultSummary = "Donation",
amountStatus = AmountFieldStatus.Default("20", "ARS"),
- payStatus = PayStatus.AlreadyPaid,
+ payStatus = PayStatus.AlreadyPaid(transactionId = "transactionId"),
currencies = listOf("KUDOS", "ARS"),
onCreateAmount = { text, currency ->
AmountResult.Success(amount = Amount.fromString(currency, text))
diff --git a/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt b/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt
index 3a3069c..19be280 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt
@@ -41,7 +41,7 @@ sealed class PayStatus {
object Loading : PayStatus()
data class Prepared(
val contractTerms: ContractTerms,
- val proposalId: String,
+ val transactionId: String,
val amountRaw: Amount,
val amountEffective: Amount,
) : PayStatus()
@@ -51,10 +51,18 @@ sealed class PayStatus {
val amountRaw: Amount,
) : PayStatus()
- // TODO bring user to fulfilment URI
- object AlreadyPaid : PayStatus()
- data class Error(val error: TalerErrorInfo) : PayStatus()
- data class Success(val currency: String) : PayStatus()
+ data class AlreadyPaid(
+ val transactionId: String,
+ ) : PayStatus()
+
+ data class Error(
+ val transactionId: String? = null,
+ val error: TalerErrorInfo,
+ ) : PayStatus()
+ data class Success(
+ val transactionId: String,
+ val currency: String,
+ ) : PayStatus()
}
class PaymentManager(
@@ -76,32 +84,33 @@ class PaymentManager(
mPayStatus.value = when (response) {
is PaymentPossibleResponse -> response.toPayStatusPrepared()
is InsufficientBalanceResponse -> InsufficientBalance(
- response.contractTerms,
- response.amountRaw
+ contractTerms = response.contractTerms,
+ amountRaw = response.amountRaw
+ )
+ is AlreadyConfirmedResponse -> AlreadyPaid(
+ transactionId = response.transactionId,
)
-
- is AlreadyConfirmedResponse -> AlreadyPaid
}
}
}
- fun confirmPay(proposalId: String, currency: String) = scope.launch {
+ fun confirmPay(transactionId: String, currency: String) = scope.launch {
api.request("confirmPay", ConfirmPayResult.serializer()) {
- put("proposalId", proposalId)
+ put("transactionId", transactionId)
}.onError {
handleError("confirmPay", it)
- }.onSuccess {
- mPayStatus.postValue(PayStatus.Success(currency))
- }
- }
-
- @UiThread
- fun abortPay() {
- val ps = payStatus.value
- if (ps is PayStatus.Prepared) {
- abortProposal(ps.proposalId)
+ }.onSuccess { response ->
+ mPayStatus.postValue(when (response) {
+ is ConfirmPayResult.Done -> PayStatus.Success(
+ transactionId = response.transactionId,
+ currency = currency,
+ )
+ is ConfirmPayResult.Pending -> PayStatus.Error(
+ transactionId = response.transactionId,
+ error = response.lastError,
+ )
+ })
}
- resetPayStatus()
}
fun preparePayForTemplate(url: String, summary: String?, amount: Amount?) = scope.launch {
@@ -122,23 +131,13 @@ class PaymentManager(
amountRaw = response.amountRaw,
)
- is AlreadyConfirmedResponse -> AlreadyPaid
+ is AlreadyConfirmedResponse -> AlreadyPaid(
+ transactionId = response.transactionId,
+ )
}
}
}
- internal fun abortProposal(proposalId: String) = scope.launch {
- Log.i(TAG, "aborting proposal")
- api.request<Unit>("abortProposal") {
- put("proposalId", proposalId)
- }.onError {
- Log.e(TAG, "received error response to abortProposal")
- handleError("abortProposal", it)
- }.onSuccess {
- mPayStatus.postValue(PayStatus.None)
- }
- }
-
@UiThread
fun resetPayStatus() {
mPayStatus.value = PayStatus.None
@@ -146,7 +145,7 @@ class PaymentManager(
private fun handleError(operation: String, error: TalerErrorInfo) {
Log.e(TAG, "got $operation error result $error")
- mPayStatus.value = PayStatus.Error(error)
+ mPayStatus.value = PayStatus.Error(error = error)
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/payment/PaymentResponses.kt b/wallet/src/main/java/net/taler/wallet/payment/PaymentResponses.kt
index 7e03472..5e97f58 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PaymentResponses.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PaymentResponses.kt
@@ -32,14 +32,14 @@ sealed class PreparePayResponse {
@Serializable
@SerialName("payment-possible")
data class PaymentPossibleResponse(
- val proposalId: String,
+ val transactionId: String,
val amountRaw: Amount,
val amountEffective: Amount,
val contractTerms: ContractTerms,
) : PreparePayResponse() {
fun toPayStatusPrepared() = PayStatus.Prepared(
contractTerms = contractTerms,
- proposalId = proposalId,
+ transactionId = transactionId,
amountRaw = amountRaw,
amountEffective = amountEffective,
)
@@ -48,7 +48,6 @@ sealed class PreparePayResponse {
@Serializable
@SerialName("insufficient-balance")
data class InsufficientBalanceResponse(
- val proposalId: String,
val amountRaw: Amount,
val contractTerms: ContractTerms,
) : PreparePayResponse()
@@ -56,13 +55,13 @@ sealed class PreparePayResponse {
@Serializable
@SerialName("already-confirmed")
data class AlreadyConfirmedResponse(
- val proposalId: String,
+ val transactionId: String,
/**
* Did the payment succeed?
*/
val paid: Boolean,
val amountRaw: Amount,
- val amountEffective: Amount,
+ val amountEffective: Amount? = null,
val contractTerms: ContractTerms,
) : PreparePayResponse()
}
@@ -71,9 +70,15 @@ sealed class PreparePayResponse {
sealed class ConfirmPayResult {
@Serializable
@SerialName("done")
- data class Done(val contractTerms: ContractTerms) : ConfirmPayResult()
+ data class Done(
+ val transactionId: String,
+ val contractTerms: ContractTerms,
+ ) : ConfirmPayResult()
@Serializable
@SerialName("pending")
- data class Pending(val lastError: TalerErrorInfo) : ConfirmPayResult()
+ data class Pending(
+ val transactionId: String,
+ val lastError: TalerErrorInfo,
+ ) : ConfirmPayResult()
}
diff --git a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
index 609adb4..73da394 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
@@ -18,22 +18,27 @@ package net.taler.wallet.payment
import android.graphics.Bitmap
import android.os.Bundle
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
+import kotlinx.coroutines.launch
import net.taler.common.Amount
import net.taler.common.ContractTerms
import net.taler.common.fadeIn
import net.taler.common.fadeOut
+import net.taler.common.showError
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.TAG
import net.taler.wallet.databinding.FragmentPromptPaymentBinding
import net.taler.wallet.showError
@@ -44,6 +49,7 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener {
private val model: MainViewModel by activityViewModels()
private val paymentManager by lazy { model.paymentManager }
+ private val transactionManager by lazy { model.transactionManager }
private lateinit var ui: FragmentPromptPaymentBinding
private val adapter = ProductAdapter(this)
@@ -68,7 +74,15 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener {
override fun onDestroy() {
super.onDestroy()
if (!requireActivity().isChangingConfigurations) {
- paymentManager.abortPay()
+ val payStatus = paymentManager.payStatus.value as? PayStatus.Prepared ?: return
+ transactionManager.abortTransaction(payStatus.transactionId) { error ->
+ Log.e(TAG, "Error abortTransaction $error")
+ if (model.devMode.value == false) {
+ showError(error.userFacingMsg)
+ } else {
+ showError(error)
+ }
+ }
}
}
@@ -92,8 +106,8 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener {
ui.bottom.confirmButton.setOnClickListener {
model.showProgressBar.value = true
paymentManager.confirmPay(
- payStatus.proposalId,
- payStatus.contractTerms.amount.currency
+ transactionId = payStatus.transactionId,
+ currency = payStatus.contractTerms.amount.currency,
)
ui.bottom.confirmButton.fadeOut()
ui.bottom.confirmProgressBar.fadeIn()
@@ -108,14 +122,14 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener {
is PayStatus.Success -> {
showLoading(false)
paymentManager.resetPayStatus()
- findNavController().navigate(R.id.action_promptPayment_to_nav_main)
- model.showTransactions(payStatus.currency)
+ navigateToTransaction(payStatus.transactionId)
Snackbar.make(requireView(), R.string.payment_initiated, LENGTH_LONG).show()
}
is PayStatus.AlreadyPaid -> {
showLoading(false)
paymentManager.resetPayStatus()
- findNavController().navigate(R.id.action_promptPayment_to_alreadyPaid)
+ navigateToTransaction(payStatus.transactionId)
+ Snackbar.make(requireView(), R.string.payment_already_paid, LENGTH_LONG).show()
}
is PayStatus.Error -> {
showLoading(false)
@@ -158,4 +172,13 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener {
f.show(parentFragmentManager, "image")
}
+ private fun navigateToTransaction(id: String) {
+ lifecycleScope.launch {
+ if (transactionManager.selectTransaction(id)) {
+ findNavController().navigate(R.id.action_promptPayment_to_nav_transactions_detail_payment)
+ } else {
+ findNavController().navigate(R.id.action_promptPayment_to_nav_main)
+ }
+ }
+ }
}
diff --git a/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt b/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt
index 6bfcf90..a76a7d1 100644
--- a/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt
@@ -17,14 +17,11 @@
package net.taler.wallet.pending
import android.os.Bundle
-import android.util.Log
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
-import android.view.View.GONE
-import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
@@ -36,13 +33,11 @@ import androidx.recyclerview.widget.RecyclerView
import net.taler.common.showError
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
-import net.taler.wallet.TAG
import net.taler.wallet.databinding.FragmentPendingOperationsBinding
import org.json.JSONObject
interface PendingOperationClickListener {
fun onPendingOperationClick(type: String, detail: JSONObject)
- fun onPendingOperationActionClick(type: String, detail: JSONObject)
}
class PendingOperationsFragment : Fragment(), PendingOperationClickListener {
@@ -113,20 +108,6 @@ class PendingOperationsFragment : Fragment(), PendingOperationClickListener {
override fun onPendingOperationClick(type: String, detail: JSONObject) {
requireActivity().showError("No detail view for $type implemented yet.")
}
-
- override fun onPendingOperationActionClick(type: String, detail: JSONObject) {
- when (type) {
- "proposal-choice" -> {
- Log.v(TAG, "got action click on proposal-choice")
- val proposalId = detail.optString("proposalId", "")
- if (proposalId == "") {
- return
- }
- model.paymentManager.abortProposal(proposalId)
- }
- }
- }
-
}
class PendingOperationsAdapter(
@@ -155,22 +136,6 @@ class PendingOperationsAdapter(
pendingContainer.setOnClickListener {
listener.onPendingOperationClick(p.type, p.detail)
}
- when (p.type) {
- "proposal-choice" -> {
- val btn1 = holder.rowView.findViewById<TextView>(R.id.button_pending_action_1)
- btn1.text = btn1.context.getString(R.string.pending_operations_refuse)
- btn1.visibility = VISIBLE
- btn1.setOnClickListener {
- listener.onPendingOperationActionClick(p.type, p.detail)
- }
- }
- else -> {
- val btn1 = holder.rowView.findViewById<TextView>(R.id.button_pending_action_1)
- btn1.text = btn1.context.getString(R.string.pending_operations_no_action)
- btn1.visibility = GONE
- btn1.setOnClickListener {}
- }
- }
val textView = holder.rowView.findViewById<TextView>(R.id.pending_text)
val subTextView = holder.rowView.findViewById<TextView>(R.id.pending_subtext)
subTextView.text = p.detail.toString(1)
diff --git a/wallet/src/main/res/layout/list_item_pending_operation.xml b/wallet/src/main/res/layout/list_item_pending_operation.xml
index bd606c3..210715c 100644
--- a/wallet/src/main/res/layout/list_item_pending_operation.xml
+++ b/wallet/src/main/res/layout/list_item_pending_operation.xml
@@ -31,12 +31,6 @@
android:textSize="24sp"
tools:text="My Pending Operation" />
- <Button
- android:id="@+id/button_pending_action_1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- tools:text="Cancel Operation" />
-
<TextView
android:id="@+id/pending_subtext"
android:layout_width="wrap_content"
diff --git a/wallet/src/main/res/navigation/nav_graph.xml b/wallet/src/main/res/navigation/nav_graph.xml
index 672bb77..18b9122 100644
--- a/wallet/src/main/res/navigation/nav_graph.xml
+++ b/wallet/src/main/res/navigation/nav_graph.xml
@@ -97,6 +97,10 @@
android:id="@+id/action_promptPayment_to_alreadyPaid"
app:destination="@id/alreadyPaid"
app:popUpTo="@id/nav_main" />
+ <action
+ android:id="@+id/action_promptPayment_to_nav_transactions_detail_payment"
+ app:destination="@id/nav_transactions_detail_payment"
+ app:popUpTo="@id/nav_main" />
</fragment>
<fragment