TransitionsComposable.kt (7994B)
1 /* 2 * This file is part of GNU Taler 3 * (C) 2023 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 androidx.compose.foundation.layout.Arrangement.Center 20 import androidx.compose.foundation.layout.Column 21 import androidx.compose.foundation.layout.ExperimentalLayoutApi 22 import androidx.compose.foundation.layout.FlowRow 23 import androidx.compose.foundation.layout.Row 24 import androidx.compose.foundation.layout.padding 25 import androidx.compose.foundation.rememberScrollState 26 import androidx.compose.foundation.verticalScroll 27 import androidx.compose.material3.AlertDialog 28 import androidx.compose.material3.Button 29 import androidx.compose.material3.ButtonDefaults 30 import androidx.compose.material3.Icon 31 import androidx.compose.material3.MaterialTheme 32 import androidx.compose.material3.Text 33 import androidx.compose.material3.TextButton 34 import androidx.compose.runtime.Composable 35 import androidx.compose.runtime.getValue 36 import androidx.compose.runtime.mutableStateOf 37 import androidx.compose.runtime.remember 38 import androidx.compose.runtime.setValue 39 import androidx.compose.ui.Alignment 40 import androidx.compose.ui.Modifier 41 import androidx.compose.ui.platform.LocalContext 42 import androidx.compose.ui.res.painterResource 43 import androidx.compose.ui.res.stringResource 44 import androidx.compose.ui.text.font.FontFamily 45 import androidx.compose.ui.unit.dp 46 import androidx.compose.ui.unit.sp 47 import kotlinx.serialization.json.Json 48 import net.taler.lib.android.copyToClipBoard 49 import net.taler.wallet.R 50 import net.taler.wallet.transactions.TransactionAction.* 51 52 @OptIn(ExperimentalLayoutApi::class) 53 @Composable 54 fun TransitionsComposable( 55 t: Transaction, 56 devMode: Boolean, 57 onTransition: (t: TransactionAction) -> Unit, 58 ) { 59 var showDialog by remember { mutableStateOf(false) } 60 61 if (showDialog) { 62 @Suppress("OPT_IN_USAGE") 63 val json = Json { 64 prettyPrint = true 65 prettyPrintIndent = " " 66 } 67 val message = json.encodeToString(t) 68 AlertDialog( 69 onDismissRequest = { 70 showDialog = false 71 }, 72 text = { 73 val scrollState = rememberScrollState() 74 Column( 75 modifier = Modifier.verticalScroll(scrollState), 76 ) { 77 Text( 78 fontFamily = FontFamily.Monospace, 79 fontSize = 10.sp, 80 text = message, 81 ) 82 } 83 }, 84 dismissButton = { 85 TextButton(onClick = { 86 showDialog = false 87 }) { 88 Text(stringResource(R.string.close)) 89 } 90 }, 91 confirmButton = { 92 val context = LocalContext.current 93 val label = stringResource(R.string.nav_error) 94 TextButton(onClick = { 95 copyToClipBoard(context, label, message) 96 }) { 97 Text(stringResource(R.string.copy)) 98 } 99 }) 100 } 101 102 FlowRow(horizontalArrangement = Center) { 103 t.txActions.forEach { 104 if (it in arrayOf(Resume, Suspend, Retry)) { 105 if (devMode) TransitionComposable(it, onTransition) 106 } else { 107 TransitionComposable(it, onTransition) 108 } 109 } 110 111 if (devMode) Button( 112 modifier = Modifier.padding(16.dp), 113 onClick = { showDialog = true }, 114 ) { 115 Text(stringResource(R.string.observability_show_json)) 116 } 117 } 118 } 119 120 @Composable 121 fun TransitionComposable(t: TransactionAction, onClick: (t: TransactionAction) -> Unit) { 122 var showConfirmDialog by remember { mutableStateOf(false) } 123 if (showConfirmDialog) { 124 AlertDialog( 125 onDismissRequest = { showConfirmDialog = false }, 126 title = { Text(stringResource(R.string.transactions_delete_dialog_title)) }, 127 text = { Text(stringResource(R.string.transactions_delete_dialog_message)) }, 128 confirmButton = { 129 TextButton(onClick = { 130 showConfirmDialog = false 131 onClick(t) 132 }) { 133 Text(stringResource(R.string.transactions_delete)) 134 } 135 }, 136 dismissButton = { 137 TextButton(onClick = { showConfirmDialog = false }) { 138 Text(stringResource(R.string.cancel)) 139 } 140 } 141 ) 142 } 143 144 Button( 145 modifier = Modifier.padding(16.dp), 146 colors = ButtonDefaults.buttonColors( 147 containerColor = when (t) { 148 Delete -> MaterialTheme.colorScheme.error 149 Retry -> MaterialTheme.colorScheme.primary 150 Abort -> MaterialTheme.colorScheme.error 151 Fail -> MaterialTheme.colorScheme.error 152 Resume -> MaterialTheme.colorScheme.primary 153 Suspend -> MaterialTheme.colorScheme.primary 154 } 155 ), 156 onClick = { 157 if (t == Delete) { 158 showConfirmDialog = true 159 } else { 160 onClick(t) 161 } 162 }, 163 ) { 164 Row(verticalAlignment = Alignment.CenterVertically) { 165 Icon( 166 painter = when (t) { 167 Delete -> painterResource(id = R.drawable.ic_delete) 168 Retry -> painterResource(id = R.drawable.ic_retry) 169 Abort -> painterResource(id = R.drawable.ic_cancel) 170 Fail -> painterResource(id = R.drawable.ic_fail) 171 Resume -> painterResource(id = R.drawable.ic_resume) 172 Suspend -> painterResource(id = R.drawable.ic_suspend) 173 }, 174 contentDescription = null, 175 tint = when (t) { 176 Delete -> MaterialTheme.colorScheme.onError 177 Retry -> MaterialTheme.colorScheme.onPrimary 178 Abort -> MaterialTheme.colorScheme.onError 179 Fail -> MaterialTheme.colorScheme.onError 180 Resume -> MaterialTheme.colorScheme.onPrimary 181 Suspend -> MaterialTheme.colorScheme.onPrimary 182 }, 183 ) 184 Text( 185 modifier = Modifier.padding(start = 8.dp), 186 text = when (t) { 187 Delete -> stringResource(R.string.transactions_delete) 188 Retry -> stringResource(R.string.transactions_retry) 189 Abort -> stringResource(R.string.transactions_abort) 190 Fail -> stringResource(R.string.transactions_fail) 191 Resume -> stringResource(R.string.transactions_resume) 192 Suspend -> stringResource(R.string.transactions_suspend) 193 }, 194 color = when (t) { 195 Delete -> MaterialTheme.colorScheme.onError 196 Retry -> MaterialTheme.colorScheme.onPrimary 197 Abort -> MaterialTheme.colorScheme.onError 198 Fail -> MaterialTheme.colorScheme.onError 199 Resume -> MaterialTheme.colorScheme.onPrimary 200 Suspend -> MaterialTheme.colorScheme.onPrimary 201 }, 202 ) 203 } 204 } 205 }