summaryrefslogtreecommitdiff
path: root/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'wallet')
-rw-r--r--wallet/build.gradle6
-rw-r--r--wallet/src/main/java/net/taler/wallet/HandleUriFragment.kt1
-rw-r--r--wallet/src/main/java/net/taler/wallet/MainActivity.kt1
-rw-r--r--wallet/src/main/java/net/taler/wallet/MainViewModel.kt8
-rw-r--r--wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt4
-rw-r--r--wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt4
-rw-r--r--wallet/src/main/java/net/taler/wallet/balances/BalanceAdapter.kt17
-rw-r--r--wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/deposit/MakeBitcoinDepositComposable.kt18
-rw-r--r--wallet/src/main/java/net/taler/wallet/deposit/MakeDepositComposable.kt16
-rw-r--r--wallet/src/main/java/net/taler/wallet/deposit/PayToUriFragment.kt4
-rw-r--r--wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt6
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt61
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PayTemplateDetails.kt126
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PayTemplateFragment.kt43
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PayTemplateOrderComposable.kt110
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt39
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt1
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt6
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/IncomingComposable.kt32
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/OutgoingPullComposable.kt6
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/OutgoingPushComposable.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullCredit.kt8
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullDebit.kt6
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushCredit.kt6
-rw-r--r--wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushDebit.kt6
-rw-r--r--wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt6
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionLossFragment.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt11
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt16
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt4
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt20
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawFragment.kt8
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenTransfer.kt22
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferIBAN.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferTaler.kt2
-rw-r--r--wallet/src/main/res/drawable/badge.xml26
-rw-r--r--wallet/src/main/res/drawable/ic_funds_receive.xml5
-rw-r--r--wallet/src/main/res/drawable/ic_funds_send.xml5
-rw-r--r--wallet/src/main/res/drawable/ic_sync.xml9
-rw-r--r--wallet/src/main/res/drawable/pending_border.xml31
-rw-r--r--wallet/src/main/res/drawable/transaction_tip_accepted.xml26
-rw-r--r--wallet/src/main/res/layout-w550dp/payment_bottom_bar.xml2
-rw-r--r--wallet/src/main/res/layout/balance_actions.xml117
-rw-r--r--wallet/src/main/res/layout/fragment_prompt_withdraw.xml4
-rw-r--r--wallet/src/main/res/layout/fragment_transactions.xml109
-rw-r--r--wallet/src/main/res/layout/fragment_uri_input.xml2
-rw-r--r--wallet/src/main/res/layout/list_item_balance.xml51
-rw-r--r--wallet/src/main/res/layout/payment_bottom_bar.xml2
-rw-r--r--wallet/src/main/res/navigation/nav_graph.xml6
-rw-r--r--wallet/src/main/res/values-es/strings.xml118
-rw-r--r--wallet/src/main/res/values-it/strings.xml2
-rw-r--r--wallet/src/main/res/values-ja/strings.xml2
-rw-r--r--wallet/src/main/res/values/strings.xml373
56 files changed, 874 insertions, 652 deletions
diff --git a/wallet/build.gradle b/wallet/build.gradle
index 93f4a49..45ab9f0 100644
--- a/wallet/build.gradle
+++ b/wallet/build.gradle
@@ -19,7 +19,7 @@ plugins {
id "kotlinx-serialization"
}
-def qtart_version = "0.10.6"
+def qtart_version = "0.11.1"
static def versionCodeEpoch() {
return (new Date().getTime() / 1000).toInteger()
@@ -41,8 +41,8 @@ android {
applicationId "net.taler.wallet"
minSdkVersion 24
targetSdkVersion 33
- versionCode 41
- versionName "0.10.2"
+ versionCode 42
+ versionName "0.11.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
diff --git a/wallet/src/main/java/net/taler/wallet/HandleUriFragment.kt b/wallet/src/main/java/net/taler/wallet/HandleUriFragment.kt
index 6b8db78..58adeee 100644
--- a/wallet/src/main/java/net/taler/wallet/HandleUriFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/HandleUriFragment.kt
@@ -228,6 +228,7 @@ class HandleUriFragment: Fragment() {
withContext(Dispatchers.Main) {
model.showProgressBar.value = false
val args = Bundle().apply {
+ putBoolean("hideScanQr", true)
if (response.amount != null) {
putString("amount", response.amount.toJSONString())
}
diff --git a/wallet/src/main/java/net/taler/wallet/MainActivity.kt b/wallet/src/main/java/net/taler/wallet/MainActivity.kt
index 00fd2d3..d15340a 100644
--- a/wallet/src/main/java/net/taler/wallet/MainActivity.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainActivity.kt
@@ -128,6 +128,7 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener,
model.networkManager.networkStatus.observe(this) { online ->
ui.content.offlineBanner.visibility = if (online) GONE else VISIBLE
+ model.hintNetworkAvailability(online)
}
model.devMode.observe(this) {
diff --git a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
index 82eb8d7..c7318de 100644
--- a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
@@ -231,6 +231,14 @@ class MainViewModel(
}
}
+ fun hintNetworkAvailability(isAvailable: Boolean) {
+ viewModelScope.launch {
+ api.request<Unit>("hintNetworkAvailability") {
+ put("isNetworkAvailable", isAvailable)
+ }
+ }
+ }
+
fun runIntegrationTest() {
viewModelScope.launch {
api.request<Unit>("runIntegrationTestV2") {
diff --git a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
index 2accaaf..25d35ec 100644
--- a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
@@ -144,9 +144,9 @@ private fun ReceiveFundsIntro(
isError = false
text = input
},
- label = { Text(stringResource(R.string.receive_amount)) },
+ label = { Text(stringResource(R.string.amount_receive)) },
supportingText = {
- if (isError) Text(stringResource(R.string.receive_amount_invalid))
+ if (isError) Text(stringResource(R.string.amount_invalid))
},
isError = isError,
numberOfDecimals = spec?.numFractionalInputDigits ?: DEFAULT_INPUT_DECIMALS,
diff --git a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
index 2581979..ca72a64 100644
--- a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
@@ -126,9 +126,9 @@ private fun SendFundsIntro(
insufficientBalance = false
text = input
},
- label = { Text(stringResource(R.string.send_amount)) },
+ label = { Text(stringResource(R.string.amount_send)) },
supportingText = {
- if (isError) Text(stringResource(R.string.receive_amount_invalid))
+ if (isError) Text(stringResource(R.string.amount_invalid))
else if (insufficientBalance) {
Text(stringResource(R.string.payment_balance_insufficient))
}
diff --git a/wallet/src/main/java/net/taler/wallet/balances/BalanceAdapter.kt b/wallet/src/main/java/net/taler/wallet/balances/BalanceAdapter.kt
index f40def4..aabef4b 100644
--- a/wallet/src/main/java/net/taler/wallet/balances/BalanceAdapter.kt
+++ b/wallet/src/main/java/net/taler/wallet/balances/BalanceAdapter.kt
@@ -61,8 +61,7 @@ class BalanceAdapter(private val listener: BalanceClickListener) : Adapter<Balan
private val amountView: TextView = v.findViewById(R.id.balanceAmountView)
private val scopeView: TextView = v.findViewById(R.id.scopeView)
private val balanceInboundAmount: TextView = v.findViewById(R.id.balanceInboundAmount)
- private val balanceInboundLabel: TextView = v.findViewById(R.id.balanceInboundLabel)
- private val pendingView: TextView = v.findViewById(R.id.pendingView)
+ private val balanceOutboundAmount: TextView = v.findViewById(R.id.balanceOutboundAmount)
fun bind(item: BalanceItem) {
v.setOnClickListener { listener.onBalanceClick(item.scopeInfo) }
@@ -71,11 +70,17 @@ class BalanceAdapter(private val listener: BalanceClickListener) : Adapter<Balan
val amountIncoming = item.pendingIncoming
if (amountIncoming.isZero()) {
balanceInboundAmount.visibility = GONE
- balanceInboundLabel.visibility = GONE
} else {
balanceInboundAmount.visibility = VISIBLE
- balanceInboundLabel.visibility = VISIBLE
- balanceInboundAmount.text = v.context.getString(R.string.amount_positive, amountIncoming.toString(showSymbol = false))
+ balanceInboundAmount.text = v.context.getString(R.string.balances_inbound_amount, amountIncoming.toString(showSymbol = false))
+ }
+
+ val amountOutgoing = item.pendingOutgoing
+ if (amountOutgoing.isZero()) {
+ balanceOutboundAmount.visibility = GONE
+ } else {
+ balanceOutboundAmount.visibility = VISIBLE
+ balanceOutboundAmount.text = v.context.getString(R.string.balances_outbound_amount, amountOutgoing.toString(showSymbol = false))
}
val scopeInfo = item.scopeInfo
@@ -90,8 +95,6 @@ class BalanceAdapter(private val listener: BalanceClickListener) : Adapter<Balan
VISIBLE
}
}
-
- pendingView.visibility = if (item.hasPending) VISIBLE else GONE
}
}
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 a524d1b..d2a877b 100644
--- a/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt
+++ b/wallet/src/main/java/net/taler/wallet/compose/AmountInputField.kt
@@ -53,6 +53,7 @@ fun AmountInputField(
keyboardActions: KeyboardActions = KeyboardActions.Default,
decimalFormatSymbols: DecimalFormatSymbols = DecimalFormat().decimalFormatSymbols,
numberOfDecimals: Int = DEFAULT_INPUT_DECIMALS,
+ readOnly: Boolean = false,
) {
var amountInput by remember { mutableStateOf(value) }
@@ -77,6 +78,7 @@ fun AmountInputField(
}
},
modifier = modifier,
+ readOnly = readOnly,
textStyle = LocalTextStyle.current.copy(fontFamily = FontFamily.Monospace),
label = label,
supportingText = supportingText,
diff --git a/wallet/src/main/java/net/taler/wallet/deposit/MakeBitcoinDepositComposable.kt b/wallet/src/main/java/net/taler/wallet/deposit/MakeBitcoinDepositComposable.kt
index 3fa0d98..d356051 100644
--- a/wallet/src/main/java/net/taler/wallet/deposit/MakeBitcoinDepositComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/deposit/MakeBitcoinDepositComposable.kt
@@ -91,7 +91,7 @@ fun MakeBitcoinDepositComposable(
}
val amountTitle = if (state.effectiveDepositAmount == null) {
R.string.amount_chosen
- } else R.string.send_deposit_amount_effective
+ } else R.string.amount_effective
TransactionAmountComposable(
label = stringResource(id = amountTitle),
amount = state.effectiveDepositAmount ?: amount,
@@ -104,14 +104,16 @@ fun MakeBitcoinDepositComposable(
) {
val totalAmount = state.totalDepositCost ?: amount
val effectiveAmount = state.effectiveDepositAmount ?: Amount.zero(amount.currency)
- val fee = totalAmount - effectiveAmount
+ if (totalAmount > effectiveAmount) {
+ val fee = totalAmount - effectiveAmount
+ TransactionAmountComposable(
+ label = stringResource(id = R.string.amount_fee),
+ amount = fee,
+ amountType = AmountType.Negative,
+ )
+ }
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
- amount = fee,
- amountType = AmountType.Negative,
- )
- TransactionAmountComposable(
- label = stringResource(id = R.string.send_amount),
+ label = stringResource(id = R.string.amount_send),
amount = totalAmount,
amountType = AmountType.Positive,
)
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 9333ce1..2f9fd88 100644
--- a/wallet/src/main/java/net/taler/wallet/deposit/MakeDepositComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/deposit/MakeDepositComposable.kt
@@ -134,16 +134,18 @@ fun MakeDepositComposable(
) {
val totalAmount = state.totalDepositCost ?: amount
val effectiveAmount = state.effectiveDepositAmount ?: Amount.zero(amount.currency)
- val fee = totalAmount - effectiveAmount
+ if (totalAmount > effectiveAmount) {
+ val fee = totalAmount - effectiveAmount
- TransactionAmountComposable(
- label = stringResource(R.string.withdraw_fees),
- amount = fee.withSpec(amount.spec),
- amountType = if (fee.isZero()) Positive else Negative,
- )
+ TransactionAmountComposable(
+ label = stringResource(R.string.amount_fee),
+ amount = fee.withSpec(amount.spec),
+ amountType = Negative,
+ )
+ }
TransactionAmountComposable(
- label = stringResource(R.string.send_amount),
+ label = stringResource(R.string.amount_send),
amount = effectiveAmount.withSpec(amount.spec),
amountType = Positive,
)
diff --git a/wallet/src/main/java/net/taler/wallet/deposit/PayToUriFragment.kt b/wallet/src/main/java/net/taler/wallet/deposit/PayToUriFragment.kt
index 8961016..0dd3abd 100644
--- a/wallet/src/main/java/net/taler/wallet/deposit/PayToUriFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/deposit/PayToUriFragment.kt
@@ -140,7 +140,7 @@ private fun PayToComposable(
amountError = ""
amountText = input
},
- label = { Text(stringResource(R.string.send_amount)) },
+ label = { Text(stringResource(R.string.amount_send)) },
supportingText = {
if (amountError.isNotBlank()) Text(amountError)
},
@@ -158,7 +158,7 @@ private fun PayToComposable(
}
val focusManager = LocalFocusManager.current
- val errorStrInvalidAmount = stringResource(id = R.string.receive_amount_invalid)
+ val errorStrInvalidAmount = stringResource(id = R.string.amount_invalid)
val errorStrInsufficientBalance = stringResource(id = R.string.payment_balance_insufficient)
Button(
modifier = Modifier.padding(16.dp),
diff --git a/wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt b/wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt
index 817dfac..11264a1 100644
--- a/wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/deposit/TransactionDepositComposable.kt
@@ -77,10 +77,10 @@ fun TransactionDepositComposable(
amountType = AmountType.Neutral,
)
- val fee = t.amountEffective - t.amountRaw
- if (!fee.isZero()) {
+ if (t.amountEffective > t.amountRaw) {
+ val fee = t.amountEffective - t.amountRaw
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = fee.withSpec(spec),
amountType = AmountType.Negative,
)
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 ffa4875..d744183 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateComposable.kt
@@ -34,42 +34,37 @@ import net.taler.wallet.R
import net.taler.wallet.compose.LoadingScreen
import net.taler.wallet.compose.TalerSurface
-sealed class AmountFieldStatus {
- object FixedAmount : AmountFieldStatus()
- class Default(
- val amountStr: String? = null,
- val currency: String? = null,
- ) : AmountFieldStatus()
-
- object Invalid : AmountFieldStatus()
-}
-
@Composable
fun PayTemplateComposable(
- defaultSummary: String?,
- amountStatus: AmountFieldStatus,
currencies: List<String>,
payStatus: PayStatus,
onCreateAmount: (String, String) -> AmountResult,
- onSubmit: (summary: String?, amount: Amount?) -> Unit,
+ onSubmit: (params: TemplateParams) -> Unit,
onError: (resId: Int) -> Unit,
) {
// If wallet is empty, there's no way the user can pay something
- if (amountStatus is AmountFieldStatus.Invalid) {
- PayTemplateError(stringResource(R.string.receive_amount_invalid))
- } else if (currencies.isEmpty()) {
+ if (currencies.isEmpty()) {
PayTemplateError(stringResource(R.string.payment_balance_insufficient))
} else when (val p = payStatus) {
- is PayStatus.None -> PayTemplateOrderComposable(
- currencies = currencies,
- defaultSummary = defaultSummary,
- amountStatus = amountStatus,
- onCreateAmount = onCreateAmount,
- onError = onError,
- onSubmit = onSubmit,
- )
+ is PayStatus.Checked -> {
+ val usableCurrencies = currencies
+ .intersect(p.supportedCurrencies.toSet())
+ .toList()
+ if (usableCurrencies.isEmpty()) {
+ // If user doesn't have any supported currency, they can't pay either
+ PayTemplateError(stringResource(R.string.payment_balance_insufficient))
+ } else {
+ PayTemplateOrderComposable(
+ usableCurrencies = usableCurrencies,
+ templateDetails = p.details,
+ onCreateAmount = onCreateAmount,
+ onError = onError,
+ onSubmit = onSubmit,
+ )
+ }
+ }
- is PayStatus.Loading -> PayTemplateLoading()
+ is PayStatus.None, is PayStatus.Loading -> PayTemplateLoading()
is PayStatus.AlreadyPaid -> PayTemplateError(stringResource(R.string.payment_already_paid))
is PayStatus.InsufficientBalance -> PayTemplateError(stringResource(R.string.payment_balance_insufficient))
is PayStatus.Pending -> {
@@ -109,14 +104,12 @@ fun PayTemplateLoading() {
fun PayTemplateLoadingPreview() {
TalerSurface {
PayTemplateComposable(
- defaultSummary = "Donation",
- amountStatus = AmountFieldStatus.Default("20", "ARS"),
payStatus = PayStatus.Loading,
currencies = listOf("KUDOS", "ARS"),
onCreateAmount = { text, currency ->
AmountResult.Success(amount = Amount.fromString(currency, text))
},
- onSubmit = { _, _ -> },
+ onSubmit = { _ -> },
onError = { _ -> },
)
}
@@ -127,8 +120,6 @@ fun PayTemplateLoadingPreview() {
fun PayTemplateInsufficientBalancePreview() {
TalerSurface {
PayTemplateComposable(
- defaultSummary = "Donation",
- amountStatus = AmountFieldStatus.Default("20", "ARS"),
payStatus = PayStatus.InsufficientBalance(
ContractTerms(
"test",
@@ -140,7 +131,7 @@ fun PayTemplateInsufficientBalancePreview() {
onCreateAmount = { text, currency ->
AmountResult.Success(amount = Amount.fromString(currency, text))
},
- onSubmit = { _, _ -> },
+ onSubmit = { _ -> },
onError = { _ -> },
)
}
@@ -151,14 +142,12 @@ fun PayTemplateInsufficientBalancePreview() {
fun PayTemplateAlreadyPaidPreview() {
TalerSurface {
PayTemplateComposable(
- defaultSummary = "Donation",
- amountStatus = AmountFieldStatus.Default("20", "ARS"),
payStatus = PayStatus.AlreadyPaid(transactionId = "transactionId"),
currencies = listOf("KUDOS", "ARS"),
onCreateAmount = { text, currency ->
AmountResult.Success(amount = Amount.fromString(currency, text))
},
- onSubmit = { _, _ -> },
+ onSubmit = { _ -> },
onError = { _ -> },
)
}
@@ -170,14 +159,12 @@ fun PayTemplateAlreadyPaidPreview() {
fun PayTemplateNoCurrenciesPreview() {
TalerSurface {
PayTemplateComposable(
- defaultSummary = "Donation",
- amountStatus = AmountFieldStatus.Default("20", "ARS"),
payStatus = PayStatus.None,
currencies = emptyList(),
onCreateAmount = { text, currency ->
AmountResult.Success(amount = Amount.fromString(currency, text))
},
- onSubmit = { _, _ -> },
+ onSubmit = { _ -> },
onError = { _ -> },
)
}
diff --git a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateDetails.kt b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateDetails.kt
new file mode 100644
index 0000000..4c3f0a5
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateDetails.kt
@@ -0,0 +1,126 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2024 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/>
+ */
+
+package net.taler.wallet.payment
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+import net.taler.common.Amount
+import net.taler.common.RelativeTime
+
+@Serializable
+data class TemplateContractDetails(
+ /**
+ * Human-readable summary for the template.
+ */
+ val summary: String? = null,
+
+ /**
+ * Required currency for payments to the template. The user may specify
+ * any amount, but it must be in this currency. This parameter is
+ * optional and should not be present if "amount" is given.
+ */
+ val currency: String? = null,
+
+ /**
+ * The price is imposed by the merchant and cannot be changed by the
+ * customer. This parameter is optional.
+ */
+ val amount: Amount? = null,
+
+ /**
+ * Minimum age buyer must have (in years). Default is 0.
+ */
+ @SerialName("minimum_age")
+ val minimumAge: Int,
+
+ /**
+ * The time the customer need to pay before his order will be deleted. It
+ * is deleted if the customer did not pay and if the duration is over.
+ */
+ @SerialName("pay_duration")
+ val payDuration: RelativeTime,
+)
+
+@Serializable
+data class TemplateContractDetailsDefaults(
+ val summary: String? = null,
+ val currency: String? = null,
+ val amount: Amount? = null,
+ @SerialName("minimum_age")
+ val minimumAge: Int? = null,
+)
+
+@Serializable
+class WalletTemplateDetails(
+ /**
+ * Hard-coded information about the contract terms for this template.
+ */
+ @SerialName("template_contract")
+ val templateContract: TemplateContractDetails,
+
+ /**
+ * Key-value pairs matching a subset of the fields from template_contract
+ * that are user-editable defaults for this template.
+ */
+ @SerialName("editable_defaults")
+ val editableDefaults: TemplateContractDetailsDefaults? = null,
+
+ /**
+ * Required currency for payments. Useful if no amount is specified in
+ * the template_contract but the user should be required to pay in a
+ * particular currency anyway. Merchant backends may reject requests if
+ * the template_contract or editable_defaults do specify an amount in a
+ * different currency. This parameter is optional.
+ */
+ @SerialName("required_currency")
+ val requiredCurrency: String? = null,
+) {
+ val defaultSummary get() = editableDefaults?.summary
+ ?: templateContract.summary
+
+ val defaultAmount get() = editableDefaults?.amount
+ ?: templateContract.amount
+
+ val defaultCurrency get() = requiredCurrency
+ ?: editableDefaults?.currency
+ ?: templateContract.currency
+
+ fun isSummaryEditable() = templateContract.summary == null
+
+ fun isAmountEditable() = templateContract.amount == null
+
+ fun isCurrencyEditable(usableCurrencies: List<String>) = isAmountEditable()
+ && requiredCurrency == null
+ && templateContract.currency == null
+ && usableCurrencies.size > 1
+
+ fun isTemplateEditable(usableCurrencies: List<String>) = isSummaryEditable()
+ || isAmountEditable()
+ || isCurrencyEditable(usableCurrencies)
+
+ // NOTE: it is important to nullify non-editable values!
+ fun toTemplateParams() = TemplateParams(
+ amount = if(isAmountEditable()) templateContract.amount else null,
+ summary = if(isSummaryEditable()) templateContract.summary else null,
+ )
+}
+
+@Serializable
+data class TemplateParams(
+ val amount: Amount? = null,
+ val summary: String? = null,
+) \ No newline at end of file
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 4eb2c11..51c0bc0 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateFragment.kt
@@ -26,7 +26,6 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.asFlow
import androidx.navigation.fragment.findNavController
-import net.taler.common.Amount
import net.taler.common.showError
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
@@ -39,6 +38,7 @@ class PayTemplateFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private lateinit var uriString: String
private lateinit var uri: Uri
+ private val currencies by lazy { model.getCurrencies() }
override fun onCreateView(
inflater: LayoutInflater,
@@ -48,10 +48,6 @@ class PayTemplateFragment : Fragment() {
uriString = arguments?.getString("uri") ?: error("no amount passed")
uri = Uri.parse(uriString)
- val defaultSummary = uri.getQueryParameter("summary")
- val defaultAmount = uri.getQueryParameter("amount")
- val amountFieldStatus = getAmountFieldStatus(defaultAmount)
-
val payStatusFlow = model.paymentManager.payStatus.asFlow()
return ComposeView(requireContext()).apply {
@@ -59,9 +55,7 @@ class PayTemplateFragment : Fragment() {
val payStatus = payStatusFlow.collectAsStateLifecycleAware(initial = PayStatus.None)
TalerSurface {
PayTemplateComposable(
- currencies = model.getCurrencies(),
- defaultSummary = defaultSummary,
- amountStatus = amountFieldStatus,
+ currencies = currencies,
payStatus = payStatus.value,
onCreateAmount = model::createAmount,
onSubmit = this@PayTemplateFragment::createOrder,
@@ -74,9 +68,7 @@ class PayTemplateFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- if (uri.queryParameterNames?.isEmpty() == true) {
- createOrder(null, null)
- }
+ checkTemplate()
model.paymentManager.payStatus.observe(viewLifecycleOwner) { payStatus ->
when (payStatus) {
@@ -88,28 +80,25 @@ class PayTemplateFragment : Fragment() {
showError(payStatus.error)
}
+ is PayStatus.Checked -> {
+ val usableCurrencies = currencies
+ .intersect(payStatus.supportedCurrencies.toSet())
+ .toList()
+ if (!payStatus.details.isTemplateEditable(usableCurrencies)) {
+ createOrder(payStatus.details.toTemplateParams())
+ }
+ }
+
else -> {}
}
}
}
- private fun getAmountFieldStatus(defaultAmount: String?): AmountFieldStatus {
- return if (defaultAmount == null) {
- AmountFieldStatus.FixedAmount
- } else if (defaultAmount.isBlank()) {
- AmountFieldStatus.Default()
- } else {
- val parts = defaultAmount.split(":")
- when (parts.size) {
- 0 -> AmountFieldStatus.Default()
- 1 -> AmountFieldStatus.Default(currency = parts[0])
- 2 -> AmountFieldStatus.Default(parts[1], parts[0])
- else -> AmountFieldStatus.Invalid
- }
- }
+ private fun checkTemplate() {
+ model.paymentManager.checkPayForTemplate(uriString)
}
- private fun createOrder(summary: String?, amount: Amount?) {
- model.paymentManager.preparePayForTemplate(uriString, summary, amount)
+ private fun createOrder(params: TemplateParams) {
+ model.paymentManager.preparePayForTemplate(uriString, params)
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateOrderComposable.kt b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateOrderComposable.kt
index d6131c7..2febfbb 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PayTemplateOrderComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PayTemplateOrderComposable.kt
@@ -24,84 +24,118 @@ import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
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.Companion.End
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.focus.onFocusChanged
+import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.taler.common.Amount
+import net.taler.common.RelativeTime
import net.taler.wallet.AmountResult
import net.taler.wallet.R
import net.taler.wallet.compose.AmountInputField
import net.taler.wallet.compose.TalerSurface
import net.taler.wallet.deposit.CurrencyDropdown
+@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun PayTemplateOrderComposable(
- currencies: List<String>, // assumed to have size > 0
- defaultSummary: String? = null,
- amountStatus: AmountFieldStatus,
+ usableCurrencies: List<String>, // non-empty intersection between the stored currencies and the ones supported by the merchant
+ templateDetails: WalletTemplateDetails,
onCreateAmount: (String, String) -> AmountResult,
onError: (msgRes: Int) -> Unit,
- onSubmit: (summary: String?, amount: Amount?) -> Unit,
+ onSubmit: (params: TemplateParams) -> Unit,
) {
- val amountDefault = amountStatus as? AmountFieldStatus.Default
+ val defaultSummary = templateDetails.defaultSummary
+ val defaultAmount = templateDetails.defaultAmount
+ val defaultCurrency = templateDetails.defaultCurrency
- var summary by remember { mutableStateOf(defaultSummary) }
- var currency by remember { mutableStateOf(amountDefault?.currency ?: currencies[0]) }
- var amount by remember { mutableStateOf(amountDefault?.amountStr ?: "0") }
+ val summaryFocusRequester = remember { FocusRequester() }
+ val keyboardController = LocalSoftwareKeyboardController.current
+
+ var summary by remember { mutableStateOf(defaultSummary ?: "") }
+ var currency by remember { mutableStateOf(defaultCurrency ?: usableCurrencies[0]) }
+ var amount by remember { mutableStateOf(defaultAmount?.amountStr ?: "0") }
Column(horizontalAlignment = End) {
- if (defaultSummary != null) OutlinedTextField(
+ OutlinedTextField(
modifier = Modifier
.padding(horizontal = 16.dp)
- .fillMaxWidth(),
- value = summary ?: "",
- isError = summary.isNullOrBlank(),
+ .fillMaxWidth()
+ .focusRequester(summaryFocusRequester)
+ .onFocusChanged {
+ if (it.isFocused) {
+ keyboardController?.show()
+ }
+ },
+ value = summary,
+ isError = templateDetails.isSummaryEditable() && summary.isBlank(),
onValueChange = { summary = it },
singleLine = true,
+ readOnly = !templateDetails.isSummaryEditable(),
label = { Text(stringResource(R.string.withdraw_manual_ready_subject)) },
)
- if (amountDefault != null) AmountField(
+
+ AmountField(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
amount = amount,
currency = currency,
- currencies = currencies,
- fixedCurrency = (amountStatus as? AmountFieldStatus.Default)?.currency != null,
+ currencies = usableCurrencies,
+ readOnlyCurrency = !templateDetails.isCurrencyEditable(usableCurrencies),
+ readOnlyAmount = !templateDetails.isAmountEditable(),
onAmountChosen = { a, c ->
amount = a
currency = c
},
)
+
Button(
modifier = Modifier.padding(16.dp),
- enabled = defaultSummary == null || !summary.isNullOrBlank(),
+ enabled = !templateDetails.isSummaryEditable() || summary.isNotBlank(),
onClick = {
when (val res = onCreateAmount(amount, currency)) {
is AmountResult.InsufficientBalance -> onError(R.string.payment_balance_insufficient)
- is AmountResult.InvalidAmount -> onError(R.string.receive_amount_invalid)
- is AmountResult.Success -> onSubmit(summary, res.amount)
+ is AmountResult.InvalidAmount -> onError(R.string.amount_invalid)
+ // NOTE: it is important to nullify non-editable values!
+ is AmountResult.Success -> onSubmit(TemplateParams(
+ summary = if (templateDetails.isSummaryEditable()) summary else null,
+ amount = if(templateDetails.isAmountEditable()) res.amount else null,
+ ))
}
},
) {
Text(stringResource(R.string.payment_create_order))
}
}
+
+ LaunchedEffect(Unit) {
+ if (templateDetails.isSummaryEditable()
+ && templateDetails.defaultSummary == null) {
+ summaryFocusRequester.requestFocus()
+ }
+ }
}
@Composable
private fun AmountField(
modifier: Modifier = Modifier,
currencies: List<String>,
- fixedCurrency: Boolean,
amount: String,
currency: String,
+ readOnlyAmount: Boolean = true,
+ readOnlyCurrency: Boolean = true,
onAmountChosen: (amount: String, currency: String) -> Unit,
) {
Row(
@@ -113,30 +147,42 @@ private fun AmountField(
.weight(1f),
value = amount,
onValueChange = { onAmountChosen(it, currency) },
- label = { Text(stringResource(R.string.send_amount)) }
+ label = { Text(stringResource(R.string.amount_send)) },
+ readOnly = readOnlyAmount,
)
+
CurrencyDropdown(
modifier = Modifier.weight(1f),
initialCurrency = currency,
currencies = currencies,
onCurrencyChanged = { onAmountChosen(amount, it) },
- readOnly = fixedCurrency,
+ readOnly = readOnlyCurrency,
)
}
}
+val defaultTemplateDetails = WalletTemplateDetails(
+ templateContract = TemplateContractDetails(
+ minimumAge = 18,
+ payDuration = RelativeTime.forever(),
+ ),
+ editableDefaults = TemplateContractDetailsDefaults(
+ summary = "Donation",
+ amount = Amount.fromJSONString("KUDOS:10.0"),
+ ),
+)
+
@Preview
@Composable
fun PayTemplateDefaultPreview() {
TalerSurface {
PayTemplateOrderComposable(
- defaultSummary = "Donation",
- amountStatus = AmountFieldStatus.Default("20", "ARS"),
- currencies = listOf("KUDOS", "ARS"),
+ templateDetails = defaultTemplateDetails,
+ usableCurrencies = listOf("KUDOS", "ARS"),
onCreateAmount = { text, currency ->
AmountResult.Success(amount = Amount.fromString(currency, text))
},
- onSubmit = { _, _ -> },
+ onSubmit = { _ -> },
onError = { },
)
}
@@ -147,13 +193,12 @@ fun PayTemplateDefaultPreview() {
fun PayTemplateFixedAmountPreview() {
TalerSurface {
PayTemplateOrderComposable(
- defaultSummary = "default summary",
- amountStatus = AmountFieldStatus.FixedAmount,
- currencies = listOf("KUDOS", "ARS"),
+ templateDetails = defaultTemplateDetails,
+ usableCurrencies = listOf("KUDOS", "ARS"),
onCreateAmount = { text, currency ->
AmountResult.Success(amount = Amount.fromString(currency, text))
},
- onSubmit = { _, _ -> },
+ onSubmit = { _ -> },
onError = { },
)
}
@@ -164,13 +209,12 @@ fun PayTemplateFixedAmountPreview() {
fun PayTemplateBlankSubjectPreview() {
TalerSurface {
PayTemplateOrderComposable(
- defaultSummary = "",
- amountStatus = AmountFieldStatus.FixedAmount,
- currencies = listOf("KUDOS", "ARS"),
+ templateDetails = defaultTemplateDetails,
+ usableCurrencies = listOf("KUDOS", "ARS"),
onCreateAmount = { text, currency ->
AmountResult.Success(amount = Amount.fromString(currency, text))
},
- onSubmit = { _, _ -> },
+ onSubmit = { _ -> },
onError = { },
)
}
diff --git a/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt b/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt
index 35cd9e6..647c98c 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt
@@ -22,9 +22,12 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.encodeToString
import net.taler.common.Amount
import net.taler.common.ContractTerms
import net.taler.wallet.TAG
+import net.taler.wallet.backend.BackendManager
import net.taler.wallet.backend.TalerErrorInfo
import net.taler.wallet.backend.WalletBackendApi
import net.taler.wallet.payment.PayStatus.AlreadyPaid
@@ -37,8 +40,8 @@ import org.json.JSONObject
val REGEX_PRODUCT_IMAGE = Regex("^data:image/(jpeg|png);base64,([A-Za-z0-9+/=]+)$")
sealed class PayStatus {
- object None : PayStatus()
- object Loading : PayStatus()
+ data object None : PayStatus()
+ data object Loading : PayStatus()
data class Prepared(
val contractTerms: ContractTerms,
val transactionId: String,
@@ -46,6 +49,11 @@ sealed class PayStatus {
val amountEffective: Amount,
) : PayStatus()
+ data class Checked(
+ val details: WalletTemplateDetails,
+ val supportedCurrencies: List<String>,
+ ) : PayStatus()
+
data class InsufficientBalance(
val contractTerms: ContractTerms,
val amountRaw: Amount,
@@ -65,6 +73,12 @@ sealed class PayStatus {
) : PayStatus()
}
+@Serializable
+data class CheckPayTemplateResponse(
+ val templateDetails: WalletTemplateDetails,
+ val supportedCurrencies: List<String>,
+)
+
class PaymentManager(
private val api: WalletBackendApi,
private val scope: CoroutineScope,
@@ -113,14 +127,25 @@ class PaymentManager(
}
}
- fun preparePayForTemplate(url: String, summary: String?, amount: Amount?) = scope.launch {
+ fun checkPayForTemplate(url: String) = scope.launch {
+ mPayStatus.value = PayStatus.Loading
+ api.request("checkPayForTemplate", CheckPayTemplateResponse.serializer()) {
+ put("talerPayTemplateUri", url)
+ }.onError {
+ handleError("checkPayForTemplate", it)
+ }.onSuccess { response ->
+ mPayStatus.value = PayStatus.Checked(
+ details = response.templateDetails,
+ supportedCurrencies = response.supportedCurrencies,
+ )
+ }
+ }
+
+ fun preparePayForTemplate(url: String, params: TemplateParams) = scope.launch {
mPayStatus.value = PayStatus.Loading
api.request("preparePayForTemplate", PreparePayResponse.serializer()) {
put("talerPayTemplateUri", url)
- put("templateParams", JSONObject().apply {
- summary?.let { put("summary", it) }
- amount?.let { put("amount", it.toJSONString()) }
- })
+ put("templateParams", JSONObject(BackendManager.json.encodeToString(params)))
}.onError {
handleError("preparePayForTemplate", it)
}.onSuccess { response ->
diff --git a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
index 31c26a0..1995f9d 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
@@ -98,6 +98,7 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener {
private fun onPaymentStatusChanged(payStatus: PayStatus?) {
when (payStatus) {
null -> {}
+ is PayStatus.Checked -> {} // does not apply, only used for templates
is PayStatus.Prepared -> {
showLoading(false)
val fees = payStatus.amountEffective - payStatus.amountRaw
diff --git a/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
index 0f6d661..beb37d9 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
@@ -82,10 +82,10 @@ fun TransactionPaymentComposable(
amountType = AmountType.Neutral,
)
- val fee = t.amountEffective - t.amountRaw
- if (!fee.isZero()) {
+ if (t.amountEffective > t.amountRaw) {
+ val fee = t.amountEffective - t.amountRaw
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = fee.withSpec(spec),
amountType = AmountType.Negative,
)
diff --git a/wallet/src/main/java/net/taler/wallet/peer/IncomingComposable.kt b/wallet/src/main/java/net/taler/wallet/peer/IncomingComposable.kt
index 1ce0175..609629e 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/IncomingComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/IncomingComposable.kt
@@ -134,7 +134,7 @@ fun ColumnScope.PeerPullTermsComposable(
modifier = Modifier.align(End),
) {
Text(
- text = stringResource(id = R.string.payment_label_amount_total),
+ text = stringResource(id = R.string.amount_total_label),
style = MaterialTheme.typography.bodyLarge,
)
Text(
@@ -145,22 +145,26 @@ fun ColumnScope.PeerPullTermsComposable(
)
}
// this gets used for credit and debit, so fee calculation differs
- val fee = if (data.isCredit) {
+ val fee = if (data.isCredit && terms.amountRaw > terms.amountEffective) {
terms.amountRaw - terms.amountEffective
- } else {
+ } else if (terms.amountEffective > terms.amountRaw) {
terms.amountEffective - terms.amountRaw
+ } else null
+
+ if (fee != null) {
+ val feeStr = if (data.isCredit) {
+ stringResource(R.string.amount_negative, fee)
+ } else {
+ stringResource(R.string.amount_positive, fee)
+ }
+ Text(
+ modifier = Modifier.align(End),
+ text = feeStr,
+ style = MaterialTheme.typography.bodyLarge,
+ color = MaterialTheme.colorScheme.error,
+ )
}
- val feeStr = if (data.isCredit) {
- stringResource(R.string.amount_negative, fee)
- } else {
- stringResource(R.string.amount_positive, fee)
- }
- if (!fee.isZero()) Text(
- modifier = Modifier.align(End),
- text = feeStr,
- style = MaterialTheme.typography.bodyLarge,
- color = MaterialTheme.colorScheme.error,
- )
+
if (terms is IncomingAccepting) {
CircularProgressIndicator(
modifier = Modifier
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 90b520e..f3d569f 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullComposable.kt
@@ -148,10 +148,10 @@ fun OutgoingPullIntroComposable(
amountType = AmountType.Positive,
)
- if (state is OutgoingChecked) {
+ if (state is OutgoingChecked && state.amountRaw > state.amountEffective) {
val fee = state.amountRaw - state.amountEffective
- if (!fee.isZero()) TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ TransactionAmountComposable(
+ label = stringResource(id = R.string.amount_fee),
amount = fee.withSpec(amount.spec),
amountType = AmountType.Negative,
)
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 d39fdc8..7eba733 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushComposable.kt
@@ -89,7 +89,7 @@ fun OutgoingPushIntroComposable(
style = MaterialTheme.typography.titleLarge,
)
- if (state is OutgoingChecked) {
+ if (state is OutgoingChecked && state.amountEffective > state.amountRaw) {
val fee = state.amountEffective - state.amountRaw
Text(
modifier = Modifier.padding(vertical = 16.dp),
diff --git a/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullCredit.kt b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullCredit.kt
index 3b15b6f..59d405c 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullCredit.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullCredit.kt
@@ -49,15 +49,15 @@ fun ColumnScope.TransactionPeerPullCreditComposable(t: TransactionPeerPullCredit
)
TransactionAmountComposable(
- label = stringResource(id = R.string.receive_peer_amount_invoiced),
+ label = stringResource(id = R.string.amount_invoiced),
amount = t.amountRaw.withSpec(spec),
amountType = AmountType.Neutral,
)
- val fee = t.amountRaw - t.amountEffective
- if (!fee.isZero()) {
+ if (t.amountRaw > t.amountEffective) {
+ val fee = t.amountRaw - t.amountEffective
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = fee.withSpec(spec),
amountType = AmountType.Negative,
)
diff --git a/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullDebit.kt b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullDebit.kt
index dadff4a..b8966d4 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullDebit.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPullDebit.kt
@@ -46,10 +46,10 @@ fun TransactionPeerPullDebitComposable(t: TransactionPeerPullDebit, spec: Curren
amountType = AmountType.Neutral,
)
- val fee = t.amountEffective - t.amountRaw
- if (!fee.isZero()) {
+ if (t.amountEffective > t.amountRaw) {
+ val fee = t.amountEffective - t.amountRaw
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = fee.withSpec(spec),
amountType = AmountType.Negative,
)
diff --git a/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushCredit.kt b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushCredit.kt
index dbf0fb9..d407ff2 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushCredit.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushCredit.kt
@@ -46,10 +46,10 @@ fun TransactionPeerPushCreditComposable(t: TransactionPeerPushCredit, spec: Curr
amountType = AmountType.Neutral,
)
- val fee = t.amountRaw - t.amountEffective
- if (!fee.isZero()) {
+ if (t.amountRaw > t.amountEffective) {
+ val fee = t.amountRaw - t.amountEffective
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = fee.withSpec(spec),
amountType = AmountType.Negative,
)
diff --git a/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushDebit.kt b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushDebit.kt
index e592c3e..f2edc19 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushDebit.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushDebit.kt
@@ -65,10 +65,10 @@ fun ColumnScope.TransactionPeerPushDebitComposable(t: TransactionPeerPushDebit,
amountType = AmountType.Neutral,
)
- val fee = t.amountEffective - t.amountRaw
- if (!fee.isZero()) {
+ if (t.amountEffective > t.amountRaw) {
+ val fee = t.amountEffective - t.amountRaw
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = fee.withSpec(spec),
amountType = AmountType.Negative,
)
diff --git a/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt b/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
index 637b41a..b17658a 100644
--- a/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
@@ -81,10 +81,10 @@ fun TransactionRefundComposable(
amount = t.amountRaw.withSpec(spec),
amountType = AmountType.Neutral,
)
- val fee = t.amountRaw - t.amountEffective
- if (!fee.isZero()) {
+ if (t.amountRaw > t.amountEffective) {
+ val fee = t.amountRaw - t.amountEffective
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = fee.withSpec(spec),
amountType = AmountType.Negative,
)
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionLossFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionLossFragment.kt
index 9138345..2c95880 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionLossFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionLossFragment.kt
@@ -99,7 +99,7 @@ fun TransitionLossComposable(
)
TransactionAmountComposable(
- label = stringResource(id = R.string.loss_amount),
+ label = stringResource(id = R.string.amount_lost),
amount = t.amountEffective.withSpec(spec),
amountType = AmountType.Negative,
)
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
index 8f474f9..e55d887 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
@@ -91,7 +91,7 @@ private fun TransactionRefreshComposable(
style = MaterialTheme.typography.bodyLarge,
)
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = t.amountEffective.withSpec(spec),
amountType = AmountType.Negative,
)
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
index 7ccdbde..2bd204c 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
@@ -17,6 +17,7 @@
package net.taler.wallet.transactions
import android.content.Context
+import android.net.Uri
import android.util.Log
import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
@@ -354,10 +355,7 @@ class TransactionRefund(
@Transient
override val amountType = AmountType.Positive
- override fun getTitle(context: Context): String {
- val merchantName = paymentInfo?.merchant?.name ?: "null"
- return context.getString(R.string.transaction_refund_from, merchantName)
- }
+ override fun getTitle(context: Context) = paymentInfo?.merchant?.name ?: context.getString(R.string.transaction_refund)
override val generalTitleRes = R.string.refund_title
}
@@ -404,7 +402,10 @@ class TransactionDeposit(
@Transient
override val amountType = AmountType.Negative
override fun getTitle(context: Context): String {
- return context.getString(R.string.transaction_deposit)
+ val uri = Uri.parse(targetPaytoUri)
+ return uri.getQueryParameter("receiver-name")?.let { receiverName ->
+ context.getString(R.string.transaction_deposit_to, receiverName)
+ } ?: context.getString(R.string.transaction_deposit)
}
override val generalTitleRes = R.string.transaction_deposit
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
index 5243427..d2d0c9c 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
@@ -26,6 +26,7 @@ import android.view.MenuItem
import android.view.View
import android.view.View.INVISIBLE
import android.view.ViewGroup
+import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.SearchView.OnQueryTextListener
import androidx.fragment.app.Fragment
@@ -44,6 +45,8 @@ import net.taler.wallet.MainViewModel
import net.taler.wallet.R
import net.taler.wallet.TAG
import net.taler.wallet.balances.BalanceState.Success
+import net.taler.wallet.balances.ScopeInfo
+import net.taler.wallet.cleanExchange
import net.taler.wallet.databinding.FragmentTransactionsBinding
import net.taler.wallet.showError
@@ -115,7 +118,7 @@ class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode.
if (balances.size == 1) ui.mainFab.visibility = INVISIBLE
balances.find { it.scopeInfo == scopeInfo }?.let { balance ->
- ui.amount.text = balance.available.toString(showSymbol = false)
+ ui.actionsBar.amount.text = balance.available.toString(showSymbol = false)
transactionAdapter.setCurrencySpec(balance.available.spec)
}
}
@@ -125,10 +128,10 @@ class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode.
transactionManager.transactions.observe(viewLifecycleOwner) { result ->
onTransactionsResult(result)
}
- ui.sendButton.setOnClickListener {
+ ui.actionsBar.sendButton.setOnClickListener {
findNavController().navigate(R.id.sendFunds)
}
- ui.receiveButton.setOnClickListener {
+ ui.actionsBar.receiveButton.setOnClickListener {
findNavController().navigate(R.id.action_global_receiveFunds)
}
ui.mainFab.setOnClickListener {
@@ -154,6 +157,8 @@ class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode.
override fun onStart() {
super.onStart()
requireActivity().title = getString(R.string.transactions_detail_title_currency, scopeInfo.currency)
+ (requireActivity() as AppCompatActivity).supportActionBar?.subtitle =
+ (scopeInfo as? ScopeInfo.Exchange)?.url?.let { cleanExchange(it) }
}
private fun setupSearch(item: MenuItem) {
@@ -261,6 +266,11 @@ class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode.
return true
}
+ override fun onStop() {
+ super.onStop()
+ (requireActivity() as AppCompatActivity).supportActionBar?.subtitle = null
+ }
+
override fun onDestroyActionMode(mode: ActionMode) {
tracker?.clearSelection()
actionMode = null
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt
index 424cc2a..1d91107 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransitionsComposable.kt
@@ -44,7 +44,7 @@ fun TransitionsComposable(
) {
FlowRow(horizontalArrangement = Center) {
t.txActions.forEach {
- if (it in arrayOf(Resume, Suspend)) {
+ if (it in arrayOf(Resume, Suspend, Retry)) {
if (devMode) TransitionComposable(it, onTransition)
} else {
TransitionComposable(it, onTransition)
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 56f56f7..9983409 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
@@ -175,8 +175,8 @@ class PromptWithdrawFragment : Fragment() {
ui.chosenAmountView.text = amountRaw.toString()
ui.chosenAmountView.fadeIn()
- val fee = amountRaw - amountEffective
- if (!fee.isZero()) {
+ if (amountRaw > amountEffective) {
+ val fee = amountRaw - amountEffective
ui.feeLabel.fadeIn()
ui.feeView.text = getString(R.string.amount_negative, fee.toString())
ui.feeView.fadeIn()
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt b/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
index 20f8280..9bfeda6 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
@@ -81,23 +81,25 @@ fun TransactionWithdrawalComposable(
ActionButton(tx = t, listener = actionListener)
- TransactionAmountComposable(
- label = stringResource(R.string.amount_chosen),
- amount = t.amountRaw.withSpec(spec),
- amountType = AmountType.Neutral,
- )
+ if (t.amountRaw != t.amountEffective) {
+ TransactionAmountComposable(
+ label = stringResource(R.string.amount_chosen),
+ amount = t.amountRaw.withSpec(spec),
+ amountType = AmountType.Neutral,
+ )
+ }
- val fee = t.amountRaw - t.amountEffective
- if (!fee.isZero()) {
+ if (t.amountRaw > t.amountEffective) {
+ val fee = t.amountRaw - t.amountEffective
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = fee.withSpec(spec),
amountType = AmountType.Negative,
)
}
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_total),
+ label = stringResource(id = R.string.amount_total),
amount = t.amountEffective.withSpec(spec),
amountType = AmountType.Positive,
)
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawFragment.kt
index c499c3b..e829bb1 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawFragment.kt
@@ -20,6 +20,7 @@ import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
+import android.view.View.GONE
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@@ -55,6 +56,13 @@ class ManualWithdrawFragment : Fragment() {
ui.amountView.setText(amount.amountStr)
}
+ arguments?.getBoolean("hideScanQr")?.let {
+ if (it) {
+ ui.qrCodeButton.visibility = GONE
+ ui.orView.visibility = GONE
+ }
+ }
+
ui.qrCodeButton.setOnClickListener {
model.scanCode()
}
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenTransfer.kt b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenTransfer.kt
index 75d03b5..00495fb 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenTransfer.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenTransfer.kt
@@ -193,33 +193,33 @@ fun WithdrawalAmountTransfer(
horizontalAlignment = Alignment.CenterHorizontally,
) {
TransactionAmountComposable(
- label = stringResource(R.string.withdraw_transfer),
+ label = stringResource(R.string.amount_transfer),
amount = conversionAmountRaw,
amountType = AmountType.Neutral,
)
if (amountRaw.currency != conversionAmountRaw.currency) {
TransactionAmountComposable(
- label = stringResource(R.string.withdraw_conversion),
+ label = stringResource(R.string.amount_conversion),
amount = amountRaw,
amountType = AmountType.Neutral,
)
}
- val fee = amountRaw - amountEffective
- if (!fee.isZero()) {
+ if (amountRaw > amountEffective) {
+ val fee = amountRaw - amountEffective
TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_fees),
+ label = stringResource(id = R.string.amount_fee),
amount = fee,
amountType = AmountType.Negative,
)
- }
- TransactionAmountComposable(
- label = stringResource(id = R.string.withdraw_total),
- amount = amountEffective,
- amountType = AmountType.Positive,
- )
+ TransactionAmountComposable(
+ label = stringResource(id = R.string.amount_total),
+ amount = amountEffective,
+ amountType = AmountType.Positive,
+ )
+ }
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferIBAN.kt b/wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferIBAN.kt
index d0bc893..1698530 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferIBAN.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferIBAN.kt
@@ -73,11 +73,11 @@ fun TransferIBAN(
.padding(all = 16.dp)
)
+ DetailRow(stringResource(R.string.withdraw_manual_ready_subject), transfer.subject)
transfer.receiverName?.let {
DetailRow(stringResource(R.string.withdraw_manual_ready_receiver), it)
}
DetailRow(stringResource(R.string.withdraw_manual_ready_iban), transfer.iban)
- DetailRow(stringResource(R.string.withdraw_manual_ready_subject), transfer.subject)
TransactionInfoComposable(
label = stringResource(R.string.withdraw_exchange),
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferTaler.kt b/wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferTaler.kt
index 2ec43b9..089d0de 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferTaler.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/manual/TransferTaler.kt
@@ -73,11 +73,11 @@ fun TransferTaler(
.padding(all = 16.dp)
)
+ DetailRow(stringResource(R.string.withdraw_manual_ready_subject), transfer.subject)
transfer.receiverName?.let {
DetailRow(stringResource(R.string.withdraw_manual_ready_receiver), it)
}
DetailRow(stringResource(R.string.withdraw_manual_ready_account), transfer.account)
- DetailRow(stringResource(R.string.withdraw_manual_ready_subject), transfer.subject)
TransactionInfoComposable(
label = stringResource(R.string.withdraw_exchange),
diff --git a/wallet/src/main/res/drawable/badge.xml b/wallet/src/main/res/drawable/badge.xml
deleted file mode 100644
index 0b06ce5..0000000
--- a/wallet/src/main/res/drawable/badge.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
- ~ This file is part of GNU Taler
- ~ (C) 2020 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/>
- -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="?android:textColorSecondary" />
- <corners android:radius="8dp" />
- <padding
- android:bottom="2dp"
- android:left="8dp"
- android:right="8dp"
- android:top="2dp" />
-</shape> \ No newline at end of file
diff --git a/wallet/src/main/res/drawable/ic_funds_receive.xml b/wallet/src/main/res/drawable/ic_funds_receive.xml
new file mode 100644
index 0000000..f540e4e
--- /dev/null
+++ b/wallet/src/main/res/drawable/ic_funds_receive.xml
@@ -0,0 +1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z"/>
+
+</vector>
diff --git a/wallet/src/main/res/drawable/ic_funds_send.xml b/wallet/src/main/res/drawable/ic_funds_send.xml
new file mode 100644
index 0000000..9696eb6
--- /dev/null
+++ b/wallet/src/main/res/drawable/ic_funds_send.xml
@@ -0,0 +1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M4,12l1.41,1.41L11,7.83V20h2V7.83l5.58,5.59L20,12l-8,-8 -8,8z"/>
+
+</vector>
diff --git a/wallet/src/main/res/drawable/ic_sync.xml b/wallet/src/main/res/drawable/ic_sync.xml
deleted file mode 100644
index 8991613..0000000
--- a/wallet/src/main/res/drawable/ic_sync.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M12,4L12,1L8,5l4,4L12,6c3.31,0 6,2.69 6,6 0,1.01 -0.25,1.97 -0.7,2.8l1.46,1.46C19.54,15.03 20,13.57 20,12c0,-4.42 -3.58,-8 -8,-8zM12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24,7.74C4.46,8.97 4,10.43 4,12c0,4.42 3.58,8 8,8v3l4,-4 -4,-4v3z" />
-</vector>
diff --git a/wallet/src/main/res/drawable/pending_border.xml b/wallet/src/main/res/drawable/pending_border.xml
deleted file mode 100644
index 0e201dc..0000000
--- a/wallet/src/main/res/drawable/pending_border.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ This file is part of GNU Taler
- ~ (C) 2020 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/>
- -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
-
- <!-- View background color -->
- <solid android:color="@android:color/transparent"/>
-
- <!-- View border color and width -->
- <stroke
- android:width="1dp"
- android:color="@color/colorPrimary"/>
-
- <!-- The radius makes the corners rounded -->
- <corners android:radius="2dp"/>
-
-</shape> \ No newline at end of file
diff --git a/wallet/src/main/res/drawable/transaction_tip_accepted.xml b/wallet/src/main/res/drawable/transaction_tip_accepted.xml
deleted file mode 100644
index 27b1ae4..0000000
--- a/wallet/src/main/res/drawable/transaction_tip_accepted.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
- ~ This file is part of GNU Taler
- ~ (C) 2020 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/>
- -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:tint="?attr/colorControlNormal"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="#000"
- android:pathData="M18,21L15,18L18,15V17H22V19H18V21M10,4A4,4 0 0,1 14,8A4,4 0 0,1 10,12A4,4 0 0,1 6,8A4,4 0 0,1 10,4M10,14C11.15,14 12.25,14.12 13.24,14.34C12.46,15.35 12,16.62 12,18C12,18.7 12.12,19.37 12.34,20H2V18C2,15.79 5.58,14 10,14Z" />
-</vector>
diff --git a/wallet/src/main/res/layout-w550dp/payment_bottom_bar.xml b/wallet/src/main/res/layout-w550dp/payment_bottom_bar.xml
index b5eabbe..ebfeabb 100644
--- a/wallet/src/main/res/layout-w550dp/payment_bottom_bar.xml
+++ b/wallet/src/main/res/layout-w550dp/payment_bottom_bar.xml
@@ -31,7 +31,7 @@
android:id="@+id/totalLabelView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/payment_label_amount_total"
+ android:text="@string/amount_total_label"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/totalView"
diff --git a/wallet/src/main/res/layout/balance_actions.xml b/wallet/src/main/res/layout/balance_actions.xml
new file mode 100644
index 0000000..d071a78
--- /dev/null
+++ b/wallet/src/main/res/layout/balance_actions.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ This file is part of GNU Taler
+ ~ (C) 2024 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/>
+ -->
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools">
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/sendButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="10dp"
+ android:layout_marginVertical="10dp"
+ android:paddingHorizontal="18dp"
+ android:text="@string/transactions_send_funds"
+ app:icon="@drawable/ic_funds_send"
+ tools:ignore="MissingConstraints" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/receiveButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="10dp"
+ android:layout_marginVertical="10dp"
+ android:paddingHorizontal="18dp"
+ android:text="@string/transactions_receive_funds"
+ app:icon="@drawable/ic_funds_receive"
+ tools:ignore="MissingConstraints" />
+
+ <androidx.constraintlayout.helper.widget.Flow
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ app:constraint_referenced_ids="sendButton,receiveButton"
+ android:paddingHorizontal="10dp"
+ app:flow_horizontalGap="10dp"
+ app:flow_horizontalBias="0"
+ app:flow_horizontalAlign="start"
+ app:flow_horizontalStyle="packed"
+ app:flow_wrapMode="chain"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/amountBarrier"
+ app:layout_constraintBottom_toBottomOf="@id/topBarrier"/>
+
+ <androidx.constraintlayout.widget.Barrier
+ android:id="@+id/amountBarrier"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/divider"
+ app:barrierDirection="start"/>
+
+ <LinearLayout
+ android:id="@+id/amountLayout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:orientation="vertical"
+ android:gravity="end"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/divider"
+ app:layout_constraintStart_toEndOf="@id/amountBarrier">
+
+ <TextView
+ android:id="@+id/balanceLabel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="16dp"
+ android:text="@string/transactions_balance"
+ android:textSize="14sp" />
+
+ <TextView
+ android:id="@+id/amount"
+ style="@style/TextAppearance.Material3.TitleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="16dp"
+ android:layout_marginBottom="8dp"
+ android:textStyle="bold"
+ tools:text="23.42"
+ tools:visibility="visible" />
+
+ </LinearLayout>
+
+ <androidx.constraintlayout.widget.Barrier
+ android:id="@+id/topBarrier"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:barrierDirection="bottom"
+ app:constraint_referenced_ids="sendButton,receiveButton,amountLayout" />
+
+ <com.google.android.material.divider.MaterialDivider
+ android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/topBarrier" />
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/wallet/src/main/res/layout/fragment_prompt_withdraw.xml b/wallet/src/main/res/layout/fragment_prompt_withdraw.xml
index 44d95de..e77a549 100644
--- a/wallet/src/main/res/layout/fragment_prompt_withdraw.xml
+++ b/wallet/src/main/res/layout/fragment_prompt_withdraw.xml
@@ -64,7 +64,7 @@
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:gravity="center"
- android:text="@string/withdraw_fees"
+ android:text="@string/amount_fee"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/feeView"
app:layout_constraintEnd_toEndOf="parent"
@@ -100,7 +100,7 @@
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:gravity="center"
- android:text="@string/withdraw_total"
+ android:text="@string/amount_total"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/effectiveAmountView"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/wallet/src/main/res/layout/fragment_transactions.xml b/wallet/src/main/res/layout/fragment_transactions.xml
index 8fa46f5..c417540 100644
--- a/wallet/src/main/res/layout/fragment_transactions.xml
+++ b/wallet/src/main/res/layout/fragment_transactions.xml
@@ -20,87 +20,40 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.google.android.material.button.MaterialButton
- android:id="@+id/sendButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="10dp"
- android:text="@string/transactions_send_funds"
- app:layout_constraintBottom_toTopOf="@+id/divider"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
+ <androidx.core.widget.NestedScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <com.google.android.material.button.MaterialButton
- android:id="@+id/receiveButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginHorizontal="10dp"
- android:text="@string/transactions_receive_funds"
- app:layout_constraintBottom_toTopOf="@+id/divider"
- app:layout_constraintEnd_toStartOf="@+id/amount"
- app:layout_constraintHorizontal_chainStyle="spread_inside"
- app:layout_constraintStart_toEndOf="@+id/sendButton"
- app:layout_constraintTop_toTopOf="parent" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
- <TextView
- android:id="@+id/balanceLabel"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginEnd="16dp"
- android:text="@string/transactions_balance"
- android:textSize="14sp"
- app:layout_constraintBottom_toTopOf="@+id/amount"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_bias="1.0"
- app:layout_constraintStart_toEndOf="@+id/receiveButton"
- app:layout_constraintTop_toTopOf="parent" />
+ <FrameLayout
+ android:id="@+id/actionsFrame"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent">
+ <include
+ android:id="@+id/actionsBar"
+ layout="@layout/balance_actions"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"/>
+ </FrameLayout>
- <TextView
- android:id="@+id/amount"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="16dp"
- android:layout_marginBottom="8dp"
- android:textSize="24sp"
- android:textStyle="bold"
- app:layout_constrainedWidth="true"
- app:layout_constraintBottom_toTopOf="@+id/divider"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintStart_toEndOf="@+id/receiveButton"
- app:layout_constraintTop_toBottomOf="@+id/balanceLabel"
- tools:text="23.42"
- tools:visibility="visible" />
-
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/topBarrier"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:barrierDirection="bottom"
- app:constraint_referenced_ids="sendButton,receiveButton,amount" />
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:nestedScrollingEnabled="false"
+ android:scrollbars="vertical"
+ android:visibility="invisible"
+ app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+ tools:listitem="@layout/list_item_transaction"
+ tools:visibility="visible" />
- <com.google.android.material.divider.MaterialDivider
- android:id="@+id/divider"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/topBarrier" />
+ </LinearLayout>
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/list"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:scrollbars="vertical"
- android:visibility="invisible"
- app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/divider"
- tools:listitem="@layout/list_item_transaction"
- tools:visibility="visible" />
+ </androidx.core.widget.NestedScrollView>
<TextView
android:id="@+id/emptyState"
@@ -115,7 +68,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/divider"
+ app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<ProgressBar
@@ -128,7 +81,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/divider"
+ app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
diff --git a/wallet/src/main/res/layout/fragment_uri_input.xml b/wallet/src/main/res/layout/fragment_uri_input.xml
index 95c2297..6547625 100644
--- a/wallet/src/main/res/layout/fragment_uri_input.xml
+++ b/wallet/src/main/res/layout/fragment_uri_input.xml
@@ -68,7 +68,7 @@
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:backgroundTint="@color/green"
- android:text="@string/ok"
+ android:text="@string/open"
android:textColor="@android:color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/pasteButton"
diff --git a/wallet/src/main/res/layout/list_item_balance.xml b/wallet/src/main/res/layout/list_item_balance.xml
index 53e3d89..6e5e440 100644
--- a/wallet/src/main/res/layout/list_item_balance.xml
+++ b/wallet/src/main/res/layout/list_item_balance.xml
@@ -14,9 +14,9 @@
~ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-->
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
@@ -26,26 +26,16 @@
android:id="@+id/balanceAmountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="8dp"
style="?textAppearanceDisplaySmall"
- app:layout_constraintEnd_toStartOf="@+id/pendingView"
- app:layout_constraintHorizontal_bias="0.0"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
tools:text="100.50" />
<TextView
android:id="@+id/scopeView"
- android:layout_width="0dp"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
style="?textAppearanceBodyMedium"
android:visibility="gone"
- app:layout_constraintTop_toBottomOf="@id/balanceAmountView"
- app:layout_constraintBottom_toTopOf="@id/balanceInboundAmount"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/pendingView"
tools:text="@string/balance_scope_exchange"
tools:visibility="visible"/>
@@ -54,40 +44,17 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/green"
- android:textSize="20sp"
style="?textAppearanceBodyLarge"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@+id/balanceInboundLabel"
- app:layout_constraintHorizontal_bias="0.0"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/scopeView"
- tools:text="+10 TESTKUDOS"
+ tools:text="+10 TESTKUDOS inbound"
tools:visibility="visible" />
<TextView
- android:id="@+id/balanceInboundLabel"
+ android:id="@+id/balanceOutboundAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
- android:text="@string/balances_inbound_label"
- android:textColor="@color/green"
- style="?textAppearanceBodyMedium"
- app:layout_constraintBottom_toBottomOf="@+id/balanceInboundAmount"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toEndOf="@+id/balanceInboundAmount"
- app:layout_constraintTop_toTopOf="@+id/balanceInboundAmount"
+ android:textColor="?colorError"
+ style="?textAppearanceBodyLarge"
+ tools:text="-10 TESTKUDOS outbound"
tools:visibility="visible" />
- <TextView
- android:id="@+id/pendingView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/badge"
- android:text="@string/transaction_pending"
- android:textColor="?android:textColorPrimaryInverse"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
+</LinearLayout>
diff --git a/wallet/src/main/res/layout/payment_bottom_bar.xml b/wallet/src/main/res/layout/payment_bottom_bar.xml
index 496f2f3..9026127 100644
--- a/wallet/src/main/res/layout/payment_bottom_bar.xml
+++ b/wallet/src/main/res/layout/payment_bottom_bar.xml
@@ -33,7 +33,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
- android:text="@string/payment_label_amount_total"
+ android:text="@string/amount_total_label"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="@+id/confirmButton"
app:layout_constraintEnd_toStartOf="@+id/totalView"
diff --git a/wallet/src/main/res/navigation/nav_graph.xml b/wallet/src/main/res/navigation/nav_graph.xml
index f6c90ab..ea3ae38 100644
--- a/wallet/src/main/res/navigation/nav_graph.xml
+++ b/wallet/src/main/res/navigation/nav_graph.xml
@@ -36,7 +36,7 @@
<fragment
android:id="@+id/handleUri"
android:name="net.taler.wallet.HandleUriFragment"
- android:label="@string/handle_uri_title">
+ android:label="@string/loading">
<argument
android:name="uri"
app:argType="string"
@@ -172,6 +172,10 @@
android:name="amount"
app:argType="string"
app:nullable="false" />
+ <argument
+ android:name="hideScanQr"
+ app:argType="boolean"
+ app:nullable="false" />
</fragment>
<fragment
diff --git a/wallet/src/main/res/values-es/strings.xml b/wallet/src/main/res/values-es/strings.xml
index bcc216d..5cb3e73 100644
--- a/wallet/src/main/res/values-es/strings.xml
+++ b/wallet/src/main/res/values-es/strings.xml
@@ -2,10 +2,10 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="google_play_title" tools:keep="@string/google_play_title">Cartera Taler (experimental)</string>
<string name="nav_prompt_withdraw">Retirar efectivo digital</string>
- <string name="nav_exchange_tos">Términos de servicio del cambiario</string>
+ <string name="nav_exchange_tos">Términos de servicio del proveedor</string>
<string name="nav_exchange_select">Seleccionar cambiario</string>
<string name="button_back">Regresar</string>
- <string name="enter_uri">Ingresa la URI de Taler</string>
+ <string name="enter_uri">Ingresa la dirección taler://</string>
<string name="paste">Pegar</string>
<string name="paste_invalid">El portapapeles contiene un tipo de dato inválido</string>
<string name="ok">OK</string>
@@ -13,11 +13,11 @@
<string name="search">Buscar</string>
<string name="menu">Menú</string>
<string name="or">o</string>
- <string name="error_unsupported_uri">Error: esta URI de Taler no está soportada.</string>
+ <string name="error_unsupported_uri">Error: esta dirección taler:// no está soportada.</string>
<string name="menu_settings">Ajustes</string>
<string name="balances_title">Saldos</string>
<string name="amount_positive">+%s</string>
- <string name="amount_chosen">Monto elegido</string>
+ <string name="amount_chosen">Monto seleccionado</string>
<string name="balances_inbound_label">entrada</string>
<string name="transactions_empty">No tienes ninguna transacción</string>
<string name="transactions_detail_title">Transacción</string>
@@ -25,7 +25,7 @@
<string name="transactions_select_all">Seleccionar todo</string>
<string name="transaction_paid">Pagado</string>
<string name="transaction_order_total">Total</string>
- <string name="transaction_order_id">Recibo #%1$s</string>
+ <string name="transaction_order_id">Orden #%1$s</string>
<string name="transaction_tip_from">Premio de %s</string>
<string name="transaction_refund">Devolución</string>
<string name="transaction_refund_from">Devolución de %s</string>
@@ -45,30 +45,30 @@
<string name="withdraw_title">Retiro</string>
<string name="withdraw_total">Retirar</string>
<string name="withdraw_fees">Comisión</string>
- <string name="withdraw_exchange">Cambiario</string>
+ <string name="withdraw_exchange">Proveedor</string>
<string name="withdraw_button_confirm">Confirmar retiro</string>
<string name="withdraw_button_tos">Revisar términos</string>
<string name="withdraw_waiting_confirm">Esperando confirmación</string>
- <string name="withdraw_manual_title">Realizar transferencia manual al cambiario</string>
+ <string name="withdraw_manual_title">Realizar transferencia manual al proveedor</string>
<string name="withdraw_amount">¿Cuánto deseas retirar\?</string>
<string name="withdraw_manual_check_fees">Comisiones por cheque</string>
<string name="withdraw_error_title">Error en el retiro</string>
<string name="withdraw_error_test">Error retirando TESTKUDOS</string>
- <string name="exchange_settings_title">Cambiarios</string>
- <string name="exchange_settings_summary">Gestionar la lista de cambiarios conocidos en esta cartera</string>
- <string name="exchange_list_title">Cambiarios</string>
- <string name="exchange_list_empty">Sin cambiarios conocidos
+ <string name="exchange_settings_title">Proveedores</string>
+ <string name="exchange_settings_summary">Gestionar la lista de proveedores conocidos en esta cartera</string>
+ <string name="exchange_list_title">Proveedores</string>
+ <string name="exchange_list_empty">Sin proveedores conocidos
\n
\nAñade uno manualmente or retira efectivo digital.</string>
<string name="exchange_list_currency">Divisa: %s</string>
- <string name="exchange_list_add">Añadir cambiario</string>
- <string name="exchange_add_url">Ingresa dirección del cambiario</string>
- <string name="exchange_add_error">No se pudo añadir el cambiario</string>
+ <string name="exchange_list_add">Añadir proveedor</string>
+ <string name="exchange_add_url">Ingresa dirección del proveedor</string>
+ <string name="exchange_add_error">No se pudo añadir el proveedor</string>
<string name="exchange_fee_withdrawal_fee_label">Comisión por retiro:</string>
<string name="exchange_fee_overhead_label">Pérdida por redondeo:</string>
<string name="exchange_fee_coin_expiration_label">Expiración de moneda más temprana:</string>
<string name="exchange_fee_coin_fees_label">Comisiones de moneda</string>
- <string name="exchange_fee_wire_fees_label">Comisiones de transferencia</string>
+ <string name="exchange_fee_wire_fees_label">Comisiones por transferencia</string>
<string name="exchange_fee_withdraw_fee">Comisión por retiro: %s</string>
<string name="exchange_fee_deposit_fee">Comisión por depósito: %s</string>
<string name="exchange_fee_refresh_fee">Comisión por cambio: %s</string>
@@ -99,18 +99,18 @@
<string name="refund_error">Error procesando la devolución</string>
<string name="refund_success">Devolución recibida: %s</string>
<string name="tip_title">Premio</string>
- <string name="wifi_disabled_error">Enciende tu Wi-Fi para obtener Wi-Fi gratis</string>
- <string name="wifi_connect_error">No se pudo conectar al Wi-Fi gratis: %s</string>
+ <string name="wifi_disabled_error">Enciende tu Wi-Fi para obtener Wi-Fi gratuito</string>
+ <string name="wifi_connect_error">No se pudo conectar al Wi-Fi gratuito: %s</string>
<string name="app_name">Cartera Taler</string>
<string name="google_play_short_desc" tools:keep="@string/google_play_short_desc">GNU Taler hace transacciones en línea amigables con la privacidad, de forma rápida y sencilla.</string>
<string name="google_play_full_desc" tools:keep="@string/google_play_full_desc">Esta aplicación es una cartera para GNU Taler. Es altamente experimental, y aún no está lista para producción. GNU Taler es un sistema de pago que preserva la privacidad. Los clientes pueden permanecer anónimos, pero los comerciantes no pueden esconder sus ingresos a través de GNU Taler. Esto ayuda a evitar la evasión de impuestos y el lavado de dinero. El uso principal de GNU Taler son los pagos; su intención no es servir como reserva de valor. Los pagos siempre están respaldados por una divisa existente. El pago se realiza después de cambiar dinero existente por dinero electrónico con la ayuda de un servicio de cambiario, que es un proveedor de servicios de pagos para Taler. Cuando se realiza un pago, los clientes solo necesitan una cartera con fondos. Un comerciante puede aceptar pagos sin hacer que sus clientes se registren en su página Web. GNU Taler es inmune contra varios tipos de fraude, como el phising de información de tarjetas de crédito o el fraude por devolución. En caso de pérdida o robo, solo una cantidad limitada de dinero guardado en la cartera podría perderse.</string>
<string name="nav_header_title">GNU Taler</string>
<string name="nav_header_subtitle">Cartera</string>
- <string name="nav_exchange_fees">Comisiones del cambiario</string>
+ <string name="nav_exchange_fees">Comisiones del proveedor</string>
<string name="nav_error">Error</string>
<string name="button_scan_qr_code">Escanear código QR de Taler</string>
- <string name="uri_invalid">URI de Taler inválida</string>
- <string name="offline">La operación requiere acceso a Internet. Por favor asegúrate que tu conexión a Internet funcione y prueba de nuevo.</string>
+ <string name="uri_invalid">Dirección taler:// inválida</string>
+ <string name="offline">La operación requiere de acceso a Internet. Por favor asegúrate que tu conexión a Internet funcione y prueba de nuevo.</string>
<string name="menu_retry_pending_operations">Reintentar operaciones pendientes</string>
<string name="amount_negative">-%s</string>
<string name="balances_empty_state">No hay efectivo digital en tu cartera.
@@ -150,7 +150,7 @@
<string name="transaction_peer_push_credit">Pago push</string>
<string name="transaction_peer_pull_credit">Cobro</string>
<string name="receive_peer_invoice_instruction">Muestra este código QR a quien pagará:</string>
- <string name="receive_peer_invoice_uri">O bien, copia y envía esta URI:</string>
+ <string name="receive_peer_invoice_uri">O bien, copia y envía esta dirección:</string>
<string name="receive_peer_create_button">Crear cobro</string>
<string name="pay_peer_title">Pagar factura</string>
<string name="send_peer_create_button">Enviar fondos ahora</string>
@@ -164,10 +164,8 @@
<string name="transactions_balance">Saldo</string>
<string name="withdraw_manual_ready_bank_button">Abrir en aplicación de banco</string>
<string name="copy_uri">Copiar URI de Taler</string>
- <string name="transactions_send_funds">Enviar
-\nfondos</string>
- <string name="transactions_receive_funds">Recibir
-\nfondos</string>
+ <string name="transactions_send_funds">Enviar</string>
+ <string name="transactions_receive_funds">Recibir</string>
<string name="transactions_cancel_dialog_message">¿Estás seguro de que deseas cancelar este retiro\? Los fondos que están en tránsito podrían perderse.</string>
<string name="transactions_detail_title_currency">Transacciones de %s</string>
<string name="receive_peer_title">Solicitar pago</string>
@@ -197,20 +195,20 @@
<string name="withdraw_manual_bitcoin_intro">Ahora haz una transacción dividida con las siguientes tres salidas.</string>
<string name="withdraw_manual_ready_subject">Sujeto</string>
<string name="settings_logcat_error">Error exportando bitácora</string>
- <string name="settings_logcat_success">Bitácora exportada al archivo</string>
+ <string name="settings_logcat_success">La bitácora fue exportada al archivo</string>
<string name="tip_total">Total</string>
<string name="send_peer_purpose">Motivo</string>
<string name="send_peer_bitcoin">A otra cartera de Taler</string>
- <string name="withdraw_manual_ready_intro">Para completar el proceso, necesitas transferir %s a la cuenta bancaria del cambiario</string>
+ <string name="withdraw_manual_ready_intro">Para completar el proceso, necesitas transferir %s a la cuenta bancaria del proveedor</string>
<string name="withdraw_manual_bitcoin_title">Cambiario de Bitcoin listo para el retiro</string>
<string name="settings_db_export_summary">Guardar base de datos interna</string>
- <string name="settings_db_export_success">Base de datos exportada al archivo</string>
+ <string name="settings_db_export_success">La base de datos fue exportada al archivo</string>
<string name="tip_button_confirm">Aceptar premio</string>
<string name="tip_received">Premio recibido</string>
<string name="tip_fees">Comisión</string>
<string name="send_deposit_bitcoin">A una cartera de Bitcoin</string>
<string name="settings_db_export">Exportar base de datos</string>
- <string name="settings_db_export_error">Error exportando base de datos</string>
+ <string name="settings_db_export_error">Error al exportar la base de datos</string>
<string name="withdraw_manual_ready_warning">Asegúrate de usar el sujeto correcto; de lo contrario, el dinero no llegará a esta cartera.</string>
<string name="transaction_action_kyc">Completar KYC</string>
<string name="withdraw_restrict_age">Restringir uso a edad</string>
@@ -218,28 +216,28 @@
<string name="withdraw_manual_ready_iban">IBAN</string>
<string name="send_deposit_check_fees_button">Revisar comisiones</string>
<string name="char_count">%1$d/%2$d</string>
- <string name="transactions_delete_selected_dialog_message">¿Estás seguro de que deseas eliminar las transacciones seleccionadas de tu cartera\?</string>
+ <string name="transactions_delete_selected_dialog_message">¿Estás seguro de que deseas eliminar de tu cartera las transacciones seleccionadas?</string>
<string name="send_deposit_bitcoin_address">Dirección Bitcoin</string>
<string name="send_deposit_bitcoin_create_button">Transferir Bitcoin</string>
<string name="transaction_dummy_title">Transacción desconocida</string>
<string name="send_deposit_bic_error">BIC es inválido</string>
<string name="send_peer_expiration_period">Expira en</string>
<string name="send_peer_expiration_1d">1 día</string>
- <string name="send_peer_expiration_7d">7 días</string>
+ <string name="send_peer_expiration_7d">1 semana</string>
<string name="settings_test_summary">Realizar transacciones de prueba con el banco demostrativo</string>
<string name="settings_test">Ejecutar pruebas de integración</string>
<string name="button_scan_qr_code_label">Escanear código QR</string>
- <string name="send_deposit_iban_error">IBAN es inválido</string>
+ <string name="send_deposit_iban_error">IBAN inválido</string>
<string name="send_peer_expiration_30d">30 días</string>
<string name="send_peer_expiration_custom">Personalizado</string>
<string name="send_peer_expiration_days">Días</string>
<string name="send_peer_expiration_hours">Horas</string>
- <string name="exchange_list_error">No se pudo listar los cambiarios</string>
+ <string name="exchange_list_error">No se pudo listar los proveedores</string>
<string name="payment_prompt_title">Revisar pago</string>
<string name="payment_pay_template_title">Personaliza tu orden</string>
<string name="payment_create_order">Crear orden</string>
<string name="payment_confirmation_code">Código de confirmación</string>
- <string name="payment_template_error">Error creando orden</string>
+ <string name="payment_template_error">Error al crear la orden</string>
<string name="transactions_retry">Reintentar</string>
<string name="transactions_abort">Abortar</string>
<string name="transactions_fail">Matar</string>
@@ -247,27 +245,67 @@
<string name="transactions_resume">Resumir</string>
<string name="transactions_abort_dialog_title">Abortar transacción</string>
<string name="transactions_fail_dialog_message">¿Estás seguro de que deseas matar esta transacción\? Los fondos en tránsito SE PERDERÁN.</string>
- <string name="exchange_not_contacted">Cambiario aún no contactado</string>
+ <string name="exchange_not_contacted">Proveedor aún no contactado</string>
<string name="transactions_fail_dialog_title">Matar transacción</string>
<string name="transactions_abort_dialog_message">¿Estás seguro de que deseas abortar esta transacción\? Los fondos en tránsito podrían perderse.</string>
<string name="offline_banner">Sin acceso a internet</string>
- <string name="error_broken_uri">Error: Este URI taler no funciona actualmente.</string>
+ <string name="error_broken_uri">Error: esta dirección taler:// no funciona actualmente.</string>
<string name="withdraw_subtitle">Seleccione un cuenta bancaria destino</string>
<string name="withdraw_account">Cuenta #%1$d</string>
<string name="withdraw_account_currency">Cuenta #%1$d (%2$s)</string>
<string name="withdraw_transfer">Transferencia</string>
<string name="withdraw_conversion">Conversión</string>
<string name="withdraw_conversion_support">Este exchange soporta conversión de moneda</string>
- <string name="exchange_list_add_dev">Agregar exchange de desarrollo</string>
+ <string name="exchange_list_add_dev">Agregar proveedores de desarrollo</string>
<string name="settings_db_import">Importar base de datos</string>
<string name="settings_db_import_summary">Restaurar base de datos desde archivo</string>
<string name="settings_db_import_error">Error al importar la base de datos</string>
- <string name="settings_db_import_success">Base de datos importada desde archivo</string>
- <string name="settings_dialog_reset_message">Realmente quieres reiniciar la biiletera y perder todas las monedas y compras?</string>
- <string name="settings_dialog_import_message">Esta operación sobreescribirá toda tu base de datos. Realmente quieres continuar?</string>
+ <string name="settings_db_import_success">La base de datos fue importada desde el archivo</string>
+ <string name="settings_dialog_reset_message">¿Realmente deseas reiniciar la biiletera y perder todas las monedas y compras?</string>
+ <string name="settings_dialog_import_message">Esta operación sobreescribirá tu base de datos. ¿Realmente deseas continuar?</string>
<string name="settings_alert_reset_done">La billetera ha sido reiniciada</string>
<string name="settings_alert_reset_canceled">Reinicio cancelado</string>
<string name="settings_alert_import_canceled">Importación cancelada</string>
<string name="import_db">Importar</string>
<string name="reset">Reiniciar</string>
+ <string name="share_payment">Compartir enlace de pago</string>
+ <string name="balance_scope_auditor">Auditor: %1$s</string>
+ <string name="balance_scope_exchange">De %1$s</string>
+ <string name="exchange_list_select">Seleccionar proveedor</string>
+ <string name="exchange_delete">Eliminar proveedor</string>
+ <string name="transactions_send_funds_title">Enviar %1$s</string>
+ <string name="show_logs">Mostrar bitácora</string>
+ <string name="settings_db_clear_error">Error limpiando base de datos</string>
+ <string name="amount_conversion">Conversión</string>
+ <string name="balances_inbound_amount">+%1$s entrante</string>
+ <string name="transactions_receive_funds_title">Recibir %1$s</string>
+ <string name="observability_title">Bitácora interna de eventos</string>
+ <string name="amount_received">Monto recibido</string>
+ <string name="amount_sent">Monto enviado</string>
+ <string name="transaction_denom_loss">Pérdida de fondos</string>
+ <string name="payment_pending">El pago no fue completado, se volverá a intentar</string>
+ <string name="exchange_delete_force">Forzar eliminación (purgar)</string>
+ <string name="loading">Cargando</string>
+ <string name="open">Abrir</string>
+ <string name="amount_effective">Monto efectivo</string>
+ <string name="amount_fee">Comisión</string>
+ <string name="amount_invalid">Monto inválido</string>
+ <string name="amount_lost">Monto perdido</string>
+ <string name="amount_receive">Monto a recibir</string>
+ <string name="amount_send">Monto a enviar</string>
+ <string name="amount_total">Monto total</string>
+ <string name="amount_total_label">Total:</string>
+ <string name="balances_outbound_amount">-%1$s saliente</string>
+ <string name="amount_invoiced">Monto cobrado</string>
+ <string name="amount_transfer">Transferir</string>
+ <string name="transaction_deposit_to">Depósito a %1$s</string>
+ <string name="withdraw_manual_ready_account">Cuenta</string>
+ <string name="withdraw_manual_ready_receiver">Nombre del receptor</string>
+ <string name="exchange_reload">Recargar información</string>
+ <string name="loss_reason">Razón</string>
+ <string name="loss_reason_expired">Los fondos no fueron renovados porque la cartera no se abrió en un largo tiempo</string>
+ <string name="loss_reason_unoffered">El proveedor de pagos dejó de ofrecer la denominación que respaldaba los fondos</string>
+ <string name="loss_reason_vanished">El proveedor de pagos perdió el registro de los fondos</string>
+ <string name="observability_hide_json">Ocultar JSON</string>
+ <string name="observability_show_json">Mostrar JSON</string>
</resources> \ No newline at end of file
diff --git a/wallet/src/main/res/values-it/strings.xml b/wallet/src/main/res/values-it/strings.xml
index fdc4594..61bb306 100644
--- a/wallet/src/main/res/values-it/strings.xml
+++ b/wallet/src/main/res/values-it/strings.xml
@@ -226,7 +226,7 @@
<string name="settings_db_export_error">Errore nell\'esportazione della banca dati</string>
<string name="transactions_abort">Annulla</string>
<string name="transactions_fail">Arresta</string>
- <string name="transactions_abort_dialog_title">Annulla la Transazione</string>
+ <string name="transactions_abort_dialog_title">Annulla la transazione</string>
<string name="transactions_fail_dialog_title">Annulla la Transazione</string>
<string name="transactions_fail_dialog_message">Sei sicuro di voler annullare questa transazione? I fondi ancora in transito ANDRANNO PERSI.</string>
<string name="transactions_abort_dialog_message">Sei sicuro di voler annullare questa transazione? I fondi ancora in transito potrebbero andare persi.</string>
diff --git a/wallet/src/main/res/values-ja/strings.xml b/wallet/src/main/res/values-ja/strings.xml
index ea841bd..beb6110 100644
--- a/wallet/src/main/res/values-ja/strings.xml
+++ b/wallet/src/main/res/values-ja/strings.xml
@@ -59,4 +59,4 @@
<string name="transaction_refund">返金</string>
<string name="transaction_refund_from">%sの返金</string>
<string name="transaction_pending">保留中</string>
-</resources>
+</resources> \ No newline at end of file
diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml
index 8466e2d..b5dcc02 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -14,9 +14,13 @@
~ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-->
+<!-- NOTE: please organize strings in alphabetic order! -->
+
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Taler Wallet</string>
+ <!-- Google Play Store -->
+
<string name="google_play_title" tools:keep="@string/google_play_title">Taler Wallet (experimental)</string>
<string name="google_play_short_desc" tools:keep="@string/google_play_short_desc">GNU Taler makes privacy-friendly online transactions fast and easy.</string>
<string name="google_play_full_desc" tools:keep="@string/google_play_full_desc"><![CDATA[
@@ -33,147 +37,161 @@ When making a payment, customers only need a charged wallet. A merchant can acce
GNU Taler is immune against many types of fraud, such as phishing of credit card information or chargeback fraud. In case of loss or theft, only the limited amount of money left in the wallet might be gone.
]]></string>
- <string name="nav_header_title">GNU Taler</string>
- <string name="nav_header_subtitle">Wallet</string>
+ <!-- Navigation -->
- <string name="nav_prompt_withdraw">Withdraw Digital Cash</string>
- <string name="nav_exchange_tos">Exchange\'s Terms of Service</string>
- <string name="nav_exchange_select">Select Exchange</string>
- <string name="nav_exchange_fees">Exchange Fees</string>
<string name="nav_error">Error</string>
+ <string name="nav_exchange_fees">Provider fees</string>
+ <string name="nav_exchange_tos">PSP\'s Terms of Service</string>
+ <string name="nav_header_subtitle">Wallet</string>
+ <string name="nav_header_title">GNU Taler</string>
+ <string name="nav_prompt_withdraw">Withdraw Digital Cash</string>
+
+ <!-- General -->
<string name="button_back">Go Back</string>
<string name="button_scan_qr_code">Scan Taler QR Code</string>
<string name="button_scan_qr_code_label">Scan QR code</string>
- <string name="enter_uri">Enter Taler URI</string>
- <string name="copy" tools:override="true">Copy</string>
- <string name="copy_uri">Copy Taler URI</string>
- <string name="paste">Paste</string>
- <string name="paste_invalid">Clipboard contains an invalid data type</string>
- <string name="uri_invalid">Not a valid Taler URI</string>
- <string name="ok">OK</string>
<string name="cancel">Cancel</string>
- <string name="search">Search</string>
- <string name="menu">Menu</string>
- <string name="or">or</string>
- <string name="currency">Currency</string>
<!-- The count should be mirrored in RTL languages -->
<string name="char_count">%1$d/%2$d</string>
+ <string name="copy" tools:override="true">Copy</string>
+ <string name="currency">Currency</string>
+ <string name="enter_uri">Enter taler:// URI</string>
<string name="import_db">Import</string>
+ <string name="loading">Loading</string>
+ <string name="menu">Menu</string>
+ <string name="offline">Operation requires internet access. Please ensure your internet connection works and try again.</string>
+ <string name="offline_banner">No internet access</string>
+ <string name="ok">OK</string>
+ <string name="open">Open</string>
+ <string name="or">or</string>
+ <string name="paste">Paste</string>
+ <string name="paste_invalid">Clipboard contains an invalid data type</string>
<string name="reset">Reset</string>
+ <string name="search">Search</string>
<string name="share_payment">Share payment link</string>
+ <string name="uri_invalid">Not a valid Taler URI</string>
+
+ <!-- Errors -->
- <string name="offline">Operation requires internet access. Please ensure your internet connection works and try again.</string>
- <string name="offline_banner">No internet access</string>
<string name="error_unsupported_uri">Error: This Taler URI is not supported.</string>
<string name="error_broken_uri">Error: This Taler URI is (currently) not working.</string>
- <string name="menu_settings">Settings</string>
- <string name="menu_retry_pending_operations">Retry Pending Operations</string>
+ <!-- Amounts -->
- <string name="host_apdu_service_desc">Taler NFC Payments</string>
-
- <string name="handle_uri_title">Loading action</string>
-
- <string name="balances_title">Balances</string>
- <string name="amount_positive">+%s</string>
+ <string name="amount_chosen">Chosen amount</string>
+ <string name="amount_conversion">Conversion</string>
+ <string name="amount_effective">Effective amount</string>
+ <string name="amount_fee">Fee</string>
+ <string name="amount_invalid">Amount invalid</string>
+ <string name="amount_invoiced">Amount invoiced</string>
+ <string name="amount_lost">Amount lost</string>
<string name="amount_negative">-%s</string>
- <string name="amount_chosen">Chosen Amount</string>
- <string name="amount_sent">Amount sent</string>
+ <string name="amount_positive">+%s</string>
+ <string name="amount_receive">Amount to receive</string>
<string name="amount_received">Amount received</string>
- <string name="balances_inbound_label">inbound</string>
- <string name="balances_empty_state">There is no digital cash in your wallet.\n\nYou can get test money from the demo bank:\n\nhttps://bank.demo.taler.net</string>
- <string name="balance_scope_exchange">Exchange: %1$s</string>
+ <string name="amount_send">Amount to send</string>
+ <string name="amount_sent">Amount sent</string>
+ <string name="amount_total">Total amount</string>
+ <string name="amount_total_label">Total:</string>
+ <string name="amount_transfer">Transfer</string>
+
+ <!-- Balances -->
+
<string name="balance_scope_auditor">Auditor: %1$s</string>
+ <string name="balance_scope_exchange">From %1$s</string>
+ <string name="balances_empty_state">There is no digital cash in your wallet.\n\nYou can get test money from the demo bank:\n\nhttps://bank.demo.taler.net</string>
+ <string name="balances_inbound_amount">+%1$s inbound</string>
+ <string name="balances_outbound_amount">-%1$s outbound</string>
+ <string name="balances_title">Balances</string>
- <string name="transactions_title">Transactions</string>
+ <!-- Transactions -->
+
+ <string name="transaction_action_kyc">Complete KYC</string>
+ <string name="transaction_denom_loss">Loss of funds</string>
+ <string name="transaction_deposit">Deposit</string>
+ <string name="transaction_deposit_to">Deposit to %1$s</string>
+ <string name="transaction_dummy_title">Unknown Transaction</string>
+ <string name="transaction_order">Purchase</string>
+ <string name="transaction_order_id">Order #%1$s</string>
+ <string name="transaction_order_total">Total</string>
+ <string name="transaction_paid">Paid</string>
+ <string name="transaction_peer_pull_credit">Invoice</string>
+ <string name="transaction_peer_pull_debit">Invoice paid</string>
+ <string name="transaction_peer_push_credit">Push payment</string>
+ <string name="transaction_peer_push_debit">Push payment</string>
+ <string name="transaction_pending">PENDING</string>
+ <string name="transaction_refresh">Coin expiry change fee</string>
+ <string name="transaction_refund">Refund</string>
+ <string name="transactions_abort">Abort</string>
+ <string name="transactions_abort_dialog_message">Are you sure you want to abort this transaction? Funds still in transit might get lost.</string>
+ <string name="transactions_abort_dialog_title">Abort Transaction</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_delete">Delete</string>
+ <string name="transactions_delete_dialog_message">Are you sure you want to remove this transaction from your wallet?</string>
+ <string name="transactions_delete_dialog_title">Delete Transaction</string>
+ <string name="transactions_delete_selected_dialog_message">Are you sure you want to remove the selected transactions from your wallet?</string>
+ <string name="transactions_detail_title">Transaction</string>
+ <string name="transactions_detail_title_currency">%s transactions</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>
- <string name="transactions_detail_title">Transaction</string>
- <string name="transactions_detail_title_currency">%s Transactions</string>
- <string name="transactions_delete">Delete</string>
- <string name="transactions_retry">Retry</string>
- <string name="transactions_abort">Abort</string>
<string name="transactions_fail">Kill</string>
- <string name="transactions_suspend">Suspend</string>
+ <string name="transactions_fail_dialog_message">Are you sure you want to kill this transaction? Funds still in transit WILL GET LOST.</string>
+ <string name="transactions_fail_dialog_title">Kill Transaction</string>
+ <string name="transactions_receive_funds">Receive</string>
+ <string name="transactions_receive_funds_title">Receive %1$s</string>
<string name="transactions_resume">Resume</string>
+ <string name="transactions_retry">Retry</string>
<string name="transactions_select_all">Select All</string>
- <string name="transactions_delete_dialog_title">Delete Transaction</string>
- <string name="transactions_delete_dialog_message">Are you sure you want to remove this transaction from your wallet?</string>
- <string name="transactions_delete_selected_dialog_message">Are you sure you want to remove the selected transactions from your wallet?</string>
- <string name="transactions_abort_dialog_title">Abort Transaction</string>
- <string name="transactions_abort_dialog_message">Are you sure you want to abort this transaction? Funds still in transit might get lost.</string>
- <string name="transactions_fail_dialog_title">Kill Transaction</string>
- <string name="transactions_fail_dialog_message">Are you sure you want to kill this transaction? Funds still in transit WILL GET LOST.</string>
- <string name="transactions_cancel_dialog_message">Are you sure you want to cancel this withdrawal? Funds still in transit might get lost.</string>
+ <string name="transactions_send_funds">Send</string>
+ <string name="transactions_send_funds_title">Send %1$s</string>
+ <string name="transactions_suspend">Suspend</string>
+ <string name="transactions_title">Transactions</string>
- <!-- Transactions -->
- <string name="transaction_paid">Paid</string>
- <string name="transaction_order_total">Total</string>
- <string name="transaction_order">Purchase</string>
- <string name="transaction_order_id">Receipt #%1$s</string>
- <string name="transaction_refund">Refund</string>
- <string name="transaction_refund_from">Refund from %s</string>
- <string name="transaction_pending">PENDING</string>
- <string name="transaction_refresh">Coin expiry change fee</string>
- <string name="transaction_deposit">Deposit</string>
- <string name="transaction_peer_push_debit">Push payment</string>
- <string name="transaction_peer_pull_credit">Invoice</string>
- <string name="transaction_peer_pull_debit">Invoice paid</string>
- <string name="transaction_peer_push_credit">Push payment</string>
- <string name="transaction_action_kyc">Complete KYC</string>
- <string name="transaction_denom_loss">Loss of funds</string>
- <string name="transaction_dummy_title">Unknown Transaction</string>
+ <!-- Payments -->
- <string name="payment_title">Payment</string>
- <string name="payment_prompt_title">Review Payment</string>
- <string name="payment_fee">+%s payment fee</string>
+ <string name="payment_aborted">Aborted</string>
+ <string name="payment_already_paid">You\'ve already paid for this purchase.</string>
+ <string name="payment_balance_insufficient">Balance insufficient!</string>
<string name="payment_button_confirm">Confirm Payment</string>
- <string name="payment_label_amount_total">Total Amount:</string>
- <string name="payment_label_order_summary">Purchase</string>
+ <string name="payment_confirmation_code">Confirmation code</string>
+ <string name="payment_create_order">Create order</string>
<string name="payment_error">Error: %s</string>
- <string name="payment_pending">Payment not completed, it will be retried</string>
- <string name="payment_balance_insufficient">Balance insufficient!</string>
- <string name="payment_aborted">Aborted</string>
<string name="payment_failed">Failed</string>
+ <string name="payment_fee">+%s payment fee</string>
<string name="payment_initiated">Payment initiated</string>
- <string name="payment_already_paid_title">Already paid</string>
- <string name="payment_already_paid">You\'ve already paid for this purchase.</string>
+ <string name="payment_label_order_summary">Purchase</string>
<string name="payment_pay_template_title">Customize your order</string>
- <string name="payment_create_order">Create order</string>
- <string name="payment_confirmation_code">Confirmation code</string>
+ <string name="payment_pending">Payment not completed, it will be retried</string>
+ <string name="payment_prompt_title">Review Payment</string>
<string name="payment_template_error">Error creating order</string>
+ <string name="payment_title">Payment</string>
+
+ <!-- P2P receive -->
- <string name="receive_amount">Amount to receive</string>
- <string name="receive_amount_invalid">Amount invalid</string>
<string name="receive_intro">Choose where to receive money from:</string>
- <string name="receive_withdraw">Withdraw from bank account</string>
<string name="receive_peer">Invoice another wallet</string>
- <string name="receive_peer_title">Request payment</string>
<string name="receive_peer_create_button">Create invoice</string>
- <string name="receive_peer_invoice_instruction">Let the payer scan this QR code to pay:</string>
<string name="receive_peer_invoice_uri">Alternatively, copy and send this URI:</string>
- <string name="receive_peer_amount_invoiced">Amount invoiced</string>
+ <string name="receive_peer_payment_intro">Do you want to receive this payment?</string>
+ <string name="receive_peer_payment_title">Receive payment</string>
+ <string name="receive_peer_title">Request payment</string>
+ <string name="receive_withdraw">Withdraw from bank account</string>
- <string name="send_amount">Amount to send</string>
+ <!-- P2P send -->
+
+ <string name="pay_peer_title">Pay invoice</string>
+ <string name="pay_peer_intro">Do you want to pay this invoice?</string>
<string name="send_intro">Choose where to send money to:</string>
<string name="send_deposit">To a bank account</string>
<string name="send_deposit_bitcoin">To a Bitcoin wallet</string>
<string name="send_deposit_title">Deposit to a bank account</string>
<string name="send_deposit_iban">IBAN</string>
<string name="send_deposit_iban_error">IBAN is invalid</string>
- <string name="send_deposit_bic_error">BIC is invalid</string>
- <string name="send_deposit_bic">BIC/SWIFT</string>
<string name="send_deposit_name">Account holder</string>
<string name="send_deposit_bitcoin_address">Bitcoin address</string>
<string name="send_deposit_check_fees_button">Check fees</string>
- <string name="send_deposit_amount_effective">Effective Amount</string>
<string name="send_deposit_create_button">Make deposit</string>
<string name="send_deposit_bitcoin_create_button">Transfer Bitcoin</string>
<string name="send_peer">To another wallet</string>
@@ -183,149 +201,140 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card
<string name="send_peer_payment_instruction">Let the payee scan this QR code to receive:</string>
<string name="send_peer_expiration_period">Expires in</string>
<string name="send_peer_expiration_1d">1 day</string>
- <string name="send_peer_expiration_7d">7 days</string>
+ <string name="send_peer_expiration_7d">1 week</string>
<string name="send_peer_expiration_30d">30 days</string>
<string name="send_peer_expiration_custom">Custom</string>
<string name="send_peer_expiration_days">Days</string>
<string name="send_peer_expiration_hours">Hours</string>
<string name="send_peer_purpose">Purpose</string>
- <string name="pay_peer_title">Pay invoice</string>
- <string name="pay_peer_intro">Do you want to pay this invoice?</string>
- <string name="receive_peer_payment_title">Receive payment</string>
- <string name="receive_peer_payment_intro">Do you want to receive this payment?</string>
+ <!-- Withdrawals -->
- <string name="withdraw_initiated">Withdrawal initiated</string>
- <string name="withdraw_title">Withdrawal</string>
- <string name="withdraw_subtitle">Select target bank account</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_bank">Bank</string>
+ <string name="withdraw_account">Account #%1$d</string>
+ <string name="withdraw_account_currency">Account #%1$d (%2$s)</string>
+ <string name="withdraw_amount_error">Enter valid amount</string>
<string name="withdraw_button_confirm">Confirm Withdraw</string>
<string name="withdraw_button_confirm_bank">Confirm with bank</string>
<string name="withdraw_button_tos">Review Terms</string>
- <string name="withdraw_waiting_confirm">Waiting for confirmation</string>
- <string name="withdraw_manual_title">Make a manual transfer to the exchange</string>
- <string name="withdraw_amount">How much to withdraw?</string>
- <string name="withdraw_amount_error">Enter valid amount</string>
- <string name="withdraw_manual_payment_options">Payment options supported by %1$s:\n\n%2$s</string>
+ <string name="withdraw_error_message">Withdrawing is currently not possible. Please try again later!</string>
+ <string name="withdraw_error_test">Error withdrawing TESTKUDOS</string>
+ <string name="withdraw_error_title">Withdrawal Error</string>
+ <string name="withdraw_exchange">Provider</string>
+ <string name="withdraw_initiated">Withdrawal initiated</string>
+ <string name="withdraw_manual_bitcoin_intro">Now make a split transaction with the following three outputs.</string>
<string name="withdraw_manual_check_fees">Check fees</string>
- <string name="withdraw_manual_ready_title">Exchange is ready for withdrawal!</string>
- <string name="withdraw_manual_ready_intro">To complete the process you need to wire %s to the exchange bank account</string>
+ <string name="withdraw_manual_payment_options">Payment options supported by %1$s:\n\n%2$s</string>
+ <string name="withdraw_manual_ready_account">Account</string>
+ <string name="withdraw_manual_ready_bank_button">Open in banking app</string>
<string name="withdraw_manual_ready_details_intro">Bank transfer details</string>
- <string name="withdraw_manual_bitcoin_title">Bitcoin exchange ready for withdrawal</string>
- <string name="withdraw_manual_bitcoin_intro">Now make a split transaction with the following three outputs.</string>
<string name="withdraw_manual_ready_iban">IBAN</string>
- <string name="withdraw_manual_ready_account">Account</string>
+ <string name="withdraw_manual_ready_intro">To complete the process you need to wire %s to the provider\'s bank account</string>
<string name="withdraw_manual_ready_receiver">Receiver name</string>
<string name="withdraw_manual_ready_subject">Subject</string>
- <string name="withdraw_manual_ready_bank_button">Open in banking app</string>
- <string name="withdraw_manual_ready_cancel">Cancel withdrawal</string>
<string name="withdraw_manual_ready_warning">Make sure to use the correct subject, otherwise the money will not arrive in this wallet.</string>
- <string name="withdraw_error_title">Withdrawal Error</string>
- <string name="withdraw_error_message">Withdrawing is currently not possible. Please try again later!</string>
- <string name="withdraw_error_test">Error withdrawing TESTKUDOS</string>
- <string name="withdraw_account">Account #%1$d</string>
- <string name="withdraw_account_currency">Account #%1$d (%2$s)</string>
- <string name="withdraw_transfer">Transfer</string>
- <string name="withdraw_conversion">Conversion</string>
- <string name="withdraw_conversion_support">This exchange supports currency conversion</string>
-
- <string name="exchange_settings_title">Exchanges</string>
- <string name="exchange_settings_summary">Manage list of exchanges known to this wallet</string>
- <string name="exchange_list_title">Exchanges</string>
- <string name="exchange_list_empty">No exchanges known\n\nAdd one manually or withdraw digital cash!</string>
- <string name="exchange_list_currency">Currency: %s</string>
- <string name="exchange_list_add">Add exchange</string>
- <string name="exchange_list_select">Select exchange</string>
- <string name="exchange_delete">Delete exchange</string>
- <string name="exchange_delete_force">Force deletion (purge)</string>
- <string name="exchange_dialog_delete_message">Are you sure you want to delete this exchange? Forcing this operation will result in a loss of funds.</string>
- <string name="exchange_reload">Reload information</string>
- <string name="exchange_not_contacted">Exchange not contacted</string>
- <string name="exchange_add_url">Enter address of exchange</string>
- <string name="exchange_add_error">Could not add exchange</string>
- <string name="exchange_list_error">Could not list exchanges</string>
- <string name="exchange_list_add_dev">Add development exchanges</string>
- <string name="exchange_menu_manual_withdraw">Withdraw</string>
+ <string name="withdraw_manual_title">Make a manual transfer to the provider</string>
+ <string name="withdraw_restrict_age">Restrict Usage to Age</string>
+ <string name="withdraw_restrict_age_unrestricted">Unrestricted</string>
+ <string name="withdraw_subtitle">Select target bank account</string>
+ <string name="withdraw_title">Withdrawal</string>
+ <string name="withdraw_waiting_confirm">Waiting for confirmation</string>
- <string name="exchange_fee_withdrawal_fee_label">Withdrawal Fee:</string>
- <string name="exchange_fee_overhead_label">Rounding Loss:</string>
- <string name="exchange_fee_coin_expiration_label">Earliest Coin Expiry:</string>
- <string name="exchange_fee_coin_fees_label">Coin Fees</string>
- <string name="exchange_fee_wire_fees_label">Wire Fees</string>
+ <!-- Exchanges -->
+
+ <string name="exchange_add_error">Could not add provider</string>
+ <string name="exchange_add_url">Enter address of provider</string>
+ <string name="exchange_delete">Delete provider</string>
+ <string name="exchange_delete_force">Force deletion (purge)</string>
<plurals name="exchange_fee_coin">
<item quantity="one">Coin: %s (used %d time)</item>
<item quantity="other">Coin: %s (used %d times)</item>
</plurals>
- <string name="exchange_fee_withdraw_fee">Withdraw Fee: %s</string>
+ <string name="exchange_fee_coin_expiration_label">Earliest Coin Expiry:</string>
+ <string name="exchange_fee_coin_fees_label">Coin Fees</string>
<string name="exchange_fee_deposit_fee">Deposit Fee: %s</string>
+ <string name="exchange_fee_overhead_label">Rounding Loss:</string>
<string name="exchange_fee_refresh_fee">Change Fee: %s</string>
<string name="exchange_fee_refund_fee">Refund Fee: %s</string>
+ <string name="exchange_fee_wire_fee_closing_fee">Closing Fee: %s</string>
<string name="exchange_fee_wire_fee_timespan">Timespan: %1$s - %2$s</string>
<string name="exchange_fee_wire_fee_wire_fee">Wire Fee: %s</string>
- <string name="exchange_fee_wire_fee_closing_fee">Closing Fee: %s</string>
+ <string name="exchange_fee_wire_fees_label">Wire Fees</string>
+ <string name="exchange_fee_withdraw_fee">Withdraw Fee: %s</string>
+ <string name="exchange_fee_withdrawal_fee_label">Withdrawal Fee:</string>
+ <string name="exchange_list_add">Add provider</string>
+ <string name="exchange_list_add_dev">Add development providers</string>
+ <string name="exchange_list_currency">Currency: %s</string>
+ <string name="exchange_list_empty">No providers known\n\nAdd one manually or withdraw digital cash!</string>
+ <string name="exchange_list_error">Could not list providers</string>
+ <string name="exchange_list_select">Select provider</string>
+ <string name="exchange_list_title">Providers</string>
+ <string name="exchange_menu_manual_withdraw">Withdraw</string>
+ <string name="exchange_not_contacted">Provider not contacted</string>
+ <string name="exchange_reload">Reload information</string>
+ <string name="exchange_settings_summary">Manage list of providers known to this wallet</string>
+ <string name="exchange_settings_title">Providers</string>
<string name="exchange_tos_accept">Accept Terms of Service</string>
<string name="exchange_tos_error">Error showing Terms of Service: %s</string>
- <string name="loss_amount">Amount lost</string>
+ <!-- Losses -->
+
<string name="loss_reason">Reason</string>
<string name="loss_reason_expired">Funds were not renewed, because the wallet was not opened for a long time</string>
- <string name="loss_reason_vanished">The payment provider lost the record of the funds</string>
<string name="loss_reason_unoffered">The payment provider stopped offering the denomination backing the funds</string>
-
-
- <string name="pending_operations_title">Pending Operations</string>
- <string name="pending_operations_refuse">Refuse Proposal</string>
- <string name="pending_operations_no_action">(no action)</string>
+ <string name="loss_reason_vanished">The payment provider lost the record of the funds</string>
<!-- Observability -->
- <string name="show_logs">Show logs</string>
- <string name="observability_title">Internal event log</string>
- <string name="observability_show_json">Show JSON</string>
+
<string name="observability_hide_json">Hide JSON</string>
+ <string name="observability_show_json">Show JSON</string>
+ <string name="observability_title">Internal event log</string>
+ <string name="show_logs">Show logs</string>
- <string name="settings_dev_mode">Developer Mode</string>
- <string name="settings_dev_mode_summary">Shows more information intended for debugging</string>
- <string name="settings_withdraw_testkudos">Withdraw TESTKUDOS</string>
- <string name="settings_withdraw_testkudos_summary">Get money for testing</string>
- <string name="settings_logcat">Debug log</string>
- <string name="settings_logcat_summary">Save internal log</string>
- <string name="settings_logcat_error">Error exporting log</string>
- <string name="settings_logcat_success">Log exported to file</string>
+ <!-- Settings -->
+
+ <string name="menu_settings">Settings</string>
+ <string name="settings_alert_import_canceled">Import cancelled</string>
+ <string name="settings_alert_reset_canceled">Reset cancelled</string>
+ <string name="settings_alert_reset_done">Wallet has been reset</string>
+ <string name="settings_db_clear_error">Error cleaning database</string>
<string name="settings_db_export">Export database</string>
+ <string name="settings_db_export_error">Error exporting database</string>
+ <string name="settings_db_export_success">Database exported to file</string>
<string name="settings_db_export_summary">Save internal database</string>
<string name="settings_db_import">Import database</string>
- <string name="settings_db_import_summary">Restore database from file</string>
- <string name="settings_db_export_error">Error exporting database</string>
<string name="settings_db_import_error">Error importing database</string>
- <string name="settings_db_clear_error">Error cleaning database</string>
- <string name="settings_db_export_success">Database exported to file</string>
<string name="settings_db_import_success">Database imported from file</string>
+ <string name="settings_db_import_summary">Restore database from file</string>
+ <string name="settings_dev_mode">Developer Mode</string>
+ <string name="settings_dev_mode_summary">Shows more information intended for debugging</string>
+ <string name="settings_dialog_import_message">This operation will overwrite your existing database. Do you want to continue?</string>
+ <string name="settings_dialog_reset_message">Do you really want to reset the wallet and lose all coins and purchases?</string>
+ <string name="settings_logcat">Debug log</string>
+ <string name="settings_logcat_error">Error exporting log</string>
+ <string name="settings_logcat_success">Log exported to file</string>
+ <string name="settings_logcat_summary">Save internal log</string>
+ <string name="settings_reset">Reset Wallet (dangerous!)</string>
+ <string name="settings_reset_summary">Throws away your money</string>
+ <string name="settings_test">Run integration test</string>
+ <string name="settings_test_summary">Performs test transactions with demo setup</string>
<string name="settings_version_app">App Version</string>
<string name="settings_version_core">Wallet Core Version</string>
<string name="settings_version_protocol_exchange">Supported Exchange Versions</string>
<string name="settings_version_protocol_merchant">Supported Merchant Versions</string>
<string name="settings_version_unknown">Unknown</string>
- <string name="settings_test">Run integration test</string>
- <string name="settings_test_summary">Performs test transactions with demo setup</string>
- <string name="settings_reset">Reset Wallet (dangerous!)</string>
- <string name="settings_reset_summary">Throws away your money</string>
+ <string name="settings_withdraw_testkudos">Withdraw TESTKUDOS</string>
+ <string name="settings_withdraw_testkudos_summary">Get money for testing</string>
- <string name="settings_dialog_reset_message">Do you really want to reset the wallet and lose all coins and purchases?</string>
- <string name="settings_dialog_import_message">This operation will overwrite your existing database. Do you want to continue?</string>
- <string name="settings_alert_reset_done">Wallet has been reset</string>
- <string name="settings_alert_reset_canceled">Reset cancelled</string>
- <string name="settings_alert_import_canceled">Import cancelled</string>
+ <!-- Refunds -->
- <string name="refund_title">Refund</string>
<string name="refund_error">Error processing refund</string>
<string name="refund_success">Refund received!</string>
+ <string name="refund_title">Refund</string>
- <string name="wifi_disabled_error">Turn on Wi-Fi to get free Wi-Fi</string>
+ <!-- Miscellaneous -->
+
+ <string name="host_apdu_service_desc">Taler NFC Payments</string>
<string name="wifi_connect_error">Could not connect to free Wi-Fi: %s</string>
+ <string name="wifi_disabled_error">Turn on Wi-Fi to get free Wi-Fi</string>
</resources>