TransactionStateComposable.kt (8431B)
1 /* 2 * This file is part of GNU Taler 3 * (C) 2024 Taler Systems S.A. 4 * 5 * GNU Taler is free software; you can redistribute it and/or modify it under the 6 * terms of the GNU General Public License as published by the Free Software 7 * Foundation; either version 3, or (at your option) any later version. 8 * 9 * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY 10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 package net.taler.wallet.transactions 18 19 import android.content.res.Configuration 20 import androidx.compose.foundation.layout.Column 21 import androidx.compose.foundation.layout.fillMaxWidth 22 import androidx.compose.foundation.layout.padding 23 import androidx.compose.material3.CardDefaults 24 import androidx.compose.material3.MaterialTheme 25 import androidx.compose.material3.Text 26 import androidx.compose.runtime.Composable 27 import androidx.compose.ui.Modifier 28 import androidx.compose.ui.platform.LocalContext 29 import androidx.compose.ui.res.stringResource 30 import androidx.compose.ui.tooling.preview.Preview 31 import androidx.compose.ui.unit.dp 32 import net.taler.common.Amount 33 import net.taler.common.RelativeTime 34 import net.taler.common.Timestamp 35 import net.taler.lib.android.toAbsoluteTime 36 import net.taler.wallet.R 37 import net.taler.wallet.balances.ScopeInfo 38 import net.taler.wallet.compose.Banner 39 import net.taler.wallet.compose.TalerSurface 40 import net.taler.wallet.transactions.TransactionMajorState.Aborted 41 import net.taler.wallet.transactions.TransactionMajorState.Aborting 42 import net.taler.wallet.transactions.TransactionMajorState.Done 43 import net.taler.wallet.transactions.TransactionMajorState.Expired 44 import net.taler.wallet.transactions.TransactionMajorState.Failed 45 import net.taler.wallet.transactions.TransactionMajorState.Finalizing 46 import net.taler.wallet.transactions.TransactionMajorState.Pending 47 import net.taler.wallet.transactions.TransactionMajorState.Suspended 48 import net.taler.wallet.transactions.TransactionMinorState.BalanceKycRequired 49 import net.taler.wallet.transactions.TransactionMinorState.BankConfirmTransfer 50 import net.taler.wallet.transactions.TransactionMinorState.KycAuthRequired 51 import net.taler.wallet.transactions.TransactionMinorState.KycInit 52 import net.taler.wallet.transactions.TransactionMinorState.KycRequired 53 import net.taler.wallet.transactions.TransactionMinorState.Repurchase 54 import net.taler.wallet.transactions.WithdrawalDetails.ManualTransfer 55 import net.taler.wallet.ui.theme.TalerTheme 56 57 @Composable 58 fun TransactionStateComposable( 59 modifier: Modifier = Modifier, 60 state: TransactionState, 61 tx: Transaction? = null, 62 ) { 63 val message = when (state) { 64 TransactionState(Done) -> stringResource(R.string.transaction_state_done) 65 TransactionState(Pending, BankConfirmTransfer) -> stringResource(R.string.transaction_state_pending_bank) 66 TransactionState(Pending, KycInit) -> stringResource(R.string.transaction_preparing_kyc) 67 TransactionState(Pending, KycRequired) -> stringResource(R.string.transaction_state_pending_kyc_bank) 68 TransactionState(Pending, BalanceKycRequired) -> stringResource(R.string.transaction_state_pending_kyc_bank) 69 TransactionState(Pending, KycAuthRequired) -> stringResource(R.string.transaction_state_pending_kyc_auth) 70 TransactionState(Pending) -> stringResource(R.string.transaction_state_pending) 71 TransactionState(Aborted) -> if (tx is TransactionWithdrawal && tx.withdrawalDetails is ManualTransfer) { 72 stringResource( 73 R.string.transaction_state_aborted_manual, 74 (tx.timestamp + tx.withdrawalDetails.reserveClosingDelay).ms.toAbsoluteTime(LocalContext.current).toString(), 75 ) 76 } else stringResource(R.string.transaction_state_aborted) 77 TransactionState(Aborting) -> stringResource(R.string.transaction_state_aborting) 78 TransactionState(Suspended) -> stringResource(R.string.transaction_state_suspended) 79 TransactionState(Failed, Repurchase) -> stringResource(R.string.payment_already_paid) 80 TransactionState(Failed) -> stringResource(R.string.transaction_state_failed) 81 TransactionState(Finalizing) -> stringResource(R.string.transaction_state_finalizing) 82 TransactionState(Expired) -> stringResource(R.string.transaction_state_expired) 83 else -> return 84 } 85 86 val cardColor = when (state) { 87 TransactionState(Done) -> TalerTheme.extraColors.successContainer 88 TransactionState(Pending), 89 TransactionState(Suspended), 90 TransactionState(Failed, Repurchase), 91 TransactionState(Finalizing) -> MaterialTheme.colorScheme.surfaceVariant 92 TransactionState(Aborted), 93 TransactionState(Aborting), 94 TransactionState(Failed), 95 TransactionState(Expired) -> MaterialTheme.colorScheme.errorContainer 96 else -> return 97 } 98 99 val textColor = when (state) { 100 TransactionState(Done) -> TalerTheme.extraColors.onSuccessContainer 101 TransactionState(Pending), 102 TransactionState(Suspended), 103 TransactionState(Failed, Repurchase), 104 TransactionState(Finalizing) -> MaterialTheme.colorScheme.onSurfaceVariant 105 TransactionState(Aborted), 106 TransactionState(Aborting), 107 TransactionState(Failed), 108 TransactionState(Expired) -> MaterialTheme.colorScheme.onErrorContainer 109 else -> return 110 } 111 112 Banner( 113 modifier = Modifier.padding(horizontal = 9.dp), 114 colors = CardDefaults.cardColors(containerColor = cardColor), 115 ) { 116 Text( 117 modifier = Modifier 118 .fillMaxWidth(), 119 text = message, 120 color = textColor, 121 ) 122 } 123 } 124 125 @Preview 126 @Composable 127 fun TransactionStateComposablePreview() { 128 TalerSurface { 129 Column { 130 131 val modifier = Modifier.padding(vertical = 6.dp) 132 TransactionStateComposable(modifier, state = TransactionState(Pending, BankConfirmTransfer)) 133 TransactionStateComposable(modifier, state = TransactionState(Pending, KycInit)) 134 TransactionStateComposable(modifier, state = TransactionState(Pending, KycRequired)) 135 TransactionStateComposable(modifier, state = TransactionState(Pending, BalanceKycRequired)) 136 TransactionStateComposable(modifier, state = TransactionState(Pending, KycAuthRequired)) 137 TransactionStateComposable(modifier, state = TransactionState(Pending)) 138 TransactionStateComposable(modifier, state = TransactionState(Aborted)) 139 TransactionStateComposable(modifier, state = TransactionState(Aborting)) 140 TransactionStateComposable(modifier, state = TransactionState(Suspended)) 141 TransactionStateComposable(modifier, state = TransactionState(Failed, Repurchase)) 142 TransactionStateComposable(modifier, state = TransactionState(Failed)) 143 TransactionStateComposable(modifier, state = TransactionState(Finalizing)) 144 TransactionStateComposable(modifier, state = TransactionState(Expired)) 145 TransactionStateComposable(modifier, state = TransactionState(Done)) 146 147 TransactionStateComposable(modifier, state = TransactionState(Aborted), tx = TransactionWithdrawal( 148 transactionId = "1234", 149 timestamp = Timestamp.fromMillis(1722629432000L), 150 txState = TransactionState(Aborted), 151 txActions = emptyList(), 152 exchangeBaseUrl = "exchange.demo.taler.net", 153 withdrawalDetails = ManualTransfer( 154 exchangeCreditAccountDetails = emptyList(), 155 reserveClosingDelay = RelativeTime(10_000_000_000_000), 156 ), 157 amountRaw = Amount.zero("KUDOS"), 158 amountEffective = Amount.zero("KUDOS"), 159 scopes = listOf(ScopeInfo.Exchange( 160 currency = "KUDOS", 161 url = "exchange.demo.taler.net", 162 )) 163 )) 164 } 165 } 166 } 167 168 @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) 169 @Composable 170 fun TransactionStateComposableNightPreview() { 171 TransactionStateComposablePreview() 172 }