[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-android] branch master updated (0532aa1 -> 3ab1c7d)
From: |
gnunet |
Subject: |
[taler-taler-android] branch master updated (0532aa1 -> 3ab1c7d) |
Date: |
Tue, 21 Mar 2023 16:16:10 +0100 |
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 0532aa1 Translated using Weblate (French)
new 1c979ef [wallet] Add support for expiration of peer payments
new 3ab1c7d [wallet] use a default expiry constant
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:
.../net/taler/wallet/compose/NumericInputField.kt | 71 ++++++++++++
.../java/net/taler/wallet/compose/SelectionChip.kt | 48 ++++++++
.../net/taler/wallet/peer/ExpirationComposable.kt | 128 +++++++++++++++++++++
.../net/taler/wallet/peer/OutgoingPullFragment.kt | 4 +-
.../wallet/peer/OutgoingPullIntroComposable.kt | 23 +++-
.../net/taler/wallet/peer/OutgoingPushFragment.kt | 4 +-
.../wallet/peer/OutgoingPushIntroComposable.kt | 43 +++++--
.../main/java/net/taler/wallet/peer/PeerManager.kt | 11 +-
wallet/src/main/res/values/strings.xml | 7 ++
9 files changed, 315 insertions(+), 24 deletions(-)
create mode 100644
wallet/src/main/java/net/taler/wallet/compose/NumericInputField.kt
create mode 100644
wallet/src/main/java/net/taler/wallet/compose/SelectionChip.kt
create mode 100644
wallet/src/main/java/net/taler/wallet/peer/ExpirationComposable.kt
diff --git a/wallet/src/main/java/net/taler/wallet/compose/NumericInputField.kt
b/wallet/src/main/java/net/taler/wallet/compose/NumericInputField.kt
new file mode 100644
index 0000000..c9d2fc5
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/compose/NumericInputField.kt
@@ -0,0 +1,71 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2023 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.compose
+
+import androidx.compose.foundation.layout.Row
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Add
+import androidx.compose.material.icons.filled.Remove
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.OutlinedTextField
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun NumericInputField(
+ modifier: Modifier = Modifier,
+ value: Long,
+ onValueChange: (Long) -> Unit,
+ readOnly: Boolean = true,
+ label: @Composable () -> Unit,
+ minValue: Long? = 0L,
+ maxValue: Long? = null,
+) {
+ OutlinedTextField(
+ modifier = modifier,
+ value = value.toString(),
+ readOnly = readOnly,
+ onValueChange = {
+ val dd = it.toLongOrNull() ?: 0
+ onValueChange(dd)
+ },
+ trailingIcon = {
+ Row {
+ IconButton(
+ content = { Icon(Icons.Default.Remove, "add1") },
+ onClick = {
+ if (minValue != null && value - 1 >= minValue) {
+ onValueChange(value - 1)
+ }
+ },
+ )
+ IconButton(
+ content = { Icon(Icons.Default.Add, "add1") },
+ onClick = {
+ if (maxValue != null && value + 1 <= maxValue) {
+ onValueChange(value + 1)
+ }
+ },
+ )
+ }
+ },
+ label = label,
+ )
+}
\ No newline at end of file
diff --git a/wallet/src/main/java/net/taler/wallet/compose/SelectionChip.kt
b/wallet/src/main/java/net/taler/wallet/compose/SelectionChip.kt
new file mode 100644
index 0000000..454bbfa
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/compose/SelectionChip.kt
@@ -0,0 +1,48 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2023 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.compose
+
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.SuggestionChip
+import androidx.compose.material3.SuggestionChipDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun <T> SelectionChip(
+ label: @Composable () -> Unit,
+ modifier: Modifier = Modifier,
+ selected: Boolean,
+ value: T,
+ onSelected: (T) -> Unit,
+) {
+ val theme = MaterialTheme.colorScheme
+ SuggestionChip(
+ label = label,
+ modifier = modifier,
+ onClick = {
+ onSelected(value)
+ },
+ colors = SuggestionChipDefaults.suggestionChipColors(
+ containerColor = if (selected) theme.primaryContainer else
Color.Transparent,
+ labelColor = if (selected) theme.onPrimaryContainer else
theme.onSurface
+ )
+ )
+}
\ No newline at end of file
diff --git a/wallet/src/main/java/net/taler/wallet/peer/ExpirationComposable.kt
b/wallet/src/main/java/net/taler/wallet/peer/ExpirationComposable.kt
new file mode 100644
index 0000000..4393e47
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/peer/ExpirationComposable.kt
@@ -0,0 +1,128 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2023 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.peer
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import net.taler.wallet.R
+import net.taler.wallet.compose.NumericInputField
+import net.taler.wallet.compose.SelectionChip
+import net.taler.wallet.compose.TalerSurface
+
+enum class ExpirationOption(val hours: Long) {
+ DAYS_1(24),
+ DAYS_7(24 * 7),
+ DAYS_30(24 * 30),
+ CUSTOM(-1)
+}
+
+@Composable
+fun ExpirationComposable(
+ modifier: Modifier = Modifier,
+ option: ExpirationOption,
+ hours: Long,
+ onOptionChange: (ExpirationOption) -> Unit,
+ onHoursChange: (Long) -> Unit,
+) {
+ val options = listOf(
+ ExpirationOption.DAYS_1 to
stringResource(R.string.send_peer_expiration_1d),
+ ExpirationOption.DAYS_7 to
stringResource(R.string.send_peer_expiration_7d),
+ ExpirationOption.DAYS_30 to
stringResource(R.string.send_peer_expiration_30d),
+ ExpirationOption.CUSTOM to
stringResource(R.string.send_peer_expiration_custom),
+ )
+ Column(
+ modifier = modifier,
+ ) {
+ LazyRow(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ ) {
+ items(items = options, key = { it.first }) {
+ SelectionChip(
+ label = { Text(it.second) },
+ modifier = Modifier.padding(horizontal = 4.dp),
+ selected = it.first == option,
+ value = it.first,
+ onSelected = { o ->
+ onOptionChange(o)
+ if (o != ExpirationOption.CUSTOM) {
+ onHoursChange(o.hours)
+ }
+ },
+ )
+ }
+ }
+
+ if (option == ExpirationOption.CUSTOM) {
+ val d = hours / 24L
+ val h = hours - d * 24L
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ NumericInputField(
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(1f)
+ .padding(end = 4.dp),
+ value = d,
+ onValueChange = {
+ onHoursChange(it * 24 + h)
+ },
+ label = {
Text(stringResource(R.string.send_peer_expiration_days)) },
+ maxValue = 365,
+ )
+ NumericInputField(
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(1f)
+ .padding(start = 4.dp),
+ value = h,
+ onValueChange = {
+ onHoursChange(d * 24 + it)
+ },
+ label = {
Text(stringResource(R.string.send_peer_expiration_hours)) },
+ maxValue = 23,
+ )
+ }
+ }
+ }
+}
+
+@Preview
+@Composable
+fun ExpirationComposablePreview() {
+ TalerSurface {
+ var option = ExpirationOption.CUSTOM
+ var hours = 25L
+ ExpirationComposable(
+ option = option,
+ hours = hours,
+ onOptionChange = { option = it }
+ ) { hours = it }
+ }
+}
\ No newline at end of file
diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
index 79030f1..565aeb1 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
@@ -76,7 +76,7 @@ class OutgoingPullFragment : Fragment() {
if (!requireActivity().isChangingConfigurations)
peerManager.resetPullPayment()
}
- private fun onCreateInvoice(amount: Amount, summary: String, exchange:
ExchangeItem) {
- peerManager.initiatePeerPullCredit(amount, summary, exchange)
+ private fun onCreateInvoice(amount: Amount, summary: String, hours: Long,
exchange: ExchangeItem) {
+ peerManager.initiatePeerPullCredit(amount, summary, hours, exchange)
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
index a7cd2a8..f227dec 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
@@ -57,7 +57,7 @@ import kotlin.random.Random
fun OutgoingPullIntroComposable(
amount: Amount,
state: OutgoingState,
- onCreateInvoice: (amount: Amount, subject: String, exchange: ExchangeItem)
-> Unit,
+ onCreateInvoice: (amount: Amount, subject: String, hours: Long, exchange:
ExchangeItem) -> Unit,
) {
val scrollState = rememberScrollState()
Column(
@@ -72,7 +72,6 @@ fun OutgoingPullIntroComposable(
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
- .padding(top = 16.dp, start = 16.dp, end = 16.dp)
.focusRequester(focusRequester),
singleLine = true,
value = subject,
@@ -96,7 +95,7 @@ fun OutgoingPullIntroComposable(
Text(
modifier = Modifier
.fillMaxWidth()
- .padding(top = 5.dp, end = 16.dp),
+ .padding(top = 5.dp),
color = if (subject.isBlank()) MaterialTheme.colorScheme.error
else Color.Unspecified,
text = stringResource(R.string.char_count, subject.length,
MAX_LENGTH_SUBJECT),
textAlign = TextAlign.End,
@@ -119,6 +118,19 @@ fun OutgoingPullIntroComposable(
label = stringResource(id = R.string.withdraw_exchange),
info = if (exchangeItem == null) "" else
cleanExchange(exchangeItem.exchangeBaseUrl),
)
+ Text(
+ modifier = Modifier.padding(top = 16.dp, start = 16.dp, end =
16.dp),
+ text = stringResource(R.string.send_peer_expiration_period),
+ style = MaterialTheme.typography.bodyMedium,
+ )
+ var option by rememberSaveable { mutableStateOf(DEFAULT_EXPIRY) }
+ var hours by rememberSaveable { mutableStateOf(DEFAULT_EXPIRY.hours) }
+ ExpirationComposable(
+ modifier = Modifier.padding(top = 8.dp, bottom = 16.dp),
+ option = option,
+ hours = hours,
+ onOptionChange = { option = it }
+ ) { hours = it }
Button(
modifier = Modifier.padding(16.dp),
enabled = subject.isNotBlank() && state is OutgoingChecked,
@@ -126,6 +138,7 @@ fun OutgoingPullIntroComposable(
onCreateInvoice(
amount,
subject,
+ hours,
exchangeItem ?: error("clickable without exchange")
)
},
@@ -142,7 +155,7 @@ fun PreviewReceiveFundsCheckingIntro() {
OutgoingPullIntroComposable(
Amount.fromDouble("TESTKUDOS", 42.23),
if (Random.nextBoolean()) OutgoingIntro else OutgoingChecking,
- ) { _, _, _ -> }
+ ) { _, _, _, _ -> }
}
}
@@ -156,6 +169,6 @@ fun PreviewReceiveFundsCheckedIntro() {
OutgoingPullIntroComposable(
Amount.fromDouble("TESTKUDOS", 42.23),
OutgoingChecked(amountRaw, amountEffective, exchangeItem)
- ) { _, _, _ -> }
+ ) { _, _, _, _ -> }
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
index 7019757..0aa029b 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
@@ -74,7 +74,7 @@ class OutgoingPushFragment : Fragment() {
if (!requireActivity().isChangingConfigurations)
peerManager.resetPushPayment()
}
- private fun onSend(amount: Amount, summary: String) {
- peerManager.initiatePeerPushDebit(amount, summary)
+ private fun onSend(amount: Amount, summary: String, hours: Long) {
+ peerManager.initiatePeerPushDebit(amount, summary, hours)
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
index 33e8390..0bf835c 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
@@ -16,7 +16,6 @@
package net.taler.wallet.peer
-import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
@@ -29,12 +28,16 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
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.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
@@ -49,7 +52,7 @@ import kotlin.random.Random
fun OutgoingPushIntroComposable(
state: OutgoingState,
amount: Amount,
- onSend: (amount: Amount, summary: String) -> Unit,
+ onSend: (amount: Amount, summary: String, hours: Long) -> Unit,
) {
val scrollState = rememberScrollState()
Column(
@@ -58,9 +61,9 @@ fun OutgoingPushIntroComposable(
.padding(16.dp)
.verticalScroll(scrollState),
horizontalAlignment = CenterHorizontally,
- verticalArrangement = spacedBy(16.dp),
) {
Text(
+ modifier = Modifier.padding(vertical = 16.dp),
text = amount.toString(),
softWrap = false,
style = MaterialTheme.typography.titleLarge,
@@ -68,6 +71,7 @@ fun OutgoingPushIntroComposable(
if (state is OutgoingChecked) {
val fee = state.amountEffective - state.amountRaw
Text(
+ modifier = Modifier.padding(vertical = 16.dp),
text = stringResource(id = R.string.payment_fee, fee),
softWrap = false,
color = MaterialTheme.colorScheme.error,
@@ -75,8 +79,11 @@ fun OutgoingPushIntroComposable(
}
var subject by rememberSaveable { mutableStateOf("") }
+ val focusRequester = remember { FocusRequester() }
OutlinedTextField(
- modifier = Modifier.fillMaxWidth(),
+ modifier = Modifier
+ .fillMaxWidth()
+ .focusRequester(focusRequester),
singleLine = true,
value = subject,
onValueChange = { input ->
@@ -93,21 +100,37 @@ fun OutgoingPushIntroComposable(
)
}
)
+ LaunchedEffect(Unit) {
+ focusRequester.requestFocus()
+ }
Text(
modifier = Modifier
- .fillMaxWidth(),
+ .fillMaxWidth()
+ .padding(top = 5.dp),
color = if (subject.isBlank()) MaterialTheme.colorScheme.error
else Color.Unspecified,
text = stringResource(R.string.char_count, subject.length,
MAX_LENGTH_SUBJECT),
textAlign = TextAlign.End,
)
Text(
+ modifier = Modifier.padding(top = 16.dp, start = 16.dp, end =
16.dp),
+ text = stringResource(R.string.send_peer_expiration_period),
+ style = MaterialTheme.typography.bodyMedium,
+ )
+ var option by rememberSaveable { mutableStateOf(DEFAULT_EXPIRY) }
+ var hours by rememberSaveable { mutableStateOf(DEFAULT_EXPIRY.hours) }
+ ExpirationComposable(
+ modifier = Modifier.padding(top = 8.dp, bottom = 16.dp),
+ option = option,
+ hours = hours,
+ onOptionChange = { option = it }
+ ) { hours = it }
+ Text(
+ modifier = Modifier.padding(top = 8.dp, bottom = 16.dp),
text = stringResource(R.string.send_peer_warning),
)
Button(
enabled = state is OutgoingChecked && subject.isNotBlank(),
- onClick = {
- onSend(amount, subject)
- },
+ onClick = { onSend(amount, subject, hours) },
) {
Text(text = stringResource(R.string.send_peer_create_button))
}
@@ -119,7 +142,7 @@ fun OutgoingPushIntroComposable(
fun PeerPushIntroComposableCheckingPreview() {
Surface {
val state = if (Random.nextBoolean()) OutgoingIntro else
OutgoingChecking
- OutgoingPushIntroComposable(state, Amount.fromDouble("TESTKUDOS",
42.23)) { _, _ -> }
+ OutgoingPushIntroComposable(state, Amount.fromDouble("TESTKUDOS",
42.23)) { _, _, _ -> }
}
}
@@ -130,6 +153,6 @@ fun PeerPushIntroComposableCheckedPreview() {
val amountEffective = Amount.fromDouble("TESTKUDOS", 42.42)
val amountRaw = Amount.fromDouble("TESTKUDOS", 42.23)
val state = OutgoingChecked(amountRaw, amountEffective)
- OutgoingPushIntroComposable(state, amountEffective) { _, _ -> }
+ OutgoingPushIntroComposable(state, amountEffective) { _, _, _ -> }
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt
b/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt
index f031d44..bff55ff 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt
@@ -34,9 +34,10 @@ import net.taler.wallet.backend.WalletBackendApi
import net.taler.wallet.exchanges.ExchangeItem
import net.taler.wallet.exchanges.ExchangeManager
import org.json.JSONObject
-import java.util.concurrent.TimeUnit.DAYS
+import java.util.concurrent.TimeUnit.HOURS
const val MAX_LENGTH_SUBJECT = 100
+val DEFAULT_EXPIRY = ExpirationOption.DAYS_1
class PeerManager(
private val api: WalletBackendApi,
@@ -82,10 +83,10 @@ class PeerManager(
}
}
- fun initiatePeerPullCredit(amount: Amount, summary: String, exchange:
ExchangeItem) {
+ fun initiatePeerPullCredit(amount: Amount, summary: String,
expirationHours: Long, exchange: ExchangeItem) {
_outgoingPullState.value = OutgoingCreating
scope.launch(Dispatchers.IO) {
- val expiry = Timestamp.fromMillis(System.currentTimeMillis() +
DAYS.toMillis(3))
+ val expiry = Timestamp.fromMillis(System.currentTimeMillis() +
HOURS.toMillis(expirationHours))
api.request("initiatePeerPullCredit",
InitiatePeerPullPaymentResponse.serializer()) {
put("exchangeBaseUrl", exchange.exchangeBaseUrl)
put("partialContractTerms", JSONObject().apply {
@@ -125,10 +126,10 @@ class PeerManager(
}
}
- fun initiatePeerPushDebit(amount: Amount, summary: String) {
+ fun initiatePeerPushDebit(amount: Amount, summary: String,
expirationHours: Long) {
_outgoingPushState.value = OutgoingCreating
scope.launch(Dispatchers.IO) {
- val expiry = Timestamp.fromMillis(System.currentTimeMillis() +
DAYS.toMillis(3))
+ val expiry = Timestamp.fromMillis(System.currentTimeMillis() +
HOURS.toMillis(expirationHours))
api.request("initiatePeerPushDebit",
InitiatePeerPullCreditResponse.serializer()) {
put("amount", amount.toJSONString())
put("partialContractTerms", JSONObject().apply {
diff --git a/wallet/src/main/res/values/strings.xml
b/wallet/src/main/res/values/strings.xml
index 52dacfe..c313248 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -151,6 +151,13 @@ 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_payment_amount_received">Amount received</string>
<string name="send_peer_payment_amount_sent">Amount sent</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_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>
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-android] branch master updated (0532aa1 -> 3ab1c7d),
gnunet <=