taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

commit 19a965a3bb7dc181bff92890a357c1c16bd7dca7
parent db36bb282b4cb47fa82816ab419badac0e0a415c
Author: Iván Ávalos <avalos@disroot.org>
Date:   Wed,  4 Nov 2026 14:21:20 +0100

[wallet] refine colors/styles of new balances screen

Diffstat:
Mwallet/src/main/java/net/taler/wallet/balances/BalancesPagerComposable.kt | 392++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Mwallet/src/main/java/net/taler/wallet/compose/ActionButton.kt | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Mwallet/src/main/java/net/taler/wallet/compose/Utils.kt | 2+-
Mwallet/src/main/java/net/taler/wallet/main/NewMainScreen.kt | 13++++++++++++-
Mwallet/src/main/java/net/taler/wallet/transactions/TransactionsComposable.kt | 17++++++++++-------
5 files changed, 334 insertions(+), 156 deletions(-)

diff --git a/wallet/src/main/java/net/taler/wallet/balances/BalancesPagerComposable.kt b/wallet/src/main/java/net/taler/wallet/balances/BalancesPagerComposable.kt @@ -35,6 +35,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.PagerState @@ -56,15 +57,16 @@ import androidx.compose.material3.AssistChip import androidx.compose.material3.AssistChipDefaults import androidx.compose.material3.Badge import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.ElevatedCard import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon +import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.OutlinedCard import androidx.compose.material3.ProvideTextStyle import androidx.compose.material3.Text +import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -76,11 +78,14 @@ import androidx.compose.ui.draw.dropShadow import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.lerp +import androidx.compose.ui.layout.Layout import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.AndroidUiModes.UI_MODE_NIGHT_YES import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset @@ -96,6 +101,7 @@ import net.taler.wallet.balances.ScopeInfo.Auditor import net.taler.wallet.balances.ScopeInfo.Exchange import net.taler.wallet.cleanExchange import net.taler.wallet.compose.ActionButton +import net.taler.wallet.compose.ActionButtonSize import net.taler.wallet.compose.EmptyComposable import net.taler.wallet.compose.ErrorComposable import net.taler.wallet.compose.LoadingScreen @@ -108,11 +114,7 @@ import net.taler.wallet.transactions.DummyTransaction import net.taler.wallet.transactions.Transaction import net.taler.wallet.transactions.TransactionRow import net.taler.wallet.transactions.TransactionsResult -import net.taler.wallet.ui.theme.errorContainerLight -import net.taler.wallet.ui.theme.onErrorContainerLight -import net.taler.wallet.ui.theme.onSuccessContainerLight -import net.taler.wallet.ui.theme.onSurfaceVariantLight -import net.taler.wallet.ui.theme.successContainerLight +import net.taler.wallet.ui.theme.TalerTheme import kotlin.math.abs import kotlin.math.roundToInt @@ -158,19 +160,47 @@ internal fun pageToBalance( @Composable fun balanceContainerColor() = if (isSystemInDarkTheme()) { - MaterialTheme.colorScheme.primary + MaterialTheme.colorScheme.onSecondary } else { MaterialTheme.colorScheme.primaryContainer } @Composable fun balanceContentColor() = if (isSystemInDarkTheme()) { - MaterialTheme.colorScheme.onPrimary + MaterialTheme.colorScheme.secondary } else { MaterialTheme.colorScheme.onPrimaryContainer } @Composable +fun balanceActionContainerColor() = if (isSystemInDarkTheme()) { + MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.6f) +} else { + MaterialTheme.colorScheme.secondaryContainer +} + +@Composable +fun balanceActionContentColor() = if (isSystemInDarkTheme()) { + contentColorFor(balanceActionContainerColor()) +} else { + MaterialTheme.colorScheme.onSecondaryContainer +} + +@Composable +fun balanceAssetContainerColor() = if (isSystemInDarkTheme()) { + MaterialTheme.colorScheme.secondaryContainer +} else { + MaterialTheme.colorScheme.secondaryContainer +} + +@Composable +fun balanceAssetContentColor() = if (isSystemInDarkTheme()) { + MaterialTheme.colorScheme.onSecondaryContainer +} else { + MaterialTheme.colorScheme.onSecondaryContainer +} + +@Composable fun BalancesPagerComposable( innerPadding: PaddingValues, bottomFabSkip: Dp, @@ -342,7 +372,6 @@ fun BalancesPage( ) Spacer(Modifier.height(spacing)) BalanceRecentTransactions( - balance = balance, devMode = devMode, recentTxs = recentTxs, onTransactionClicked = onTransactionClicked, @@ -376,47 +405,76 @@ fun PageIndicator( Modifier .wrapContentHeight() .fillMaxWidth() - .padding(vertical = 3.dp) - // Counter-translate so the row stays centered while pages slide. + .padding(vertical = 8.dp) + // Counter-translate so the capsule stays put while pages slide. .offset { IntOffset( x = (-pagerState.getOffsetDistanceInPages(page) * pageWidth).roundToInt(), y = 0, ) } - // Fade out as this page leaves the viewport, cross-fading with - // the adjacent page's indicator (and out at the balances list). + // Cross-fade with the adjacent page's indicator. .graphicsLayer { alpha = (1f - abs(page - pagerPosition) * 1.25f).coerceIn(0f, 1f) }, horizontalArrangement = Center, verticalAlignment = Alignment.CenterVertically, ) { - val inactive = MaterialTheme.colorScheme.outlineVariant - val active = MaterialTheme.colorScheme.outline - repeat(pagerState.pageCount) { iteration -> - // Ease the highlight between adjacent dots while paging. - val weight = (1f - abs(iteration - pagerPosition)).coerceIn(0f, 1f) - val color = lerp(inactive, active, weight) - val size = 12.dp - if (iteration > 0) Box( + Row( + modifier = Modifier + .clip(CircleShape) + .background(MaterialTheme.colorScheme.surfaceContainerHigh) + .padding(4.dp) + .padding(end = 4.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Row( modifier = Modifier - .padding(8.dp) .clip(CircleShape) - .background(color) - .size(size) - .clickable { onSelectBalance(iteration) } - ) else { - OutlinedButton( + .clickable { onSelectBalance(0) } + .padding(horizontal = 10.dp, vertical = 6.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = Icons.AutoMirrored.Default.List, + contentDescription = stringResource(R.string.balances_title), + tint = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.size(16.dp), + ) + Spacer(Modifier.width(6.dp)) + Text( + text = stringResource(R.string.balances_title), + style = MaterialTheme.typography.labelMedium.copy( + color = MaterialTheme.colorScheme.onSurfaceVariant, + fontWeight = FontWeight.Medium, + ), + ) + } + + Spacer(Modifier.width(2.dp)) + + for (iteration in 1 until pagerState.pageCount) { + val weight = (1f - abs(iteration - pagerPosition)).coerceIn(0f, 1f) + val dotColor = lerp( + MaterialTheme.colorScheme.outlineVariant, + MaterialTheme.colorScheme.primary, + weight, + ) + val dotWidth = (8f + 10f * weight).dp + val dotHeight = (8f + 2f * weight).dp + + Box( modifier = Modifier - .padding(end = 6.dp), - contentPadding = PaddingValues(0.dp), - onClick = { onSelectBalance(0) }, + .height(32.dp) + .width(dotWidth + 10.dp) + .clip(CircleShape) + .clickable { onSelectBalance(iteration) }, + contentAlignment = Alignment.Center, ) { - Icon( + Box( modifier = Modifier - .size(size * 2f), - imageVector = Icons.AutoMirrored.Default.List, - tint = MaterialTheme.colorScheme.onPrimaryContainer, - contentDescription = stringResource(R.string.balances_title), + .height(dotHeight) + .width(dotWidth) + .clip(CircleShape) + .background(dotColor), ) } } @@ -437,8 +495,8 @@ fun BalanceHeaderCard( .fillMaxWidth() .dropShadow(CardDefaults.elevatedShape, block = { radius = 5f - offset = Offset(0f, 6f) - alpha = 0.16f + offset = Offset(0f, 8f) + alpha = 0.10f color = onBackground }), elevation = CardDefaults.elevatedCardElevation( @@ -454,15 +512,21 @@ fun BalanceHeaderCard( .align(Alignment.End) .padding(16.dp) .padding(bottom = 10.dp)) { + val scopeLabel = when (val info = balance.scopeInfo) { + is Exchange -> cleanExchange(info.url) + is Auditor -> cleanExchange(info.url) + // Keep the line so cards without a URL have the same height. + else -> "\u00A0" + } ProvideTextStyle(MaterialTheme.typography.bodySmall.copy( fontStyle = FontStyle.Italic, - color = onSurfaceVariantLight, + color = balanceContentColor().copy(alpha = 0.6f), )) { - when (val info = balance.scopeInfo) { - is Exchange -> Text(cleanExchange(info.url)) - is Auditor -> Text(cleanExchange(info.url)) - else -> {} - } + Text( + text = scopeLabel, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) } } @@ -477,50 +541,84 @@ fun BalanceHeaderCard( ), ) - HorizontalDivider() + val hasPending = + !balance.pendingOutgoing.isZero() || !balance.pendingIncoming.isZero() - Row( - modifier = Modifier - .padding(horizontal = 16.dp) - .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceEvenly, - ) { - Text( - text = stringResource(R.string.balances_pending_label), - modifier = Modifier.weight(1f), - textAlign = TextAlign.End, - style = MaterialTheme.typography.labelLarge, - ) - AssistChip( - modifier = Modifier - .padding(start = 16.dp), - label = { Text(balance.pendingIncoming.toString(showSymbol = false)) }, - leadingIcon = { Icon(Icons.Default.Add, - contentDescription = stringResource(R.string.balances_pending_incoming)) }, - colors = AssistChipDefaults.assistChipColors( - containerColor = successContainerLight, - labelColor = onSuccessContainerLight, - leadingIconContentColor = onSuccessContainerLight, - ), - shape = CircleShape, - onClick = showPendingIncoming, - ) + // Always measure the pending section so every balance card keeps + // the same height, but only draw it if there is something pending. + Layout( + content = { + Column { + HorizontalDivider( + color = balanceContentColor().copy(alpha = 0.2f), + ) - AssistChip( - modifier = Modifier - .padding(start = 16.dp), - label = { Text(balance.pendingOutgoing.toString(showSymbol = false)) }, - leadingIcon = { Icon(Icons.Default.Remove, - contentDescription = stringResource(R.string.balances_pending_outgoing)) }, - colors = AssistChipDefaults.assistChipColors( - containerColor = errorContainerLight, - labelColor = onErrorContainerLight, - leadingIconContentColor = onErrorContainerLight, - ), - shape = CircleShape, - onClick = showPendingOutgoing, - ) + Row( + modifier = Modifier + .padding(horizontal = 16.dp) + .fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceEvenly, + ) { + Text( + text = stringResource(R.string.balances_pending_label), + modifier = Modifier.weight(1f), + textAlign = TextAlign.End, + style = MaterialTheme.typography.labelLarge, + ) + AssistChip( + modifier = Modifier + .padding(start = 16.dp), + label = { Text(balance.pendingIncoming.toString(showSymbol = false)) }, + leadingIcon = { + Icon( + Icons.Default.Add, + contentDescription = stringResource(R.string.balances_pending_incoming) + ) + }, + colors = AssistChipDefaults.assistChipColors( + containerColor = TalerTheme.extraColors.successContainer, + labelColor = TalerTheme.extraColors.onSuccessContainer, + leadingIconContentColor = TalerTheme.extraColors.onSuccessContainer, + ), + shape = CircleShape, + onClick = showPendingIncoming, + border = AssistChipDefaults.assistChipBorder( + enabled = true, + borderWidth = 0.dp + ), + ) + + AssistChip( + modifier = Modifier + .padding(start = 16.dp), + label = { Text(balance.pendingOutgoing.toString(showSymbol = false)) }, + leadingIcon = { + Icon( + Icons.Default.Remove, + contentDescription = stringResource(R.string.balances_pending_outgoing) + ) + }, + colors = AssistChipDefaults.assistChipColors( + containerColor = MaterialTheme.colorScheme.errorContainer, + labelColor = MaterialTheme.colorScheme.onErrorContainer, + leadingIconContentColor = MaterialTheme.colorScheme.onErrorContainer, + ), + shape = CircleShape, + onClick = showPendingOutgoing, + border = AssistChipDefaults.assistChipBorder( + enabled = true, + borderWidth = 0.dp + ), + ) + } + } + }, + ) { measurables, constraints -> + val pending = measurables.first().measure(constraints) + layout(pending.width, pending.height) { + if (hasPending) pending.place(0, 0) + } } } } @@ -547,10 +645,10 @@ fun BalanceShoppingCard( contentDescription = null, ) }, onClick = onClick, - cardColors = CardDefaults.cardColors( - containerColor = balanceContainerColor(), - contentColor = balanceContentColor(), - ) +// cardColors = CardDefaults.cardColors( +// containerColor = balanceContainerColor(), +// contentColor = balanceContentColor(), +// ) ) ) }) @@ -559,21 +657,25 @@ fun BalanceShoppingCard( @Composable fun BalanceRecentTransactions( - balance: BalanceItem, devMode: Boolean, recentTxs: TransactionsResult?, onTransactionClicked: (tx: Transaction) -> Unit, onShowAllTransactions: () -> Unit, ) { val placeholderHeight = 320.dp // FIXME: calculate this dynamically - OutlinedCard(Modifier.cardPaddings()) { + Card( + modifier = Modifier.cardPaddings(), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f), + ), + ) { Column { Row( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 9.dp), verticalAlignment = Alignment.CenterVertically, - ) { + ) { Text( text = stringResource(R.string.balances_recent_transactions), modifier = Modifier.weight(1f), @@ -581,8 +683,8 @@ fun BalanceRecentTransactions( Badge( modifier = Modifier.clickable { onShowAllTransactions() }, - containerColor = MaterialTheme.colorScheme.primaryContainer, - contentColor = MaterialTheme.colorScheme.onPrimaryContainer, + contentColor = balanceActionContentColor(), + containerColor = balanceActionContainerColor(), ) { Row( modifier = Modifier.padding(6.dp), @@ -607,10 +709,15 @@ fun BalanceRecentTransactions( modifier = Modifier.height(placeholderHeight), ) } else res.transactions.forEach { tx -> + val cardColors = CardDefaults.cardColors() TransactionRow( tx = tx, isSelected = false, selectionMode = false, + colors = ListItemDefaults.colors( + contentColor = cardColors.contentColor, + containerColor = cardColors.containerColor, + ), onTransactionClick = { onTransactionClicked(tx) }, onTransactionSelect = {}, ) @@ -644,7 +751,9 @@ fun BalanceActionRow( onDeposit: () -> Unit, ) { FlowRow( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .padding(horizontal = 6.dp) + .fillMaxWidth(), ) { ActionButton( icon = { Icon(Icons.AutoMirrored.Default.ArrowForward, @@ -654,8 +763,8 @@ fun BalanceActionRow( enabled = !disableActions && !balance.disablePeerPayments, modifier = Modifier.weight(1f), onClick = onSend, - contentColor = balanceContentColor(), - containerColor = balanceContainerColor(), + contentColor = balanceActionContentColor(), + containerColor = balanceActionContainerColor(), ) ActionButton( @@ -666,8 +775,8 @@ fun BalanceActionRow( enabled = !disableActions && !balance.disablePeerPayments, modifier = Modifier.weight(1f), onClick = onRequest, - contentColor = balanceContentColor(), - containerColor = balanceContainerColor(), + contentColor = balanceActionContentColor(), + containerColor = balanceActionContainerColor(), ) ActionButton( @@ -678,8 +787,8 @@ fun BalanceActionRow( modifier = Modifier.weight(1f), onClick = onWithdraw, enabled = !disableActions, - contentColor = balanceContentColor(), - containerColor = balanceContainerColor(), + contentColor = balanceActionContentColor(), + containerColor = balanceActionContainerColor(), ) ActionButton( @@ -690,8 +799,8 @@ fun BalanceActionRow( modifier = Modifier.weight(1f), onClick = onDeposit, enabled = !disableActions, - contentColor = balanceContentColor(), - containerColor = balanceContainerColor(), + contentColor = balanceActionContentColor(), + containerColor = balanceActionContainerColor(), ) } } @@ -711,8 +820,9 @@ fun BalanceAssetsRow( label = { Text(stringResource(R.string.discounts_title)) }, onClick = onShowDiscounts, modifier = Modifier.weight(1f).padding(horizontal = 6.dp), - contentColor = balanceContentColor(), - containerColor = balanceContainerColor(), + size = ActionButtonSize.MEDIUM, + contentColor = balanceAssetContentColor(), + containerColor = balanceAssetContainerColor(), ) ActionButton( @@ -721,8 +831,9 @@ fun BalanceAssetsRow( label = { Text(stringResource(R.string.passes_title)) }, onClick = onShowPasses, modifier = Modifier.weight(1f).padding(horizontal = 6.dp), - contentColor = balanceContentColor(), - containerColor = balanceContainerColor(), + size = ActionButtonSize.MEDIUM, + contentColor = balanceAssetContentColor(), + containerColor = balanceAssetContainerColor(), ) ActionButton( @@ -731,15 +842,18 @@ fun BalanceAssetsRow( label = { Text(stringResource(R.string.balances_section_statements)) }, onClick = onShowStatements, modifier = Modifier.weight(1f).padding(horizontal = 6.dp), - contentColor = balanceContentColor(), - containerColor = balanceContainerColor(), + size = ActionButtonSize.MEDIUM, + contentColor = balanceAssetContentColor(), + containerColor = balanceAssetContainerColor(), ) } } @Preview @Composable -fun BalancesPagerComposablePreview() { +fun BalancesPagerComposablePreview( + darkTheme: Boolean = false, +) { val balances = listOf( BalanceItem( scopeInfo = ScopeInfo.Global("CHF"), @@ -784,29 +898,37 @@ fun BalancesPagerComposablePreview() { ) ) - TalerSurface { - BalancesPagerComposable( - innerPadding = PaddingValues(0.dp), - bottomFabSkip = 0.dp, - selectedBalance = Exchange("KUDOS", "https://exchange.demo.taler.net"), - state = BalanceState.Success(balances, donauSummary), - recentTxs = recentTxs, - devMode = false, - networkStatus = true, - onBalanceSelected = {}, - onWithdrawMoney = {}, - onGetDemoMoney = {}, - onShopping = {}, - onSend = {}, - onRequest = {}, - onWithdraw = {}, - onDeposit = {}, - onTransactionClicked = {}, - onShowAllTransactions = {}, - onShowPendingIncoming = {}, - onShowPendingOutgoing = {}, - onShowDiscounts = {}, - onShowPasses = {}, - ) + TalerTheme(darkTheme) { + TalerSurface { + BalancesPagerComposable( + innerPadding = PaddingValues(0.dp), + bottomFabSkip = 0.dp, + selectedBalance = Exchange("KUDOS", "https://exchange.demo.taler.net"), + state = BalanceState.Success(balances, donauSummary), + recentTxs = recentTxs, + devMode = false, + networkStatus = true, + onBalanceSelected = {}, + onWithdrawMoney = {}, + onGetDemoMoney = {}, + onShopping = {}, + onSend = {}, + onRequest = {}, + onWithdraw = {}, + onDeposit = {}, + onTransactionClicked = {}, + onShowAllTransactions = {}, + onShowPendingIncoming = {}, + onShowPendingOutgoing = {}, + onShowDiscounts = {}, + onShowPasses = {}, + ) + } } +} + +@Preview(uiMode = UI_MODE_NIGHT_YES) +@Composable +fun BalancesPagerComposableDarkPreview() { + BalancesPagerComposablePreview(true) } \ No newline at end of file diff --git a/wallet/src/main/java/net/taler/wallet/compose/ActionButton.kt b/wallet/src/main/java/net/taler/wallet/compose/ActionButton.kt @@ -22,7 +22,9 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.FloatingActionButtonDefaults +import androidx.compose.material3.LargeFloatingActionButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MediumFloatingActionButton import androidx.compose.material3.ProvideTextStyle import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -30,33 +32,73 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +enum class ActionButtonSize { + SMALL, + MEDIUM, + LARGE, +} + @Composable fun ActionButton( icon: @Composable () -> Unit, label: @Composable () -> Unit, modifier: Modifier = Modifier, onClick: () -> Unit = {}, - shape: Shape = RoundedCornerShape(12.dp), + size: ActionButtonSize = ActionButtonSize.SMALL, + shape: Shape? = null, containerColor: Color = MaterialTheme.colorScheme.primaryContainer, contentColor: Color = MaterialTheme.colorScheme.onPrimaryContainer, + disabledContainerColor: Color = MaterialTheme.colorScheme.surfaceVariant, + disabledContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant, labelColor: Color = MaterialTheme.colorScheme.onPrimaryContainer, enabled: Boolean = true, ) { Column(modifier, horizontalAlignment = Alignment.CenterHorizontally) { - FloatingActionButton( - onClick = if (enabled) onClick else {{}}, - shape = shape, - containerColor = if (enabled) containerColor else MaterialTheme.colorScheme.surfaceVariant, - contentColor = if (enabled) contentColor else MaterialTheme.colorScheme.onSurfaceVariant, - elevation = FloatingActionButtonDefaults.elevation(0.dp), - content = { - icon() - }, - ) + when (size) { + ActionButtonSize.SMALL -> FloatingActionButton( + onClick = if (enabled) onClick else { + {} + }, + shape = shape ?: FloatingActionButtonDefaults.shape, + containerColor = if (enabled) containerColor else disabledContainerColor, + contentColor = if (enabled) contentColor else disabledContentColor, + elevation = FloatingActionButtonDefaults.elevation(0.dp), + content = { + icon() + }, + ) + + ActionButtonSize.MEDIUM -> MediumFloatingActionButton( + onClick = if (enabled) onClick else { + {} + }, + shape = shape ?: FloatingActionButtonDefaults.mediumShape, + containerColor = if (enabled) containerColor else disabledContainerColor, + contentColor = if (enabled) contentColor else disabledContentColor, + elevation = FloatingActionButtonDefaults.elevation(0.dp), + content = { + icon() + }, + ) + + ActionButtonSize.LARGE -> LargeFloatingActionButton( + onClick = if (enabled) onClick else { + {} + }, + shape = shape ?: FloatingActionButtonDefaults.largeShape, + containerColor = if (enabled) containerColor else disabledContainerColor, + contentColor = if (enabled) contentColor else disabledContentColor, + elevation = FloatingActionButtonDefaults.elevation(0.dp), + content = { + icon() + }, + ) + } - Spacer(modifier = Modifier.height(6.dp)) + Spacer(modifier = Modifier.height(10.dp)) ProvideTextStyle( MaterialTheme.typography.labelLarge diff --git a/wallet/src/main/java/net/taler/wallet/compose/Utils.kt b/wallet/src/main/java/net/taler/wallet/compose/Utils.kt @@ -62,7 +62,7 @@ fun Modifier.safeHorizontalPadding(): Modifier = then(Modifier.padding(horizontal = 14.dp)) fun Modifier.cardPaddings(): Modifier = - then(Modifier.padding(horizontal = 14.dp, vertical = 7.dp)) + then(Modifier.padding(horizontal = 16.dp, vertical = 10.dp)) @Composable fun TalerSurface(content: @Composable () -> Unit) { diff --git a/wallet/src/main/java/net/taler/wallet/main/NewMainScreen.kt b/wallet/src/main/java/net/taler/wallet/main/NewMainScreen.kt @@ -16,6 +16,9 @@ package net.taler.wallet.main +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.size @@ -113,7 +116,15 @@ fun NewMainScreen( GlobalScaffold( model = model, modifier = Modifier.fillMaxSize(), - title = {}, + title = { + AnimatedVisibility( + viewMode.selectedScope == null, + enter = fadeIn(), + exit = fadeOut(), + ) { + Text(stringResource(R.string.balances_title)) + } + }, snackbarHost = { SnackbarHost(snackbarHostState) }, actions = { IconButton(onClick = { diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsComposable.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsComposable.kt @@ -41,6 +41,7 @@ import androidx.compose.material3.ElevatedCard import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.ListItem +import androidx.compose.material3.ListItemColors import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle @@ -272,6 +273,10 @@ fun TransactionRow( tx: Transaction, isSelected: Boolean, selectionMode: Boolean, + colors: ListItemColors = ListItemDefaults.colors(), + selectedColors: ListItemColors = ListItemDefaults.colors( + containerColor = MaterialTheme.colorScheme.secondaryContainer, + ), onTransactionClick: () -> Unit, onTransactionSelect: () -> Unit, ) { @@ -289,6 +294,11 @@ fun TransactionRow( onTransactionSelect() }, ), + colors = if (isSelected) { + selectedColors + } else { + colors + }, trailingContent = { Box( modifier = Modifier @@ -344,13 +354,6 @@ fun TransactionRow( } } }, - colors = ListItemDefaults.colors( - containerColor = if (isSelected) { - MaterialTheme.colorScheme.secondaryContainer - } else { - ListItemDefaults.containerColor - } - ) ) HorizontalDivider()