[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-android] branch master updated (2fbda24 -> afeddc3)
From: |
gnunet |
Subject: |
[taler-taler-android] branch master updated (2fbda24 -> afeddc3) |
Date: |
Tue, 23 Aug 2022 19:42:44 +0200 |
This is an automated email from the git hooks/post-receive script.
torsten-grote pushed a change to branch master
in repository taler-android.
from 2fbda24 Upgrade libraries
new 07098f6 [wallet] Move balance down in transaction list
new afeddc3 [wallet] Clean up manual withdrawal code a bit
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../wallet/transactions/TransactionsFragment.kt | 8 +-
.../withdraw/ManualWithdrawSuccessFragment.kt | 405 ---------------------
.../wallet/withdraw/PromptWithdrawFragment.kt | 4 +-
.../net/taler/wallet/withdraw/WithdrawManager.kt | 11 +-
.../{ => manual}/ManualWithdrawFragment.kt | 2 +-
.../manual/ManualWithdrawSuccessFragment.kt | 90 +++++
.../taler/wallet/withdraw/manual/ScreenBitcoin.kt | 222 +++++++++++
.../net/taler/wallet/withdraw/manual/ScreenIBAN.kt | 162 +++++++++
.../src/main/res/layout/fragment_transactions.xml | 90 ++++-
wallet/src/main/res/navigation/nav_graph.xml | 4 +-
wallet/src/main/res/values/strings.xml | 6 +-
11 files changed, 577 insertions(+), 427 deletions(-)
delete mode 100644
wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawSuccessFragment.kt
rename wallet/src/main/java/net/taler/wallet/withdraw/{ =>
manual}/ManualWithdrawFragment.kt (98%)
create mode 100644
wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawSuccessFragment.kt
create mode 100644
wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenBitcoin.kt
create mode 100644
wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenIBAN.kt
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 dd0af84..f5840ab 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
@@ -106,8 +106,7 @@ class TransactionsFragment : Fragment(),
OnTransactionClickListener, ActionMode.
// hide extra fab when in single currency mode (uses
MainFragment's FAB)
if (balances.size == 1) ui.mainFab.visibility = INVISIBLE
balances.find { it.currency == currency }?.available?.let {
amount: Amount ->
- requireActivity().title =
- getString(R.string.transactions_detail_title_balance,
amount)
+ ui.amount.text = amount.amountStr
}
}
transactionManager.progress.observe(viewLifecycleOwner) { show ->
@@ -136,6 +135,11 @@ class TransactionsFragment : Fragment(),
OnTransactionClickListener, ActionMode.
setupSearch(menu.findItem(R.id.action_search))
}
+ override fun onStart() {
+ super.onStart()
+ requireActivity().title =
getString(R.string.transactions_detail_title_currency, currency)
+ }
+
private fun setupSearch(item: MenuItem) {
item.setOnActionExpandListener(object :
MenuItem.OnActionExpandListener {
override fun onMenuItemActionExpand(item: MenuItem) = true
diff --git
a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawSuccessFragment.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawSuccessFragment.kt
deleted file mode 100644
index b638627..0000000
---
a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawSuccessFragment.kt
+++ /dev/null
@@ -1,405 +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/>
- */
-
-package net.taler.wallet.withdraw
-
-import android.content.ClipData
-import android.content.ClipboardManager
-import android.content.Context
-import android.content.Intent
-import android.net.Uri
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.background
-import androidx.compose.foundation.border
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.wrapContentWidth
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.verticalScroll
-import androidx.compose.material.Button
-import androidx.compose.material.ButtonDefaults
-import androidx.compose.material.Icon
-import androidx.compose.material.IconButton
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Surface
-import androidx.compose.material.Text
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ContentCopy
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Alignment.Companion.CenterHorizontally
-import androidx.compose.ui.Alignment.Companion.End
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.alpha
-import androidx.compose.ui.platform.ComposeView
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.res.colorResource
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.TextUnit
-import androidx.compose.ui.unit.TextUnitType
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.em
-import androidx.compose.ui.unit.sp
-import androidx.core.content.getSystemService
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.navigation.fragment.findNavController
-import com.google.android.material.composethemeadapter.MdcTheme
-import net.taler.common.Amount
-import net.taler.common.startActivitySafe
-import net.taler.wallet.MainViewModel
-import net.taler.wallet.R
-
-class ManualWithdrawSuccessFragment : Fragment() {
- private val model: MainViewModel by activityViewModels()
- private val transactionManager by lazy { model.transactionManager }
- private val withdrawManager by lazy { model.withdrawManager }
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?,
- ): View = ComposeView(requireContext()).apply {
- val status = withdrawManager.withdrawStatus.value as
WithdrawStatus.ManualTransferRequired
- val intent = Intent().apply {
- data = status.uri
- }
- // TODO test if this works with an actual payto:// handling app
- val componentName =
intent.resolveActivity(requireContext().packageManager)
- val onBankAppClick = if (componentName == null) null else {
- { startActivitySafe(intent) }
- }
- val tid = status.transactionId
- val onCancelClick = if (tid == null) null else {
- {
- transactionManager.deleteTransaction(tid)
-
findNavController().navigate(R.id.action_nav_exchange_manual_withdrawal_success_to_nav_main)
- }
- }
- setContent {
- MdcTheme {
- Surface {
- when (status) {
- is WithdrawStatus.ManualTransferRequiredBitcoin -> {
- ScreenBitcoin(status, onBankAppClick,
onCancelClick)
- }
- is WithdrawStatus.ManualTransferRequiredIBAN -> {
- ScreenIBAN(status, onBankAppClick, onCancelClick)
- }
- }
- }
-
- }
- }
- }
-
- override fun onStart() {
- super.onStart()
- activity?.setTitle(R.string.withdraw_title)
- }
-}
-
-@Composable
-private fun ScreenIBAN(
- status: WithdrawStatus.ManualTransferRequiredIBAN,
- bankAppClick: (() -> Unit)?,
- onCancelClick: (() -> Unit)?,
-) {
- val scrollState = rememberScrollState()
- Column(modifier = Modifier
- .padding(all = 16.dp)
- .wrapContentWidth(CenterHorizontally)
- .verticalScroll(scrollState)
- ) {
- Text(
- text = stringResource(R.string.withdraw_manual_ready_title),
- style = MaterialTheme.typography.h5,
- )
- Text(
- text = stringResource(R.string.withdraw_manual_ready_intro,
- status.amountRaw.toString()),
- style = MaterialTheme.typography.body1,
- modifier = Modifier
- .padding(vertical = 8.dp)
- )
- Text(
- text =
stringResource(R.string.withdraw_manual_ready_details_intro),
- style = MaterialTheme.typography.body1,
- modifier = Modifier
- .padding(vertical = 8.dp)
- )
- DetailRow(stringResource(R.string.withdraw_manual_ready_iban),
status.iban)
- DetailRow(stringResource(R.string.withdraw_manual_ready_subject),
status.subject)
- DetailRow(stringResource(R.string.amount_chosen),
status.amountRaw.toString())
- DetailRow(stringResource(R.string.withdraw_exchange),
status.exchangeBaseUrl, false)
- Text(
- text = stringResource(R.string.withdraw_manual_ready_warning),
- style = MaterialTheme.typography.body2,
- color = colorResource(R.color.notice_text),
- modifier = Modifier
- .align(CenterHorizontally)
- .padding(all = 8.dp)
- .background(colorResource(R.color.notice_background))
- .border(BorderStroke(2.dp,
colorResource(R.color.notice_border)))
- .padding(all = 16.dp)
- )
- if (bankAppClick != null) {
- Button(
- onClick = bankAppClick,
- modifier = Modifier
- .padding(vertical = 16.dp)
- .align(CenterHorizontally),
- ) {
- Text(text =
stringResource(R.string.withdraw_manual_ready_bank_button))
- }
- }
- if (onCancelClick != null) {
- Button(
- onClick = onCancelClick,
- colors = ButtonDefaults.buttonColors(backgroundColor =
colorResource(R.color.red)),
- modifier = Modifier
- .padding(vertical = 16.dp)
- .align(End),
- ) {
- Text(text =
stringResource(R.string.withdraw_manual_ready_cancel))
- }
- }
- }
-}
-
-@Composable
-private fun ScreenBitcoin(
- status: WithdrawStatus.ManualTransferRequiredBitcoin,
- bankAppClick: (() -> Unit)?,
- onCancelClick: (() -> Unit)?,
-) {
- val scrollState = rememberScrollState()
- Column(modifier = Modifier
- .padding(all = 16.dp)
- .wrapContentWidth(CenterHorizontally)
- .verticalScroll(scrollState)
- ) {
- Text(
- text = stringResource(R.string.withdraw_manual_ready_title),
- style = MaterialTheme.typography.h5,
- )
- Text(
- text = stringResource(R.string.withdraw_manual_ready_intro,
- status.amountRaw.toString()),
- style = MaterialTheme.typography.body1,
- modifier = Modifier
- .padding(vertical = 8.dp)
- )
- Text(
- text =
stringResource(R.string.withdraw_manual_bitcoin_ready_details_intro),
- style = MaterialTheme.typography.body1,
- modifier = Modifier
- .padding(vertical = 8.dp)
- )
- Text(
- text =
stringResource(R.string.withdraw_manual_bitcoin_ready_details_segwit),
- style = MaterialTheme.typography.body1,
- modifier = Modifier
- .padding(vertical = 8.dp)
- )
- DetailRow(stringResource(R.string.withdraw_manual_ready_subject),
status.subject)
- Text(
- text =
stringResource(R.string.withdraw_manual_bitcoin_ready_details_bitcoincore),
- style = MaterialTheme.typography.body1,
- modifier = Modifier
- .padding(vertical = 8.dp)
- )
- BitcoinSegwitAddrs(
- status.amountRaw,
- status.account,
- status.segwitAddrs
- )
- Text(
- text =
stringResource(R.string.withdraw_manual_bitcoin_ready_details_confirm,
- status.amountRaw.withCurrency(Amount.SEGWIT_MIN.currency) +
Amount.SEGWIT_MIN + Amount.SEGWIT_MIN),
- style = MaterialTheme.typography.body1,
- modifier = Modifier
- .padding(vertical = 8.dp)
- )
- Text(
- text = stringResource(R.string.withdraw_manual_ready_warning),
- style = MaterialTheme.typography.body2,
- color = colorResource(R.color.notice_text),
- modifier = Modifier
- .align(CenterHorizontally)
- .padding(all = 8.dp)
- .background(colorResource(R.color.notice_background))
- .border(BorderStroke(2.dp,
colorResource(R.color.notice_border)))
- .padding(all = 16.dp)
- )
- if (bankAppClick != null) {
- Button(
- onClick = bankAppClick,
- modifier = Modifier
- .padding(vertical = 16.dp)
- .align(CenterHorizontally),
- ) {
- Text(text =
stringResource(R.string.withdraw_manual_ready_bank_button))
- }
- }
- if (onCancelClick != null) {
- Button(
- onClick = onCancelClick,
- colors = ButtonDefaults.buttonColors(backgroundColor =
colorResource(R.color.red)),
- modifier = Modifier
- .padding(vertical = 16.dp)
- .align(End),
- ) {
- Text(text =
stringResource(R.string.withdraw_manual_ready_cancel))
- }
- }
- }
-}
-
-@Composable
-fun BitcoinSegwitAddrs(amount: Amount, addr: String, segwitAddrs:
List<String>) {
- val context = LocalContext.current
-
- val sr = segwitAddrs.map { s -> """
-${s} ${Amount.SEGWIT_MIN}
- """.trimIndent()}.joinToString(separator = "\n")
- val copyText = """
-${addr} ${amount.withCurrency("BTC")}
-${sr}
- """.trimIndent()
-
- Column {
-
- Row (modifier = Modifier.padding(vertical = 8.dp)){
- Column (modifier = Modifier.weight(0.3f)) {
- Text(
- text = addr,
- style = MaterialTheme.typography.body1,
- fontWeight = FontWeight.Normal,
- fontSize = 3.em
- )
- Text(
- text = amount.withCurrency("BTC").toString(),
- style = MaterialTheme.typography.body1,
- fontWeight = FontWeight.Bold,
- )
- }
- }
- for(sAddr in segwitAddrs) {
- Row (modifier = Modifier.padding(vertical = 8.dp)){
- Column (modifier = Modifier.weight(0.3f)) {
- Text(
- text = sAddr,
- style = MaterialTheme.typography.body1,
- fontWeight = FontWeight.Normal,
- fontSize = 3.em
- )
- Text(
- text = Amount.SEGWIT_MIN.toString(),
- style = MaterialTheme.typography.body1,
- fontWeight = FontWeight.Bold,
- )
- }
- }
- }
-
- Row (verticalAlignment = Alignment.CenterVertically) {
- IconButton(
- onClick = { copyToClipBoard(context, "this", copyText) },
- ) { Icon(Icons.Default.ContentCopy, stringResource(R.string.copy))
}
- Text (
- text = stringResource(R.string.copy),
- style = MaterialTheme.typography.body1,
- )
- }
- }
-
-}
-@Composable
-fun DetailRow(label: String, content: String, copy: Boolean = true) {
- val context = LocalContext.current
- Row {
- Column(
- modifier = Modifier
- .weight(0.3f)) {
- Text(
- text = label,
- style = MaterialTheme.typography.body1,
- fontWeight = if (copy) FontWeight.Bold else FontWeight.Normal,
- )
- if (copy) {
- IconButton(
- onClick = { copyToClipBoard(context, label, content) },
- ) { Icon(Icons.Default.ContentCopy,
stringResource(R.string.copy)) }
- }
- }
- Text(
- text = content,
- style = MaterialTheme.typography.body1,
- modifier = Modifier
- .padding(bottom = 8.dp)
- .weight(0.7f)
- .then(if (copy) Modifier else Modifier.alpha(0.7f))
- )
- }
-}
-
-@Preview
-@Composable
-fun PreviewScreen2() {
- Surface {
- ScreenIBAN(WithdrawStatus.ManualTransferRequiredIBAN(
- exchangeBaseUrl = "test.exchange.taler.net",
- uri = Uri.parse("https://taler.net"),
- iban = "ASDQWEASDZXCASDQWE",
- subject = "Taler Withdrawal
P2T19EXRBY4B145JRNZ8CQTD7TCS03JE9VZRCEVKVWCP930P56WG",
- amountRaw = Amount("KUDOS", 10, 0),
- transactionId = "",
- ), {}) {}
- }
-}
-
-@Preview
-@Composable
-fun PreviewScreenBitcoin() {
- Surface {
- ScreenBitcoin(WithdrawStatus.ManualTransferRequiredBitcoin(
- exchangeBaseUrl = "bitcoin.ice.bfh.ch",
- uri = Uri.parse("https://taler.net"),
- account = "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4",
- segwitAddrs = listOf<String>(
- "bc1qqleages8702xvg9qcyu02yclst24xurdrynvxq",
- "bc1qsleagehks96u7jmqrzcf0fw80ea5g57qm3m84c"
- ),
- subject = "0ZSX8SH0M30KHX8K3Y1DAMVGDQV82XEF9DG1HC4QMQ3QWYT4AF00",
- amountRaw = Amount("BITCOINBTC", 0, 14000000),
- transactionId = "",
- ), {}) {}
- }
-}
-
-private fun copyToClipBoard(context: Context, label: String, str: String) {
- val clipboard = context.getSystemService<ClipboardManager>()
- val clip = ClipData.newPlainText(label, str)
- clipboard?.setPrimaryClip(clip)
-}
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 dfae920..3cd2f49 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
@@ -57,9 +57,9 @@ class PromptWithdrawFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- withdrawManager.withdrawStatus.observe(viewLifecycleOwner, {
+ withdrawManager.withdrawStatus.observe(viewLifecycleOwner) {
showWithdrawStatus(it)
- })
+ }
withdrawManager.exchangeSelection.observe(viewLifecycleOwner,
EventObserver {
findNavController().navigate(R.id.action_promptWithdraw_to_selectExchangeFragment)
})
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
index ca6ba17..b597237 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
@@ -16,7 +16,7 @@
package net.taler.wallet.withdraw
-import Bech32Data
+import Bech32
import android.net.Uri
import android.util.Log
import androidx.annotation.UiThread
@@ -26,7 +26,6 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import net.taler.common.Amount
-import net.taler.common.CyptoUtils
import net.taler.common.Event
import net.taler.common.toEvent
import net.taler.wallet.TAG
@@ -35,11 +34,6 @@ import net.taler.wallet.backend.WalletBackendApi
import net.taler.wallet.exchanges.ExchangeFees
import net.taler.wallet.exchanges.ExchangeItem
import net.taler.wallet.withdraw.WithdrawStatus.ReceivedDetails
-import toBech32Data
-import kotlin.experimental.and
-import kotlin.experimental.or
-import kotlin.math.floor
-import kotlin.reflect.KProperty
sealed class WithdrawStatus {
data class Loading(val talerWithdrawUri: String? = null) : WithdrawStatus()
@@ -287,7 +281,6 @@ class WithdrawManager(
}
-
fun createManualTransferRequired(
amount: Amount,
exchangeBaseUrl: String,
@@ -319,5 +312,3 @@ fun createManualTransferRequired(
transactionId = transactionId,
)
}
-
-
diff --git
a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawFragment.kt
similarity index 98%
rename from
wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
rename to
wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawFragment.kt
index 500b6e7..fbdd828 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
+++
b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawFragment.kt
@@ -14,7 +14,7 @@
* GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-package net.taler.wallet.withdraw
+package net.taler.wallet.withdraw.manual
import android.net.Uri
import android.os.Bundle
diff --git
a/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawSuccessFragment.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawSuccessFragment.kt
new file mode 100644
index 0000000..e40036d
--- /dev/null
+++
b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ManualWithdrawSuccessFragment.kt
@@ -0,0 +1,90 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2022 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.withdraw.manual
+
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.compose.material.Surface
+import androidx.compose.ui.platform.ComposeView
+import androidx.core.content.getSystemService
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.navigation.fragment.findNavController
+import com.google.android.material.composethemeadapter.MdcTheme
+import net.taler.common.startActivitySafe
+import net.taler.wallet.MainViewModel
+import net.taler.wallet.R
+import net.taler.wallet.withdraw.WithdrawStatus
+
+class ManualWithdrawSuccessFragment : Fragment() {
+ private val model: MainViewModel by activityViewModels()
+ private val transactionManager by lazy { model.transactionManager }
+ private val withdrawManager by lazy { model.withdrawManager }
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View = ComposeView(requireContext()).apply {
+ val status = withdrawManager.withdrawStatus.value as
WithdrawStatus.ManualTransferRequired
+ val intent = Intent().apply {
+ data = status.uri
+ }
+ // TODO test if this works with an actual payto:// handling app
+ val componentName =
intent.resolveActivity(requireContext().packageManager)
+ val onBankAppClick = if (componentName == null) null else {
+ { startActivitySafe(intent) }
+ }
+ val tid = status.transactionId
+ val onCancelClick = if (tid == null) null else {
+ {
+ transactionManager.deleteTransaction(tid)
+
findNavController().navigate(R.id.action_nav_exchange_manual_withdrawal_success_to_nav_main)
+ }
+ }
+ setContent {
+ MdcTheme {
+ Surface {
+ when (status) {
+ is WithdrawStatus.ManualTransferRequiredBitcoin -> {
+ ScreenBitcoin(status, onBankAppClick,
onCancelClick)
+ }
+ is WithdrawStatus.ManualTransferRequiredIBAN -> {
+ ScreenIBAN(status, onBankAppClick, onCancelClick)
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ override fun onStart() {
+ super.onStart()
+ activity?.setTitle(R.string.withdraw_title)
+ }
+}
+
+fun copyToClipBoard(context: Context, label: String, str: String) {
+ val clipboard = context.getSystemService<ClipboardManager>()
+ val clip = ClipData.newPlainText(label, str)
+ clipboard?.setPrimaryClip(clip)
+}
diff --git
a/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenBitcoin.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenBitcoin.kt
new file mode 100644
index 0000000..9ae2418
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenBitcoin.kt
@@ -0,0 +1,222 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2022 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.withdraw.manual
+
+import android.net.Uri
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.Button
+import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ContentCopy
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.em
+import net.taler.common.Amount
+import net.taler.wallet.R
+import net.taler.wallet.withdraw.WithdrawStatus
+
+@Composable
+fun ScreenBitcoin(
+ status: WithdrawStatus.ManualTransferRequiredBitcoin,
+ bankAppClick: (() -> Unit)?,
+ onCancelClick: (() -> Unit)?,
+) {
+ val scrollState = rememberScrollState()
+ Column(modifier = Modifier
+ .padding(all = 16.dp)
+ .wrapContentWidth(Alignment.CenterHorizontally)
+ .verticalScroll(scrollState)
+ ) {
+ Text(
+ text = stringResource(R.string.withdraw_manual_ready_title),
+ style = MaterialTheme.typography.h5,
+ )
+ Text(
+ text = stringResource(R.string.withdraw_manual_ready_intro,
+ status.amountRaw.toString()),
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier
+ .padding(vertical = 8.dp)
+ )
+ Text(
+ text =
stringResource(R.string.withdraw_manual_bitcoin_ready_details_intro),
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier
+ .padding(vertical = 8.dp)
+ )
+ Text(
+ text =
stringResource(R.string.withdraw_manual_bitcoin_ready_details_segwit),
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier
+ .padding(vertical = 8.dp)
+ )
+ DetailRow(stringResource(R.string.withdraw_manual_ready_subject),
status.subject)
+ Text(
+ text =
stringResource(R.string.withdraw_manual_bitcoin_ready_details_bitcoincore),
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier
+ .padding(vertical = 8.dp)
+ )
+ BitcoinSegwitAddrs(
+ status.amountRaw,
+ status.account,
+ status.segwitAddrs
+ )
+ Text(
+ text =
stringResource(R.string.withdraw_manual_bitcoin_ready_details_confirm,
+ status.amountRaw.withCurrency(Amount.SEGWIT_MIN.currency) +
Amount.SEGWIT_MIN + Amount.SEGWIT_MIN),
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier
+ .padding(vertical = 8.dp)
+ )
+ Text(
+ text = stringResource(R.string.withdraw_manual_ready_warning),
+ style = MaterialTheme.typography.body2,
+ color = colorResource(R.color.notice_text),
+ modifier = Modifier
+ .align(Alignment.CenterHorizontally)
+ .padding(all = 8.dp)
+ .background(colorResource(R.color.notice_background))
+ .border(BorderStroke(2.dp,
colorResource(R.color.notice_border)))
+ .padding(all = 16.dp)
+ )
+ if (bankAppClick != null) {
+ Button(
+ onClick = bankAppClick,
+ modifier = Modifier
+ .padding(vertical = 16.dp)
+ .align(Alignment.CenterHorizontally),
+ ) {
+ Text(text =
stringResource(R.string.withdraw_manual_ready_bank_button))
+ }
+ }
+ if (onCancelClick != null) {
+ Button(
+ onClick = onCancelClick,
+ colors = ButtonDefaults.buttonColors(backgroundColor =
colorResource(R.color.red)),
+ modifier = Modifier
+ .padding(vertical = 16.dp)
+ .align(Alignment.End),
+ ) {
+ Text(text =
stringResource(R.string.withdraw_manual_ready_cancel))
+ }
+ }
+ }
+}
+
+@Composable
+fun BitcoinSegwitAddrs(amount: Amount, addr: String, segwitAddresses:
List<String>) {
+ val context = LocalContext.current
+
+ val sr = segwitAddresses.joinToString(separator = "\n") { s ->
+ """
+$s ${Amount.SEGWIT_MIN}
+ """.trimIndent()
+ }
+ val copyText = """
+$addr ${amount.withCurrency("BTC")}
+$sr
+ """.trimIndent()
+
+ Column {
+ Row(modifier = Modifier.padding(vertical = 8.dp)) {
+ Column(modifier = Modifier.weight(0.3f)) {
+ Text(
+ text = addr,
+ style = MaterialTheme.typography.body1,
+ fontWeight = FontWeight.Normal,
+ fontSize = 3.em
+ )
+ Text(
+ text = amount.withCurrency("BTC").toString(),
+ style = MaterialTheme.typography.body1,
+ fontWeight = FontWeight.Bold,
+ )
+ }
+ }
+ for (segwitAddress in segwitAddresses) {
+ Row(modifier = Modifier.padding(vertical = 8.dp)) {
+ Column(modifier = Modifier.weight(0.3f)) {
+ Text(
+ text = segwitAddress,
+ style = MaterialTheme.typography.body1,
+ fontWeight = FontWeight.Normal,
+ fontSize = 3.em
+ )
+ Text(
+ text = Amount.SEGWIT_MIN.toString(),
+ style = MaterialTheme.typography.body1,
+ fontWeight = FontWeight.Bold,
+ )
+ }
+ }
+ }
+
+ IconButton(
+ onClick = { copyToClipBoard(context, "Bitcoin", copyText) },
+ ) {
+ Row {
+ Icon(Icons.Default.ContentCopy, stringResource(R.string.copy))
+ Text(
+ modifier = Modifier.padding(start = 8.dp),
+ text = stringResource(R.string.copy),
+ style = MaterialTheme.typography.body1,
+ )
+ }
+ }
+ }
+
+}
+
+@Preview
+@Composable
+fun PreviewScreenBitcoin() {
+ Surface {
+ ScreenBitcoin(WithdrawStatus.ManualTransferRequiredBitcoin(
+ exchangeBaseUrl = "bitcoin.ice.bfh.ch",
+ uri = Uri.parse("https://taler.net"),
+ account = "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4",
+ segwitAddrs = listOf(
+ "bc1qqleages8702xvg9qcyu02yclst24xurdrynvxq",
+ "bc1qsleagehks96u7jmqrzcf0fw80ea5g57qm3m84c"
+ ),
+ subject = "0ZSX8SH0M30KHX8K3Y1DAMVGDQV82XEF9DG1HC4QMQ3QWYT4AF00",
+ amountRaw = Amount("BITCOINBTC", 0, 14000000),
+ transactionId = "",
+ ), {}) {}
+ }
+}
diff --git
a/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenIBAN.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenIBAN.kt
new file mode 100644
index 0000000..9dc5d5e
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/manual/ScreenIBAN.kt
@@ -0,0 +1,162 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2022 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.withdraw.manual
+
+import android.net.Uri
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.Button
+import androidx.compose.material.ButtonDefaults
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ContentCopy
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import net.taler.common.Amount
+import net.taler.wallet.R
+import net.taler.wallet.withdraw.WithdrawStatus
+
+@Composable
+fun ScreenIBAN(
+ status: WithdrawStatus.ManualTransferRequiredIBAN,
+ bankAppClick: (() -> Unit)?,
+ onCancelClick: (() -> Unit)?,
+) {
+ val scrollState = rememberScrollState()
+ Column(modifier = Modifier
+ .padding(all = 16.dp)
+ .wrapContentWidth(Alignment.CenterHorizontally)
+ .verticalScroll(scrollState)
+ ) {
+ Text(
+ text = stringResource(R.string.withdraw_manual_ready_title),
+ style = MaterialTheme.typography.h5,
+ )
+ Text(
+ text = stringResource(R.string.withdraw_manual_ready_intro,
+ status.amountRaw.toString()),
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier
+ .padding(vertical = 8.dp)
+ )
+ Text(
+ text =
stringResource(R.string.withdraw_manual_ready_details_intro),
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier
+ .padding(vertical = 8.dp)
+ )
+ DetailRow(stringResource(R.string.withdraw_manual_ready_iban),
status.iban)
+ DetailRow(stringResource(R.string.withdraw_manual_ready_subject),
status.subject)
+ DetailRow(stringResource(R.string.amount_chosen),
status.amountRaw.toString())
+ DetailRow(stringResource(R.string.withdraw_exchange),
status.exchangeBaseUrl, false)
+ Text(
+ text = stringResource(R.string.withdraw_manual_ready_warning),
+ style = MaterialTheme.typography.body2,
+ color = colorResource(R.color.notice_text),
+ modifier = Modifier
+ .align(Alignment.CenterHorizontally)
+ .padding(all = 8.dp)
+ .background(colorResource(R.color.notice_background))
+ .border(BorderStroke(2.dp,
colorResource(R.color.notice_border)))
+ .padding(all = 16.dp)
+ )
+ if (bankAppClick != null) {
+ Button(
+ onClick = bankAppClick,
+ modifier = Modifier
+ .padding(vertical = 16.dp)
+ .align(Alignment.CenterHorizontally),
+ ) {
+ Text(text =
stringResource(R.string.withdraw_manual_ready_bank_button))
+ }
+ }
+ if (onCancelClick != null) {
+ Button(
+ onClick = onCancelClick,
+ colors = ButtonDefaults.buttonColors(backgroundColor =
colorResource(R.color.red)),
+ modifier = Modifier
+ .padding(vertical = 16.dp)
+ .align(Alignment.End),
+ ) {
+ Text(text =
stringResource(R.string.withdraw_manual_ready_cancel))
+ }
+ }
+ }
+}
+
+@Composable
+fun DetailRow(label: String, content: String, copy: Boolean = true) {
+ val context = LocalContext.current
+ Row {
+ Column(
+ modifier = Modifier
+ .weight(0.3f)) {
+ Text(
+ text = label,
+ style = MaterialTheme.typography.body1,
+ fontWeight = if (copy) FontWeight.Bold else FontWeight.Normal,
+ )
+ if (copy) {
+ IconButton(
+ onClick = { copyToClipBoard(context, label, content) },
+ ) { Icon(Icons.Default.ContentCopy,
stringResource(R.string.copy)) }
+ }
+ }
+ Text(
+ text = content,
+ style = MaterialTheme.typography.body1,
+ modifier = Modifier
+ .padding(bottom = 8.dp)
+ .weight(0.7f)
+ .then(if (copy) Modifier else Modifier.alpha(0.7f))
+ )
+ }
+}
+
+@Preview
+@Composable
+fun PreviewScreenIBAN() {
+ Surface {
+ ScreenIBAN(WithdrawStatus.ManualTransferRequiredIBAN(
+ exchangeBaseUrl = "test.exchange.taler.net",
+ uri = Uri.parse("https://taler.net"),
+ iban = "ASDQWEASDZXCASDQWE",
+ subject = "Taler Withdrawal
P2T19EXRBY4B145JRNZ8CQTD7TCS03JE9VZRCEVKVWCP930P56WG",
+ amountRaw = Amount("KUDOS", 10, 0),
+ transactionId = "",
+ ), {}) {}
+ }
+}
diff --git a/wallet/src/main/res/layout/fragment_transactions.xml
b/wallet/src/main/res/layout/fragment_transactions.xml
index 22d6d48..60675bb 100644
--- a/wallet/src/main/res/layout/fragment_transactions.xml
+++ b/wallet/src/main/res/layout/fragment_transactions.xml
@@ -14,19 +14,91 @@
~ GNU Taler; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/sendButton"
+ style="@style/Widget.MaterialComponents.Button.TextButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/transactions_send_funds"
+ app:layout_constraintBottom_toTopOf="@+id/divider"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/receiveButton"
+ style="@style/Widget.MaterialComponents.Button.TextButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ 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" />
+
+ <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" />
+
+ <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" />
+
+ <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.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
- android:layout_height="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" />
@@ -37,6 +109,10 @@
android:layout_gravity="center"
android:text="@string/transactions_empty"
android:visibility="invisible"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/divider"
tools:visibility="visible" />
<ProgressBar
@@ -46,6 +122,10 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="invisible"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/divider"
tools:visibility="visible" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
@@ -55,6 +135,8 @@
android:layout_height="wrap_content"
android:contentDescription="@string/button_scan_qr_code"
android:src="@drawable/ic_scan_qr"
-
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
/>
+
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
-</FrameLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/wallet/src/main/res/navigation/nav_graph.xml
b/wallet/src/main/res/navigation/nav_graph.xml
index 724fd93..871ba53 100644
--- a/wallet/src/main/res/navigation/nav_graph.xml
+++ b/wallet/src/main/res/navigation/nav_graph.xml
@@ -86,7 +86,7 @@
<fragment
android:id="@+id/nav_exchange_manual_withdrawal"
- android:name="net.taler.wallet.withdraw.ManualWithdrawFragment"
+ android:name="net.taler.wallet.withdraw.manual.ManualWithdrawFragment"
android:label="@string/withdraw_title">
<action
android:id="@+id/action_nav_exchange_manual_withdrawal_to_promptWithdraw"
@@ -95,7 +95,7 @@
<fragment
android:id="@+id/nav_exchange_manual_withdrawal_success"
- android:name="net.taler.wallet.withdraw.ManualWithdrawSuccessFragment"
+
android:name="net.taler.wallet.withdraw.manual.ManualWithdrawSuccessFragment"
android:label="@string/withdraw_title">
<action
android:id="@+id/action_nav_exchange_manual_withdrawal_success_to_nav_main"
diff --git a/wallet/src/main/res/values/strings.xml
b/wallet/src/main/res/values/strings.xml
index d1a0c78..4fdfd4f 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -45,6 +45,7 @@ GNU Taler is immune against many types of fraud, such as
phishing of credit card
<string name="button_back">Go Back</string>
<string name="button_scan_qr_code">Scan Taler QR Code</string>
<string name="enter_uri">Enter Taler URI</string>
+ <string name="copy" tools:override="true">Copy</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>
@@ -70,11 +71,14 @@ GNU Taler is immune against many types of fraud, such as
phishing of credit card
<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="transactions_title">Transactions</string>
+ <string name="transactions_balance">Balance</string>
+ <string name="transactions_send_funds">Send\nFunds</string>
+ <string name="transactions_receive_funds">Receive\nFunds</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_balance">Balance: %s</string>
+ <string name="transactions_detail_title_currency">%s Transactions</string>
<string name="transactions_delete">Delete</string>
<string name="transactions_select_all">Select All</string>
<string name="transactions_delete_dialog_title">Delete Transaction</string>
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-android] branch master updated (2fbda24 -> afeddc3),
gnunet <=