From be84c35579a3776d53fbe7c9055a1567c4f2ec56 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 6 Dec 2023 11:51:14 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../presentation/wallet/ui/WalletScreenV2.kt | 14 ++ .../ui/components/common/WalletContent.kt | 7 +- .../components/visa/BalancesAndLimitsBlock.kt | 197 ++++++++++++++++++ .../ui/components/visa/VisaDepositButton.kt | 21 ++ 4 files changed, 234 insertions(+), 5 deletions(-) create mode 100644 features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/BalancesAndLimitsBlock.kt create mode 100644 features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/VisaDepositButton.kt diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreenV2.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreenV2.kt index d4953aec0d..47a88420e6 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreenV2.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreenV2.kt @@ -39,6 +39,8 @@ import com.tangem.feature.wallet.presentation.wallet.ui.components.common.* import com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrency.organizeTokensButton import com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency.controlButtons import com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency.marketPriceBlock +import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.balancesAndLimitsBlock +import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.depositButton import com.tangem.feature.wallet.presentation.wallet.ui.utils.changeWalletAnimator import kotlinx.collections.immutable.toImmutableList @@ -141,6 +143,18 @@ private fun WalletContent( } } + (selectedWallet as? WalletState.Visa.Content)?.let { + depositButton( + modifier = itemModifier.fillMaxWidth(), + state = it.depositButtonState, + ) + + balancesAndLimitsBlock( + modifier = itemModifier, + state = it.balancesAndLimitBlockState, + ) + } + contentItemsV2( state = selectedWallet, txHistoryItems = txHistoryItems, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletContent.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletContent.kt index 4ca696aa9a..30cf4bb156 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletContent.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletContent.kt @@ -46,11 +46,8 @@ internal fun LazyListScope.contentItemsV2( is WalletStateV2.SingleCurrency -> { txHistoryItems(state.txHistoryState, txHistoryItems, isBalanceHidden, modifier) } - is WalletStateV2.Visa.Content -> { - // TODO: Will be implemented soon - } - is WalletStateV2.Visa.Locked -> { - // TODO: Will be implemented soon + is WalletStateV2.Visa -> { + txHistoryItems(state.txHistoryState, txHistoryItems, isBalanceHidden, modifier) } } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/BalancesAndLimitsBlock.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/BalancesAndLimitsBlock.kt new file mode 100644 index 0000000000..26ede92649 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/BalancesAndLimitsBlock.kt @@ -0,0 +1,197 @@ +package com.tangem.feature.wallet.presentation.wallet.ui.components.visa + +import androidx.compose.animation.AnimatedContent +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.components.RectangleShimmer +import com.tangem.core.ui.res.TangemTheme +import com.tangem.feature.wallet.impl.R +import com.tangem.feature.wallet.presentation.wallet.state2.model.BalancesAndLimitsBlockState + +private const val BALANCES_AND_LIMITS_BLOCK_KEY = "BalancesAndLimitsBlock" + +internal fun LazyListScope.balancesAndLimitsBlock(state: BalancesAndLimitsBlockState, modifier: Modifier = Modifier) { + item(key = BALANCES_AND_LIMITS_BLOCK_KEY, contentType = BALANCES_AND_LIMITS_BLOCK_KEY) { + BalancesAndLimitsBlock(state, modifier) + } +} + +@Composable +private fun BalancesAndLimitsBlock(state: BalancesAndLimitsBlockState, modifier: Modifier = Modifier) { + val onClick: () -> Unit = remember(state) { + { (state as? BalancesAndLimitsBlockState.Content)?.onClick?.invoke() } + } + val isEnabled: Boolean = remember(state) { + state is BalancesAndLimitsBlockState.Content && state.isEnabled + } + + ContentContainer( + modifier = modifier.fillMaxWidth(), + enabled = isEnabled, + onClick = onClick, + title = { + Text( + text = "Balances & Limits", + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + ) + }, + content = { + Content(state = state) + }, + endIcon = { + Icon( + modifier = Modifier.size(TangemTheme.dimens.size24), + painter = painterResource(id = R.drawable.ic_chevron_right_24), + tint = TangemTheme.colors.icon.informative, + contentDescription = null, + ) + }, + ) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private inline fun ContentContainer( + enabled: Boolean, + noinline onClick: () -> Unit, + crossinline title: @Composable () -> Unit, + crossinline content: @Composable () -> Unit, + crossinline endIcon: @Composable () -> Unit, + modifier: Modifier = Modifier, +) { + Card( + modifier = modifier.fillMaxWidth(), + shape = RoundedCornerShape(TangemTheme.dimens.radius16), + colors = CardDefaults.cardColors( + containerColor = TangemTheme.colors.background.primary, + contentColor = TangemTheme.colors.text.primary1, + disabledContainerColor = TangemTheme.colors.background.primary, + disabledContentColor = TangemTheme.colors.text.primary1, + ), + onClick = onClick, + enabled = enabled, + ) { + Row( + modifier = Modifier + .padding(all = TangemTheme.dimens.spacing12) + .fillMaxWidth() + .heightIn(min = TangemTheme.dimens.size48), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Column( + verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing6), + horizontalAlignment = Alignment.Start, + ) { + title() + content() + } + endIcon() + } + } +} + +@Composable +private fun Content(state: BalancesAndLimitsBlockState, modifier: Modifier = Modifier) { + AnimatedContent( + modifier = modifier, + targetState = state, + label = "Update the balances and limits block", + ) { blockState -> + when (blockState) { + is BalancesAndLimitsBlockState.Content -> with(blockState) { + AvailableLimit( + availableBalance = availableBalance, + currencySymbol = currencySymbol, + limitDays = limitDays, + ) + } + is BalancesAndLimitsBlockState.Error -> { + Text( + text = "–", + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.primary1, + ) + } + is BalancesAndLimitsBlockState.Loading -> { + RectangleShimmer( + modifier = Modifier + .width(TangemTheme.dimens.size200) + .height(TangemTheme.dimens.size20), + ) + } + } + } +} + +@Composable +private fun AvailableLimit( + availableBalance: String, + currencySymbol: String, + limitDays: Int, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), + ) { + Text( + text = "$availableBalance $currencySymbol", + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.primary1, + ) + Text( + text = "available $limitDays-day limit", + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.tertiary, + ) + } +} + +// region Preview +@Preview(showBackground = true, widthDp = 360) +@Composable +private fun BalancesAndLimitsBlockPreview_Light( + @PreviewParameter(BalancesAndLimitsBlockParameterProvider::class) state: BalancesAndLimitsBlockState, +) { + TangemTheme { + BalancesAndLimitsBlock(state) + } +} + +@Preview(showBackground = true, widthDp = 360) +@Composable +private fun BalancesAndLimitsBlockPreview_Dark( + @PreviewParameter(BalancesAndLimitsBlockParameterProvider::class) state: BalancesAndLimitsBlockState, +) { + TangemTheme(isDark = true) { + BalancesAndLimitsBlock(state) + } +} + +private class BalancesAndLimitsBlockParameterProvider : CollectionPreviewParameterProvider( + collection = listOf( + BalancesAndLimitsBlockState.Loading, + BalancesAndLimitsBlockState.Error, + BalancesAndLimitsBlockState.Content( + availableBalance = "400.00", + currencySymbol = "USDT", + limitDays = 7, + isEnabled = true, + onClick = {}, + ), + ), +) +// endregion Preview \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/VisaDepositButton.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/VisaDepositButton.kt new file mode 100644 index 0000000000..85dab308e0 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/VisaDepositButton.kt @@ -0,0 +1,21 @@ +package com.tangem.feature.wallet.presentation.wallet.ui.components.visa + +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.ui.Modifier +import com.tangem.core.ui.components.SecondaryButtonIconStart +import com.tangem.feature.wallet.impl.R +import com.tangem.feature.wallet.presentation.wallet.state2.model.DepositButtonState + +private const val DEPOSIT_BUTTON_CONTENT_TYPE = "DepositButton" + +internal fun LazyListScope.depositButton(state: DepositButtonState, modifier: Modifier = Modifier) { + item(key = DEPOSIT_BUTTON_CONTENT_TYPE, contentType = DEPOSIT_BUTTON_CONTENT_TYPE) { + SecondaryButtonIconStart( + modifier = modifier, + text = "Deposit", + iconResId = R.drawable.ic_arrow_down_24, + onClick = state.onClick, + enabled = state.isEnabled, + ) + } +} \ No newline at end of file