summaryrefslogtreecommitdiff
path: root/wallet/src/main/java/net/taler/wallet/transactions
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2023-04-11 12:18:13 -0600
committerTorsten Grote <t@grobox.de>2023-04-13 09:55:59 -0300
commit4d37a683d1028b374abe03d310cc2d7ca47416c2 (patch)
tree36e9cb25fcfc0ec4ffbb67bdd7c1f0d205b146bc /wallet/src/main/java/net/taler/wallet/transactions
parent7cd48e38a0d502fb0748c9b1e04738be43c8c1cf (diff)
downloadtaler-android-4d37a683d1028b374abe03d310cc2d7ca47416c2.tar.gz
taler-android-4d37a683d1028b374abe03d310cc2d7ca47416c2.tar.bz2
taler-android-4d37a683d1028b374abe03d310cc2d7ca47416c2.zip
[wallet] Migrated withdrawal and refresh detail to Compose
Diffstat (limited to 'wallet/src/main/java/net/taler/wallet/transactions')
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/ActionButtonComposable.kt136
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt47
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt123
3 files changed, 190 insertions, 116 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/ActionButtonComposable.kt b/wallet/src/main/java/net/taler/wallet/transactions/ActionButtonComposable.kt
new file mode 100644
index 0000000..2e2b4ac
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/transactions/ActionButtonComposable.kt
@@ -0,0 +1,136 @@
+/*
+ * 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 androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.defaultMinSize
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.AccountBalance
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.Icon
+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.unit.dp
+import net.taler.wallet.R
+import net.taler.wallet.backend.TalerErrorCode
+import net.taler.wallet.transactions.WithdrawalDetails.TalerBankIntegrationApi
+import net.taler.wallet.transactions.WithdrawalDetails.ManualTransfer
+
+interface ActionListener {
+ enum class Type {
+ COMPLETE_KYC,
+ CONFIRM_WITH_BANK,
+ CONFIRM_MANUAL
+ }
+
+ fun onActionButtonClicked(tx: Transaction, type: Type)
+}
+
+@Composable
+fun ActionButton(
+ modifier: Modifier = Modifier,
+ tx: Transaction,
+ listener: ActionListener,
+ isSmall: Boolean = false,
+) {
+ if (tx.error != null) {
+ // There is an error!
+ when (tx.error!!.code) {
+ TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED -> {
+ KycButton(modifier, tx, listener, isSmall)
+ }
+ else -> {}
+ }
+ } else if (tx is TransactionWithdrawal && !tx.confirmed) {
+ // There is a transaction!
+ if (tx.withdrawalDetails is TalerBankIntegrationApi &&
+ tx.withdrawalDetails.bankConfirmationUrl != null
+ ) {
+ // The transaction can be completed with a link!
+ ConfirmBankButton(modifier, tx, listener, isSmall)
+ } else if (tx.withdrawalDetails is ManualTransfer) {
+ // The transaction must be completed manually!
+ ConfirmManualButton(modifier, tx, listener, isSmall)
+ }
+ }
+}
+
+@Composable
+private fun KycButton(
+ modifier: Modifier = Modifier,
+ tx: Transaction,
+ listener: ActionListener,
+ isSmall: Boolean = false,
+) {
+ val minSize = if (isSmall) 1.dp else 0.dp
+ Button(
+ onClick = { listener.onActionButtonClicked(tx, ActionListener.Type.COMPLETE_KYC) },
+ modifier = modifier.defaultMinSize(minSize, minSize),
+ ) {
+ Text(stringResource(R.string.transaction_action_kyc))
+ }
+}
+
+@Composable
+private fun ConfirmBankButton(
+ modifier: Modifier = Modifier,
+ tx: TransactionWithdrawal,
+ listener: ActionListener,
+ isSmall: Boolean = false,
+) {
+ val minSize = if (isSmall) 1.dp else 0.dp
+ Button(
+ onClick = { listener.onActionButtonClicked(tx, ActionListener.Type.CONFIRM_WITH_BANK) },
+ modifier = modifier.defaultMinSize(minSize, minSize),
+ ) {
+ val label = stringResource(R.string.withdraw_button_confirm_bank)
+ Icon(
+ Icons.Default.AccountBalance,
+ label,
+ modifier = Modifier.size(ButtonDefaults.IconSize)
+ )
+ Spacer(Modifier.size(ButtonDefaults.IconSpacing))
+ Text(label)
+ }
+}
+
+@Composable
+private fun ConfirmManualButton(
+ modifier: Modifier = Modifier,
+ tx: TransactionWithdrawal,
+ listener: ActionListener,
+ isSmall: Boolean = false,
+) {
+ val minSize = if (isSmall) 1.dp else 0.dp
+ Button(
+ onClick = { listener.onActionButtonClicked(tx, ActionListener.Type.CONFIRM_MANUAL) },
+ modifier = modifier.defaultMinSize(minSize, minSize),
+ ) {
+ val label = stringResource(R.string.withdraw_manual_ready_details_intro)
+ Icon(
+ Icons.Default.AccountBalance,
+ label,
+ modifier = Modifier.size(ButtonDefaults.IconSize)
+ )
+ Spacer(Modifier.size(ButtonDefaults.IconSpacing))
+ Text(label)
+ }
+}
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
index 36d3bc7..7bd4999 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
@@ -19,50 +19,31 @@ package net.taler.wallet.transactions
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
-import android.view.View.GONE
-import android.view.View.VISIBLE
import android.view.ViewGroup
-import net.taler.common.toAbsoluteTime
-import net.taler.wallet.R
-import net.taler.wallet.cleanExchange
-import net.taler.wallet.databinding.FragmentTransactionWithdrawalBinding
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.platform.ComposeView
+import net.taler.wallet.compose.TalerSurface
+import net.taler.wallet.withdraw.TransactionWithdrawalComposable
class TransactionRefreshFragment : TransactionDetailFragment() {
- private lateinit var ui: FragmentTransactionWithdrawalBinding
-
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
- ): View {
- ui = FragmentTransactionWithdrawalBinding.inflate(inflater, container, false)
- return ui.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- transactionManager.selectedTransaction.observe(viewLifecycleOwner) { t ->
- if (t !is TransactionRefresh) return@observe
- ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
-
- ui.effectiveAmountLabel.visibility = GONE
- ui.effectiveAmountView.visibility = GONE
- ui.confirmWithdrawalButton.visibility = GONE
- ui.chosenAmountLabel.visibility = GONE
- ui.chosenAmountView.visibility = GONE
- val fee = t.amountEffective
- ui.feeView.text = getString(R.string.amount_negative, fee.toString())
- ui.exchangeView.text = cleanExchange(t.exchangeBaseUrl)
- ui.deleteButton.setOnClickListener {
- onDeleteButtonClicked(t)
- }
- if (devMode.value == true && t.error != null) {
- ui.showErrorButton.visibility = VISIBLE
- ui.showErrorButton.setOnClickListener {
- onShowErrorButtonClicked(t)
+ ): View = ComposeView(requireContext()).apply {
+ setContent {
+ TalerSurface {
+ val t = transactionManager.selectedTransaction.observeAsState().value
+ if (t is TransactionRefresh) {
+ TransactionWithdrawalComposable(t, devMode.value, null) {
+ onDeleteButtonClicked(t)
+ }
}
}
}
}
+
+
}
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
index ad70d2f..3a5b0d0 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
@@ -19,115 +19,72 @@ package net.taler.wallet.transactions
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
-import android.view.View.GONE
-import android.view.View.VISIBLE
import android.view.ViewGroup
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
-import net.taler.common.toAbsoluteTime
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
-import net.taler.wallet.cleanExchange
-import net.taler.wallet.databinding.FragmentTransactionWithdrawalBinding
-import net.taler.wallet.handleKyc
+import net.taler.wallet.compose.TalerSurface
import net.taler.wallet.launchInAppBrowser
-import net.taler.wallet.transactions.ExtendedStatus.Pending
import net.taler.wallet.transactions.WithdrawalDetails.ManualTransfer
import net.taler.wallet.transactions.WithdrawalDetails.TalerBankIntegrationApi
+import net.taler.wallet.withdraw.TransactionWithdrawalComposable
import net.taler.wallet.withdraw.createManualTransferRequired
-class TransactionWithdrawalFragment : TransactionDetailFragment() {
+class TransactionWithdrawalFragment : TransactionDetailFragment(), ActionListener {
private val model: MainViewModel by activityViewModels()
private val withdrawManager by lazy { model.withdrawManager }
- private lateinit var ui: FragmentTransactionWithdrawalBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
- ): View {
- ui = FragmentTransactionWithdrawalBinding.inflate(inflater, container, false)
- return ui.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- transactionManager.selectedTransaction.observe(viewLifecycleOwner) { t ->
- if (t !is TransactionWithdrawal) return@observe
- ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
-
- ui.effectiveAmountLabel.text = getString(R.string.withdraw_total)
- ui.effectiveAmountView.text = t.amountEffective.toString()
- setupConfirmWithdrawalButton(t)
- setupActionButton(t)
- ui.chosenAmountLabel.text = getString(R.string.amount_chosen)
- ui.chosenAmountView.text =
- getString(R.string.amount_positive, t.amountRaw.toString())
- val fee = t.amountRaw - t.amountEffective
- ui.feeView.text = getString(R.string.amount_negative, fee.toString())
- ui.exchangeView.text = cleanExchange(t.exchangeBaseUrl)
- if (t.extendedStatus == Pending) {
- ui.deleteButton.setIconResource(R.drawable.ic_cancel)
- ui.deleteButton.setText(R.string.cancel)
- }
- ui.deleteButton.setOnClickListener {
- onDeleteButtonClicked(t)
- }
- if (devMode.value == true && t.error != null) {
- ui.showErrorButton.visibility = VISIBLE
- ui.showErrorButton.setOnClickListener {
- onShowErrorButtonClicked(t)
+ ): View = ComposeView(requireContext()).apply {
+ setContent {
+ TalerSurface {
+ val t = transactionManager.selectedTransaction.observeAsState().value
+ if (t is TransactionWithdrawal) {
+ TransactionWithdrawalComposable(t, devMode.value, this@TransactionWithdrawalFragment) {
+ onDeleteButtonClicked(t)
+ }
}
}
}
}
- private val isPending get() = transactionManager.selectedTransaction.value?.extendedStatus == Pending
-
- override val deleteDialogTitle: Int
- get() = if (isPending) R.string.cancel else super.deleteDialogTitle
- override val deleteDialogMessage: Int
- get() = if (isPending) R.string.transactions_cancel_dialog_message
- else super.deleteDialogMessage
- override val deleteDialogButton: Int
- get() = if (isPending) R.string.ok else super.deleteDialogButton
-
- private fun setupConfirmWithdrawalButton(t: TransactionWithdrawal) {
- if (t.extendedStatus == Pending && !t.confirmed) {
- if (t.withdrawalDetails is TalerBankIntegrationApi &&
- t.withdrawalDetails.bankConfirmationUrl != null
- ) {
- ui.confirmWithdrawalButton.setOnClickListener {
- launchInAppBrowser(requireContext(), t.withdrawalDetails.bankConfirmationUrl)
- }
- } else if (t.withdrawalDetails is ManualTransfer) {
- ui.confirmWithdrawalButton.setText(R.string.withdraw_manual_ready_details_intro)
- ui.confirmWithdrawalButton.setOnClickListener {
- val status = createManualTransferRequired(
- amount = t.amountRaw,
- exchangeBaseUrl = t.exchangeBaseUrl,
- // TODO what if there's more than one or no URI?
- uriStr = t.withdrawalDetails.exchangePaytoUris[0],
- transactionId = t.transactionId,
- )
- withdrawManager.viewManualWithdrawal(status)
- findNavController().navigate(
- R.id.action_nav_transactions_detail_withdrawal_to_nav_exchange_manual_withdrawal_success
- )
- }
- } else ui.confirmWithdrawalButton.visibility = GONE
- } else ui.confirmWithdrawalButton.visibility = GONE
- }
-
- private fun setupActionButton(t: TransactionWithdrawal) {
- ui.actionButton.visibility = t.handleKyc({ GONE }) { error ->
- ui.actionButton.setText(R.string.transaction_action_kyc)
- error.getStringExtra("kycUrl")?.let { kycUrl ->
- ui.actionButton.setOnClickListener {
+ override fun onActionButtonClicked(tx: Transaction, type: ActionListener.Type) {
+ when(type) {
+ ActionListener.Type.COMPLETE_KYC -> {
+ tx.error?.getStringExtra("kycUrl")?.let { kycUrl ->
launchInAppBrowser(requireContext(), kycUrl)
}
}
- VISIBLE
+ ActionListener.Type.CONFIRM_WITH_BANK -> {
+ if (tx !is TransactionWithdrawal) return
+ if (tx.withdrawalDetails !is TalerBankIntegrationApi) return
+ tx.withdrawalDetails.bankConfirmationUrl?.let { url ->
+ launchInAppBrowser(requireContext(), url)
+ }
+ }
+ ActionListener.Type.CONFIRM_MANUAL -> {
+ if (tx !is TransactionWithdrawal) return
+ if (tx.withdrawalDetails !is ManualTransfer) return
+ // TODO what if there's more than one or no URI?
+ if (tx.withdrawalDetails.exchangePaytoUris.isEmpty()) return
+ val status = createManualTransferRequired(
+ amount = tx.amountRaw,
+ exchangeBaseUrl = tx.exchangeBaseUrl,
+ uriStr = tx.withdrawalDetails.exchangePaytoUris[0],
+ transactionId = tx.transactionId,
+ )
+ withdrawManager.viewManualWithdrawal(status)
+ findNavController().navigate(
+ R.id.action_nav_transactions_detail_withdrawal_to_nav_exchange_manual_withdrawal_success,
+ )
+ }
}
}
}