diff options
author | Torsten Grote <t@grobox.de> | 2023-01-06 11:43:10 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2023-01-06 11:43:10 -0300 |
commit | 905c63242ba6d80caece6c18b2b867cb300bbe7b (patch) | |
tree | 4fa9ac1249c498adba221892077cd1895a38f28e /wallet/src | |
parent | 6f45cd9e9f4e25df5048854cc421178f1cd66a59 (diff) | |
download | taler-android-905c63242ba6d80caece6c18b2b867cb300bbe7b.tar.gz taler-android-905c63242ba6d80caece6c18b2b867cb300bbe7b.tar.bz2 taler-android-905c63242ba6d80caece6c18b2b867cb300bbe7b.zip |
[wallet] Allow to restrict coins to age when withdrawing
#0007352
Diffstat (limited to 'wallet/src')
5 files changed, 104 insertions, 12 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt index 3cd2f49..dbf901a 100644 --- a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt @@ -20,6 +20,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.ArrayAdapter import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController @@ -114,13 +115,18 @@ class PromptWithdrawFragment : Fragment() { } private fun onReceivedDetails(s: ReceivedDetails) { - showContent(s.amountRaw, s.amountEffective, s.exchangeBaseUrl, s.talerWithdrawUri) + showContent(s.amountRaw, s.amountEffective, s.exchangeBaseUrl, s.talerWithdrawUri, + s.ageRestrictionOptions) ui.confirmWithdrawButton.apply { text = getString(R.string.withdraw_button_confirm) setOnClickListener { it.fadeOut() ui.confirmProgressBar.fadeIn() - withdrawManager.acceptWithdrawal() + val ageRestrict = (ui.ageSelector.selectedItem as String?)?.let { age -> + if (age == context.getString(R.string.withdraw_restrict_age_unrestricted)) null + else age.toIntOrNull() + } + withdrawManager.acceptWithdrawal(ageRestrict) } isEnabled = true } @@ -131,6 +137,7 @@ class PromptWithdrawFragment : Fragment() { amountEffective: Amount, exchange: String, uri: String?, + ageRestrictionOptions: List<Int>? = null, ) { model.showProgressBar.value = false ui.progressBar.fadeOut() @@ -160,6 +167,15 @@ class PromptWithdrawFragment : Fragment() { } } + if (ageRestrictionOptions != null) { + ui.ageLabel.fadeIn() + val context = requireContext() + val items = listOf(context.getString(R.string.withdraw_restrict_age_unrestricted)) + + ageRestrictionOptions.map { it.toString() } + ui.ageSelector.adapter = ArrayAdapter(context, R.layout.list_item_age, items) + ui.ageSelector.fadeIn() + } + ui.withdrawCard.fadeIn() } diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt index 6fdc916..1698a10 100644 --- a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt +++ b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt @@ -44,6 +44,7 @@ sealed class WithdrawStatus { val exchangeBaseUrl: String, val amountRaw: Amount, val amountEffective: Amount, + val ageRestrictionOptions: List<Int>? = null, val tosText: String, val tosEtag: String, val showImmediately: Event<Boolean>, @@ -54,11 +55,12 @@ sealed class WithdrawStatus { val exchangeBaseUrl: String, val amountRaw: Amount, val amountEffective: Amount, + val ageRestrictionOptions: List<Int>? = null, ) : WithdrawStatus() object Withdrawing : WithdrawStatus() data class Success(val currency: String) : WithdrawStatus() - sealed class ManualTransferRequired: WithdrawStatus() { + sealed class ManualTransferRequired : WithdrawStatus() { abstract val uri: Uri abstract val transactionId: String? } @@ -103,6 +105,7 @@ data class WithdrawalDetails( val tosAccepted: Boolean, val amountRaw: Amount, val amountEffective: Amount, + val ageRestrictionOptions: List<Int>? = null, ) @Serializable @@ -152,9 +155,12 @@ class WithdrawManager( if (details.defaultExchangeBaseUrl == null) { val exchangeSelection = ExchangeSelection(details.amount, uri) withdrawStatus.value = WithdrawStatus.NeedsExchange(exchangeSelection.toEvent()) - } else { - getWithdrawalDetails(details.defaultExchangeBaseUrl, details.amount, false, uri) - } + } else getWithdrawalDetails( + exchangeBaseUrl = details.defaultExchangeBaseUrl, + amount = details.amount, + showTosImmediately = false, + uri = uri, + ) } } @@ -177,6 +183,7 @@ class WithdrawManager( exchangeBaseUrl = exchangeBaseUrl, amountRaw = details.amountRaw, amountEffective = details.amountEffective, + ageRestrictionOptions = details.ageRestrictionOptions, ) } else getExchangeTos(exchangeBaseUrl, details, showTosImmediately, uri) } @@ -198,6 +205,7 @@ class WithdrawManager( exchangeBaseUrl = exchangeBaseUrl, amountRaw = details.amountRaw, amountEffective = details.amountEffective, + ageRestrictionOptions = details.ageRestrictionOptions, tosText = it.content, tosEtag = it.currentEtag, showImmediately = showImmediately.toEvent(), @@ -221,23 +229,28 @@ class WithdrawManager( exchangeBaseUrl = s.exchangeBaseUrl, amountRaw = s.amountRaw, amountEffective = s.amountEffective, + ageRestrictionOptions = s.ageRestrictionOptions, ) } } @UiThread - fun acceptWithdrawal() = scope.launch { + fun acceptWithdrawal(restrictAge: Int? = null) = scope.launch { val status = withdrawStatus.value as ReceivedDetails withdrawStatus.value = WithdrawStatus.Withdrawing if (status.talerWithdrawUri == null) { - acceptManualWithdrawal(status) + acceptManualWithdrawal(status, restrictAge) } else { - acceptBankIntegratedWithdrawal(status) + acceptBankIntegratedWithdrawal(status, restrictAge) } } - private suspend fun acceptBankIntegratedWithdrawal(status: ReceivedDetails) { + private suspend fun acceptBankIntegratedWithdrawal( + status: ReceivedDetails, + restrictAge: Int? = null, + ) { api.request<Unit>("acceptBankIntegratedWithdrawal") { + restrictAge?.let { put("restrictAge", restrictAge) } put("exchangeBaseUrl", status.exchangeBaseUrl) put("talerWithdrawUri", status.talerWithdrawUri) }.onError { @@ -247,8 +260,9 @@ class WithdrawManager( } } - private suspend fun acceptManualWithdrawal(status: ReceivedDetails) { + private suspend fun acceptManualWithdrawal(status: ReceivedDetails, restrictAge: Int? = null) { api.request("acceptManualWithdrawal", AcceptManualWithdrawalResponse.serializer()) { + restrictAge?.let { put("restrictAge", restrictAge) } put("exchangeBaseUrl", status.exchangeBaseUrl) put("amount", status.amountRaw.toJSONString()) }.onError { diff --git a/wallet/src/main/res/layout/fragment_prompt_withdraw.xml b/wallet/src/main/res/layout/fragment_prompt_withdraw.xml index 372163b..03e7d1a 100644 --- a/wallet/src/main/res/layout/fragment_prompt_withdraw.xml +++ b/wallet/src/main/res/layout/fragment_prompt_withdraw.xml @@ -152,7 +152,7 @@ android:textSize="24sp" android:visibility="invisible" app:layout_constrainedWidth="true" - app:layout_constraintBottom_toTopOf="@+id/withdrawCard" + app:layout_constraintBottom_toTopOf="@+id/ageLabel" app:layout_constraintEnd_toStartOf="@+id/selectExchangeButton" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintStart_toStartOf="parent" @@ -176,6 +176,40 @@ app:tint="?attr/colorOnPrimary" tools:visibility="visible" /> + <TextView + android:id="@+id/ageLabel" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="32dp" + android:layout_marginEnd="16dp" + android:gravity="center" + android:text="@string/withdraw_restrict_age" + android:visibility="invisible" + app:layout_constraintBottom_toTopOf="@+id/ageSelector" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/withdrawExchangeUrl" + tools:visibility="visible" /> + + <Spinner + android:id="@+id/ageSelector" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + android:gravity="center" + android:spinnerMode="dropdown" + android:textSize="20sp" + android:visibility="invisible" + app:layout_constraintBottom_toTopOf="@+id/withdrawCard" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/ageLabel" + tools:visibility="visible" /> + <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleLarge" diff --git a/wallet/src/main/res/layout/list_item_age.xml b/wallet/src/main/res/layout/list_item_age.xml new file mode 100644 index 0000000..2d3a6e5 --- /dev/null +++ b/wallet/src/main/res/layout/list_item_age.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ This file is part of GNU Taler + ~ (C) 2023 Taler Systems S.A. + ~ + ~ GNU Taler is free software; you can redistribute it and/or modify it under the + ~ terms of the GNU General Public License as published by the Free Software + ~ Foundation; either version 3, or (at your option) any later version. + ~ + ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + ~ A PARTICULAR PURPOSE. See the GNU General Public License for more details. + ~ + ~ You should have received a copy of the GNU General Public License along with + ~ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + --> + +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@android:id/text1" + style="?android:attr/spinnerItemStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:padding="8dp" + android:singleLine="true" + android:textAlignment="inherit" + android:textSize="20sp" /> diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml index eb15021..0595fa0 100644 --- a/wallet/src/main/res/values/strings.xml +++ b/wallet/src/main/res/values/strings.xml @@ -156,6 +156,8 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card <string name="withdraw_title">Withdrawal</string> <string name="withdraw_total">Withdraw</string> <string name="withdraw_fees">Fee</string> + <string name="withdraw_restrict_age">Restrict Usage to Age</string> + <string name="withdraw_restrict_age_unrestricted">Unrestricted</string> <string name="withdraw_exchange">Exchange</string> <string name="withdraw_button_confirm">Confirm Withdraw</string> <string name="withdraw_button_confirm_bank">Confirm with bank</string> |