[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-android] branch master updated: [wallet] implement prototyp
From: |
gnunet |
Subject: |
[taler-taler-android] branch master updated: [wallet] implement prototype for handling incoming pay-pull URI |
Date: |
Wed, 07 Sep 2022 21:44:25 +0200 |
This is an automated email from the git hooks/post-receive script.
torsten-grote pushed a commit to branch master
in repository taler-android.
The following commit(s) were added to refs/heads/master by this push:
new e350d49 [wallet] implement prototype for handling incoming pay-pull
URI
e350d49 is described below
commit e350d497abe560aeeef88081ae93d73135ece00f
Author: Torsten Grote <t@grobox.de>
AuthorDate: Wed Sep 7 16:28:04 2022 -0300
[wallet] implement prototype for handling incoming pay-pull URI
---
.../src/main/java/net/taler/wallet/MainActivity.kt | 4 ++
.../java/net/taler/wallet/SendFundsFragment.kt | 12 ++--
...lPaymentComposable.kt => IncomingComposable.kt} | 65 +++++++++++-------
...tFragment.kt => IncomingPullPaymentFragment.kt} | 10 +--
...tFragment.kt => IncomingPushPaymentFragment.kt} | 16 ++---
.../{PeerIncomingState.kt => IncomingState.kt} | 25 ++++---
...PeerPullFragment.kt => OutgoingPullFragment.kt} | 10 +--
...omposable.kt => OutgoingPullIntroComposable.kt} | 4 +-
...mposable.kt => OutgoingPullResultComposable.kt} | 28 ++++----
...omposable.kt => OutgoingPushIntroComposable.kt} | 4 +-
...mposable.kt => OutgoingPushResultComposable.kt} | 28 ++++----
.../{PeerOutgoingState.kt => OutgoingState.kt} | 14 ++--
.../main/java/net/taler/wallet/peer/PeerManager.kt | 77 ++++++++++++++++------
.../taler/wallet/peer/TransactionPeerPushCredit.kt | 77 ++++++++++++++++++++++
.../wallet/transactions/TransactionPeerFragment.kt | 3 +-
.../net/taler/wallet/transactions/Transactions.kt | 4 +-
wallet/src/main/res/navigation/nav_graph.xml | 18 ++++-
wallet/src/main/res/values/strings.xml | 5 ++
18 files changed, 283 insertions(+), 121 deletions(-)
diff --git a/wallet/src/main/java/net/taler/wallet/MainActivity.kt
b/wallet/src/main/java/net/taler/wallet/MainActivity.kt
index 2797a69..df974ff 100644
--- a/wallet/src/main/java/net/taler/wallet/MainActivity.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainActivity.kt
@@ -257,6 +257,10 @@ class MainActivity : AppCompatActivity(),
OnNavigationItemSelectedListener,
nav.navigate(R.id.action_global_prompt_pull_payment)
model.peerManager.checkPeerPullPayment(u)
}
+ action.startsWith("pay-push/") -> {
+ nav.navigate(R.id.action_global_prompt_push_payment)
+ model.peerManager.checkPeerPushPayment(u)
+ }
else -> {
showError(R.string.error_unsupported_uri, "From:
$from\nURI: $u")
}
diff --git a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
index 27f2c96..290c91b 100644
--- a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
@@ -28,9 +28,9 @@ import androidx.navigation.findNavController
import com.google.android.material.composethemeadapter.MdcTheme
import net.taler.common.Amount
import net.taler.wallet.compose.collectAsStateLifecycleAware
-import net.taler.wallet.peer.PeerOutgoingIntro
-import net.taler.wallet.peer.PeerPushIntroComposable
-import net.taler.wallet.peer.PeerPushResultComposable
+import net.taler.wallet.peer.OutgoingIntro
+import net.taler.wallet.peer.OutgoingPushIntroComposable
+import net.taler.wallet.peer.OutgoingPushResultComposable
class SendFundsFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
@@ -45,12 +45,12 @@ class SendFundsFragment : Fragment() {
MdcTheme {
Surface {
val state =
peerManager.pushState.collectAsStateLifecycleAware()
- if (state.value is PeerOutgoingIntro) {
+ if (state.value is OutgoingIntro) {
val currency = transactionManager.selectedCurrency
?: error("No currency selected")
- PeerPushIntroComposable(currency,
this@SendFundsFragment::onSend)
+ OutgoingPushIntroComposable(currency,
this@SendFundsFragment::onSend)
} else {
- PeerPushResultComposable(state.value) {
+ OutgoingPushResultComposable(state.value) {
findNavController().popBackStack()
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/peer/PeerPullPaymentComposable.kt
b/wallet/src/main/java/net/taler/wallet/peer/IncomingComposable.kt
similarity index 80%
rename from
wallet/src/main/java/net/taler/wallet/peer/PeerPullPaymentComposable.kt
rename to wallet/src/main/java/net/taler/wallet/peer/IncomingComposable.kt
index fff74ea..0095bc4 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerPullPaymentComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/IncomingComposable.kt
@@ -17,6 +17,7 @@
package net.taler.wallet.peer
import android.annotation.SuppressLint
+import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
@@ -49,10 +50,26 @@ import net.taler.common.Amount
import net.taler.wallet.R
import net.taler.wallet.backend.TalerErrorInfo
+data class IncomingData(
+ @StringRes val intro: Int,
+ @StringRes val button: Int,
+)
+
+val incomingPush = IncomingData(
+ intro = R.string.receive_peer_payment_intro,
+ button = R.string.receive_peer_payment_title,
+)
+
+val incomingPull = IncomingData(
+ intro = R.string.pay_peer_intro,
+ button = R.string.payment_button_confirm,
+)
+
@Composable
-fun PeerPullPaymentComposable(
- state: State<PeerIncomingState>,
- onAccept: (PeerIncomingTerms) -> Unit,
+fun IncomingComposable(
+ state: State<IncomingState>,
+ data: IncomingData,
+ onAccept: (IncomingTerms) -> Unit,
) {
val scrollState = rememberScrollState()
Column(
@@ -64,15 +81,16 @@ fun PeerPullPaymentComposable(
modifier = Modifier
.padding(16.dp)
.align(CenterHorizontally),
- text = stringResource(id = R.string.pay_peer_intro))
+ text = stringResource(id = data.intro),
+ )
when (val s = state.value) {
- PeerIncomingChecking -> PeerPullCheckingComposable()
- is PeerIncomingTerms -> PeerPullTermsComposable(s, onAccept)
- is PeerIncomingAccepting -> PeerPullTermsComposable(s, onAccept)
- PeerIncomingAccepted -> {
+ IncomingChecking -> PeerPullCheckingComposable()
+ is IncomingTerms -> PeerPullTermsComposable(s, onAccept, data)
+ is IncomingAccepting -> PeerPullTermsComposable(s, onAccept, data)
+ IncomingAccepted -> {
// we navigate away, don't show anything
}
- is PeerIncomingError -> PeerPullErrorComposable(s)
+ is IncomingError -> PeerPullErrorComposable(s)
}
}
}
@@ -88,8 +106,9 @@ fun ColumnScope.PeerPullCheckingComposable() {
@Composable
fun ColumnScope.PeerPullTermsComposable(
- terms: PeerIncomingTerms,
- onAccept: (PeerIncomingTerms) -> Unit,
+ terms: IncomingTerms,
+ onAccept: (IncomingTerms) -> Unit,
+ data: IncomingData,
) {
Text(
modifier = Modifier
@@ -126,7 +145,7 @@ fun ColumnScope.PeerPullTermsComposable(
style = MaterialTheme.typography.body1,
)
}
- if (terms is PeerIncomingAccepting) {
+ if (terms is IncomingAccepting) {
CircularProgressIndicator(
modifier = Modifier
.padding(end = 64.dp)
@@ -144,7 +163,7 @@ fun ColumnScope.PeerPullTermsComposable(
onClick = { onAccept(terms) },
) {
Text(
- text = stringResource(id =
R.string.payment_button_confirm),
+ text = stringResource(id = data.button),
)
}
}
@@ -153,7 +172,7 @@ fun ColumnScope.PeerPullTermsComposable(
}
@Composable
-fun ColumnScope.PeerPullErrorComposable(s: PeerIncomingError) {
+fun ColumnScope.PeerPullErrorComposable(s: IncomingError) {
Text(
modifier = Modifier
.align(CenterHorizontally)
@@ -169,8 +188,8 @@ fun ColumnScope.PeerPullErrorComposable(s:
PeerIncomingError) {
fun PeerPullCheckingPreview() {
Surface {
@SuppressLint("UnrememberedMutableState")
- val s = mutableStateOf(PeerIncomingChecking)
- PeerPullPaymentComposable(s) {}
+ val s = mutableStateOf(IncomingChecking)
+ IncomingComposable(s, incomingPush) {}
}
}
@@ -178,7 +197,7 @@ fun PeerPullCheckingPreview() {
@Composable
fun PeerPullTermsPreview() {
Surface {
- val terms = PeerIncomingTerms(
+ val terms = IncomingTerms(
amount = Amount.fromDouble("TESTKUDOS", 42.23),
contractTerms = PeerContractTerms(
summary = "This is a long test summary that can be more than
one line long for sure",
@@ -189,7 +208,7 @@ fun PeerPullTermsPreview() {
@SuppressLint("UnrememberedMutableState")
val s = mutableStateOf(terms)
- PeerPullPaymentComposable(s) {}
+ IncomingComposable(s, incomingPush) {}
}
}
@@ -197,7 +216,7 @@ fun PeerPullTermsPreview() {
@Composable
fun PeerPullAcceptingPreview() {
Surface {
- val terms = PeerIncomingTerms(
+ val terms = IncomingTerms(
amount = Amount.fromDouble("TESTKUDOS", 42.23),
contractTerms = PeerContractTerms(
summary = "This is a long test summary that can be more than
one line long for sure",
@@ -207,8 +226,8 @@ fun PeerPullAcceptingPreview() {
)
@SuppressLint("UnrememberedMutableState")
- val s = mutableStateOf(PeerIncomingAccepting(terms))
- PeerPullPaymentComposable(s) {}
+ val s = mutableStateOf(IncomingAccepting(terms))
+ IncomingComposable(s, incomingPush) {}
}
}
@@ -217,7 +236,7 @@ fun PeerPullAcceptingPreview() {
fun PeerPullPayErrorPreview() {
Surface {
@SuppressLint("UnrememberedMutableState")
- val s = mutableStateOf(PeerIncomingError(TalerErrorInfo(42, "hint",
"msg")))
- PeerPullPaymentComposable(s) {}
+ val s = mutableStateOf(IncomingError(TalerErrorInfo(42, "hint",
"msg")))
+ IncomingComposable(s, incomingPush) {}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/peer/PullPaymentFragment.kt
b/wallet/src/main/java/net/taler/wallet/peer/IncomingPullPaymentFragment.kt
similarity index 87%
copy from wallet/src/main/java/net/taler/wallet/peer/PullPaymentFragment.kt
copy to
wallet/src/main/java/net/taler/wallet/peer/IncomingPullPaymentFragment.kt
index 71b1bcc..cd2f39b 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PullPaymentFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/IncomingPullPaymentFragment.kt
@@ -31,7 +31,7 @@ import net.taler.wallet.MainViewModel
import net.taler.wallet.R
import net.taler.wallet.compose.collectAsStateLifecycleAware
-class PullPaymentFragment : Fragment() {
+class IncomingPullPaymentFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val peerManager get() = model.peerManager
@@ -41,8 +41,8 @@ class PullPaymentFragment : Fragment() {
savedInstanceState: Bundle?,
): View {
lifecycleScope.launchWhenResumed {
- peerManager.paymentState.collect {
- if (it is PeerIncomingAccepted) {
+ peerManager.incomingPullState.collect {
+ if (it is IncomingAccepted) {
findNavController().navigate(R.id.action_promptPullPayment_to_nav_main)
}
}
@@ -51,8 +51,8 @@ class PullPaymentFragment : Fragment() {
setContent {
MdcTheme {
Surface {
- val state =
peerManager.paymentState.collectAsStateLifecycleAware()
- PeerPullPaymentComposable(state) { terms ->
+ val state =
peerManager.incomingPullState.collectAsStateLifecycleAware()
+ IncomingComposable(state, incomingPull) { terms ->
peerManager.acceptPeerPullPayment(terms)
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/peer/PullPaymentFragment.kt
b/wallet/src/main/java/net/taler/wallet/peer/IncomingPushPaymentFragment.kt
similarity index 81%
rename from wallet/src/main/java/net/taler/wallet/peer/PullPaymentFragment.kt
rename to
wallet/src/main/java/net/taler/wallet/peer/IncomingPushPaymentFragment.kt
index 71b1bcc..8429ecc 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PullPaymentFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/IncomingPushPaymentFragment.kt
@@ -31,7 +31,7 @@ import net.taler.wallet.MainViewModel
import net.taler.wallet.R
import net.taler.wallet.compose.collectAsStateLifecycleAware
-class PullPaymentFragment : Fragment() {
+class IncomingPushPaymentFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val peerManager get() = model.peerManager
@@ -41,9 +41,9 @@ class PullPaymentFragment : Fragment() {
savedInstanceState: Bundle?,
): View {
lifecycleScope.launchWhenResumed {
- peerManager.paymentState.collect {
- if (it is PeerIncomingAccepted) {
-
findNavController().navigate(R.id.action_promptPullPayment_to_nav_main)
+ peerManager.incomingPushState.collect {
+ if (it is IncomingAccepted) {
+
findNavController().navigate(R.id.action_promptPushPayment_to_nav_main)
}
}
}
@@ -51,9 +51,9 @@ class PullPaymentFragment : Fragment() {
setContent {
MdcTheme {
Surface {
- val state =
peerManager.paymentState.collectAsStateLifecycleAware()
- PeerPullPaymentComposable(state) { terms ->
- peerManager.acceptPeerPullPayment(terms)
+ val state =
peerManager.incomingPushState.collectAsStateLifecycleAware()
+ IncomingComposable(state, incomingPush) { terms ->
+ peerManager.acceptPeerPushPayment(terms)
}
}
}
@@ -63,6 +63,6 @@ class PullPaymentFragment : Fragment() {
override fun onStart() {
super.onStart()
- activity?.setTitle(R.string.pay_peer_title)
+ activity?.setTitle(R.string.receive_peer_payment_title)
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/peer/PeerIncomingState.kt
b/wallet/src/main/java/net/taler/wallet/peer/IncomingState.kt
similarity index 72%
rename from wallet/src/main/java/net/taler/wallet/peer/PeerIncomingState.kt
rename to wallet/src/main/java/net/taler/wallet/peer/IncomingState.kt
index c021c2f..7ca38c4 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerIncomingState.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/IncomingState.kt
@@ -20,21 +20,21 @@ import kotlinx.serialization.Serializable
import net.taler.common.Amount
import net.taler.wallet.backend.TalerErrorInfo
-sealed class PeerIncomingState
-object PeerIncomingChecking : PeerIncomingState()
-open class PeerIncomingTerms(
+sealed class IncomingState
+object IncomingChecking : IncomingState()
+open class IncomingTerms(
val amount: Amount,
val contractTerms: PeerContractTerms,
val id: String,
-) : PeerIncomingState()
+) : IncomingState()
-class PeerIncomingAccepting(s: PeerIncomingTerms) :
- PeerIncomingTerms(s.amount, s.contractTerms, s.id)
+class IncomingAccepting(s: IncomingTerms) :
+ IncomingTerms(s.amount, s.contractTerms, s.id)
-object PeerIncomingAccepted : PeerIncomingState()
-data class PeerIncomingError(
+object IncomingAccepted : IncomingState()
+data class IncomingError(
val info: TalerErrorInfo,
-) : PeerIncomingState()
+) : IncomingState()
@Serializable
data class PeerContractTerms(
@@ -48,3 +48,10 @@ data class CheckPeerPullPaymentResponse(
val contractTerms: PeerContractTerms,
val peerPullPaymentIncomingId: String,
)
+
+@Serializable
+data class CheckPeerPushPaymentResponse(
+ val amount: Amount,
+ val contractTerms: PeerContractTerms,
+ val peerPushPaymentIncomingId: String,
+)
diff --git a/wallet/src/main/java/net/taler/wallet/peer/PeerPullFragment.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
similarity index 90%
rename from wallet/src/main/java/net/taler/wallet/peer/PeerPullFragment.kt
rename to wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
index be79e9d..b1593ff 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerPullFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
@@ -32,7 +32,7 @@ import net.taler.wallet.R
import net.taler.wallet.compose.collectAsStateLifecycleAware
import net.taler.wallet.exchanges.ExchangeItem
-class PeerPullFragment : Fragment() {
+class OutgoingPullFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val exchangeManager get() = model.exchangeManager
private val peerManager get() = model.peerManager
@@ -51,16 +51,16 @@ class PeerPullFragment : Fragment() {
MdcTheme {
Surface {
val state =
peerManager.pullState.collectAsStateLifecycleAware()
- if (state.value is PeerOutgoingIntro) {
+ if (state.value is OutgoingIntro) {
val exchangeState =
exchangeFlow.collectAsStateLifecycleAware(initial = null)
- PeerPullIntroComposable(
+ OutgoingPullIntroComposable(
amount = amount,
exchangeState = exchangeState,
- onCreateInvoice =
this@PeerPullFragment::onCreateInvoice,
+ onCreateInvoice =
this@OutgoingPullFragment::onCreateInvoice,
)
} else {
- PeerPullResultComposable(state.value) {
+ OutgoingPullResultComposable(state.value) {
findNavController().popBackStack()
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/peer/PeerPullIntroComposable.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
similarity index 97%
rename from
wallet/src/main/java/net/taler/wallet/peer/PeerPullIntroComposable.kt
rename to
wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
index 02f2c7c..a338836 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerPullIntroComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
@@ -50,7 +50,7 @@ import net.taler.wallet.cleanExchange
import net.taler.wallet.exchanges.ExchangeItem
@Composable
-fun PeerPullIntroComposable(
+fun OutgoingPullIntroComposable(
amount: Amount,
exchangeState: State<ExchangeItem?>,
onCreateInvoice: (amount: Amount, exchange: ExchangeItem) -> Unit,
@@ -124,6 +124,6 @@ fun PreviewReceiveFundsIntro() {
@SuppressLint("UnrememberedMutableState")
val exchangeFlow =
mutableStateOf(ExchangeItem("https://example.org", "TESTKUDOS",
emptyList()))
- PeerPullIntroComposable(Amount.fromDouble("TESTKUDOS", 42.23),
exchangeFlow) { _, _ -> }
+ OutgoingPullIntroComposable(Amount.fromDouble("TESTKUDOS", 42.23),
exchangeFlow) { _, _ -> }
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/peer/PeerPullResultComposable.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullResultComposable.kt
similarity index 85%
rename from
wallet/src/main/java/net/taler/wallet/peer/PeerPullResultComposable.kt
rename to
wallet/src/main/java/net/taler/wallet/peer/OutgoingPullResultComposable.kt
index d37ca4b..2c4001f 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerPullResultComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullResultComposable.kt
@@ -55,7 +55,7 @@ import net.taler.wallet.compose.getQrCodeSize
import org.json.JSONObject
@Composable
-fun PeerPullResultComposable(state: PeerOutgoingState, onClose: () -> Unit) {
+fun OutgoingPullResultComposable(state: OutgoingState, onClose: () -> Unit) {
val scrollState = rememberScrollState()
Column(
modifier = Modifier
@@ -68,10 +68,10 @@ fun PeerPullResultComposable(state: PeerOutgoingState,
onClose: () -> Unit) {
text = stringResource(id =
R.string.receive_peer_invoice_instruction),
)
when (state) {
- PeerOutgoingIntro -> error("Result composable with
PullPaymentIntro")
- is PeerOutgoingCreating -> PeerPullCreatingComposable()
- is PeerOutgoingResponse -> PeerPullResponseComposable(state)
- is PeerOutgoingError -> PeerPullErrorComposable(state)
+ OutgoingIntro -> error("Result composable with PullPaymentIntro")
+ is OutgoingCreating -> PeerPullCreatingComposable()
+ is OutgoingResponse -> PeerPullResponseComposable(state)
+ is OutgoingError -> PeerPullErrorComposable(state)
}
Button(modifier = Modifier
.padding(16.dp)
@@ -94,7 +94,7 @@ private fun ColumnScope.PeerPullCreatingComposable() {
}
@Composable
-private fun ColumnScope.PeerPullResponseComposable(state:
PeerOutgoingResponse) {
+private fun ColumnScope.PeerPullResponseComposable(state: OutgoingResponse) {
val qrCodeSize = getQrCodeSize()
Image(
modifier = Modifier
@@ -135,7 +135,7 @@ private fun ColumnScope.PeerPullResponseComposable(state:
PeerOutgoingResponse)
}
@Composable
-private fun ColumnScope.PeerPullErrorComposable(state: PeerOutgoingError) {
+private fun ColumnScope.PeerPullErrorComposable(state: OutgoingError) {
Text(
modifier = Modifier
.align(CenterHorizontally)
@@ -150,7 +150,7 @@ private fun ColumnScope.PeerPullErrorComposable(state:
PeerOutgoingError) {
@Composable
fun PeerPullCreatingPreview() {
Surface {
- PeerPullResultComposable(PeerOutgoingCreating) {}
+ OutgoingPullResultComposable(OutgoingCreating) {}
}
}
@@ -159,8 +159,8 @@ fun PeerPullCreatingPreview() {
fun PeerPullResponsePreview() {
Surface {
val talerUri =
"https://example.org/foo/bar/can/be/very/long/url/so/fit/it/on/screen"
- val response = PeerOutgoingResponse(talerUri,
QrCodeManager.makeQrCode(talerUri))
- PeerPullResultComposable(response) {}
+ val response = OutgoingResponse(talerUri,
QrCodeManager.makeQrCode(talerUri))
+ OutgoingPullResultComposable(response) {}
}
}
@@ -169,8 +169,8 @@ fun PeerPullResponsePreview() {
fun PeerPullResponseLandscapePreview() {
Surface {
val talerUri =
"https://example.org/foo/bar/can/be/very/long/url/so/fit/it/on/screen"
- val response = PeerOutgoingResponse(talerUri,
QrCodeManager.makeQrCode(talerUri))
- PeerPullResultComposable(response) {}
+ val response = OutgoingResponse(talerUri,
QrCodeManager.makeQrCode(talerUri))
+ OutgoingPullResultComposable(response) {}
}
}
@@ -179,7 +179,7 @@ fun PeerPullResponseLandscapePreview() {
fun PeerPullErrorPreview() {
Surface {
val json = JSONObject().apply { put("foo", "bar") }
- val response = PeerOutgoingError(TalerErrorInfo(42, "hint", "message",
json))
- PeerPullResultComposable(response) {}
+ val response = OutgoingError(TalerErrorInfo(42, "hint", "message",
json))
+ OutgoingPullResultComposable(response) {}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/peer/PeerPushComposable.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
similarity index 98%
rename from wallet/src/main/java/net/taler/wallet/peer/PeerPushComposable.kt
rename to
wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
index 1399fbb..72c8862 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerPushComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
@@ -47,7 +47,7 @@ import net.taler.wallet.R
import net.taler.wallet.getAmount
@Composable
-fun PeerPushIntroComposable(
+fun OutgoingPushIntroComposable(
currency: String,
onSend: (amount: Amount, summary: String) -> Unit,
) {
@@ -134,6 +134,6 @@ fun PeerPushIntroComposable(
@Composable
fun PeerPushIntroComposablePreview() {
Surface {
- PeerPushIntroComposable("TESTKUDOS") { _, _ -> }
+ OutgoingPushIntroComposable("TESTKUDOS") { _, _ -> }
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/peer/PeerPushResultComposable.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushResultComposable.kt
similarity index 85%
rename from
wallet/src/main/java/net/taler/wallet/peer/PeerPushResultComposable.kt
rename to
wallet/src/main/java/net/taler/wallet/peer/OutgoingPushResultComposable.kt
index b33fc4f..6d8b5dc 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerPushResultComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushResultComposable.kt
@@ -55,7 +55,7 @@ import net.taler.wallet.compose.getQrCodeSize
import org.json.JSONObject
@Composable
-fun PeerPushResultComposable(state: PeerOutgoingState, onClose: () -> Unit) {
+fun OutgoingPushResultComposable(state: OutgoingState, onClose: () -> Unit) {
val scrollState = rememberScrollState()
Column(
modifier = Modifier
@@ -68,10 +68,10 @@ fun PeerPushResultComposable(state: PeerOutgoingState,
onClose: () -> Unit) {
text = stringResource(id = R.string.send_peer_payment_instruction),
)
when (state) {
- PeerOutgoingIntro -> error("Result composable with
PullPaymentIntro")
- is PeerOutgoingCreating -> PeerPushCreatingComposable()
- is PeerOutgoingResponse -> PeerPushResponseComposable(state)
- is PeerOutgoingError -> PeerPushErrorComposable(state)
+ OutgoingIntro -> error("Result composable with PullPaymentIntro")
+ is OutgoingCreating -> PeerPushCreatingComposable()
+ is OutgoingResponse -> PeerPushResponseComposable(state)
+ is OutgoingError -> PeerPushErrorComposable(state)
}
Button(modifier = Modifier
.padding(16.dp)
@@ -94,7 +94,7 @@ private fun ColumnScope.PeerPushCreatingComposable() {
}
@Composable
-private fun ColumnScope.PeerPushResponseComposable(state:
PeerOutgoingResponse) {
+private fun ColumnScope.PeerPushResponseComposable(state: OutgoingResponse) {
val qrCodeSize = getQrCodeSize()
Image(
modifier = Modifier
@@ -135,7 +135,7 @@ private fun ColumnScope.PeerPushResponseComposable(state:
PeerOutgoingResponse)
}
@Composable
-private fun ColumnScope.PeerPushErrorComposable(state: PeerOutgoingError) {
+private fun ColumnScope.PeerPushErrorComposable(state: OutgoingError) {
Text(
modifier = Modifier
.align(CenterHorizontally)
@@ -150,7 +150,7 @@ private fun ColumnScope.PeerPushErrorComposable(state:
PeerOutgoingError) {
@Composable
fun PeerPushCreatingPreview() {
Surface {
- PeerPushResultComposable(PeerOutgoingCreating) {}
+ OutgoingPushResultComposable(OutgoingCreating) {}
}
}
@@ -159,8 +159,8 @@ fun PeerPushCreatingPreview() {
fun PeerPushResponsePreview() {
Surface {
val talerUri =
"https://example.org/foo/bar/can/be/very/long/url/so/fit/it/on/screen"
- val response = PeerOutgoingResponse(talerUri,
QrCodeManager.makeQrCode(talerUri))
- PeerPushResultComposable(response) {}
+ val response = OutgoingResponse(talerUri,
QrCodeManager.makeQrCode(talerUri))
+ OutgoingPushResultComposable(response) {}
}
}
@@ -169,8 +169,8 @@ fun PeerPushResponsePreview() {
fun PeerPushResponseLandscapePreview() {
Surface {
val talerUri =
"https://example.org/foo/bar/can/be/very/long/url/so/fit/it/on/screen"
- val response = PeerOutgoingResponse(talerUri,
QrCodeManager.makeQrCode(talerUri))
- PeerPushResultComposable(response) {}
+ val response = OutgoingResponse(talerUri,
QrCodeManager.makeQrCode(talerUri))
+ OutgoingPushResultComposable(response) {}
}
}
@@ -179,7 +179,7 @@ fun PeerPushResponseLandscapePreview() {
fun PeerPushErrorPreview() {
Surface {
val json = JSONObject().apply { put("foo", "bar") }
- val response = PeerOutgoingError(TalerErrorInfo(42, "hint", "message",
json))
- PeerPushResultComposable(response) {}
+ val response = OutgoingError(TalerErrorInfo(42, "hint", "message",
json))
+ OutgoingPushResultComposable(response) {}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/peer/PeerOutgoingState.kt
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingState.kt
similarity index 83%
rename from wallet/src/main/java/net/taler/wallet/peer/PeerOutgoingState.kt
rename to wallet/src/main/java/net/taler/wallet/peer/OutgoingState.kt
index 0b6b2a8..0e01056 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerOutgoingState.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingState.kt
@@ -20,17 +20,17 @@ import android.graphics.Bitmap
import kotlinx.serialization.Serializable
import net.taler.wallet.backend.TalerErrorInfo
-sealed class PeerOutgoingState
-object PeerOutgoingIntro : PeerOutgoingState()
-object PeerOutgoingCreating : PeerOutgoingState()
-data class PeerOutgoingResponse(
+sealed class OutgoingState
+object OutgoingIntro : OutgoingState()
+object OutgoingCreating : OutgoingState()
+data class OutgoingResponse(
val talerUri: String,
val qrCode: Bitmap,
-) : PeerOutgoingState()
+) : OutgoingState()
-data class PeerOutgoingError(
+data class OutgoingError(
val info: TalerErrorInfo,
-) : PeerOutgoingState()
+) : OutgoingState()
@Serializable
data class InitiatePeerPullPaymentResponse(
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 5bfd030..b02b2b6 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt
@@ -34,17 +34,20 @@ class PeerManager(
private val scope: CoroutineScope,
) {
- private val _pullState =
MutableStateFlow<PeerOutgoingState>(PeerOutgoingIntro)
- val pullState: StateFlow<PeerOutgoingState> = _pullState
+ private val _outgoingPullState =
MutableStateFlow<OutgoingState>(OutgoingIntro)
+ val pullState: StateFlow<OutgoingState> = _outgoingPullState
- private val _pushState =
MutableStateFlow<PeerOutgoingState>(PeerOutgoingIntro)
- val pushState: StateFlow<PeerOutgoingState> = _pushState
+ private val _outgoingPushState =
MutableStateFlow<OutgoingState>(OutgoingIntro)
+ val pushState: StateFlow<OutgoingState> = _outgoingPushState
- private val _paymentState =
MutableStateFlow<PeerIncomingState>(PeerIncomingChecking)
- val paymentState: StateFlow<PeerIncomingState> = _paymentState
+ private val _incomingPullState =
MutableStateFlow<IncomingState>(IncomingChecking)
+ val incomingPullState: StateFlow<IncomingState> = _incomingPullState
+
+ private val _incomingPushState =
MutableStateFlow<IncomingState>(IncomingChecking)
+ val incomingPushState: StateFlow<IncomingState> = _incomingPushState
fun initiatePullPayment(amount: Amount, exchange: ExchangeItem) {
- _pullState.value = PeerOutgoingCreating
+ _outgoingPullState.value = OutgoingCreating
scope.launch(Dispatchers.IO) {
api.request("initiatePeerPullPayment",
InitiatePeerPullPaymentResponse.serializer()) {
put("exchangeBaseUrl", exchange.exchangeBaseUrl)
@@ -54,20 +57,20 @@ class PeerManager(
})
}.onSuccess {
val qrCode = QrCodeManager.makeQrCode(it.talerUri)
- _pullState.value = PeerOutgoingResponse(it.talerUri, qrCode)
+ _outgoingPullState.value = OutgoingResponse(it.talerUri,
qrCode)
}.onError { error ->
Log.e(TAG, "got initiatePeerPullPayment error result $error")
- _pullState.value = PeerOutgoingError(error)
+ _outgoingPullState.value = OutgoingError(error)
}
}
}
fun resetPullPayment() {
- _pullState.value = PeerOutgoingIntro
+ _outgoingPullState.value = OutgoingIntro
}
fun initiatePeerPushPayment(amount: Amount, summary: String) {
- _pushState.value = PeerOutgoingCreating
+ _outgoingPushState.value = OutgoingCreating
scope.launch(Dispatchers.IO) {
api.request("initiatePeerPushPayment",
InitiatePeerPushPaymentResponse.serializer()) {
put("amount", amount.toJSONString())
@@ -76,46 +79,78 @@ class PeerManager(
})
}.onSuccess { response ->
val qrCode = QrCodeManager.makeQrCode(response.talerUri)
- _pushState.value = PeerOutgoingResponse(response.talerUri,
qrCode)
+ _outgoingPushState.value = OutgoingResponse(response.talerUri,
qrCode)
}.onError { error ->
Log.e(TAG, "got initiatePeerPushPayment error result $error")
- _pushState.value = PeerOutgoingError(error)
+ _outgoingPushState.value = OutgoingError(error)
}
}
}
fun resetPushPayment() {
- _pushState.value = PeerOutgoingIntro
+ _outgoingPushState.value = OutgoingIntro
}
fun checkPeerPullPayment(talerUri: String) {
- _paymentState.value = PeerIncomingChecking
+ _incomingPullState.value = IncomingChecking
scope.launch(Dispatchers.IO) {
api.request("checkPeerPullPayment",
CheckPeerPullPaymentResponse.serializer()) {
put("talerUri", talerUri)
}.onSuccess { response ->
- _paymentState.value = PeerIncomingTerms(
+ _incomingPullState.value = IncomingTerms(
amount = response.amount,
contractTerms = response.contractTerms,
id = response.peerPullPaymentIncomingId,
)
}.onError { error ->
Log.e(TAG, "got checkPeerPushPayment error result $error")
- _paymentState.value = PeerIncomingError(error)
+ _incomingPullState.value = IncomingError(error)
}
}
}
- fun acceptPeerPullPayment(terms: PeerIncomingTerms) {
- _paymentState.value = PeerIncomingAccepting(terms)
+ fun acceptPeerPullPayment(terms: IncomingTerms) {
+ _incomingPullState.value = IncomingAccepting(terms)
scope.launch(Dispatchers.IO) {
api.request<Unit>("acceptPeerPullPayment") {
put("peerPullPaymentIncomingId", terms.id)
}.onSuccess {
- _paymentState.value = PeerIncomingAccepted
+ _incomingPullState.value = IncomingAccepted
+ }.onError { error ->
+ Log.e(TAG, "got checkPeerPushPayment error result $error")
+ _incomingPullState.value = IncomingError(error)
+ }
+ }
+ }
+
+ fun checkPeerPushPayment(talerUri: String) {
+ _incomingPushState.value = IncomingChecking
+ scope.launch(Dispatchers.IO) {
+ api.request("checkPeerPushPayment",
CheckPeerPushPaymentResponse.serializer()) {
+ put("talerUri", talerUri)
+ }.onSuccess { response ->
+ _incomingPushState.value = IncomingTerms(
+ amount = response.amount,
+ contractTerms = response.contractTerms,
+ id = response.peerPushPaymentIncomingId,
+ )
+ }.onError { error ->
+ Log.e(TAG, "got checkPeerPushPayment error result $error")
+ _incomingPushState.value = IncomingError(error)
+ }
+ }
+ }
+
+ fun acceptPeerPushPayment(terms: IncomingTerms) {
+ _incomingPushState.value = IncomingAccepting(terms)
+ scope.launch(Dispatchers.IO) {
+ api.request<Unit>("acceptPeerPushPayment") {
+ put("peerPushPaymentIncomingId", terms.id)
+ }.onSuccess {
+ _incomingPushState.value = IncomingAccepted
}.onError { error ->
Log.e(TAG, "got checkPeerPushPayment error result $error")
- _paymentState.value = PeerIncomingError(error)
+ _incomingPushState.value = IncomingError(error)
}
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushCredit.kt
b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushCredit.kt
new file mode 100644
index 0000000..b986f57
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/peer/TransactionPeerPushCredit.kt
@@ -0,0 +1,77 @@
+/*
+ * 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.peer
+
+import androidx.compose.material.Surface
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import net.taler.common.Amount
+import net.taler.common.Timestamp
+import net.taler.wallet.R
+import net.taler.wallet.transactions.AmountType
+import net.taler.wallet.transactions.PeerInfoShort
+import net.taler.wallet.transactions.TransactionAmountComposable
+import net.taler.wallet.transactions.TransactionInfoComposable
+import net.taler.wallet.transactions.TransactionPeerComposable
+import net.taler.wallet.transactions.TransactionPeerPushCredit
+
+@Composable
+fun TransactionPeerPushCreditComposable(t: TransactionPeerPushCredit) {
+ TransactionAmountComposable(
+ label = stringResource(id =
R.string.send_peer_payment_amount_received),
+ amount = t.amountEffective,
+ amountType = AmountType.Positive,
+ )
+ TransactionAmountComposable(
+ label = stringResource(id = R.string.send_peer_payment_amount_sent),
+ amount = t.amountRaw,
+ amountType = AmountType.Neutral,
+ )
+ val fee = t.amountRaw - t.amountEffective
+ if (!fee.isZero()) {
+ TransactionAmountComposable(
+ label = stringResource(id = R.string.withdraw_fees),
+ amount = fee,
+ amountType = AmountType.Negative,
+ )
+ }
+ TransactionInfoComposable(
+ label = stringResource(id = R.string.withdraw_manual_ready_subject),
+ info = t.info.summary ?: "",
+ )
+}
+
+@Preview
+@Composable
+fun TransactionPeerPushCreditPreview() {
+ val t = TransactionPeerPushCredit(
+ transactionId = "transactionId",
+ timestamp = Timestamp(System.currentTimeMillis() - 360 * 60 * 1000),
+ pending = true,
+ exchangeBaseUrl = "https://exchange.example.org/",
+ amountRaw = Amount.fromDouble("TESTKUDOS", 42.23),
+ amountEffective = Amount.fromDouble("TESTKUDOS", 42.1337),
+ info = PeerInfoShort(
+ expiration = Timestamp(System.currentTimeMillis() + 60 * 60 *
1000),
+ summary = "test invoice",
+ ),
+ )
+ Surface {
+ TransactionPeerComposable(t) {}
+ }
+}
diff --git
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
index 9b0c208..749ec30 100644
---
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
+++
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
@@ -50,6 +50,7 @@ import net.taler.common.toAbsoluteTime
import net.taler.wallet.R
import net.taler.wallet.peer.TransactionPeerPullCreditComposable
import net.taler.wallet.peer.TransactionPeerPullDebitComposable
+import net.taler.wallet.peer.TransactionPeerPushCreditComposable
import net.taler.wallet.peer.TransactionPeerPushDebitComposable
class TransactionPeerFragment : TransactionDetailFragment() {
@@ -89,7 +90,7 @@ fun TransactionPeerComposable(t: Transaction, onDelete: () ->
Unit) {
)
when (t) {
is TransactionPeerPullCredit ->
TransactionPeerPullCreditComposable(t)
- is TransactionPeerPushCredit -> TODO()
+ is TransactionPeerPushCredit ->
TransactionPeerPushCreditComposable(t)
is TransactionPeerPullDebit ->
TransactionPeerPullDebitComposable(t)
is TransactionPeerPushDebit ->
TransactionPeerPushDebitComposable(t)
else -> error("unexpected transaction: ${t::class.simpleName}")
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 6ef6c88..97ac5ea 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
@@ -361,7 +361,7 @@ class TransactionPeerPushCredit(
@Transient
override val amountType = AmountType.Positive
override fun getTitle(context: Context): String {
- return context.getString(R.string.transaction_peer_push_debit)
+ return context.getString(R.string.transaction_peer_push_credit)
}
- override val generalTitleRes = R.string.withdraw_title
+ override val generalTitleRes = R.string.transaction_peer_push_credit
}
diff --git a/wallet/src/main/res/navigation/nav_graph.xml
b/wallet/src/main/res/navigation/nav_graph.xml
index 3170216..f9060c5 100644
--- a/wallet/src/main/res/navigation/nav_graph.xml
+++ b/wallet/src/main/res/navigation/nav_graph.xml
@@ -131,7 +131,7 @@
<fragment
android:id="@+id/nav_peer_pull"
- android:name="net.taler.wallet.peer.PeerPullFragment"
+ android:name="net.taler.wallet.peer.OutgoingPullFragment"
android:label="@string/receive_peer_title">
<argument
android:name="amount"
@@ -142,7 +142,7 @@
<fragment
android:id="@+id/promptPullPayment"
- android:name="net.taler.wallet.peer.PullPaymentFragment"
+ android:name="net.taler.wallet.peer.IncomingPullPaymentFragment"
android:label="@string/pay_peer_title">
<action
android:id="@+id/action_promptPullPayment_to_nav_main"
@@ -150,6 +150,16 @@
app:popUpTo="@id/nav_main" />
</fragment>
+ <fragment
+ android:id="@+id/promptPushPayment"
+ android:name="net.taler.wallet.peer.IncomingPushPaymentFragment"
+ android:label="@string/receive_peer_payment_title">
+ <action
+ android:id="@+id/action_promptPushPayment_to_nav_main"
+ app:destination="@id/nav_main"
+ app:popUpTo="@id/nav_main" />
+ </fragment>
+
<fragment
android:id="@+id/nav_transactions"
android:name="net.taler.wallet.transactions.TransactionsFragment"
@@ -289,6 +299,10 @@
android:id="@+id/action_global_prompt_pull_payment"
app:destination="@id/promptPullPayment" />
+ <action
+ android:id="@+id/action_global_prompt_push_payment"
+ app:destination="@id/promptPushPayment" />
+
<action
android:id="@+id/action_global_pending_operations"
app:destination="@id/nav_pending_operations" />
diff --git a/wallet/src/main/res/values/strings.xml
b/wallet/src/main/res/values/strings.xml
index 8601b14..ab8984c 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -99,6 +99,7 @@ GNU Taler is immune against many types of fraud, such as
phishing of credit card
<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="payment_title">Payment</string>
<string name="payment_fee">+%s payment fee</string>
@@ -127,9 +128,13 @@ GNU Taler is immune against many types of fraud, such as
phishing of credit card
<string name="send_peer_create_button">Send funds now</string>
<string name="send_peer_warning">Warning: Funds will leave the wallet
immediately.</string>
<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="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>
<string name="withdraw_initiated">Withdrawal initiated</string>
<string name="withdraw_title">Withdrawal</string>
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-taler-android] branch master updated: [wallet] implement prototype for handling incoming pay-pull URI,
gnunet <=