Updated on 2026-08-14

This commit is contained in:
Tangem 2023-12-06 11:51:14 +04:00
parent ae07a9ed30
commit be84c35579
4 changed files with 234 additions and 5 deletions

View file

@ -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,

View file

@ -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)
}
}
}

View file

@ -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<BalancesAndLimitsBlockState>(
collection = listOf(
BalancesAndLimitsBlockState.Loading,
BalancesAndLimitsBlockState.Error,
BalancesAndLimitsBlockState.Content(
availableBalance = "400.00",
currencySymbol = "USDT",
limitDays = 7,
isEnabled = true,
onClick = {},
),
),
)
// endregion Preview

View file

@ -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,
)
}
}