summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2023-04-13 11:31:44 -0300
committerTorsten Grote <t@grobox.de>2023-04-13 11:31:44 -0300
commit656ab6bb848920986734681a4d6bd69d7fbf5b14 (patch)
treeca495f9cd45b635dc5fa21e76cc00c4bcb3b2eab
parent1c6fda4c3bfd7599f530b313e6533aa1a5c7c7e8 (diff)
downloadtaler-android-656ab6bb848920986734681a4d6bd69d7fbf5b14.tar.gz
taler-android-656ab6bb848920986734681a4d6bd69d7fbf5b14.tar.bz2
taler-android-656ab6bb848920986734681a4d6bd69d7fbf5b14.zip
[wallet] Clean up compose migration of payment and refund transactions
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt67
-rw-r--r--wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt118
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt63
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionLinkComposable.kt86
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt3
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt38
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt5
7 files changed, 221 insertions, 159 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
index d2a88f6..c760bb4 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
@@ -24,7 +24,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
@@ -43,18 +43,16 @@ import net.taler.wallet.transactions.DeleteTransactionComposable
import net.taler.wallet.transactions.ErrorTransactionButton
import net.taler.wallet.transactions.ExtendedStatus
import net.taler.wallet.transactions.PaymentStatus
-import net.taler.wallet.transactions.Transaction
import net.taler.wallet.transactions.TransactionAmountComposable
import net.taler.wallet.transactions.TransactionInfo
import net.taler.wallet.transactions.TransactionInfoComposable
import net.taler.wallet.transactions.TransactionLinkComposable
import net.taler.wallet.transactions.TransactionPayment
-import net.taler.wallet.transactions.TransactionRefund
@Composable
fun TransactionPaymentComposable(
- t: Transaction,
- devMode: Boolean?,
+ t: TransactionPayment,
+ devMode: Boolean,
onFulfill: (url: String) -> Unit,
onDelete: () -> Unit,
) {
@@ -63,7 +61,7 @@ fun TransactionPaymentComposable(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(scrollState),
- horizontalAlignment = Alignment.CenterHorizontally,
+ horizontalAlignment = CenterHorizontally,
) {
val context = LocalContext.current
Text(
@@ -72,15 +70,9 @@ fun TransactionPaymentComposable(
style = MaterialTheme.typography.bodyLarge,
)
TransactionAmountComposable(
- label = stringResource(id = when (t) {
- is TransactionPayment -> R.string.transaction_paid
- else -> R.string.transaction_refund
- }),
+ label = stringResource(id = R.string.transaction_paid),
amount = t.amountEffective,
- amountType = when (t) {
- is TransactionPayment -> AmountType.Negative
- else -> AmountType.Positive
- },
+ amountType = AmountType.Negative,
)
TransactionAmountComposable(
label = stringResource(id = R.string.transaction_order_total),
@@ -89,24 +81,15 @@ fun TransactionPaymentComposable(
)
TransactionAmountComposable(
label = stringResource(id = R.string.withdraw_fees),
- amount = when (t) {
- is TransactionPayment -> t.amountEffective - t.amountRaw
- else -> t.amountRaw - t.amountEffective
- },
+ amount = t.amountEffective - t.amountRaw,
amountType = AmountType.Negative,
)
- when (t) {
- is TransactionPayment -> t.info
- is TransactionRefund -> t.info
- else -> null
- }?.let { info ->
- PurchaseDetails(info = info) {
- onFulfill(info.fulfillmentUrl!!)
- }
+ PurchaseDetails(info = t.info) {
+ onFulfill(t.info.fulfillmentUrl ?: "")
}
DeleteTransactionComposable(onDelete)
- if (devMode == true && t.error != null) {
- ErrorTransactionButton(error = t.error!!)
+ if (devMode && t.error != null) {
+ ErrorTransactionButton(error = t.error)
}
}
}
@@ -117,7 +100,7 @@ fun PurchaseDetails(
onClick: () -> Unit,
) {
Column(
- horizontalAlignment = Alignment.CenterHorizontally,
+ horizontalAlignment = CenterHorizontally,
) {
// Summary and fulfillment message
val text = if (info.fulfillmentMessage == null) {
@@ -136,7 +119,6 @@ fun PurchaseDetails(
info = text,
)
}
-
// Order ID
Text(
stringResource(id = R.string.transaction_order_id, info.orderId),
@@ -169,28 +151,3 @@ fun TransactionPaymentComposablePreview() {
TransactionPaymentComposable(t = t, devMode = true, onFulfill = {}) {}
}
}
-
-@Preview
-@Composable
-fun TransactionRefundComposablePreview() {
- val t = TransactionRefund(
- transactionId = "transactionId",
- timestamp = Timestamp.fromMillis(System.currentTimeMillis() - 360 * 60 * 1000),
- extendedStatus = ExtendedStatus.Pending,
- info = TransactionInfo(
- orderId = "123",
- merchant = ContractMerchant(name = "Taler"),
- summary = "Some Product that was bought and can have quite a long label",
- fulfillmentMessage = "This is some fulfillment message",
- fulfillmentUrl = "https://bank.demo.taler.net/",
- products = listOf(),
- ),
- refundedTransactionId = "transactionId",
- amountRaw = Amount.fromDouble("TESTKUDOS", 42.23),
- amountEffective = Amount.fromDouble("TESTKUDOS", 42.1337),
- error = TalerErrorInfo(code = TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED),
- )
- TalerSurface {
- TransactionPaymentComposable(t = t, devMode = true, onFulfill = {}) {}
- }
-} \ No newline at end of file
diff --git a/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt b/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
new file mode 100644
index 0000000..bb077f1
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
@@ -0,0 +1,118 @@
+/*
+ * 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.refund
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import net.taler.common.Amount
+import net.taler.common.ContractMerchant
+import net.taler.common.Timestamp
+import net.taler.common.toAbsoluteTime
+import net.taler.wallet.R
+import net.taler.wallet.backend.TalerErrorCode
+import net.taler.wallet.backend.TalerErrorInfo
+import net.taler.wallet.compose.TalerSurface
+import net.taler.wallet.payment.PurchaseDetails
+import net.taler.wallet.transactions.AmountType
+import net.taler.wallet.transactions.DeleteTransactionComposable
+import net.taler.wallet.transactions.ErrorTransactionButton
+import net.taler.wallet.transactions.ExtendedStatus
+import net.taler.wallet.transactions.TransactionAmountComposable
+import net.taler.wallet.transactions.TransactionInfo
+import net.taler.wallet.transactions.TransactionRefund
+
+@Composable
+fun TransactionRefundComposable(
+ t: TransactionRefund,
+ devMode: Boolean,
+ onFulfill: (url: String) -> Unit,
+ onDelete: () -> Unit,
+) {
+ val scrollState = rememberScrollState()
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .verticalScroll(scrollState),
+ horizontalAlignment = CenterHorizontally,
+ ) {
+ val context = LocalContext.current
+ Text(
+ modifier = Modifier.padding(16.dp),
+ text = t.timestamp.ms.toAbsoluteTime(context).toString(),
+ style = MaterialTheme.typography.bodyLarge,
+ )
+ TransactionAmountComposable(
+ label = stringResource(id = R.string.transaction_refund),
+ amount = t.amountEffective,
+ amountType = AmountType.Positive,
+ )
+ TransactionAmountComposable(
+ label = stringResource(id = R.string.transaction_order_total),
+ amount = t.amountRaw,
+ amountType = AmountType.Neutral,
+ )
+ TransactionAmountComposable(
+ label = stringResource(id = R.string.withdraw_fees),
+ amount = t.amountRaw - t.amountEffective,
+ amountType = AmountType.Negative,
+ )
+ PurchaseDetails(info = t.info) {
+ onFulfill(t.info.fulfillmentUrl ?: "")
+ }
+ DeleteTransactionComposable(onDelete)
+ if (devMode && t.error != null) {
+ ErrorTransactionButton(error = t.error)
+ }
+ }
+}
+
+@Preview
+@Composable
+fun TransactionRefundComposablePreview() {
+ val t = TransactionRefund(
+ transactionId = "transactionId",
+ timestamp = Timestamp.fromMillis(System.currentTimeMillis() - 360 * 60 * 1000),
+ extendedStatus = ExtendedStatus.Pending,
+ info = TransactionInfo(
+ orderId = "123",
+ merchant = ContractMerchant(name = "Taler"),
+ summary = "Some Product that was bought and can have quite a long label",
+ fulfillmentMessage = "This is some fulfillment message",
+ fulfillmentUrl = "https://bank.demo.taler.net/",
+ products = listOf(),
+ ),
+ refundedTransactionId = "transactionId",
+ amountRaw = Amount.fromDouble("TESTKUDOS", 42.23),
+ amountEffective = Amount.fromDouble("TESTKUDOS", 42.1337),
+ error = TalerErrorInfo(code = TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED),
+ )
+ TalerSurface {
+ TransactionRefundComposable(t = t, devMode = true, onFulfill = {}) {}
+ }
+}
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
index d37728f..678bed2 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
@@ -17,25 +17,16 @@
package net.taler.wallet.transactions
import android.os.Bundle
-import android.text.SpannableString
-import android.text.style.UnderlineSpan
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
-import android.widget.TextView
import androidx.annotation.StringRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import kotlinx.serialization.encodeToString
-import kotlinx.serialization.json.Json
-import net.taler.common.Amount
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
-import net.taler.wallet.compose.copyToClipBoard
-import net.taler.wallet.getAttrColor
-import net.taler.wallet.launchInAppBrowser
abstract class TransactionDetailFragment : Fragment() {
@@ -72,34 +63,6 @@ abstract class TransactionDetailFragment : Fragment() {
}
}
- protected fun bindOrderAndFee(
- orderSummaryView: TextView,
- orderAmountView: TextView,
- orderIdView: TextView,
- feeView: TextView,
- info: TransactionInfo,
- raw: Amount,
- fee: Amount,
- ) {
- orderAmountView.text = raw.toString()
- feeView.text = getString(R.string.amount_negative, fee.toString())
- orderSummaryView.text = if (info.fulfillmentMessage == null) {
- info.summary
- } else {
- "${info.summary}\n\n${info.fulfillmentMessage}"
- }
- if (info.fulfillmentUrl?.startsWith("http", ignoreCase = true) == true) {
- val content = SpannableString(info.summary)
- content.setSpan(UnderlineSpan(), 0, info.summary.length, 0)
- orderSummaryView.text = content
- orderSummaryView.setTextColor(requireContext().getAttrColor(android.R.attr.textColorLink))
- orderSummaryView.setOnClickListener {
- launchInAppBrowser(requireContext(), info.fulfillmentUrl)
- }
- }
- orderIdView.text = getString(R.string.transaction_order_id, info.orderId)
- }
-
@StringRes
protected open val deleteDialogTitle = R.string.transactions_delete
@@ -128,30 +91,4 @@ abstract class TransactionDetailFragment : Fragment() {
findNavController().popBackStack()
}
- protected fun onShowErrorButtonClicked(t: Transaction) {
- val err = t.error
- require(err != null) { "Transaction had no error." }
-
- @Suppress("OPT_IN_USAGE")
- val json = Json {
- prettyPrint = true
- prettyPrintIndent = " "
- }
- val message = json.encodeToString(err)
- MaterialAlertDialogBuilder(requireContext(), R.style.MaterialAlertDialog_Material3)
- .setTitle(getString(R.string.nav_error))
- .setMessage(message)
- .setNeutralButton(R.string.close) { dialog, _ ->
- dialog.cancel()
- }
- .setPositiveButton(R.string.copy) { _, _ ->
- copyToClipBoard(
- requireContext(),
- getString(R.string.nav_error),
- message,
- )
- }
- .show()
- }
-
}
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionLinkComposable.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionLinkComposable.kt
new file mode 100644
index 0000000..e8fca0f
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionLinkComposable.kt
@@ -0,0 +1,86 @@
+/*
+ * 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.transactions
+
+import android.R
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.text.ClickableText
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import net.taler.wallet.compose.TalerSurface
+import net.taler.wallet.getAttrColor
+
+@Composable
+// FIXME this assumes that it is used in a column and applies its own padding, not really re-usable
+fun TransactionLinkComposable(label: String, info: String, onClick: () -> Unit) {
+ Text(
+ modifier = Modifier.padding(top = 16.dp, start = 16.dp, end = 16.dp),
+ text = label,
+ style = MaterialTheme.typography.bodyMedium,
+ )
+ val context = LocalContext.current
+ val linkColor = Color(context.getAttrColor(R.attr.textColorLink))
+ val annotatedString = buildAnnotatedString {
+ pushStringAnnotation(tag = "url", annotation = info)
+ withStyle(style = SpanStyle(color = linkColor)) {
+ append(info)
+ }
+ pop()
+ }
+ ClickableText(
+ modifier = Modifier.padding(top = 8.dp, start = 16.dp, end = 16.dp, bottom = 16.dp),
+ text = annotatedString,
+ style = TextStyle(fontSize = 24.sp, textAlign = TextAlign.Center),
+ ) { offset ->
+ annotatedString.getStringAnnotations(
+ tag = "url",
+ start = offset,
+ end = offset,
+ ).firstOrNull()?.let {
+ onClick()
+ }
+ }
+}
+
+@Preview
+@Composable
+fun TransactionLinkComposablePreview() {
+ TalerSurface {
+ Column(
+ horizontalAlignment = CenterHorizontally,
+ ) {
+ TransactionLinkComposable(
+ label = "This is a label",
+ info = "This is some fulfillment message"
+ ) {}
+ }
+ }
+}
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
index ac35fe0..e9eb5b8 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
@@ -36,7 +36,8 @@ class TransactionPaymentFragment : TransactionDetailFragment() {
setContent {
TalerSurface {
val t = transactionManager.selectedTransaction.observeAsState().value
- if (t is TransactionPayment) TransactionPaymentComposable(t, devMode.value,
+ val devMode = devMode.observeAsState().value ?: false
+ if (t is TransactionPayment) TransactionPaymentComposable(t, devMode,
onFulfill = { url ->
launchInAppBrowser(requireContext(), url)
},
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 170c719..297c937 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPeerFragment.kt
@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -36,18 +35,12 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
-import androidx.compose.ui.text.SpanStyle
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.buildAnnotatedString
-import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import net.taler.common.Amount
import net.taler.common.toAbsoluteTime
import net.taler.wallet.R
import net.taler.wallet.compose.TalerSurface
-import net.taler.wallet.getAttrColor
import net.taler.wallet.peer.TransactionPeerPullCreditComposable
import net.taler.wallet.peer.TransactionPeerPullDebitComposable
import net.taler.wallet.peer.TransactionPeerPushCreditComposable
@@ -132,34 +125,3 @@ fun TransactionInfoComposable(label: String, info: String) {
fontSize = 24.sp,
)
}
-
-@Composable
-fun TransactionLinkComposable(label: String, info: String, onClick: () -> Unit) {
- Text(
- modifier = Modifier.padding(top = 16.dp, start = 16.dp, end = 16.dp),
- text = label,
- style = MaterialTheme.typography.bodyMedium,
- )
- val context = LocalContext.current
- val linkColor = Color(context.getAttrColor(android.R.attr.textColorLink))
- val annotatedString = buildAnnotatedString {
- pushStringAnnotation(tag = "url", annotation = info)
- withStyle(style = SpanStyle(color = linkColor)) {
- append(info)
- }
- pop()
- }
- ClickableText(
- modifier = Modifier.padding(top = 8.dp, start = 16.dp, end = 16.dp, bottom = 16.dp),
- text = annotatedString,
- style = TextStyle(fontSize = 24.sp, textAlign = TextAlign.Center),
- ) { offset ->
- annotatedString.getStringAnnotations(
- tag = "url",
- start = offset,
- end = offset,
- ).firstOrNull()?.let {
- onClick()
- }
- }
-} \ No newline at end of file
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
index b4a3be8..61c0364 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
@@ -24,7 +24,7 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.platform.ComposeView
import net.taler.wallet.compose.TalerSurface
import net.taler.wallet.launchInAppBrowser
-import net.taler.wallet.payment.TransactionPaymentComposable
+import net.taler.wallet.refund.TransactionRefundComposable
class TransactionRefundFragment : TransactionDetailFragment() {
@@ -36,7 +36,8 @@ class TransactionRefundFragment : TransactionDetailFragment() {
setContent {
TalerSurface {
val t = transactionManager.selectedTransaction.observeAsState().value
- if (t is TransactionRefund) TransactionPaymentComposable(t, devMode.value,
+ val devMode = devMode.observeAsState().value ?: false
+ if (t is TransactionRefund) TransactionRefundComposable(t, devMode,
onFulfill = { url ->
launchInAppBrowser(requireContext(), url)
},