From 6734a0fa768a9acbb3193efbfd1bf7c1897877ce Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Fri, 18 Aug 2023 13:49:52 +0200 Subject: [wallet] Improve internal logic of templates --- .../taler/wallet/payment/PayTemplateComposable.kt | 45 +++++++++++---------- .../taler/wallet/payment/PayTemplateFragment.kt | 46 ++++++++++++++++------ wallet/src/main/res/values/strings.xml | 1 + 3 files changed, 59 insertions(+), 33 deletions(-) (limited to 'wallet') 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 3279c71..f9b72f7 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt @@ -31,7 +31,6 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -41,15 +40,13 @@ import androidx.compose.ui.Alignment.Companion.Center import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.fragment.app.Fragment -import androidx.lifecycle.asFlow import net.taler.common.Amount import net.taler.common.AmountParserException -import net.taler.common.showError import net.taler.wallet.AmountResult -import net.taler.wallet.MainViewModel import net.taler.wallet.R +import net.taler.wallet.compose.TalerSurface import net.taler.wallet.deposit.CurrencyDropdown @@ -58,9 +55,10 @@ import net.taler.wallet.deposit.CurrencyDropdown fun PayTemplateComposable( uri: Uri, currencies: List, - fragment: Fragment, - model: MainViewModel, + payStatus: PayStatus, + onCreateAmount: (String, String) -> AmountResult, onSubmit: (Map) -> Unit, + onError: (resId: Int) -> Unit, ) { val queryParams = uri.queryParameterNames @@ -81,9 +79,6 @@ fun PayTemplateComposable( } else null, ) } - val payStatus by model.paymentManager.payStatus.asFlow() - .collectAsState(initial = PayStatus.None) - // If wallet is empty, there's no way the user can pay something if (payStatus is PayStatus.InsufficientBalance || currencies.isEmpty()) { Box( @@ -128,16 +123,16 @@ fun PayTemplateComposable( enabled = summary == null || summary!!.isNotBlank(), onClick = { if (amount != null) { - val result = model.createAmount( + val result = onCreateAmount( amount!!.amountStr, amount!!.currency, ) when (result) { AmountResult.InsufficientBalance -> { - fragment.showError(R.string.payment_balance_insufficient) + onError(R.string.payment_balance_insufficient) } AmountResult.InvalidAmount -> { - fragment.showError(R.string.receive_amount_invalid) + onError(R.string.receive_amount_invalid) } else -> { onSubmit( @@ -218,11 +213,19 @@ private fun AmountField( } } -// TODO cleanup composable -//@Preview -//@Composable -//fun PayTemplateComposablePreview() { -// TalerSurface { -// PayTemplateComposable(Uri.EMPTY, listOf("KUDOS")) -// } -//} +@Preview +@Composable +fun PayTemplateComposablePreview() { + TalerSurface { + PayTemplateComposable( + uri = Uri.parse("taler://pay-template/demo.backend.taler.net/test?amount=KUDOS&summary="), + currencies = listOf("KUDOS", "ARS"), + payStatus = PayStatus.None, + onCreateAmount = { text, currency -> + AmountResult.Success(amount = Amount.fromString(currency, text)) + }, + onSubmit = { }, + onError = { }, + ) + } +} diff --git a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateFragment.kt b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateFragment.kt index 080d319..1812db0 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateFragment.kt @@ -21,14 +21,19 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.platform.ComposeView import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.lifecycle.asFlow import androidx.navigation.NavOptions import androidx.navigation.fragment.findNavController +import net.taler.common.showError import net.taler.wallet.MainViewModel import net.taler.wallet.R import net.taler.wallet.compose.TalerSurface +import net.taler.wallet.showError class PayTemplateFragment : Fragment() { @@ -46,13 +51,19 @@ class PayTemplateFragment : Fragment() { return ComposeView(requireContext()).apply { setContent { + val payStatus by model.paymentManager.payStatus + .asFlow() + .collectAsState(initial = PayStatus.None) TalerSurface { PayTemplateComposable( uri = uri, currencies = model.getCurrencies(), - fragment = this@PayTemplateFragment, - model = model, + payStatus = payStatus, + onCreateAmount = { text, currency -> + model.createAmount(text, currency) + }, onSubmit = { createOrder(it) }, + onError = { this@PayTemplateFragment.showError(it) }, ) } } @@ -66,18 +77,29 @@ class PayTemplateFragment : Fragment() { if (uri.queryParameterNames?.isEmpty() == true) { createOrder(emptyMap()) } - } - private fun createOrder(params: Map) { - model.paymentManager.preparePayForTemplate(uriString, params).invokeOnCompletion { - // TODO maybe better to observe/collect payStatus instead of invokeOnCompletion - // and then only reacting to one of the possible payStatus values - if (model.paymentManager.payStatus.value is PayStatus.Prepared) { - val navOptions = NavOptions.Builder() - .setPopUpTo(R.id.nav_main, true) - .build() - findNavController().navigate(R.id.action_global_promptPayment, null, navOptions) + model.paymentManager.payStatus.observe(viewLifecycleOwner) { payStatus -> + when (payStatus) { + is PayStatus.Prepared -> { + val navOptions = NavOptions.Builder() + .setPopUpTo(R.id.nav_main, true) + .build() + findNavController() + .navigate(R.id.action_global_promptPayment, null, navOptions) + } + is PayStatus.Error -> { + if (model.devMode.value == true) { + showError(payStatus.error) + } else { + showError(R.string.payment_template_error, payStatus.error.userFacingMsg) + } + } + else -> {} } } } + + private fun createOrder(params: Map) { + model.paymentManager.preparePayForTemplate(uriString, params) + } } diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml index 6fa1227..e037055 100644 --- a/wallet/src/main/res/values/strings.xml +++ b/wallet/src/main/res/values/strings.xml @@ -134,6 +134,7 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card Customize your order Create order Confirmation code + Error creating order Amount to receive Amount invalid -- cgit v1.2.3