From 0b91663b223688b92d5128e7969a5453ce6618d5 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Wed, 20 Mar 2024 13:08:22 -0600 Subject: [wallet] DD51'd more views, UX improvements and some fixes (cherry picked from commit 0498e424a0bdcf8ffe74419a2ad42ade9283d08f) --- .../main/java/net/taler/wallet/ReceiveFundsFragment.kt | 14 +++++++++----- .../src/main/java/net/taler/wallet/SendFundsFragment.kt | 16 ++++++++++++---- .../java/net/taler/wallet/balances/BalanceManager.kt | 2 +- .../java/net/taler/wallet/compose/AmountInputField.kt | 7 ++++++- .../java/net/taler/wallet/deposit/DepositFragment.kt | 11 +++++++++-- .../net/taler/wallet/deposit/MakeDepositComposable.kt | 4 ++-- .../java/net/taler/wallet/peer/OutgoingPullComposable.kt | 2 +- .../java/net/taler/wallet/peer/OutgoingPullFragment.kt | 10 +++++++++- .../java/net/taler/wallet/peer/OutgoingPushComposable.kt | 2 +- .../java/net/taler/wallet/peer/OutgoingPushFragment.kt | 9 ++++++++- wallet/src/main/res/navigation/nav_graph.xml | 14 ++++++++++++++ wallet/src/main/res/values/strings.xml | 2 ++ 12 files changed, 74 insertions(+), 19 deletions(-) (limited to 'wallet/src/main') diff --git a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt index 0aaae93..4da06e2 100644 --- a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt @@ -50,6 +50,8 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import net.taler.common.Amount import net.taler.common.CurrencySpecification import net.taler.wallet.compose.AmountInputField @@ -63,7 +65,7 @@ class ReceiveFundsFragment : Fragment() { private val withdrawManager get() = model.withdrawManager private val balanceManager get() = model.balanceManager private val peerManager get() = model.peerManager - + private val scopeInfo get() = model.transactionManager.selectedScope ?: error("No scope selected") override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -71,10 +73,9 @@ class ReceiveFundsFragment : Fragment() { ): View = ComposeView(requireContext()).apply { setContent { TalerSurface { - val scopeInfo = model.transactionManager.selectedScope ?: error("No scope selected") ReceiveFundsIntro( scopeInfo.currency, - model.balanceManager.getSpecForScopeInfo(scopeInfo), + balanceManager.getSpecForScopeInfo(scopeInfo), this@ReceiveFundsFragment::onManualWithdraw, this@ReceiveFundsFragment::onPeerPull, ) @@ -84,7 +85,7 @@ class ReceiveFundsFragment : Fragment() { override fun onStart() { super.onStart() - activity?.setTitle(R.string.transactions_receive_funds) + activity?.setTitle(getString(R.string.transactions_receive_funds_title, scopeInfo.currency)) } private fun onManualWithdraw(amount: Amount) { @@ -110,7 +111,10 @@ class ReceiveFundsFragment : Fragment() { } private fun onPeerPull(amount: Amount) { - val bundle = bundleOf("amount" to amount.toJSONString()) + val bundle = bundleOf( + "amount" to amount.toJSONString(), + "scopeInfo" to Json.encodeToString(scopeInfo), + ) peerManager.checkPeerPullCredit(amount) findNavController().navigate(R.id.action_receiveFunds_to_nav_peer_pull, bundle) } diff --git a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt index c43c5f8..d6d2034 100644 --- a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt @@ -47,6 +47,8 @@ import androidx.core.os.bundleOf import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import net.taler.common.Amount import net.taler.common.CurrencySpecification import net.taler.wallet.compose.AmountInputField @@ -57,6 +59,7 @@ class SendFundsFragment : Fragment() { private val model: MainViewModel by activityViewModels() private val balanceManager get() = model.balanceManager private val peerManager get() = model.peerManager + private val scopeInfo get() = model.transactionManager.selectedScope ?: error("No scope selected") override fun onCreateView( inflater: LayoutInflater, @@ -65,7 +68,6 @@ class SendFundsFragment : Fragment() { ): View = ComposeView(requireContext()).apply { setContent { TalerSurface { - val scopeInfo = model.transactionManager.selectedScope ?: error("No scope selected") SendFundsIntro( currency = scopeInfo.currency, spec = balanceManager.getSpecForScopeInfo(scopeInfo), @@ -79,16 +81,22 @@ class SendFundsFragment : Fragment() { override fun onStart() { super.onStart() - activity?.setTitle(R.string.transactions_send_funds) + activity?.setTitle(getString(R.string.transactions_send_funds_title, scopeInfo.currency)) } private fun onDeposit(amount: Amount) { - val bundle = bundleOf("amount" to amount.toJSONString()) + val bundle = bundleOf( + "amount" to amount.toJSONString(), + "scopeInfo" to Json.encodeToString(scopeInfo), + ) findNavController().navigate(R.id.action_sendFunds_to_nav_deposit, bundle) } private fun onPeerPush(amount: Amount) { - val bundle = bundleOf("amount" to amount.toJSONString()) + val bundle = bundleOf( + "amount" to amount.toJSONString(), + "scopeInfo" to Json.encodeToString(scopeInfo), + ) peerManager.checkPeerPushDebit(amount) findNavController().navigate(R.id.action_sendFunds_to_nav_peer_push, bundle) } diff --git a/wallet/src/main/java/net/taler/wallet/balances/BalanceManager.kt b/wallet/src/main/java/net/taler/wallet/balances/BalanceManager.kt index 4448490..42e67cf 100644 --- a/wallet/src/main/java/net/taler/wallet/balances/BalanceManager.kt +++ b/wallet/src/main/java/net/taler/wallet/balances/BalanceManager.kt @@ -77,7 +77,7 @@ class BalanceManager( mState.postValue(BalanceState.Error(it)) } response.onSuccess { - mState.postValue(BalanceState.Success(it.balances)) + mBalances.postValue(it.balances) scope.launch { // Fetch missing currency specs for all balances it.balances.forEach { balance -> diff --git a/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt b/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt index 3d1d284..a524d1b 100644 --- a/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt +++ b/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt @@ -148,7 +148,12 @@ private class AmountInputVisualTransformation( } } - val formattedNumber = intPart + decimalSeparator + fractionPart + // Hide trailing decimal separator if decimals are 0 + val formattedNumber = if (numberOfDecimals > 0) { + intPart + decimalSeparator + fractionPart + } else { + intPart + } val newText = AnnotatedString( text = formattedNumber, diff --git a/wallet/src/main/java/net/taler/wallet/deposit/DepositFragment.kt b/wallet/src/main/java/net/taler/wallet/deposit/DepositFragment.kt index 28dcc3f..08e4180 100644 --- a/wallet/src/main/java/net/taler/wallet/deposit/DepositFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/deposit/DepositFragment.kt @@ -25,11 +25,13 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController +import kotlinx.serialization.json.Json import net.taler.common.Amount import net.taler.common.showError import net.taler.wallet.CURRENCY_BTC import net.taler.wallet.MainViewModel import net.taler.wallet.R +import net.taler.wallet.balances.ScopeInfo import net.taler.wallet.compose.TalerSurface import net.taler.wallet.compose.collectAsStateLifecycleAware import net.taler.wallet.showError @@ -37,6 +39,7 @@ import net.taler.wallet.showError class DepositFragment : Fragment() { private val model: MainViewModel by activityViewModels() private val depositManager get() = model.depositManager + private val balanceManager get() = model.balanceManager override fun onCreateView( inflater: LayoutInflater, @@ -46,6 +49,10 @@ class DepositFragment : Fragment() { val amount = arguments?.getString("amount")?.let { Amount.fromJSONString(it) } ?: error("no amount passed") + val scopeInfo: ScopeInfo? = arguments?.getString("scopeInfo")?.let { + Json.decodeFromString(it) + } + val spec = scopeInfo?.let { balanceManager.getSpecForScopeInfo(it) } val receiverName = arguments?.getString("receiverName") val iban = arguments?.getString("IBAN") if (receiverName != null && iban != null) { @@ -57,14 +64,14 @@ class DepositFragment : Fragment() { val state = depositManager.depositState.collectAsStateLifecycleAware() if (amount.currency == CURRENCY_BTC) MakeBitcoinDepositComposable( state = state.value, - amount = amount, + amount = amount.withSpec(spec), bitcoinAddress = null, onMakeDeposit = { amount, bitcoinAddress -> depositManager.onDepositButtonClicked(amount, bitcoinAddress) }, ) else MakeDepositComposable( state = state.value, - amount = amount, + amount = amount.withSpec(spec), presetName = receiverName, presetIban = iban, onMakeDeposit = this@DepositFragment::onDepositButtonClicked, diff --git a/wallet/src/main/java/net/taler/wallet/deposit/MakeDepositComposable.kt b/wallet/src/main/java/net/taler/wallet/deposit/MakeDepositComposable.kt index 97e2eb0..9333ce1 100644 --- a/wallet/src/main/java/net/taler/wallet/deposit/MakeDepositComposable.kt +++ b/wallet/src/main/java/net/taler/wallet/deposit/MakeDepositComposable.kt @@ -138,13 +138,13 @@ fun MakeDepositComposable( TransactionAmountComposable( label = stringResource(R.string.withdraw_fees), - amount = fee, + amount = fee.withSpec(amount.spec), amountType = if (fee.isZero()) Positive else Negative, ) TransactionAmountComposable( label = stringResource(R.string.send_amount), - amount = effectiveAmount, + amount = effectiveAmount.withSpec(amount.spec), amountType = Positive, ) } diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullComposable.kt b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullComposable.kt index d58b0b8..90b520e 100644 --- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullComposable.kt +++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullComposable.kt @@ -152,7 +152,7 @@ fun OutgoingPullIntroComposable( val fee = state.amountRaw - state.amountEffective if (!fee.isZero()) TransactionAmountComposable( label = stringResource(id = R.string.withdraw_fees), - amount = fee, + amount = fee.withSpec(amount.spec), amountType = AmountType.Negative, ) } diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt index 0205ae0..b61707e 100644 --- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt @@ -28,9 +28,11 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.fragment.findNavController import kotlinx.coroutines.launch +import kotlinx.serialization.json.Json import net.taler.common.Amount import net.taler.wallet.MainViewModel import net.taler.wallet.R +import net.taler.wallet.balances.ScopeInfo import net.taler.wallet.compose.TalerSurface import net.taler.wallet.compose.collectAsStateLifecycleAware import net.taler.wallet.exchanges.ExchangeItem @@ -40,6 +42,7 @@ class OutgoingPullFragment : Fragment() { private val model: MainViewModel by activityViewModels() private val peerManager get() = model.peerManager private val transactionManager get() = model.transactionManager + private val balanceManager get() = model.balanceManager override fun onCreateView( inflater: LayoutInflater, @@ -49,12 +52,17 @@ class OutgoingPullFragment : Fragment() { val amount = arguments?.getString("amount")?.let { Amount.fromJSONString(it) } ?: error("no amount passed") + val scopeInfo: ScopeInfo? = arguments?.getString("scopeInfo")?.let { + Json.decodeFromString(it) + } + val spec = scopeInfo?.let { balanceManager.getSpecForScopeInfo(it) } + return ComposeView(requireContext()).apply { setContent { TalerSurface { val state = peerManager.pullState.collectAsStateLifecycleAware().value OutgoingPullComposable( - amount = amount, + amount = amount.withSpec(spec), state = state, onCreateInvoice = this@OutgoingPullFragment::onCreateInvoice, onClose = { diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushComposable.kt b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushComposable.kt index ea303d0..d39fdc8 100644 --- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushComposable.kt +++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushComposable.kt @@ -93,7 +93,7 @@ fun OutgoingPushIntroComposable( val fee = state.amountEffective - state.amountRaw Text( modifier = Modifier.padding(vertical = 16.dp), - text = stringResource(id = R.string.payment_fee, fee), + text = stringResource(id = R.string.payment_fee, fee.withSpec(amount.spec)), softWrap = false, color = MaterialTheme.colorScheme.error, ) diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt index 97dbcc2..ebf10db 100644 --- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt @@ -30,9 +30,11 @@ import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController import kotlinx.coroutines.launch +import kotlinx.serialization.json.Json import net.taler.common.Amount import net.taler.wallet.MainViewModel import net.taler.wallet.R +import net.taler.wallet.balances.ScopeInfo import net.taler.wallet.compose.TalerSurface import net.taler.wallet.compose.collectAsStateLifecycleAware import net.taler.wallet.showError @@ -41,6 +43,7 @@ class OutgoingPushFragment : Fragment() { private val model: MainViewModel by activityViewModels() private val peerManager get() = model.peerManager private val transactionManager get() = model.transactionManager + private val balanceManager get() = model.balanceManager // hacky way to change back action until we have navigation for compose private val backPressedCallback = object : OnBackPressedCallback(false) { @@ -57,6 +60,10 @@ class OutgoingPushFragment : Fragment() { val amount = arguments?.getString("amount")?.let { Amount.fromJSONString(it) } ?: error("no amount passed") + val scopeInfo: ScopeInfo? = arguments?.getString("scopeInfo")?.let { + Json.decodeFromString(it) + } + val spec = scopeInfo?.let { balanceManager.getSpecForScopeInfo(it) } requireActivity().onBackPressedDispatcher.addCallback( viewLifecycleOwner, backPressedCallback @@ -67,7 +74,7 @@ class OutgoingPushFragment : Fragment() { TalerSurface { val state = peerManager.pushState.collectAsStateLifecycleAware().value OutgoingPushComposable( - amount = amount, + amount = amount.withSpec(spec), state = state, onSend = this@OutgoingPushFragment::onSend, onClose = { diff --git a/wallet/src/main/res/navigation/nav_graph.xml b/wallet/src/main/res/navigation/nav_graph.xml index a968365..c48d93d 100644 --- a/wallet/src/main/res/navigation/nav_graph.xml +++ b/wallet/src/main/res/navigation/nav_graph.xml @@ -133,6 +133,10 @@ android:name="amount" app:argType="string" app:nullable="false" /> + + + Transactions Balance Send\nFunds + Send %1$s Receive\nFunds + Receive %1$s You don\'t have any transactions No transactions found. Try a different search. Could not load transactions\n\n%s -- cgit v1.2.3