summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2023-03-07 22:33:37 -0600
committerIván Ávalos <avalos@disroot.org>2023-04-03 14:08:48 -0600
commit4c9330be60632e8fef3df179f1e482d7d51edbeb (patch)
tree96e5e1df0b58fc4cb8fa43fa49c43c2e536e968f
parentc3ffef4ceae3159d3ac387d918ccf195047a60a3 (diff)
downloadtaler-android-dev/ivan-avalos/actionbutton.tar.gz
taler-android-dev/ivan-avalos/actionbutton.tar.bz2
taler-android-dev/ivan-avalos/actionbutton.zip
[wallet] Refactor action buttons into composabledev/ivan-avalos/actionbutton
-rw-r--r--wallet/src/main/java/net/taler/wallet/Utils.kt11
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/ActionButtonComposable.kt136
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt22
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt72
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt27
-rw-r--r--wallet/src/main/res/layout/fragment_transaction_withdrawal.xml28
-rw-r--r--wallet/src/main/res/layout/list_item_transaction.xml10
8 files changed, 201 insertions, 107 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/Utils.kt b/wallet/src/main/java/net/taler/wallet/Utils.kt
index 435aa96..afa7350 100644
--- a/wallet/src/main/java/net/taler/wallet/Utils.kt
+++ b/wallet/src/main/java/net/taler/wallet/Utils.kt
@@ -35,9 +35,6 @@ import androidx.core.content.getSystemService
import net.taler.common.Amount
import net.taler.common.AmountParserException
import net.taler.common.startActivitySafe
-import net.taler.wallet.backend.TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED
-import net.taler.wallet.backend.TalerErrorInfo
-import net.taler.wallet.transactions.Transaction
const val CURRENCY_BTC = "BITCOINBTC"
@@ -110,14 +107,6 @@ fun Context.getAttrColor(attr: Int): Int {
return value.data
}
-fun <T> Transaction.handleKyc(notRequired: () -> T, required: (TalerErrorInfo) -> T): T {
- return error?.let { error ->
- when (error.code) {
- WALLET_WITHDRAWAL_KYC_REQUIRED -> required(error)
- else -> notRequired()
- }
- } ?: notRequired()
-}
fun launchInAppBrowser(context: Context, url: String) {
val builder = CustomTabsIntent.Builder()
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/TransactionAdapter.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt
index c2f7122..88f6211 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt
@@ -25,6 +25,7 @@ import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
+import androidx.compose.ui.platform.ComposeView
import androidx.core.content.ContextCompat.getColor
import androidx.recyclerview.selection.ItemDetailsLookup
import androidx.recyclerview.selection.ItemKeyProvider
@@ -32,11 +33,10 @@ import androidx.recyclerview.selection.SelectionTracker
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.Adapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import com.google.android.material.button.MaterialButton
import net.taler.common.exhaustive
import net.taler.common.toRelativeTime
import net.taler.wallet.R
-import net.taler.wallet.handleKyc
+import net.taler.wallet.compose.TalerSurface
import net.taler.wallet.transactions.ExtendedStatus.Pending
import net.taler.wallet.transactions.TransactionAdapter.TransactionViewHolder
@@ -81,7 +81,7 @@ internal class TransactionAdapter(
private val icon: ImageView = v.findViewById(R.id.icon)
private val title: TextView = v.findViewById(R.id.title)
private val extraInfoView: TextView = v.findViewById(R.id.extraInfoView)
- private val actionButton: MaterialButton = v.findViewById(R.id.actionButton)
+ private val actionButton: ComposeView = v.findViewById(R.id.actionButton)
private val time: TextView = v.findViewById(R.id.time)
private val amount: TextView = v.findViewById(R.id.amount)
private val pendingView: TextView = v.findViewById(R.id.pendingView)
@@ -129,20 +129,10 @@ internal class TransactionAdapter(
}
private fun bindActionButton(t: Transaction) {
- actionButton.setOnClickListener { listener.onActionButtonClicked(t) }
- if (t.error != null) {
- actionButton.visibility = t.handleKyc({ GONE }) {
- actionButton.setText(R.string.transaction_action_kyc)
- VISIBLE
+ actionButton.setContent {
+ TalerSurface {
+ ActionButton(tx = t, listener = listener, isSmall = true)
}
- } else if (t is TransactionWithdrawal && !t.confirmed) {
- actionButton.setIconResource(R.drawable.ic_account_balance)
- actionButton.visibility =
- if (t.withdrawalDetails is WithdrawalDetails.TalerBankIntegrationApi &&
- t.withdrawalDetails.bankConfirmationUrl != null) {
- actionButton.setText(R.string.withdraw_button_confirm_bank)
- VISIBLE
- } else GONE
}
}
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..86881ff 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
@@ -47,7 +47,7 @@ class TransactionRefreshFragment : TransactionDetailFragment() {
ui.effectiveAmountLabel.visibility = GONE
ui.effectiveAmountView.visibility = GONE
- ui.confirmWithdrawalButton.visibility = GONE
+ ui.actionButton.visibility = GONE
ui.chosenAmountLabel.visibility = GONE
ui.chosenAmountView.visibility = GONE
val fee = t.amountEffective
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..86ff683 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
@@ -19,7 +19,6 @@ 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.fragment.app.activityViewModels
@@ -28,15 +27,18 @@ import net.taler.common.toAbsoluteTime
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
import net.taler.wallet.cleanExchange
+import net.taler.wallet.compose.TalerSurface
import net.taler.wallet.databinding.FragmentTransactionWithdrawalBinding
-import net.taler.wallet.handleKyc
import net.taler.wallet.launchInAppBrowser
+import net.taler.wallet.transactions.ActionListener.Type.COMPLETE_KYC
+import net.taler.wallet.transactions.ActionListener.Type.CONFIRM_MANUAL
+import net.taler.wallet.transactions.ActionListener.Type.CONFIRM_WITH_BANK
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.createManualTransferRequired
-class TransactionWithdrawalFragment : TransactionDetailFragment() {
+class TransactionWithdrawalFragment : TransactionDetailFragment(), ActionListener {
private val model: MainViewModel by activityViewModels()
private val withdrawManager by lazy { model.withdrawManager }
@@ -58,7 +60,6 @@ class TransactionWithdrawalFragment : TransactionDetailFragment() {
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 =
@@ -92,42 +93,43 @@ class TransactionWithdrawalFragment : TransactionDetailFragment() {
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.setContent {
+ TalerSurface {
+ ActionButton(tx = t, listener = this)
+ }
+ }
}
- 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) {
+ COMPLETE_KYC -> {
+ tx.error?.getStringExtra("kycUrl")?.let { kycUrl ->
launchInAppBrowser(requireContext(), kycUrl)
}
}
- VISIBLE
+ CONFIRM_WITH_BANK -> {
+ if (tx !is TransactionWithdrawal) return
+ if (tx.withdrawalDetails !is TalerBankIntegrationApi) return
+ tx.withdrawalDetails.bankConfirmationUrl?.let { url ->
+ launchInAppBrowser(requireContext(), url)
+ }
+ }
+ CONFIRM_MANUAL -> {
+ if (tx !is TransactionWithdrawal) return
+ if (tx.withdrawalDetails !is ManualTransfer) return
+ val status = createManualTransferRequired(
+ amount = tx.amountRaw,
+ exchangeBaseUrl = tx.exchangeBaseUrl,
+ // TODO what if there's more than one or no URI?
+ 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
+ )
+ }
}
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
index f2a74e2..06077a4 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
@@ -42,12 +42,12 @@ import net.taler.common.fadeOut
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
import net.taler.wallet.databinding.FragmentTransactionsBinding
-import net.taler.wallet.handleKyc
import net.taler.wallet.launchInAppBrowser
+import net.taler.wallet.transactions.ActionListener.Type.COMPLETE_KYC
+import net.taler.wallet.transactions.ActionListener.Type.CONFIRM_WITH_BANK
-interface OnTransactionClickListener {
+interface OnTransactionClickListener: ActionListener {
fun onTransactionClicked(transaction: Transaction)
- fun onActionButtonClicked(transaction: Transaction)
}
class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode.Callback {
@@ -180,18 +180,21 @@ class TransactionsFragment : Fragment(), OnTransactionClickListener, ActionMode.
}
}
- override fun onActionButtonClicked(transaction: Transaction) {
- if (transaction.error != null) {
- transaction.handleKyc({ error("Unhandled Action Button Event") }) { error ->
- error.getStringExtra("kycUrl")?.let {
- launchInAppBrowser(requireContext(), it)
+ override fun onActionButtonClicked(tx: Transaction, type: ActionListener.Type) {
+ when (type) {
+ COMPLETE_KYC -> {
+ tx.error?.getStringExtra("kycUrl")?.let { kycUrl ->
+ launchInAppBrowser(requireContext(), kycUrl)
}
}
- } else if (transaction is TransactionWithdrawal && !transaction.confirmed) {
- if (transaction.withdrawalDetails is WithdrawalDetails.TalerBankIntegrationApi &&
- transaction.withdrawalDetails.bankConfirmationUrl != null) {
- launchInAppBrowser(requireContext(), transaction.withdrawalDetails.bankConfirmationUrl)
+ CONFIRM_WITH_BANK -> {
+ if (tx !is TransactionWithdrawal) return
+ if (tx.withdrawalDetails !is WithdrawalDetails.TalerBankIntegrationApi) return
+ tx.withdrawalDetails.bankConfirmationUrl?.let { url ->
+ launchInAppBrowser(requireContext(), url)
+ }
}
+ else -> {}
}
}
diff --git a/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml b/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml
index 87530a4..126f2fd 100644
--- a/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml
+++ b/wallet/src/main/res/layout/fragment_transaction_withdrawal.xml
@@ -48,41 +48,21 @@
android:id="@+id/effectiveAmountView"
style="@style/TransactionContent"
android:textColor="@color/green"
- app:layout_constraintBottom_toTopOf="@+id/confirmWithdrawalButton"
+ app:layout_constraintBottom_toTopOf="@+id/actionButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/effectiveAmountLabel"
tools:text="23.42 TESTKUDOS" />
- <com.google.android.material.button.MaterialButton
- android:id="@+id/confirmWithdrawalButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:icon="@drawable/ic_account_balance"
- android:text="@string/withdraw_button_confirm_bank"
- android:textColor="?colorOnPrimary"
- app:iconTint="?colorOnPrimary"
- app:drawableTint="?attr/colorOnPrimarySurface"
- app:layout_constraintBottom_toTopOf="@+id/actionButton"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/effectiveAmountView"
- tools:ignore="RtlHardcoded" />
-
- <Button
+ <androidx.compose.ui.platform.ComposeView
android:id="@+id/actionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="10dp"
- android:textColor="?colorOnTertiary"
- android:backgroundTint="?colorTertiary"
- android:visibility="gone"
- app:layout_constraintBottom_toTopOf="@id/chosenAmountLabel"
+ app:layout_constraintBottom_toTopOf="@+id/chosenAmountLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/confirmWithdrawalButton"
- tools:text="@string/transaction_action_kyc"
- tools:visibility="visible" />
+ app:layout_constraintTop_toBottomOf="@+id/effectiveAmountView" />
<TextView
android:id="@+id/chosenAmountLabel"
diff --git a/wallet/src/main/res/layout/list_item_transaction.xml b/wallet/src/main/res/layout/list_item_transaction.xml
index 8cd10a8..4377d98 100644
--- a/wallet/src/main/res/layout/list_item_transaction.xml
+++ b/wallet/src/main/res/layout/list_item_transaction.xml
@@ -62,19 +62,13 @@
tools:text="@string/withdraw_waiting_confirm"
tools:visibility="visible" />
- <com.google.android.material.button.MaterialButton
+ <androidx.compose.ui.platform.ComposeView
android:id="@+id/actionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
- android:visibility="gone"
- android:textColor="?colorOnPrimary"
- app:iconTint="?colorOnPrimary"
- app:backgroundTint="?colorPrimary"
app:layout_constraintStart_toStartOf="@id/title"
- app:layout_constraintTop_toBottomOf="@id/extraInfoView"
- tools:text="Complete KYC"
- tools:visibility="visible"/>
+ app:layout_constraintTop_toBottomOf="@id/extraInfoView" />
<TextView
android:id="@+id/time"