From 7883fcc2c663e92ae2fa612d20f88710d7c64347 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 11 Jun 2026 14:54:51 +0200 Subject: [PATCH] Updated on 2026-08-14 --- .../TangemPayAddToWalletComponent.kt | 6 +- .../TangemPayCardPageScreenComponent.kt | 1 + .../TangemPayEditDisplayNameComponent.kt | 1 + .../TangemPayCardDetailsBlockComponent.kt | 1 + .../TangemPayCardDetailsBlockStateFactory.kt | 3 + .../tangempay/entity/TangemPayDetailsUM.kt | 1 + .../model/TangemPayCardDetailsBlockModel.kt | 15 +- .../tangempay/model/TangemPayCardPageModel.kt | 2 +- .../DetailsHiddenStateTransformer.kt | 2 + .../ui/TangemPayAddToWalletScreenV2.kt | 167 +++++++++--------- .../tangempay/ui/TangemPayCardDetailsBlock.kt | 4 +- .../tangempay/ui/TangemPayTxHistoryUiV2.kt | 18 +- 12 files changed, 128 insertions(+), 93 deletions(-) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayAddToWalletComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayAddToWalletComponent.kt index 876e0818cd..2df7c0f605 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayAddToWalletComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayAddToWalletComponent.kt @@ -29,6 +29,7 @@ internal class TangemPayAddToWalletComponent( initialStatus = params.initialStatus, userWalletId = params.initialStatus.userWalletId, isEditingNameEnabled = false, + shouldShowCardDetailsButtonOnCard = true, ), ) @@ -37,7 +38,10 @@ internal class TangemPayAddToWalletComponent( val state by model.uiState.collectAsStateWithLifecycle() BackHandler(onBack = router::pop) if (model.isRedesignEnabled()) { - TangemPayAddToWalletScreenV2(state = state) + TangemPayAddToWalletScreenV2( + state = state, + cardDetailsBlockComponent = cardDetailsBlockComponent, + ) } else { TangemPayAddToWalletScreen( state = state, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageScreenComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageScreenComponent.kt index 8f34c3f102..cac0a0bdd9 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageScreenComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageScreenComponent.kt @@ -41,6 +41,7 @@ internal class TangemPayCardPageScreenComponent( initialStatus = params.initialStatus, userWalletId = params.initialStatus.userWalletId, isEditingNameEnabled = true, + shouldShowCardDetailsButtonOnCard = false, ), ) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayEditDisplayNameComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayEditDisplayNameComponent.kt index 0eaac3c857..a9054040c6 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayEditDisplayNameComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayEditDisplayNameComponent.kt @@ -29,6 +29,7 @@ internal class TangemPayEditDisplayNameComponent( initialStatus = params.initialStatus, userWalletId = params.initialStatus.userWalletId, isEditingNameEnabled = false, + shouldShowCardDetailsButtonOnCard = false, ), ) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/cardDetails/TangemPayCardDetailsBlockComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/cardDetails/TangemPayCardDetailsBlockComponent.kt index 8d556c14b1..849d447921 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/cardDetails/TangemPayCardDetailsBlockComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/cardDetails/TangemPayCardDetailsBlockComponent.kt @@ -19,5 +19,6 @@ internal interface TangemPayCardDetailsBlockComponent { val initialStatus: AccountStatus.Payment, val userWalletId: UserWalletId, val isEditingNameEnabled: Boolean, + val shouldShowCardDetailsButtonOnCard: Boolean, ) } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayCardDetailsBlockStateFactory.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayCardDetailsBlockStateFactory.kt index b517eff87f..39b7c9d84a 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayCardDetailsBlockStateFactory.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayCardDetailsBlockStateFactory.kt @@ -7,6 +7,7 @@ import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.model.CardDataType import com.tangem.utils.StringsSigns +@Suppress("LongParameterList") internal class TangemPayCardDetailsBlockStateFactory( private val cardNumberEnd: String, private val displayName: CardDisplayName?, @@ -14,6 +15,7 @@ internal class TangemPayCardDetailsBlockStateFactory( private val onEditNameClick: () -> Unit, private val onReveal: () -> Unit, private val onCopy: (String, CardDataType) -> Unit, + private val shouldShowCardDetailsButtonOnCard: Boolean, ) { fun getInitialState(): TangemPayCardDetailsUM { @@ -36,6 +38,7 @@ internal class TangemPayCardDetailsBlockStateFactory( } else { null }, + shouldShowCardDetailsButtonOnCard = shouldShowCardDetailsButtonOnCard, ) } } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsUM.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsUM.kt index 668988f260..7a591620f2 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsUM.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsUM.kt @@ -33,6 +33,7 @@ internal data class TangemPayCardDetailsUM( val cardFrozenState: TangemPayCardFrozenState, val displayNameState: DisplayNameState?, val isActionsAvailable: Boolean = false, + val shouldShowCardDetailsButtonOnCard: Boolean = false, ) @Immutable diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardDetailsBlockModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardDetailsBlockModel.kt index 664be22e7a..a1d6822bf7 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardDetailsBlockModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardDetailsBlockModel.kt @@ -72,6 +72,7 @@ internal class TangemPayCardDetailsBlockModel @Inject constructor( onEditNameClick = ::startEditingDisplayName, onReveal = ::requestReveal, onCopy = ::copyData, + shouldShowCardDetailsButtonOnCard = params.shouldShowCardDetailsButtonOnCard, ) val uiState: StateFlow @@ -153,7 +154,12 @@ internal class TangemPayCardDetailsBlockModel @Inject constructor( launchShowDetailsTimer() } .onLeft { - uiState.transformerUpdate(transformer = DetailsHiddenStateTransformer(stateFactory)) + uiState.transformerUpdate( + transformer = DetailsHiddenStateTransformer( + stateFactory = stateFactory, + shouldShowCardDetailsButtonOnCard = params.shouldShowCardDetailsButtonOnCard, + ), + ) showError() } }.saveIn(revealCardDetailsJobHolder) @@ -168,7 +174,12 @@ internal class TangemPayCardDetailsBlockModel @Inject constructor( private fun hideCardDetails() { revealCardDetailsJobHolder.cancel() - uiState.transformerUpdate(transformer = DetailsHiddenStateTransformer(stateFactory)) + uiState.transformerUpdate( + transformer = DetailsHiddenStateTransformer( + stateFactory = stateFactory, + shouldShowCardDetailsButtonOnCard = params.shouldShowCardDetailsButtonOnCard, + ), + ) } private fun showError() { diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt index 31c439172e..1dd7f176d3 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt @@ -196,7 +196,7 @@ internal class TangemPayCardPageModel @Inject constructor( return persistentListOf( TangemPayCardPageSettingV2( id = TangemPayCardPageSettingV2.Id.Details, - title = TextReference.Res(R.string.details_title), + title = TextReference.Res(R.string.tangempay_card_details_title), onClick = ::onClickViewDetails, iconRes = CoreUiR.drawable.ic_visa_card_details_24, ), diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/DetailsHiddenStateTransformer.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/DetailsHiddenStateTransformer.kt index 2bbd791ced..223399b865 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/DetailsHiddenStateTransformer.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/DetailsHiddenStateTransformer.kt @@ -6,6 +6,7 @@ import com.tangem.utils.transformer.Transformer internal class DetailsHiddenStateTransformer( private val stateFactory: TangemPayCardDetailsBlockStateFactory, + private val shouldShowCardDetailsButtonOnCard: Boolean, ) : Transformer { override fun transform(prevState: TangemPayCardDetailsUM): TangemPayCardDetailsUM { @@ -15,6 +16,7 @@ internal class DetailsHiddenStateTransformer( onClick = initialState.onClick, isHidden = initialState.isHidden, isLoading = initialState.isLoading, + shouldShowCardDetailsButtonOnCard = shouldShowCardDetailsButtonOnCard, ) } } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletScreenV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletScreenV2.kt index e0022695ac..16e72c71f8 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletScreenV2.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletScreenV2.kt @@ -1,15 +1,20 @@ package com.tangem.features.tangempay.ui import android.content.res.Configuration -import androidx.compose.foundation.* +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.background import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue 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.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds2.button.TangemButton @@ -21,15 +26,24 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.core.ui.res.generated.icons.Icons import com.tangem.core.ui.res.generated.icons.ic_cross_20 +import com.tangem.domain.models.pay.TangemPayCardFrozenState +import com.tangem.features.tangempay.components.cardDetails.PreviewTangemPayCardDetailsBlockComponent +import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.TangemPayAddToWalletStepItemUM import com.tangem.features.tangempay.entity.TangemPayAddToWalletUM +import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @Composable -internal fun TangemPayAddToWalletScreenV2(state: TangemPayAddToWalletUM, modifier: Modifier = Modifier) { +internal fun TangemPayAddToWalletScreenV2( + state: TangemPayAddToWalletUM, + cardDetailsBlockComponent: TangemPayCardDetailsBlockComponent, + modifier: Modifier = Modifier, +) { val scrollState = rememberScrollState() + val cardDetailsState by cardDetailsBlockComponent.state.collectAsStateWithLifecycle() Column( modifier = modifier @@ -38,13 +52,24 @@ internal fun TangemPayAddToWalletScreenV2(state: TangemPayAddToWalletUM, modifie .systemBarsPadding(), ) { AddToWalletTopBar(onBackClick = state.onBackClick) - AddToWalletContent( - scrollState = scrollState, - steps = state.steps, + + Column( modifier = Modifier .fillMaxWidth() - .weight(1f), - ) + .weight(1f) + .verticalScroll(scrollState) + .padding(top = 8.dp, bottom = 12.dp), + ) { + cardDetailsBlockComponent.CardDetailsBlockContent( + modifier = Modifier + .padding(horizontal = 16.dp) + .padding(bottom = 12.dp), + state = cardDetailsState, + ) + DynamicSpacer(scrollState = scrollState) + AddToWalletTitle() + AddToWalletSteps(steps = state.steps) + } AddToWalletBottomBar(state = state) } } @@ -65,43 +90,17 @@ private fun AddToWalletTopBar(onBackClick: () -> Unit, modifier: Modifier = Modi } @Composable -private fun AddToWalletContent( - scrollState: ScrollState, - steps: ImmutableList, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier - .verticalScroll(scrollState) - .padding(horizontal = TangemTheme.dimens2.x6) - .padding(bottom = TangemTheme.dimens2.x3), - ) { - AddToWalletCardImage() - DynamicSpacer(scrollState = scrollState) - AddToWalletTitle() - AddToWalletSteps(steps = steps) +private fun ColumnScope.DynamicSpacer(scrollState: ScrollState) { + if (!scrollState.canScrollBackward && !scrollState.canScrollForward) { + Spacer(modifier = Modifier.weight(1f)) } } -@Composable -private fun AddToWalletCardImage(modifier: Modifier = Modifier) { - Image( - modifier = modifier - .fillMaxWidth() - .padding( - end = TangemTheme.dimens2.x22, - bottom = TangemTheme.dimens2.x25, - ), - painter = painterResource(R.drawable.img_tangem_pay_visa), - contentDescription = null, - ) -} - @Composable private fun AddToWalletTitle(modifier: Modifier = Modifier) { Text( modifier = modifier - .padding(vertical = TangemTheme.dimens2.x3) + .padding(vertical = 12.dp, horizontal = 16.dp) .fillMaxWidth(), text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_title), style = TangemTheme.typography3.heading.medium, @@ -115,12 +114,10 @@ private fun AddToWalletSteps(steps: ImmutableList StepItem( modifier = Modifier.padding( - top = if (idx == 0) TangemTheme.dimens2.x3 else TangemTheme.dimens2.x0, - bottom = if (idx < steps.lastIndex) { - TangemTheme.dimens2.x4 - } else { - TangemTheme.dimens2.x3 - }, + top = if (idx == 0) 12.dp else 0.dp, + bottom = if (idx < steps.lastIndex) 16.dp else 12.dp, + start = 16.dp, + end = 16.dp, ), stepNumber = step.count, title = step.text, @@ -129,51 +126,16 @@ private fun AddToWalletSteps(steps: ImmutableList }, + onClick = {}, + buttonText = TextReference.Res(R.string.tangempay_card_details_hide_text), + cardFrozenState = TangemPayCardFrozenState.Unfrozen, + displayNameState = null, + ), + ), ) } } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardDetailsBlock.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardDetailsBlock.kt index 4b87b1f576..2b9da3d7d1 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardDetailsBlock.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardDetailsBlock.kt @@ -186,7 +186,9 @@ private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modif bottom.linkTo(parent.bottom) } .testTag(TangemPayTestTags.CARD_DETAILS_SHOW_BUTTON), - visible = !LocalVisaRedesignEnabled.current || state.isLoading, + visible = !LocalVisaRedesignEnabled.current || + state.isLoading || + state.shouldShowCardDetailsButtonOnCard, ) { TangemPayCardDetailsCustomButton( text = stringResourceSafe(id = R.string.tangempay_card_details_show_details), diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUiV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUiV2.kt index 0d0f482d92..ba14336023 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUiV2.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUiV2.kt @@ -170,12 +170,18 @@ private fun GroupTitleBlock( modifier: Modifier = Modifier, ) { if (state.isLoading) { - TextShimmer( - modifier = modifier.width(TangemTheme.dimens2.x10), - text = state.title, - style = TextShimmerStyle.SUBHEADING, - radius = TangemTheme.dimens2.x25, - ) + Row( + modifier = modifier + .fillMaxWidth() + .padding(top = 6.dp, start = 16.dp), + ) { + TextShimmer( + modifier = Modifier.width(TangemTheme.dimens2.x10), + text = state.title, + style = TextShimmerStyle.SUBHEADING, + radius = TangemTheme.dimens2.x25, + ) + } } else { Text( modifier = modifier