Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-15 03:26:53 -07:00
parent b208c0dd7c
commit 640ba5af98
14 changed files with 268 additions and 127 deletions

View file

@ -8,7 +8,6 @@
<ID>BooleanPropertyNaming:TangemPayChangePinUM.kt$TangemPayChangePinUM$val submitButtonEnabled: Boolean</ID>
<ID>BooleanPropertyNaming:TangemPayChangePinUM.kt$TangemPayChangePinUM$val submitButtonLoading: Boolean</ID>
<ID>BooleanPropertyNaming:TangemPayDetailsScreen.kt$var showDropdownMenu by rememberSaveable { mutableStateOf(false) }</ID>
<ID>BooleanPropertyNaming:TangemPayDetailsUM.kt$TangemPayDetailsUM$val addFundsEnabled: Boolean</ID>
<ID>BooleanPropertyNaming:TangemPayTxHistoryListManager.kt$TangemPayTxHistoryListManager$val clearUiBatches = state.status is PaginationStatus.InitialLoading &amp;&amp; batchListState.status is PaginationStatus.Paginating</ID>
<ID>CanBeNonNullable:TangemPayTxHistoryDetailsModel.kt$TangemPayTxHistoryDetailsModel$txHash: String?</ID>
<ID>MultilineLambdaItParameter:TangemPayAddFundsContent.kt${ key(it.title) { TangemPayTopUpItem(state = it) } }</ID>

View file

@ -10,7 +10,10 @@ import com.tangem.core.ui.extensions.themedColor
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_document_20
import com.tangem.domain.models.account.PaymentAccountStatusValue
import com.tangem.domain.models.pay.TangemPayCardFrozenState
import com.tangem.domain.models.pay.TangemPayCardState
import com.tangem.domain.models.pay.isFrozen
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.utils.TangemPayDetailIntents
import kotlinx.collections.immutable.ImmutableList
@ -21,55 +24,127 @@ internal class TangemPayDetailsStateFactory(
private val onBack: () -> Unit,
private val onOpenMenu: () -> Unit,
private val intents: TangemPayDetailIntents,
private val cardFrozenState: TangemPayCardFrozenState,
private val isRedesignEnabled: Boolean,
) {
@Suppress("LongMethod")
fun getInitialState(
isTangemPayDeactivated: Boolean,
cardNumberEnd: String,
isReissuing: Boolean,
isFrozen: Boolean,
): TangemPayDetailsUM {
fun getLoadingState(): TangemPayDetailsUM {
return TangemPayDetailsUM(
topBarConfig = TangemPayDetailsTopBarConfig(
onBackClick = onBack,
onOpenMenu = onOpenMenu,
items = getTopBarMenuItems(isTangemPayDeactivated),
itemsV2 = getTopBarMenuItemsV2(isTangemPayDeactivated),
items = getTopBarMenuItems(),
itemsV2 = getTopBarMenuItemsV2(),
),
pullToRefreshConfig = PullToRefreshConfig(
isRefreshing = false,
onRefresh = intents::onRefreshSwipe,
),
balanceBlockState = TangemPayDetailsBalanceBlockState.Loading(
actionButtons = getActionButtonsConfig(),
actionButtons = persistentListOf(),
cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState(
cards = persistentListOf(
TangemPayDetailsBalanceBlockState.Card(
lastDigits = cardNumberEnd,
onClick = {},
isReissuing = isReissuing,
isFrozen = isFrozen,
),
),
cards = persistentListOf(),
onAddCardClick = intents::onAddCardClick,
).takeIf { !isTangemPayDeactivated },
),
),
isBalanceHidden = false,
addFundsEnabled = true,
addToWalletBlockState = null,
accountDeactivatedNotificationConfig = NotificationConfig(
title = resourceReference(R.string.tangempay_account_deactivated_message_title),
subtitle = resourceReference(R.string.tangempay_account_deactivated_message_subtitle),
iconResId = R.drawable.img_attention_20,
).takeIf { isTangemPayDeactivated },
errorNotificationConfig = null,
accountDeactivatedNotificationConfig = null,
)
}
private fun getTopBarMenuItems(isTangemPayDeactivated: Boolean): ImmutableList<TangemDropdownMenuItem> {
if (isTangemPayDeactivated) return persistentListOf()
fun getLoadedState(status: PaymentAccountStatusValue.Loaded): TangemPayDetailsUM {
val card = status.cards.firstOrNull()
val errorNotificationConfig = when (status.error) {
null -> null
PaymentAccountStatusValue.Error.NotSynced -> createRenewSessionNotificationConfig()
else -> createAccountUnavailableConfig()
}
return TangemPayDetailsUM(
topBarConfig = TangemPayDetailsTopBarConfig(
onBackClick = onBack,
onOpenMenu = onOpenMenu,
items = getTopBarMenuItems(),
itemsV2 = getTopBarMenuItemsV2(),
),
pullToRefreshConfig = PullToRefreshConfig(
isRefreshing = false,
onRefresh = intents::onRefreshSwipe,
),
balanceBlockState = TangemPayDetailsBalanceBlockState.Loading(
actionButtons = getActionButtonsConfig(
isEnabled = errorNotificationConfig == null &&
(card == null || card.frozenState == TangemPayCardFrozenState.Unfrozen),
),
cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState(
cards = card?.let {
persistentListOf(
TangemPayDetailsBalanceBlockState.Card(
lastDigits = card.lastDigits,
onClick = intents::onCardClick,
isReissuing = card.state != TangemPayCardState.Active,
isEnabled = errorNotificationConfig == null,
isFrozen = card.isFrozen,
),
)
} ?: persistentListOf(),
onAddCardClick = intents::onAddCardClick,
),
),
isBalanceHidden = false,
addToWalletBlockState = null,
errorNotificationConfig = errorNotificationConfig,
accountDeactivatedNotificationConfig = null,
)
}
fun getDeactivatedState(): TangemPayDetailsUM {
return TangemPayDetailsUM(
topBarConfig = TangemPayDetailsTopBarConfig(
onBackClick = onBack,
onOpenMenu = onOpenMenu,
items = persistentListOf(),
itemsV2 = persistentListOf(),
),
pullToRefreshConfig = PullToRefreshConfig(
isRefreshing = false,
onRefresh = intents::onRefreshSwipe,
),
balanceBlockState = TangemPayDetailsBalanceBlockState.Loading(
actionButtons = getActionButtonsConfig(isEnabled = true),
cardsBlockState = null,
),
isBalanceHidden = false,
addToWalletBlockState = null,
errorNotificationConfig = null,
accountDeactivatedNotificationConfig = createAccountDeactivatedConfig(),
)
}
private fun createAccountUnavailableConfig() = NotificationConfig(
title = resourceReference(R.string.tangempay_temporarily_unavailable),
subtitle = resourceReference(R.string.tangempay_service_unreachable_try_later),
iconResId = R.drawable.img_attention_20,
iconTint = NotificationConfig.IconTint.Attention,
)
private fun createAccountDeactivatedConfig() = NotificationConfig(
title = resourceReference(R.string.tangempay_account_deactivated_message_title),
subtitle = resourceReference(R.string.tangempay_account_deactivated_message_subtitle),
iconResId = R.drawable.img_attention_20,
)
private fun createRenewSessionNotificationConfig() = NotificationConfig(
title = resourceReference(R.string.tangempay_sync_needed_title),
subtitle = resourceReference(R.string.tangempay_sync_needed_body),
iconResId = R.drawable.img_attention_20,
iconTint = NotificationConfig.IconTint.Attention,
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
text = resourceReference(R.string.tangempay_sync_needed_button),
onClick = intents::onRenewSession,
),
)
private fun getTopBarMenuItems(): ImmutableList<TangemDropdownMenuItem> {
return persistentListOf(
TangemDropdownMenuItem(
title = resourceReference(R.string.tangem_pay_terms_limits),
@ -84,9 +159,7 @@ internal class TangemPayDetailsStateFactory(
)
}
private fun getTopBarMenuItemsV2(isTangemPayDeactivated: Boolean): ImmutableList<TangemPayDropDownItemUM> {
if (isTangemPayDeactivated) return persistentListOf()
private fun getTopBarMenuItemsV2(): ImmutableList<TangemPayDropDownItemUM> {
return persistentListOf(
TangemPayDropDownItemUM(
title = resourceReference(R.string.tangem_pay_terms_limits),
@ -111,7 +184,7 @@ internal class TangemPayDetailsStateFactory(
)
}
private fun getActionButtonsConfig(): ImmutableList<ActionButtonConfig> {
private fun getActionButtonsConfig(isEnabled: Boolean): ImmutableList<ActionButtonConfig> {
return persistentListOf(
ActionButtonConfig(
text = resourceReference(id = R.string.tangempay_card_details_add_funds),
@ -121,13 +194,13 @@ internal class TangemPayDetailsStateFactory(
R.drawable.ic_plus_24
},
onClick = intents::onClickAddFunds,
isEnabled = cardFrozenState == TangemPayCardFrozenState.Unfrozen,
isEnabled = isEnabled,
),
ActionButtonConfig(
text = resourceReference(id = R.string.tangempay_card_details_withdraw),
iconResId = R.drawable.ic_arrow_up_24,
onClick = intents::onClickWithdraw,
isEnabled = cardFrozenState == TangemPayCardFrozenState.Unfrozen,
isEnabled = isEnabled,
),
)
}

View file

@ -16,7 +16,7 @@ internal data class TangemPayDetailsUM(
val balanceBlockState: TangemPayDetailsBalanceBlockState,
val addToWalletBlockState: AddToWalletBlockState?,
val isBalanceHidden: Boolean,
val addFundsEnabled: Boolean,
val errorNotificationConfig: NotificationConfig?,
val accountDeactivatedNotificationConfig: NotificationConfig?,
)
@ -93,6 +93,7 @@ internal sealed class TangemPayDetailsBalanceBlockState {
val onClick: () -> Unit,
val isReissuing: Boolean,
val isFrozen: Boolean,
val isEnabled: Boolean,
)
}

View file

@ -15,27 +15,28 @@ import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig.ShowRefreshState
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.feedback.models.WalletMetaInfo
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.TokenReceiveConfig
import com.tangem.domain.models.account.PaymentAccountStatusValue
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.pay.TangemPayCardFrozenState
import com.tangem.domain.models.pay.TangemPayCardState
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
import com.tangem.domain.pay.model.TangemPayTopUpData
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
import com.tangem.domain.pay.repository.TangemPayWithdrawRepository
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
import com.tangem.features.tangempay.TangemPayConstants
import com.tangem.features.tangempay.TangemPayFeatureToggles
import com.tangem.features.tangempay.components.AddFundsListener
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayDetailsErrorType
import com.tangem.features.tangempay.entity.TangemPayDetailsNavigation
import com.tangem.features.tangempay.entity.TangemPayDetailsStateFactory
@ -73,14 +74,11 @@ internal class TangemPayDetailsModel @Inject constructor(
private val expressTransactionsEventListener: ExpressTransactionsEventListener,
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
private val produceTangemPayInitialDataUseCase: ProduceTangemPayInitialDataUseCase,
) : Model(), TangemPayTxHistoryUiActions, TangemPayDetailIntents, AddFundsListener {
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
private val isTangemPayDeactivated = params.initialStatus.isDeactivated
private val initialCard = params.initialStatus.ifLoadedOrNull { it.cards.firstOrNull() }
private val currentStatus = MutableStateFlow(params.initialStatus)
private val userWalletId
@ -93,25 +91,20 @@ internal class TangemPayDetailsModel @Inject constructor(
onBack = router::pop,
onOpenMenu = ::onOpenMenu,
intents = this,
cardFrozenState = when {
initialCard == null -> TangemPayCardFrozenState.Unfrozen
else -> initialCard.frozenState
},
isRedesignEnabled = isRedesignEnabled(),
)
val uiState: StateFlow<TangemPayDetailsUM>
field = MutableStateFlow(
stateFactory.getInitialState(
isTangemPayDeactivated = isTangemPayDeactivated,
cardNumberEnd = initialCard?.lastDigits.orEmpty(),
isReissuing = initialCard == null || initialCard.state != TangemPayCardState.Active,
isFrozen = initialCard?.frozenState == TangemPayCardFrozenState.Frozen,
),
when {
params.initialStatus.isDeactivated -> stateFactory.getDeactivatedState()
else -> stateFactory.getLoadingState()
},
)
private val refreshStateJobHolder = JobHolder()
private val addToWalletBannerJobHolder = JobHolder()
private val frozenStateJobHolder = JobHolder()
val bottomSheetNavigation: SlotNavigation<TangemPayDetailsNavigation> = SlotNavigation()
@ -119,38 +112,27 @@ internal class TangemPayDetailsModel @Inject constructor(
analytics.send(TangemPayAnalyticsEvents.MainScreenOpened())
handleBalanceHiding()
val statusFlow = paymentAccountStatusSupplier.invoke(userWalletId)
paymentAccountStatusSupplier.invoke(userWalletId)
.onEach { status -> currentStatus.update { status } }
.map { it.value }
if (isTangemPayDeactivated) {
statusFlow
.filterIsInstance<PaymentAccountStatusValue.Deactivated>()
.onEach { state ->
uiState.update(DetailsBalanceTransformer(state.balance.fiatBalance))
}
.launchIn(modelScope)
} else {
if (initialCard != null) {
subscribeToCardFrozenState(initialCard.id)
}
fetchAddToWalletBanner()
statusFlow
.filterIsInstance<PaymentAccountStatusValue.Loaded>()
.filter { it.source == StatusSource.ACTUAL }
.onEach { state ->
uiState.update(DetailsBalanceTransformer(state.balance.fiatBalance))
state.cards.firstOrNull()?.let { card ->
uiState.update(
TangemPayCardDataTransformer(
card = card,
onCardClick = { onCardClick() },
),
)
.onEach { state ->
when (state) {
is PaymentAccountStatusValue.Deactivated -> {
uiState.update { stateFactory.getDeactivatedState() }
uiState.update(DetailsBalanceTransformer(state.balance.fiatBalance))
}
is PaymentAccountStatusValue.Loaded -> {
fetchAddToWalletBanner()
uiState.update { stateFactory.getLoadedState(state) }
uiState.update(DetailsBalanceTransformer(state.balance.fiatBalance))
state.cards.firstOrNull()?.let { card ->
subscribeToCardFrozenState(card.id)
}
}
else -> uiState.update { stateFactory.getLoadingState() }
}
.launchIn(modelScope)
}
}
.launchIn(modelScope)
}
fun onResume() {
@ -168,10 +150,12 @@ internal class TangemPayDetailsModel @Inject constructor(
fun isRedesignEnabled(): Boolean = tangemPayFeatureToggles.isRedesignEnabled
private fun subscribeToCardFrozenState(cardId: String) {
frozenStateJobHolder.cancel()
cardDetailsRepository
.cardFrozenState(cardId)
.onEach { uiState.update(TangemPayFreezeUnfreezeStateTransformer(cardFrozenState = it)) }
.launchIn(modelScope)
.saveIn(frozenStateJobHolder)
}
override fun onClickAddFunds() {
@ -375,6 +359,21 @@ internal class TangemPayDetailsModel @Inject constructor(
)
}
override fun onRenewSession() {
uiState.update(TangemPayRenewSessionTransformer(shouldShowProgress = true))
modelScope.launch {
produceTangemPayInitialDataUseCase(userWalletId)
.onRight {
paymentAccountStatusFetcher.invoke(userWalletId)
uiState.update(TangemPayRenewSessionTransformer(shouldShowProgress = false))
}
.onLeft {
uiMessageSender.send(SnackbarMessage(resourceReference(R.string.common_error)))
uiState.update(TangemPayRenewSessionTransformer(shouldShowProgress = false))
}
}
}
private fun showBottomSheetError(type: TangemPayDetailsErrorType) {
uiMessageSender.send(message = TangemPayMessagesFactory.createErrorMessage(errorType = type))
}

View file

@ -1,33 +0,0 @@
package com.tangem.features.tangempay.model.transformers
import com.tangem.domain.models.pay.TangemPayCard
import com.tangem.domain.models.pay.TangemPayCardFrozenState
import com.tangem.domain.models.pay.TangemPayCardState
import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.persistentListOf
internal class TangemPayCardDataTransformer(
private val card: TangemPayCard,
private val onCardClick: () -> Unit,
) : Transformer<TangemPayDetailsUM> {
override fun transform(prevState: TangemPayDetailsUM): TangemPayDetailsUM {
val updatedCard = TangemPayDetailsBalanceBlockState.Card(
lastDigits = card.lastDigits,
onClick = onCardClick,
isReissuing = card.state != TangemPayCardState.Active,
isFrozen = card.frozenState == TangemPayCardFrozenState.Frozen,
)
val cardsBlockState = prevState.balanceBlockState.cardsBlockState?.copy(
cards = persistentListOf(updatedCard),
)
val newBalanceBlockState = when (val bs = prevState.balanceBlockState) {
is TangemPayDetailsBalanceBlockState.Loading -> bs.copy(cardsBlockState = cardsBlockState)
is TangemPayDetailsBalanceBlockState.Content -> bs.copy(cardsBlockState = cardsBlockState)
is TangemPayDetailsBalanceBlockState.Error -> bs.copy(cardsBlockState = cardsBlockState)
}
return prevState.copy(balanceBlockState = newBalanceBlockState)
}
}

View file

@ -0,0 +1,22 @@
package com.tangem.features.tangempay.model.transformers
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
import com.tangem.utils.transformer.Transformer
internal class TangemPayRenewSessionTransformer(
private val shouldShowProgress: Boolean,
) : Transformer<TangemPayDetailsUM> {
override fun transform(prevState: TangemPayDetailsUM): TangemPayDetailsUM {
val config = prevState.errorNotificationConfig ?: return prevState
val button = config.buttonsState as? NotificationConfig.ButtonsState.SecondaryButtonConfig
?: return prevState
return prevState.copy(
errorNotificationConfig = config.copy(
buttonsState = button.copy(shouldShowProgress = shouldShowProgress),
),
)
}
}

View file

@ -19,6 +19,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
@ -61,6 +62,8 @@ import com.tangem.features.tokendetails.ExpressTransactionsComponent
import com.tangem.utils.StringsSigns.DASH_SIGN
import kotlinx.collections.immutable.persistentListOf
private const val DISABLED_ALPHA = 0.5f
@Suppress("LongMethod")
@Composable
internal fun TangemPayDetailsScreen(
@ -100,6 +103,20 @@ internal fun TangemPayDetailsScreen(
.fillMaxWidth(),
)
}
if (state.errorNotificationConfig != null) {
item(
key = "error_message",
content = {
Notification(
modifier = Modifier
.padding(horizontal = TangemTheme.dimens.spacing16)
.padding(top = 12.dp)
.fillMaxWidth(),
config = state.errorNotificationConfig,
)
},
)
}
item(
key = TangemPayDetailsBalanceBlockState::class.java,
content = {
@ -300,11 +317,16 @@ private fun TangemPayCardItem(card: TangemPayDetailsBalanceBlockState.Card, modi
Box(
modifier = modifier
.clip(RoundedCornerShape(4.dp))
.clickable(onClick = card.onClick)
.clickable(
onClick = card.onClick,
enabled = card.isEnabled,
)
.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_CARD_BUTTON),
) {
Image(
modifier = Modifier.fillMaxSize(),
modifier = Modifier
.alpha(if (card.isEnabled) 1f else DISABLED_ALPHA)
.fillMaxSize(),
painter = painterResource(
if (card.isReissuing) {
R.drawable.img_visa_card_inactive_48_32
@ -464,12 +486,14 @@ internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<T
lastDigits = "1234",
onClick = {},
isReissuing = false,
isEnabled = false,
isFrozen = false,
),
TangemPayDetailsBalanceBlockState.Card(
lastDigits = "3456",
onClick = {},
isReissuing = false,
isEnabled = true,
isFrozen = false,
),
),
@ -477,12 +501,12 @@ internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<T
),
),
isBalanceHidden = false,
addFundsEnabled = true,
addToWalletBlockState = AddToWalletBlockState(
onClick = {},
onClickClose = {},
),
accountDeactivatedNotificationConfig = null,
errorNotificationConfig = null,
),
TangemPayDetailsUM(
topBarConfig = TangemPayDetailsTopBarConfig(
@ -501,15 +525,16 @@ internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<T
onClick = {},
isReissuing = true,
isFrozen = false,
isEnabled = true,
),
),
onAddCardClick = {},
),
),
isBalanceHidden = false,
addFundsEnabled = true,
addToWalletBlockState = null,
accountDeactivatedNotificationConfig = null,
errorNotificationConfig = null,
),
),
)

View file

@ -184,6 +184,14 @@ private fun LazyListScope.payDetailsBody(state: TangemPayDetailsUM) {
}
}
else -> {
if (state.errorNotificationConfig != null) {
item("errorSessionBannerBlock") {
TangemMessage(
config = state.errorNotificationConfig,
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x4),
)
}
}
if (state.addToWalletBlockState != null) {
item("addToWalletBannerBlock") {
TangemPayAddToWalletBlock(
@ -340,6 +348,7 @@ private fun CardsBlock(
isReissuing = item.isReissuing,
lastDigits = item.lastDigits,
onClick = item.onClick,
isEnabled = item.isEnabled,
isFrozen = item.isFrozen,
)
SpacerW(TangemTheme.dimens2.x2)

View file

@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
@ -41,6 +42,7 @@ private const val REISSUING_CARD_BG = 0xFF1E1E1E
@Composable
internal fun TangemPayCardView(
isReissuing: Boolean,
isEnabled: Boolean,
lastDigits: String,
onClick: () -> Unit,
isFrozen: Boolean,
@ -54,6 +56,7 @@ internal fun TangemPayCardView(
)
.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_CARD_BUTTON),
isReissuing = isReissuing,
isEnabled = isEnabled,
onClick = onClick,
) {
Row(
@ -120,6 +123,7 @@ internal fun TangemPayAddCardView(onClick: () -> Unit, modifier: Modifier = Modi
@Composable
private fun CardBackground(
isReissuing: Boolean,
isEnabled: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
content: @Composable BoxScope.() -> Unit,
@ -134,6 +138,7 @@ private fun CardBackground(
Box(
modifier = modifier
.alpha(if (isEnabled) 1f else 0.5f)
.clip(RoundedCornerShape(6.dp))
.drawBehind {
drawRect(bgColor)
@ -163,7 +168,7 @@ private fun CardBackground(
color = TangemTheme.colors3.border.primary,
shape = RoundedCornerShape(6.dp),
)
.clickableSingle(onClick = onClick),
.clickableSingle(onClick = onClick, enabled = isEnabled),
content = content,
)
}
@ -181,6 +186,7 @@ private fun CardBackgroundPreview() {
isReissuing = false,
onClick = {},
content = {},
isEnabled = true,
)
SpacerH(TangemTheme.dimens2.x4)
CardBackground(
@ -191,15 +197,28 @@ private fun CardBackgroundPreview() {
isReissuing = true,
onClick = {},
content = {},
isEnabled = true,
)
SpacerH(TangemTheme.dimens2.x4)
TangemPayCardView(isReissuing = false, onClick = {}, lastDigits = "1234", isFrozen = false)
TangemPayCardView(
isReissuing = false,
onClick = {},
lastDigits = "1234",
isEnabled = true,
isFrozen = false,
)
SpacerH(TangemTheme.dimens2.x4)
TangemPayCardView(isReissuing = true, onClick = {}, lastDigits = "", isFrozen = false)
TangemPayCardView(
isReissuing = true,
onClick = {},
lastDigits = "",
isEnabled = true,
isFrozen = false,
)
SpacerH(TangemTheme.dimens2.x4)
TangemPayAddCardView(onClick = {})
SpacerH(TangemTheme.dimens2.x4)
TangemPayCardView(isReissuing = false, onClick = {}, lastDigits = "1234", isFrozen = true)
TangemPayCardView(isReissuing = false, onClick = {}, lastDigits = "1234", isEnabled = true, isFrozen = true)
}
}
}

View file

@ -5,6 +5,7 @@ import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfi
internal interface TangemPayDetailIntents {
fun onContactSupportClicked()
fun onRefreshSwipe(refreshState: ShowRefreshState)
fun onRenewSession()
fun onClickAddFunds()
fun onClickWithdraw()
fun onClickTermsAndLimits()