ExchangeShoppingScreen.kt (5725B)
1 /* 2 * This file is part of GNU Taler 3 * (C) 2026 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.exchanges 18 19 import androidx.compose.foundation.basicMarquee 20 import androidx.compose.foundation.layout.Box 21 import androidx.compose.foundation.layout.fillMaxSize 22 import androidx.compose.foundation.layout.Column 23 import androidx.compose.foundation.layout.fillMaxWidth 24 import androidx.compose.foundation.layout.padding 25 import androidx.compose.foundation.rememberScrollState 26 import androidx.compose.foundation.verticalScroll 27 import androidx.compose.material.icons.Icons 28 import androidx.compose.material.icons.filled.Link 29 import androidx.compose.material3.Icon 30 import androidx.compose.material3.Text 31 import androidx.compose.runtime.Composable 32 import androidx.compose.runtime.getValue 33 import androidx.compose.runtime.livedata.observeAsState 34 import androidx.compose.runtime.remember 35 import androidx.compose.ui.Alignment 36 import androidx.compose.ui.Modifier 37 import androidx.compose.ui.graphics.Color 38 import androidx.compose.ui.platform.LocalContext 39 import androidx.compose.ui.res.stringResource 40 import androidx.compose.ui.tooling.preview.Preview 41 import androidx.compose.ui.unit.dp 42 import net.taler.wallet.BottomInsetsSpacer 43 import net.taler.wallet.R 44 import net.taler.wallet.balances.BalanceState 45 import net.taler.wallet.compose.EmptyComposable 46 import net.taler.wallet.compose.GlobalScaffold 47 import net.taler.wallet.compose.LoadingScreen 48 import net.taler.wallet.compose.Material3MenuGroup 49 import net.taler.wallet.compose.Material3MenuItemData 50 import net.taler.wallet.compose.TalerSurface 51 import net.taler.wallet.compose.collectAsStateLifecycleAware 52 import net.taler.wallet.getAttrColor 53 import net.taler.wallet.launchInAppBrowser 54 import net.taler.wallet.main.MainViewModel 55 import net.taler.wallet.main.ViewMode 56 57 @Composable 58 fun ExchangeShoppingScreen( 59 model: MainViewModel, 60 onNavigateBack: () -> Unit, 61 ) { 62 val viewMode by model.viewMode.collectAsStateLifecycleAware() 63 val selectedScope = (viewMode as? ViewMode.Transactions)?.selectedScope 64 val balanceState by model.balanceManager.state.observeAsState(BalanceState.None) 65 66 val selectedBalance = remember(balanceState, selectedScope) { 67 val balances = (balanceState as? BalanceState.Success)?.balances 68 selectedScope?.let { 69 balances?.find { it.scopeInfo == selectedScope } 70 } 71 } 72 73 TalerSurface { 74 GlobalScaffold( 75 model = model, 76 modifier = Modifier.fillMaxSize(), 77 onNavigateBack = onNavigateBack, 78 ) { paddingValues -> 79 Box(Modifier.padding(paddingValues)) { 80 if (selectedScope == null) { 81 EmptyComposable(message = stringResource(R.string.exchange_unselected)) 82 } else if (selectedBalance == null) { 83 LoadingScreen() 84 } else { 85 ExchangeShoppingComposable( 86 currency = selectedBalance.currency, 87 shoppingUrls = selectedBalance.shoppingUrls, 88 ) 89 } 90 } 91 } 92 } 93 } 94 95 @Composable 96 fun ExchangeShoppingComposable( 97 currency: String, 98 shoppingUrls: List<String>, 99 ) { 100 val context = LocalContext.current 101 val linkColor = Color(context.getAttrColor(android.R.attr.textColorLink)) 102 103 Column ( 104 modifier = Modifier 105 .fillMaxWidth() 106 .verticalScroll(rememberScrollState()), 107 horizontalAlignment = Alignment.CenterHorizontally, 108 ) { 109 Text( 110 modifier = Modifier.padding(16.dp), 111 text = stringResource( 112 R.string.exchange_shopping_message, 113 currency, 114 ), 115 ) 116 117 Box(Modifier.padding(horizontal = 16.dp)) { 118 Material3MenuGroup(items = buildList { 119 shoppingUrls.forEach { url -> 120 add( 121 Material3MenuItemData( 122 icon = { 123 Icon( 124 Icons.Default.Link, 125 contentDescription = null 126 ) 127 }, 128 title = { 129 Text( 130 modifier = Modifier.basicMarquee(), 131 text = url, 132 color = linkColor, 133 ) 134 }, 135 onClick = { launchInAppBrowser(context, url) }, 136 ) 137 ) 138 } 139 }) 140 } 141 142 BottomInsetsSpacer() 143 } 144 } 145 146 @Preview 147 @Composable 148 fun ExchangeShoppingComposablePreview() { 149 TalerSurface { 150 ExchangeShoppingComposable( 151 currency = "CHF", 152 shoppingUrls = listOf( 153 "https://shopping.taler.net/", 154 "https://shopping.taler.ar/", 155 "https://shopping.taler-ops.ch/", 156 ) 157 ) 158 } 159 }