taler-android

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

commit 5ed6fcff76bd3c6edb4ef5a9fd7ceba2df38e42d
parent 9ce92c84f10b5fd818225bf02c40495b5982ac73
Author: Iván Ávalos <avalos@disroot.org>
Date:   Tue, 10 Mar 2026 09:06:18 +0100

[wallet] improvements to onboarding flow

Diffstat:
Mwallet/src/main/java/net/taler/wallet/balances/EmptyBalancesComposable.kt | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mwallet/src/main/java/net/taler/wallet/compose/WarningLabel.kt | 33++++++++++++++++++++++++---------
Mwallet/src/main/java/net/taler/wallet/transfer/ScreenTransfer.kt | 13+++++++++++++
Mwallet/src/main/java/net/taler/wallet/transfer/TransferIBAN.kt | 27++++++++++++++++++++++++++-
Mwallet/src/main/res/values/strings.xml | 2+-
5 files changed, 117 insertions(+), 19 deletions(-)

diff --git a/wallet/src/main/java/net/taler/wallet/balances/EmptyBalancesComposable.kt b/wallet/src/main/java/net/taler/wallet/balances/EmptyBalancesComposable.kt @@ -29,22 +29,31 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import net.taler.wallet.R import net.taler.wallet.compose.Material3MenuGroup import net.taler.wallet.compose.Material3MenuItemData +import net.taler.wallet.compose.TalerSurface @Composable fun EmptyBalancesComposable( @@ -53,6 +62,10 @@ fun EmptyBalancesComposable( onWithdrawMoneyClicked: () -> Unit, onGetDemoMoneyClicked: () -> Unit, ) { + var loadingWithdraw by remember { mutableStateOf(false) } + var loadingDemo by remember { mutableStateOf(false) } + val enabled = networkStatus && !loadingWithdraw && !loadingDemo + LazyColumn ( modifier = Modifier .padding(innerPadding) @@ -97,11 +110,21 @@ fun EmptyBalancesComposable( Spacer(Modifier.height(6.dp)) Button( modifier = Modifier.fillMaxWidth(), - onClick = onWithdrawMoneyClicked, - enabled = networkStatus, + onClick = { + loadingWithdraw = true + onWithdrawMoneyClicked() + + }, + enabled = enabled, ) { - Text( - color = MaterialTheme.colorScheme.onPrimary, + if (loadingWithdraw) { + CircularProgressIndicator(Modifier.size(15.dp)) + } else Text( + color = if (enabled) { + ButtonDefaults.buttonColors().contentColor + } else { + ButtonDefaults.buttonColors().disabledContentColor + }, text = stringResource(R.string.balances_empty_withdraw_chf_button), ) } @@ -124,11 +147,20 @@ fun EmptyBalancesComposable( Spacer(Modifier.height(6.dp)) Button( modifier = Modifier.fillMaxWidth(), - onClick = onGetDemoMoneyClicked, - enabled = networkStatus, + onClick = { + loadingDemo = true + onGetDemoMoneyClicked() + }, + enabled = networkStatus && !(loadingWithdraw || loadingDemo), ) { - Text( - color = MaterialTheme.colorScheme.onPrimary, + if (loadingDemo) { + CircularProgressIndicator(Modifier.size(15.dp)) + } else Text( + color = if (enabled) { + ButtonDefaults.buttonColors().contentColor + } else { + ButtonDefaults.buttonColors().disabledContentColor + }, text = stringResource(R.string.balances_empty_withdraw_kudos_button), ) } @@ -139,4 +171,17 @@ fun EmptyBalancesComposable( }) } } +} + +@Preview +@Composable +fun EmptyBalancesComposablePreview() { + TalerSurface { + EmptyBalancesComposable ( + innerPadding = PaddingValues(0.dp), + networkStatus = false, + onWithdrawMoneyClicked = {}, + onGetDemoMoneyClicked = {}, + ) + } } \ No newline at end of file diff --git a/wallet/src/main/java/net/taler/wallet/compose/WarningLabel.kt b/wallet/src/main/java/net/taler/wallet/compose/WarningLabel.kt @@ -19,10 +19,15 @@ package net.taler.wallet.compose import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Warning +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.colorResource import androidx.compose.ui.unit.dp @@ -33,13 +38,23 @@ fun WarningLabel( label: String, modifier: Modifier = Modifier, ) { - Text( - text = label, - style = MaterialTheme.typography.bodyMedium, - color = colorResource(R.color.notice_text), - modifier = modifier - .background(colorResource(R.color.notice_background)) - .border(BorderStroke(2.dp, colorResource(R.color.notice_border))) - .padding(all = 16.dp) - ) + Row (modifier + .background(colorResource(R.color.notice_background)) + .border(BorderStroke(2.dp, colorResource(R.color.notice_border))) + .padding(all = 16.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + Icons.Outlined.Warning, + contentDescription = null, + modifier = Modifier.padding(end = 10.dp), + tint = colorResource(R.color.notice_text), + ) + + Text( + text = label, + style = MaterialTheme.typography.bodyMedium, + color = colorResource(R.color.notice_text), + ) + } } \ No newline at end of file diff --git a/wallet/src/main/java/net/taler/wallet/transfer/ScreenTransfer.kt b/wallet/src/main/java/net/taler/wallet/transfer/ScreenTransfer.kt @@ -62,6 +62,7 @@ import net.taler.common.canAppHandleUri import net.taler.common.copyToClipBoard import net.taler.wallet.BottomInsetsSpacer import net.taler.wallet.compose.ShareButton +import net.taler.wallet.transactions.AccountRestriction import net.taler.wallet.transactions.AmountType import net.taler.wallet.transactions.TransactionAmountComposable import net.taler.wallet.transactions.WithdrawalExchangeAccountDetails @@ -379,6 +380,18 @@ fun ScreenTransferPreview( numFractionalTrailingZeroDigits = 2, altUnitNames = emptyMap(), ), + creditRestrictions = listOf( + AccountRestriction.RegexAccount( + paytoRegex = "CH", + humanHint = "Only Swiss bank accounts", + humanHintI18n = emptyMap(), + ), + AccountRestriction.RegexAccount( + paytoRegex = "DE", + humanHint = "Only European bank accounts", + humanHintI18n = emptyMap(), + ) + ) ), ), TransferData.Cyclos( diff --git a/wallet/src/main/java/net/taler/wallet/transfer/TransferIBAN.kt b/wallet/src/main/java/net/taler/wallet/transfer/TransferIBAN.kt @@ -17,6 +17,8 @@ package net.taler.wallet.transfer import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme @@ -27,12 +29,15 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import net.taler.common.Amount +import net.taler.common.TalerUtils import net.taler.wallet.R import net.taler.wallet.accounts.PaytoUri import net.taler.wallet.accounts.PaytoUriIban import net.taler.wallet.compose.WarningLabel +import net.taler.wallet.transactions.AccountRestriction +import net.taler.wallet.transfer.TransferContext.DepositKycAuth +import net.taler.wallet.transfer.TransferContext.ManualWithdrawal import net.taler.wallet.withdraw.TransferData -import net.taler.wallet.transfer.TransferContext.* @Composable fun TransferIBAN( @@ -67,6 +72,26 @@ fun TransferIBAN( .padding(vertical = 8.dp) ) + Spacer(Modifier.padding(4.dp)) + + transfer.withdrawalAccount.creditRestrictions?.forEach { restriction -> + when (restriction) { + is AccountRestriction.RegexAccount -> { + WarningLabel ( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp), + label = TalerUtils.getLocalizedString( + restriction.humanHintI18n, + restriction.humanHint, + ) + ) + } + + else -> {} + } + } + if (transferContext is DepositKycAuth) { WarningLabel( modifier = Modifier.padding( diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml @@ -144,7 +144,7 @@ GNU Taler is immune to many types of fraud such as credit card data theft, phish <string name="balances_empty_withdraw_chf_title">Welcome to Taler Wallet!</string> <string name="balances_empty_withdraw_chf_message">To make your first payment, withdraw digital cash.</string> <string name="balances_empty_withdraw_chf_button">Withdraw CHF</string> - <string name="balances_empty_withdraw_kudos_message">Get demo cash to experience how to pay with the money of the future.</string> + <string name="balances_empty_withdraw_kudos_message">Get demo cash to experience how to pay with digital cash.</string> <string name="balances_empty_withdraw_kudos_button">Get demo cash</string> <string name="balances_inbound_amount">+%1$s incoming</string> <string name="balances_outbound_amount">-%1$s outgoing</string>