summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2024-03-20 13:08:22 -0600
committerTorsten Grote <t@grobox.de>2024-03-27 14:26:47 -0300
commit0b91663b223688b92d5128e7969a5453ce6618d5 (patch)
tree9e4b5a5e41999b3f7ba298ca0a5cc214f94fe9b1
parent945620bf15b4c7007b4bf1a63d07578a2283bcf5 (diff)
downloadtaler-android-0b91663b223688b92d5128e7969a5453ce6618d5.tar.gz
taler-android-0b91663b223688b92d5128e7969a5453ce6618d5.tar.bz2
taler-android-0b91663b223688b92d5128e7969a5453ce6618d5.zip
[wallet] DD51'd more views, UX improvements and some fixes
(cherry picked from commit 0498e424a0bdcf8ffe74419a2ad42ade9283d08f)
-rw-r--r--wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt14
-rw-r--r--wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt16
-rw-r--r--wallet/src/main/java/net/taler/wallet/balances/BalanceManager.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt7
-rw-r--r--wallet/src/main/java/net/taler/wallet/deposit/DepositFragment.kt11
-rw-r--r--wallet/src/main/java/net/taler/wallet/deposit/MakeDepositComposable.kt4
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/OutgoingPullComposable.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt10
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/OutgoingPushComposable.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt9
-rw-r--r--wallet/src/main/res/navigation/nav_graph.xml14
-rw-r--r--wallet/src/main/res/values/strings.xml2
12 files changed, 74 insertions, 19 deletions
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
@@ -134,6 +134,10 @@
app:argType="string"
app:nullable="false" />
<argument
+ android:name="scopeInfo"
+ app:argType="string"
+ app:nullable="true" />
+ <argument
android:name="IBAN"
android:defaultValue="@null"
app:argType="string"
@@ -158,6 +162,11 @@
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
+ <argument
+ android:name="scopeInfo"
+ android:defaultValue="@null"
+ app:argType="string"
+ app:nullable="true" />
<action
android:id="@+id/action_nav_peer_pull_to_nav_main"
app:destination="@id/nav_main"
@@ -177,6 +186,11 @@
android:defaultValue="@null"
app:argType="string"
app:nullable="true" />
+ <argument
+ android:name="scopeInfo"
+ android:defaultValue="@null"
+ app:argType="string"
+ app:nullable="true" />
<action
android:id="@+id/action_nav_peer_push_to_nav_main"
app:destination="@id/nav_main"
diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml
index 82a67b6..2ec3d40 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -87,7 +87,9 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card
<string name="transactions_title">Transactions</string>
<string name="transactions_balance">Balance</string>
<string name="transactions_send_funds">Send\nFunds</string>
+ <string name="transactions_send_funds_title">Send %1$s</string>
<string name="transactions_receive_funds">Receive\nFunds</string>
+ <string name="transactions_receive_funds_title">Receive %1$s</string>
<string name="transactions_empty">You don\'t have any transactions</string>
<string name="transactions_empty_search">No transactions found. Try a different search.</string>
<string name="transactions_error">Could not load transactions\n\n%s</string>