From b4d11538ea6998bdd0ddd69b37573158c9c0bc4a Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 17 Jul 2026 09:57:59 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../tangempay/TangemPayFeatureToggles.kt | 1 - .../DefaultTangemPayFeatureToggles.kt | 3 - .../components/TangemPayAddFundsComponent.kt | 7 +- .../TangemPayAddToWalletComponent.kt | 20 +- .../components/TangemPayCardPageComponent.kt | 4 - .../TangemPayCardPageScreenComponent.kt | 22 +- .../components/TangemPayChangePinComponent.kt | 16 +- .../TangemPayChangePinSuccessComponent.kt | 8 +- .../components/TangemPayDetailsComponent.kt | 32 +- .../TangemPayEditDisplayNameComponent.kt | 17 +- .../TangemPayReissueCardComponent.kt | 7 +- .../components/TangemPayViewPinComponent.kt | 7 +- .../DefaultTangemPayTxHistoryComponent.kt | 7 +- .../PreviewTangemPayTxHistoryComponent.kt | 4 +- .../TangemPayTxHistoryDetailsComponent.kt | 14 +- .../tangempay/entity/TangemPayCardPageUM.kt | 14 - .../TangemPayDetailsNotificationFactory.kt | 17 +- .../entity/TangemPayDetailsStateFactory.kt | 10 +- .../entity/TangemPayTxHistoryDetailsUM.kt | 48 +- .../setup/TangemPayCardLimitSetupComponent.kt | 15 +- .../setup/TangemPayCardLimitSetupModel.kt | 4 - .../setup/TangemPayCardLimitSetupScreen.kt | 185 ------ ...TangemPayCardLimitSetupSuccessComponent.kt | 16 +- .../TangemPayCardLimitSetupSuccessScreen.kt | 102 --- .../tangempay/model/TangemPayAddFundsModel.kt | 5 - .../model/TangemPayAddToWalletModel.kt | 4 - .../tangempay/model/TangemPayCardPageModel.kt | 44 +- .../model/TangemPayChangePinModel.kt | 8 +- .../tangempay/model/TangemPayDetailsModel.kt | 3 - .../model/TangemPayEditDisplayNameModel.kt | 4 - .../model/TangemPayReissueCardModel.kt | 4 - .../model/TangemPayTxHistoryDetailsModel.kt | 41 +- .../model/TangemPayTxHistoryModel.kt | 4 - .../tangempay/model/TangemPayViewPinModel.kt | 4 - .../TangemPayAddFundsUMConverter.kt | 43 +- .../TangemPayTxHistoryDetailsConverter.kt | 313 ---------- .../tangempay/ui/TangemPayAddFundsContent.kt | 162 ----- .../tangempay/ui/TangemPayAddToWalletBlock.kt | 101 --- .../ui/TangemPayAddToWalletScreen.kt | 193 ------ .../tangempay/ui/TangemPayCardDetailsBlock.kt | 264 +++----- .../tangempay/ui/TangemPayCardPageScreen.kt | 188 +----- .../ui/TangemPayChangePinCodeSuccessScreen.kt | 134 ---- .../tangempay/ui/TangemPayChangePinScreen.kt | 192 ------ .../tangempay/ui/TangemPayDailyLimitBlock.kt | 125 +--- .../ui/TangemPayDetailsPreviewProviders.kt | 140 +++++ .../tangempay/ui/TangemPayDetailsScreen.kt | 587 ------------------ .../ui/TangemPayEditDisplayNameScreen.kt | 80 --- .../ui/TangemPayReissueCardContent.kt | 218 ------- .../ui/TangemPayReplacingCardBlock.kt | 66 -- .../tangempay/ui/TangemPayTxHistoryUi.kt | 408 ------------ .../tangempay/ui/TangemPayViewPinContent.kt | 204 ------ .../tangempay/ui/TangempayTxDetailsUi.kt | 307 --------- .../utils/TangemPayMessagesFactory.kt | 50 +- .../TangemPayDetailsStateFactoryTest.kt | 1 - .../setup/TangemPayCardLimitSetupModelTest.kt | 3 - .../TangemPayEditDisplayNameModelTest.kt | 3 - .../TangemPayTxHistoryDetailsModelTest.kt | 14 +- 57 files changed, 361 insertions(+), 4136 deletions(-) delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupScreen.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupSuccessScreen.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverter.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddFundsContent.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletScreen.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayChangePinCodeSuccessScreen.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayChangePinScreen.kt create mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsPreviewProviders.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreen.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReissueCardContent.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReplacingCardBlock.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUi.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayViewPinContent.kt delete mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt diff --git a/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt b/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt index 5185c7092e..652aea71f0 100644 --- a/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt +++ b/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt @@ -1,7 +1,6 @@ package com.tangem.features.tangempay interface TangemPayFeatureToggles { - val isRedesignEnabled: Boolean val isRemoveAccountEnabled: Boolean val isTiersPlusPlanEnabled: Boolean val isCashbackEnabled: Boolean diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt index 2e74ccc4d7..b439254f59 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt @@ -6,9 +6,6 @@ import com.tangem.core.configtoggle.feature.FeatureTogglesManager internal class DefaultTangemPayFeatureToggles( private val featureTogglesManager: FeatureTogglesManager, ) : TangemPayFeatureToggles { - override val isRedesignEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.APP_REDESIGN_ENABLED) - override val isRemoveAccountEnabled: Boolean get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15741_VISA_PAY_REMOVE_ACCOUNT) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayAddFundsComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayAddFundsComponent.kt index 3e672b76d3..9d77b5772d 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayAddFundsComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayAddFundsComponent.kt @@ -9,7 +9,6 @@ import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.model.TangemPayTopUpData import com.tangem.features.tangempay.model.TangemPayAddFundsModel -import com.tangem.features.tangempay.ui.TangemPayAddFundsContent import com.tangem.features.tangempay.ui.TangemPayAddFundsContentV2 import java.math.BigDecimal @@ -26,11 +25,7 @@ internal class TangemPayAddFundsComponent( @Composable override fun BottomSheet() { - if (model.isRedesignEnabled()) { - TangemPayAddFundsContentV2(state = model.uiState) - } else { - TangemPayAddFundsContent(state = model.uiState) - } + TangemPayAddFundsContentV2(state = model.uiState) } data class Params( 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 a42a21d234..9b582f5134 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 @@ -2,18 +2,15 @@ package com.tangem.features.tangempay.components import androidx.activity.compose.BackHandler import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.decompose.ComposableContentComponent -import com.tangem.core.ui.res.LocalVisaRedesignEnabled import com.tangem.domain.models.pay.TangemPayCard import com.tangem.domain.models.wallet.UserWalletId import com.tangem.features.tangempay.model.TangemPayAddToWalletModel -import com.tangem.features.tangempay.ui.TangemPayAddToWalletScreen import com.tangem.features.tangempay.ui.TangemPayAddToWalletScreenV2 internal class TangemPayAddToWalletComponent( @@ -28,19 +25,10 @@ internal class TangemPayAddToWalletComponent( val state by model.uiState.collectAsStateWithLifecycle() val cardDetailsState by model.cardDetailsState.collectAsStateWithLifecycle() BackHandler(onBack = router::pop) - CompositionLocalProvider(LocalVisaRedesignEnabled provides model.isRedesignEnabled()) { - if (model.isRedesignEnabled()) { - TangemPayAddToWalletScreenV2( - state = state, - cardDetailsState = cardDetailsState, - ) - } else { - TangemPayAddToWalletScreen( - state = state, - cardDetailsState = cardDetailsState, - ) - } - } + TangemPayAddToWalletScreenV2( + state = state, + cardDetailsState = cardDetailsState, + ) } data class Params(val card: TangemPayCard, val userWalletId: UserWalletId) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageComponent.kt index 14d96d6643..2d47b1b046 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageComponent.kt @@ -17,7 +17,6 @@ import com.tangem.core.decompose.factory.ComponentFactory import com.tangem.core.decompose.navigation.inner.InnerRouter import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.domain.models.account.AccountStatus -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.limit.setup.TangemPayCardLimitSetupComponent import com.tangem.features.tangempay.limit.setup.TangemPayCardLimitSetupSuccessComponent import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute @@ -33,7 +32,6 @@ internal class TangemPayCardPageComponent @AssistedInject constructor( @Assisted private val params: Params, private val tokenReceiveComponentFactory: TokenReceiveComponent.Factory, private val virtualAccountAddFundsComponentFactory: VirtualAccountAddFundsBottomSheetComponent.Factory, - private val tangemPayFeatureToggles: TangemPayFeatureToggles, ) : ComposableContentComponent, AppComponentContext by appComponentContext { private val stackNavigation = StackNavigation() @@ -85,7 +83,6 @@ internal class TangemPayCardPageComponent @AssistedInject constructor( componentContext = componentContext, router = innerRouter, ), - isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled, ) is TangemPayCardDetailsInnerRoute.AddToWallet -> TangemPayAddToWalletComponent( appComponentContext = childByContext(componentContext = componentContext, router = innerRouter), @@ -110,7 +107,6 @@ internal class TangemPayCardPageComponent @AssistedInject constructor( ) TangemPayCardDetailsInnerRoute.LimitSetupSuccess -> TangemPayCardLimitSetupSuccessComponent( appComponentContext = childByContext(componentContext = componentContext, router = innerRouter), - isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled, ) TangemPayCardDetailsInnerRoute.VirtualAccountDepositSuccess -> TangemPayVirtualAccountDepositSuccessComponent( 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 a6ec072508..622193bd28 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 @@ -1,7 +1,6 @@ package com.tangem.features.tangempay.components import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -15,7 +14,6 @@ import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.components.NavigationBar3ButtonsScrim import com.tangem.core.ui.decompose.ComposableBottomSheetComponent import com.tangem.core.ui.decompose.ComposableContentComponent -import com.tangem.core.ui.res.LocalVisaRedesignEnabled import com.tangem.features.tangempay.closure.TangemPayCloseCardComponent import com.tangem.features.tangempay.entity.TangemPayCardNavigation import com.tangem.features.tangempay.model.TangemPayCardPageModel @@ -50,17 +48,15 @@ internal class TangemPayCardPageScreenComponent( val selectedCardId by model.selectedCardIdState.collectAsStateWithLifecycle() val bottomSheet by bottomSheetSlot.subscribeAsState() - CompositionLocalProvider(LocalVisaRedesignEnabled provides model.isRedesignEnabled()) { - NavigationBar3ButtonsScrim() - TangemPayCardPageScreen( - state = state, - cardControllers = cardControllers, - selectedCardId = selectedCardId, - onCardSelect = model::onCardPageSelected, - modifier = modifier, - ) - bottomSheet.child?.instance?.BottomSheet() - } + NavigationBar3ButtonsScrim() + TangemPayCardPageScreen( + state = state, + cardControllers = cardControllers, + selectedCardId = selectedCardId, + onCardSelect = model::onCardPageSelected, + modifier = modifier, + ) + bottomSheet.child?.instance?.BottomSheet() } @Suppress("LongMethod") diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinComponent.kt index ee61b7cf9f..c7b166c81f 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinComponent.kt @@ -12,7 +12,6 @@ import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect import com.tangem.domain.models.pay.TangemPayCard import com.tangem.domain.models.wallet.UserWalletId import com.tangem.features.tangempay.model.TangemPayChangePinModel -import com.tangem.features.tangempay.ui.TangemPayChangePinScreen import com.tangem.features.tangempay.ui.TangemPayChangePinScreenV2 internal class TangemPayChangePinComponent( @@ -27,17 +26,10 @@ internal class TangemPayChangePinComponent( val state by model.uiState.collectAsStateWithLifecycle() BackHandler(onBack = router::pop) DisableScreenshotsDisposableEffect() - if (model.isRedesignEnabled()) { - TangemPayChangePinScreenV2( - state = state, - onBackClick = router::pop, - ) - } else { - TangemPayChangePinScreen( - state = state, - onBackClick = router::pop, - ) - } + TangemPayChangePinScreenV2( + state = state, + onBackClick = router::pop, + ) } data class Params(val card: TangemPayCard, val userWalletId: UserWalletId) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinSuccessComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinSuccessComponent.kt index 292202be67..c1e4d5835e 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinSuccessComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinSuccessComponent.kt @@ -6,22 +6,16 @@ import androidx.compose.ui.Modifier import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute -import com.tangem.features.tangempay.ui.TangemPayChangePinCodeSuccessScreen import com.tangem.features.tangempay.ui.TangemPayChangePinCodeSuccessScreenV2 internal class TangemPayChangePinSuccessComponent( private val appComponentContext: AppComponentContext, - private val isRedesignEnabled: Boolean, ) : AppComponentContext by appComponentContext, ComposableContentComponent { @Composable override fun Content(modifier: Modifier) { BackHandler(onBack = ::backToDetails) - if (isRedesignEnabled) { - TangemPayChangePinCodeSuccessScreenV2(onClose = ::backToDetails) - } else { - TangemPayChangePinCodeSuccessScreen(onClick = ::backToDetails) - } + TangemPayChangePinCodeSuccessScreenV2(onClose = ::backToDetails) } private fun backToDetails() { diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayDetailsComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayDetailsComponent.kt index 0107ab0e21..2fc1148589 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayDetailsComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayDetailsComponent.kt @@ -1,7 +1,6 @@ package com.tangem.features.tangempay.components import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -18,13 +17,11 @@ import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.components.NavigationBar3ButtonsScrim import com.tangem.core.ui.decompose.ComposableBottomSheetComponent import com.tangem.core.ui.decompose.ComposableContentComponent -import com.tangem.core.ui.res.LocalVisaRedesignEnabled import com.tangem.features.promobanners.api.PromoBannersBlockComponent import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryDetailsComponent import com.tangem.features.tangempay.entity.TangemPayDetailsNavigation import com.tangem.features.tangempay.model.TangemPayDetailsModel -import com.tangem.features.tangempay.ui.TangemPayDetailsScreen import com.tangem.features.tangempay.ui.TangemPayDetailsScreenV2 import com.tangem.features.tangempay.utils.VA_DAILY_DEPOSIT_LIMIT_PLACEHOLDER import com.tangem.features.tangempay.utils.requireLoaded @@ -98,26 +95,15 @@ internal class TangemPayDetailsComponent( horizontalItemPadding = 16.dp, ) } - CompositionLocalProvider(LocalVisaRedesignEnabled provides model.isRedesignEnabled()) { - NavigationBar3ButtonsScrim() - if (LocalVisaRedesignEnabled.current) { - TangemPayDetailsScreenV2( - state = state, - txHistoryComponent = txHistoryComponent, - expressTransactionsComponent = expressTransactionsComponent, - promoBannersBlockComponent = promoBannersBlock, - modifier = modifier, - ) - } else { - TangemPayDetailsScreen( - state = state, - txHistoryComponent = txHistoryComponent, - expressTransactionsComponent = expressTransactionsComponent, - modifier = modifier, - ) - } - bottomSheet.child?.instance?.BottomSheet() - } + NavigationBar3ButtonsScrim() + TangemPayDetailsScreenV2( + state = state, + txHistoryComponent = txHistoryComponent, + expressTransactionsComponent = expressTransactionsComponent, + promoBannersBlockComponent = promoBannersBlock, + modifier = modifier, + ) + bottomSheet.child?.instance?.BottomSheet() } @Suppress("LongMethod") 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 82c5fb511b..1062fe6ab5 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 @@ -2,19 +2,17 @@ package com.tangem.features.tangempay.components import androidx.activity.compose.BackHandler import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.decompose.ComposableContentComponent -import com.tangem.core.ui.res.LocalVisaRedesignEnabled import com.tangem.domain.models.pay.TangemPayCard import com.tangem.domain.models.wallet.UserWalletId import com.tangem.features.tangempay.entity.DisplayNameState import com.tangem.features.tangempay.model.TangemPayEditDisplayNameModel -import com.tangem.features.tangempay.ui.TangemPayEditDisplayNameScreen +import com.tangem.features.tangempay.ui.TangemPayEditDisplayNameScreenV2 internal class TangemPayEditDisplayNameComponent( private val appComponentContext: AppComponentContext, @@ -38,14 +36,11 @@ internal class TangemPayEditDisplayNameComponent( ), ) BackHandler(onBack = state.onDismiss) - CompositionLocalProvider(LocalVisaRedesignEnabled provides model.isRedesignEnabled()) { - TangemPayEditDisplayNameScreen( - state = state, - cardDetailsState = editingCardDetailsState, - modifier = modifier, - isRedesignEnabled = model.isRedesignEnabled(), - ) - } + TangemPayEditDisplayNameScreenV2( + state = state, + cardDetailsState = editingCardDetailsState, + modifier = modifier, + ) } data class Params(val card: TangemPayCard, val userWalletId: UserWalletId) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayReissueCardComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayReissueCardComponent.kt index b03bd6c3ec..e15fb7ab28 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayReissueCardComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayReissueCardComponent.kt @@ -8,7 +8,6 @@ import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.decompose.ComposableBottomSheetComponent import com.tangem.domain.models.wallet.UserWalletId import com.tangem.features.tangempay.model.TangemPayReissueCardModel -import com.tangem.features.tangempay.ui.TangemPayReissueCardContent import com.tangem.features.tangempay.ui.TangemPayReissueCardContentV2 internal class TangemPayReissueCardComponent( @@ -23,11 +22,7 @@ internal class TangemPayReissueCardComponent( @Composable override fun BottomSheet() { val state by model.state.collectAsStateWithLifecycle() - if (model.isRedesignEnabled()) { - TangemPayReissueCardContentV2(state) - } else { - TangemPayReissueCardContent(state) - } + TangemPayReissueCardContentV2(state) } data class Params( diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayViewPinComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayViewPinComponent.kt index 48f67173fe..86e92eb887 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayViewPinComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayViewPinComponent.kt @@ -10,7 +10,6 @@ import com.tangem.core.ui.decompose.ComposableBottomSheetComponent import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect import com.tangem.domain.models.wallet.UserWalletId import com.tangem.features.tangempay.model.TangemPayViewPinModel -import com.tangem.features.tangempay.ui.TangemPayViewPinContent import com.tangem.features.tangempay.ui.TangemPayViewPinContentV2 internal class TangemPayViewPinComponent( @@ -29,11 +28,7 @@ internal class TangemPayViewPinComponent( val state by model.uiState.collectAsStateWithLifecycle() BackHandler(onBack = ::dismiss) DisableScreenshotsDisposableEffect() - if (model.isRedesignEnabled()) { - TangemPayViewPinContentV2(state = state) - } else { - TangemPayViewPinContent(state = state) - } + TangemPayViewPinContentV2(state = state) } data class Params( diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/DefaultTangemPayTxHistoryComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/DefaultTangemPayTxHistoryComponent.kt index dfe30677d0..d297e7c02e 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/DefaultTangemPayTxHistoryComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/DefaultTangemPayTxHistoryComponent.kt @@ -7,7 +7,6 @@ import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.domain.models.wallet.UserWalletId import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM import com.tangem.features.tangempay.model.TangemPayTxHistoryModel -import com.tangem.features.tangempay.ui.tangemPayTxHistoryItems import com.tangem.features.tangempay.ui.tangemPayTxHistoryItemsV2 import com.tangem.features.tangempay.utils.TangemPayTxHistoryUiActions import kotlinx.coroutines.flow.StateFlow @@ -21,11 +20,7 @@ internal class DefaultTangemPayTxHistoryComponent( override val state: StateFlow = model.uiState override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TangemPayTxHistoryUM) { - if (model.isRedesignEnabled()) { - tangemPayTxHistoryItemsV2(listState, state) - } else { - tangemPayTxHistoryItems(listState, state) - } + tangemPayTxHistoryItemsV2(listState, state) } data class Params( diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/PreviewTangemPayTxHistoryComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/PreviewTangemPayTxHistoryComponent.kt index a35f99e1fc..2d7982c912 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/PreviewTangemPayTxHistoryComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/PreviewTangemPayTxHistoryComponent.kt @@ -10,7 +10,7 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.TangemPayTransactionState import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM -import com.tangem.features.tangempay.ui.tangemPayTxHistoryItems +import com.tangem.features.tangempay.ui.tangemPayTxHistoryItemsV2 import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -19,7 +19,7 @@ internal class PreviewTangemPayTxHistoryComponent(txHistoryUM: TangemPayTxHistor override val state: StateFlow = MutableStateFlow(txHistoryUM) override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TangemPayTxHistoryUM) { - tangemPayTxHistoryItems(listState = listState, state = state) + tangemPayTxHistoryItemsV2(listState = listState, state = state) } companion object { diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryDetailsComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryDetailsComponent.kt index 5b6e5d8793..be256f86a3 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryDetailsComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryDetailsComponent.kt @@ -5,11 +5,8 @@ import androidx.compose.runtime.getValue import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel -import com.tangem.core.ui.res.LocalVisaRedesignEnabled import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent -import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUiState import com.tangem.features.tangempay.model.TangemPayTxHistoryDetailsModel -import com.tangem.features.tangempay.ui.TangemPayTxHistoryDetailsContent import com.tangem.features.tangempay.ui.TangemPayTxHistoryDetailsContentV2 import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -28,15 +25,8 @@ internal class TangemPayTxHistoryDetailsComponent @AssistedInject constructor( @Composable override fun BottomSheet() { - val states by model.uiState.collectAsStateWithLifecycle() - when (val uiState = states.toUiState(isRedesignEnabled = LocalVisaRedesignEnabled.current)) { - is TangemPayTxHistoryDetailsUiState.Legacy -> { - TangemPayTxHistoryDetailsContent(state = uiState.state) - } - is TangemPayTxHistoryDetailsUiState.Redesign -> { - TangemPayTxHistoryDetailsContentV2(state = uiState.state) - } - } + val state by model.uiState.collectAsStateWithLifecycle() + TangemPayTxHistoryDetailsContentV2(state = state) } @AssistedFactory diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayCardPageUM.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayCardPageUM.kt index 7b9757365a..88ec386956 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayCardPageUM.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayCardPageUM.kt @@ -12,7 +12,6 @@ import com.tangem.core.ui.R as CoreUiR @Immutable internal data class TangemPayCardPageUM( - val settings: ImmutableList, val settingsV2: ImmutableList, val onBackClick: () -> Unit, val dailyLimitState: TangemPayDailyLimitBlockState, @@ -26,17 +25,11 @@ internal data class TangemPayCardPageUM( onClick = {}, onClickClose = {}, ), - settings: ImmutableList = persistentListOf( - TangemPayCardPageSetting(TextReference.Str("Pin Code")) {}, - TangemPayCardPageSetting(TextReference.Str("Freeze Card")) {}, - TangemPayCardPageSetting(TextReference.Str("Reissue Card")) {}, - ), cardState: TangemPayCardState = TangemPayCardState.Active, dailyLimitState: TangemPayDailyLimitBlockState = TangemPayDailyLimitBlockState.Content.stub(), settingsV2: ImmutableList = TangemPayCardPageSettingV2.stubList(), ) = TangemPayCardPageUM( addToWalletBlockState = addToWalletBlockState, - settings = settings, settingsV2 = settingsV2, onBackClick = {}, cardState = cardState, @@ -46,13 +39,6 @@ internal data class TangemPayCardPageUM( } } -@Immutable -internal data class TangemPayCardPageSetting( - val title: TextReference, - val testTag: String? = null, - val onSettingClick: () -> Unit, -) - @Immutable internal data class TangemPayCardPageSettingV2( val id: Id, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsNotificationFactory.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsNotificationFactory.kt index 505b9d6252..f7c119df82 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsNotificationFactory.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsNotificationFactory.kt @@ -15,18 +15,17 @@ internal class TangemPayDetailsNotificationFactory( private val intents: TangemPayDetailIntents, private val isRemoveAccountEnabled: Boolean, private val isTiersPlusPlanEnabled: Boolean, - private val isRedesignEnabled: Boolean, ) { fun createErrorConfig(error: PaymentAccountStatusValue.Error?): NotificationConfig? = when (error) { null -> null - PaymentAccountStatusValue.Error.NotSynced -> createRenewSessionNotificationConfig(isRedesignEnabled) - else -> createAccountUnavailableConfig(isRedesignEnabled) + PaymentAccountStatusValue.Error.NotSynced -> createRenewSessionNotificationConfig() + else -> createAccountUnavailableConfig() } - fun createAccountDeactivatedConfig(isRedesignEnabled: Boolean) = NotificationConfig( + fun createAccountDeactivatedConfig() = NotificationConfig( title = resourceReference(R.string.tangempay_account_deactivated_message_title), subtitle = resourceReference(R.string.tangempay_account_deactivated_message_subtitle), - iconResId = if (isRedesignEnabled) R.drawable.ic_alert_circle_24 else R.drawable.img_attention_20, + iconResId = R.drawable.ic_alert_circle_24, buttonsState = if (isRemoveAccountEnabled) { NotificationConfig.ButtonsState.SecondaryButtonConfig( text = resourceReference(R.string.tangempay_remove_account), @@ -65,10 +64,10 @@ internal class TangemPayDetailsNotificationFactory( ) } - private fun createRenewSessionNotificationConfig(isRedesignEnabled: Boolean) = NotificationConfig( + private fun createRenewSessionNotificationConfig() = NotificationConfig( title = resourceReference(R.string.tangempay_sync_needed_title), subtitle = resourceReference(R.string.tangempay_sync_needed_body), - iconResId = if (isRedesignEnabled) 0 else R.drawable.img_attention_20, + iconResId = 0, buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( text = resourceReference(R.string.tangempay_sync_needed_button), onClick = intents::onRenewSession, @@ -76,10 +75,10 @@ internal class TangemPayDetailsNotificationFactory( ), ) - private fun createAccountUnavailableConfig(isRedesignEnabled: Boolean) = NotificationConfig( + private fun createAccountUnavailableConfig() = NotificationConfig( title = resourceReference(R.string.tangempay_temporarily_unavailable), subtitle = resourceReference(R.string.tangempay_service_unreachable_try_later), - iconResId = if (isRedesignEnabled) R.drawable.ic_alert_circle_24 else R.drawable.img_attention_20, + iconResId = R.drawable.ic_alert_circle_24, ) private fun createTariffSystemDownGradePendingConfig(tariffPlan: TangemPayTariffPlanState): NotificationConfig? { diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt index cace3cf205..538a7e2e5b 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactory.kt @@ -33,7 +33,6 @@ internal class TangemPayDetailsStateFactory( private val onBack: () -> Unit, private val onOpenMenu: () -> Unit, private val intents: TangemPayDetailIntents, - private val isRedesignEnabled: Boolean, private val isRemoveAccountEnabled: Boolean, private val isTiersPlusPlanEnabled: Boolean, ) { @@ -41,7 +40,6 @@ internal class TangemPayDetailsStateFactory( intents = intents, isRemoveAccountEnabled = isRemoveAccountEnabled, isTiersPlusPlanEnabled = isTiersPlusPlanEnabled, - isRedesignEnabled = isRedesignEnabled, ) fun getLoadingState(): TangemPayDetailsUM { @@ -130,7 +128,7 @@ internal class TangemPayDetailsStateFactory( } fun getDeactivatedState(hasWithdrawableBalance: Boolean): TangemPayDetailsUM { - val accountDeactivatedNotification = notificationFactory.createAccountDeactivatedConfig(isRedesignEnabled) + val accountDeactivatedNotification = notificationFactory.createAccountDeactivatedConfig() return TangemPayDetailsUM( topBarConfig = TangemPayDetailsTopBarConfig( onBackClick = onBack, @@ -327,11 +325,7 @@ internal class TangemPayDetailsStateFactory( action = TangemPayAction.AddFunds, config = ActionButtonConfig( text = resourceReference(id = R.string.tangempay_card_details_add_funds), - iconResId = if (isRedesignEnabled) { - R.drawable.ic_arrow_down_24 - } else { - R.drawable.ic_plus_24 - }, + iconResId = R.drawable.ic_arrow_down_24, onClick = intents::onClickAddFunds, isEnabled = isAddFundsEnabled, ), diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryDetailsUM.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryDetailsUM.kt index 3cddd9cadb..09d6962d0e 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryDetailsUM.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryDetailsUM.kt @@ -1,36 +1,9 @@ package com.tangem.features.tangempay.entity import androidx.compose.runtime.Immutable -import com.tangem.core.ui.components.label.entity.LabelUM -import com.tangem.core.ui.components.notifications.NotificationConfig import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.extensions.ColorReference import com.tangem.core.ui.extensions.ImageReference import com.tangem.core.ui.extensions.TextReference -import kotlinx.collections.immutable.ImmutableList - -internal data class TangemPayTxHistoryDetailsUM( - val isBalanceHidden: Boolean, - val title: TextReference, - val iconState: ImageReference, - val transactionTitle: TextReference, - val transactionSubtitle: TextReference, - val transactionAmount: String, - val transactionAmountColor: ColorReference, - val localTransactionText: String?, - val labelState: LabelUM?, - val notification: NotificationState?, - val buttons: ImmutableList, - val dismiss: () -> Unit, -) { - - data class NotificationState( - val config: NotificationConfig, - val titleColor: ColorReference, - val iconTint: ColorReference, - val containerColor: ColorReference?, - ) -} internal data class ButtonState( val text: TextReference, @@ -78,23 +51,4 @@ internal sealed interface TransactionDetailUM { data class Error(val onRefreshClick: () -> Unit) : TransactionDetailUM } -internal enum class TransactionLoadState { Loading, Loaded, Error } - -@Immutable -internal sealed interface TangemPayTxHistoryDetailsUiState { - data class Legacy(val state: TangemPayTxHistoryDetailsUM) : TangemPayTxHistoryDetailsUiState - data class Redesign(val state: TangemPayTxHistoryDetailsUMV2) : TangemPayTxHistoryDetailsUiState -} - -internal data class TangemPayTxHistoryDetailsUiStates( - val legacy: TangemPayTxHistoryDetailsUM, - val redesign: TangemPayTxHistoryDetailsUMV2, -) { - fun toUiState(isRedesignEnabled: Boolean): TangemPayTxHistoryDetailsUiState { - return if (isRedesignEnabled) { - TangemPayTxHistoryDetailsUiState.Redesign(redesign) - } else { - TangemPayTxHistoryDetailsUiState.Legacy(legacy) - } - } -} \ No newline at end of file +internal enum class TransactionLoadState { Loading, Loaded, Error } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupComponent.kt index 8a01b75c2d..61e7096558 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupComponent.kt @@ -22,17 +22,10 @@ internal class TangemPayCardLimitSetupComponent( override fun Content(modifier: Modifier) { val state by model.uiState.collectAsStateWithLifecycle() BackHandler(onBack = router::pop) - if (model.inRedesignEnabled()) { - TangemPayCardLimitSetupScreenV2( - state = state, - modifier = modifier, - ) - } else { - TangemPayCardLimitSetupScreen( - state = state, - modifier = modifier, - ) - } + TangemPayCardLimitSetupScreenV2( + state = state, + modifier = modifier, + ) } data class Params(val card: TangemPayCard, val userWalletId: UserWalletId) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupModel.kt index 17cc2aae2d..e0bcaab84f 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupModel.kt @@ -23,7 +23,6 @@ import com.tangem.domain.models.pay.TangemPayCardLimitPeriod import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase import com.tangem.domain.tangempay.TangemPayAnalyticsEvents -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute import com.tangem.utils.coroutines.CoroutineDispatcherProvider @@ -46,7 +45,6 @@ internal class TangemPayCardLimitSetupModel @Inject constructor( private val setTangemPayCardLimitUseCase: SetTangemPayCardLimitUseCase, private val uiMessageSender: UiMessageSender, private val analytics: AnalyticsEventHandler, - private val featureToggles: TangemPayFeatureToggles, ) : Model() { private val params: TangemPayCardLimitSetupComponent.Params = paramsContainer.require() @@ -78,8 +76,6 @@ internal class TangemPayCardLimitSetupModel @Inject constructor( observeCardState() } - fun inRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled - private fun observeCardState() { paymentAccountStatusSupplier.invoke(userWalletId) .map { it.value } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupScreen.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupScreen.kt deleted file mode 100644 index c152e6c947..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupScreen.kt +++ /dev/null @@ -1,185 +0,0 @@ -package com.tangem.features.tangempay.limit.setup - -import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.PrimaryButton -import com.tangem.core.ui.components.SpacerH12 -import com.tangem.core.ui.components.TextShimmer -import com.tangem.core.ui.components.appbar.TangemTopAppBar -import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM -import com.tangem.core.ui.components.fields.AmountTextField -import com.tangem.core.ui.components.fields.TangemAmountTextFieldColors -import com.tangem.core.ui.components.fields.visualtransformations.AmountVisualTransformation -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.utils.rememberDecimalFormat -import com.tangem.features.tangempay.details.impl.R -import kotlinx.collections.immutable.ImmutableList - -@Composable -internal fun TangemPayCardLimitSetupScreen(state: TangemPayCardLimitSetupUM, modifier: Modifier = Modifier) { - Scaffold( - modifier = modifier, - topBar = { - TangemTopAppBar( - modifier = Modifier.statusBarsPadding(), - title = stringResourceSafe(R.string.tangempay_card_page_daily_limit_title), - startButton = TopAppBarButtonUM.Close(onCloseClick = state.onBackClick), - ) - }, - containerColor = TangemTheme.colors.background.secondary, - ) { scaffoldPaddings -> - Content( - state = state, - modifier = Modifier.padding(scaffoldPaddings), - ) - } -} - -@Composable -private fun Content(state: TangemPayCardLimitSetupUM, modifier: Modifier = Modifier) { - Column( - modifier = modifier - .fillMaxSize() - .imePadding(), - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - AmountBlock( - modifier = Modifier.padding(horizontal = 16.dp), - state = state, - ) - Spacer(modifier = Modifier.weight(1f)) - PrimaryButton( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), - text = stringResourceSafe(R.string.tangempay_daily_limit_set_button), - enabled = state.isSubmitButtonEnabled, - showProgress = state.isSubmitButtonLoading, - onClick = state.onSubmitClick, - ) - PresetsRow(presets = state.presets) - } -} - -@Composable -private fun AmountBlock(state: TangemPayCardLimitSetupUM, modifier: Modifier = Modifier) { - Column( - modifier = modifier - .fillMaxWidth() - .clip(RoundedCornerShape(14.dp)) - .background(TangemTheme.colors.background.action) - .padding(vertical = 48.dp, horizontal = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - text = stringResourceSafe(R.string.common_amount), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - ) - SpacerH12() - if (state.isInitialDataLoading) { - TextShimmer( - style = TangemTheme.typography.head, - text = "$5000", - ) - } else { - val colors = TangemAmountTextFieldColors - AmountTextField( - value = state.amountFieldModel.value, - decimals = state.amountFieldModel.decimals, - onValueChange = state.amountFieldModel.onValueChange, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), - colors = colors, - visualTransformation = AmountVisualTransformation( - decimals = state.amountFieldModel.decimals, - symbol = state.currencyCode, - currencyCode = state.currencyCode, - decimalFormat = rememberDecimalFormat(), - symbolColor = if (state.amountFieldModel.value.isBlank()) { - colors.disabledTextColor - } else { - colors.textColor - }, - ), - textStyle = TangemTheme.typography.head.copy( - textAlign = TextAlign.Center, - ), - isAutoResize = true, - ) - } - Spacer(modifier = Modifier.padding(top = 8.dp)) - Text( - text = state.subtitle.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.secondary, - ) - } -} - -@Composable -private fun PresetsRow(presets: ImmutableList) { - if (presets.isEmpty()) return - Row( - modifier = Modifier - .fillMaxWidth() - .background(color = TangemTheme.colors.button.secondary) - .padding(horizontal = 8.dp, vertical = 12.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - presets.forEach { preset -> - PresetChip( - preset = preset, - modifier = Modifier.weight(1f), - ) - } - } -} - -@Composable -private fun PresetChip(preset: TangemPayCardLimitSetupUM.LimitPresetUM, modifier: Modifier = Modifier) { - Row( - modifier = modifier - .clip(RoundedCornerShape(16.dp)) - .background(TangemTheme.colors.background.primary) - .clickable(onClick = preset.onClick) - .padding(horizontal = 12.dp, vertical = 4.dp) - .wrapContentHeight(), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - modifier = Modifier.fillMaxWidth(), - text = preset.label, - style = TangemTheme.typography.caption1, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - maxLines = 1, - ) - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun preview() = TangemThemePreview { - TangemPayCardLimitSetupScreen( - state = TangemPayCardLimitSetupUM.stub(), - ) -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupSuccessComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupSuccessComponent.kt index 33d095ce49..2dfb36eea5 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupSuccessComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupSuccessComponent.kt @@ -8,24 +8,16 @@ import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute internal class TangemPayCardLimitSetupSuccessComponent( - private val isRedesignEnabled: Boolean, appComponentContext: AppComponentContext, ) : AppComponentContext by appComponentContext, ComposableContentComponent { @Composable override fun Content(modifier: Modifier) { BackHandler(onBack = ::backToDetails) - if (isRedesignEnabled) { - TangemPayCardLimitSetupSuccessScreenV2( - modifier = modifier, - onDoneClick = ::backToDetails, - ) - } else { - TangemPayCardLimitSetupSuccessScreen( - modifier = modifier, - onDoneClick = ::backToDetails, - ) - } + TangemPayCardLimitSetupSuccessScreenV2( + modifier = modifier, + onDoneClick = ::backToDetails, + ) } private fun backToDetails() { diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupSuccessScreen.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupSuccessScreen.kt deleted file mode 100644 index e615ad70f8..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupSuccessScreen.kt +++ /dev/null @@ -1,102 +0,0 @@ -package com.tangem.features.tangempay.limit.setup - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.statusBarsPadding -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.PrimaryButton -import com.tangem.core.ui.components.SpacerH12 -import com.tangem.core.ui.components.SpacerH32 -import com.tangem.core.ui.components.appbar.TangemTopAppBar -import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.features.tangempay.details.impl.R - -@Composable -internal fun TangemPayCardLimitSetupSuccessScreen(onDoneClick: () -> Unit, modifier: Modifier = Modifier) { - Column( - modifier = modifier - .fillMaxSize() - .navigationBarsPadding(), - ) { - TangemTopAppBar( - modifier = Modifier.statusBarsPadding(), - startButton = TopAppBarButtonUM.Close(onCloseClick = onDoneClick), - ) - Column( - modifier = Modifier.fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - SuccessContent( - modifier = Modifier - .fillMaxWidth() - .weight(1f), - ) - PrimaryButton( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 16.dp), - text = stringResourceSafe(R.string.common_done), - onClick = onDoneClick, - ) - } - } -} - -@Composable -private fun SuccessContent(modifier: Modifier = Modifier) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_success_blue_76), - tint = Color.Unspecified, - contentDescription = null, - modifier = Modifier.size(76.dp), - ) - SpacerH32() - Text( - modifier = Modifier.padding(horizontal = 32.dp), - text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_success_title), - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - ) - SpacerH12() - Text( - modifier = Modifier.padding(horizontal = 32.dp), - text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_success_description), - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.secondary, - textAlign = TextAlign.Center, - ) - } -} - -@Preview(showBackground = true) -@Composable -private fun Preview() { - TangemThemePreview { - TangemPayCardLimitSetupSuccessScreen(onDoneClick = {}) - } -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayAddFundsModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayAddFundsModel.kt index b385c734da..358872b3ca 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayAddFundsModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayAddFundsModel.kt @@ -9,7 +9,6 @@ import com.tangem.domain.models.ReceiveAddressModel import com.tangem.domain.models.ReceiveAddressModel.DisplayType import com.tangem.domain.pay.model.TangemPayTopUpData import com.tangem.domain.tangempay.TangemPayAnalyticsEvents -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.components.TangemPayAddFundsComponent import com.tangem.features.tangempay.entity.TangemPayAddFundsUM import com.tangem.features.tangempay.model.transformers.TangemPayAddFundsUMConverter @@ -22,7 +21,6 @@ import javax.inject.Inject internal class TangemPayAddFundsModel @Inject constructor( paramsContainer: ParamsContainer, override val dispatchers: CoroutineDispatcherProvider, - private val tangemPayFeatureToggles: TangemPayFeatureToggles, virtualAccountToggles: VirtualAccountFeatureToggles, analytics: AnalyticsEventHandler, ) : Model() { @@ -55,13 +53,10 @@ internal class TangemPayAddFundsModel @Inject constructor( ) return TangemPayAddFundsUMConverter( listener = params.listener, - isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled, shouldShowBankTransfer = isBankTransferShown, ).convert(data) } - fun isRedesignEnabled(): Boolean = tangemPayFeatureToggles.isRedesignEnabled - fun onDismiss() { params.listener.onDismissAddFunds() } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayAddToWalletModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayAddToWalletModel.kt index 1f59d04eb9..c09fc27504 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayAddToWalletModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayAddToWalletModel.kt @@ -6,7 +6,6 @@ import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.navigation.Router import com.tangem.core.ui.extensions.resourceReference -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.components.TangemPayAddToWalletComponent import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.TangemPayAddToWalletStepItemUM @@ -27,7 +26,6 @@ internal class TangemPayAddToWalletModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, private val router: Router, private val googleWalletUtil: GoogleWalletUtil, - private val featureToggles: TangemPayFeatureToggles, cardDetailsControllerFactory: TangemPayCardDetailsController.Factory, ) : Model() { @@ -49,8 +47,6 @@ internal class TangemPayAddToWalletModel @Inject constructor( val uiState: StateFlow field = MutableStateFlow(getInitialState()) - fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled - @Suppress("MagicNumber") private fun getInitialState(): TangemPayAddToWalletUM { return TangemPayAddToWalletUM( 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 19c91bb8f3..11672b695f 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 @@ -40,7 +40,6 @@ import com.tangem.domain.pay.model.TangemPayTopUpData import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository import com.tangem.domain.pay.usecase.ChangeCardFrozenStateUseCase import com.tangem.domain.tangempay.TangemPayAnalyticsEvents -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.closure.CloseCardListener import com.tangem.features.tangempay.components.AddFundsListener import com.tangem.features.tangempay.components.ReissueCardListener @@ -81,7 +80,6 @@ internal class TangemPayCardPageModel @Inject constructor( private val uiMessageSender: UiMessageSender, private val changeCardFrozenStateUseCase: ChangeCardFrozenStateUseCase, private val cardDetailsEventListener: CardDetailsEventListener, - private val tangemPayFeatureToggles: TangemPayFeatureToggles, private val cardDetailsControllerFactory: TangemPayCardDetailsController.Factory, ) : Model(), ViewPinListener, ReissueCardListener, AddFundsListener, CloseCardListener { @@ -116,7 +114,6 @@ internal class TangemPayCardPageModel @Inject constructor( TangemPayCardPageUM( onBackClick = router::pop, dailyLimitState = TangemPayDailyLimitBlockState.Loading, - settings = persistentListOf(), settingsV2 = persistentListOf(), menuItems = buildMenuItems( isLastCard = params.initialStatus.ifLoadedOrNull { it.cards.isLastCard() } ?: false, @@ -170,8 +167,6 @@ internal class TangemPayCardPageModel @Inject constructor( } } - fun isRedesignEnabled(): Boolean = tangemPayFeatureToggles.isRedesignEnabled - /** Reports the card the user swiped to so per-card UI and reveal target it. */ fun onCardPageSelected(index: Int) { cardControllersState.value.getOrNull(index)?.let { selectedCardId.value = it.cardId } @@ -223,7 +218,6 @@ internal class TangemPayCardPageModel @Inject constructor( uiState.update { uiState -> uiState.copy( dailyLimitState = buildDailyLimitState(state), - settings = buildSettings(card), settingsV2 = buildSettingsV2(card), menuItems = buildMenuItems(isLastCard = status.cards.isLastCard()), cardState = card.state, @@ -239,34 +233,7 @@ internal class TangemPayCardPageModel @Inject constructor( return (status as? PaymentAccountStatusValue.Loaded)?.findCardWithId(selectedCardId.value) } - private fun buildSettings(card: TangemPayCard): ImmutableList { - if (isRedesignEnabled()) return persistentListOf() - return persistentListOf( - TangemPayCardPageSetting( - title = TextReference.Res(R.string.tangempay_card_details_change_pin), - onSettingClick = { onClickChangePIN(card.hasPinCode) }, - testTag = TangemPayTestTags.CHANGE_PIN_ROW, - ), - TangemPayCardPageSetting( - title = TextReference.Res( - if (card.isFrozen) { - R.string.tangempay_card_details_unfreeze_card - } else { - R.string.tangempay_card_details_freeze_card - }, - ), - onSettingClick = { onClickFreezeOrUnfreezeCard(card.isFrozen) }, - testTag = TangemPayTestTags.FREEZE_CARD_ROW, - ), - TangemPayCardPageSetting( - title = TextReference.Res(R.string.tangempay_card_details_reissue_card), - onSettingClick = ::onClickReissueCard, - ), - ) - } - private suspend fun subscribeOnDetailsState() { - if (!isRedesignEnabled()) return combine(cardDetailsEventListener.event, selectedCardId) { event, selectedId -> event is CardDetailsEvent.Show && event.cardId == selectedId }.collect { isDetailsShown -> @@ -287,7 +254,6 @@ internal class TangemPayCardPageModel @Inject constructor( } private fun buildSettingsV2(card: TangemPayCard): ImmutableList { - if (!isRedesignEnabled()) return persistentListOf() return persistentListOf( TangemPayCardPageSettingV2( id = TangemPayCardPageSettingV2.Id.Details, @@ -395,15 +361,9 @@ internal class TangemPayCardPageModel @Inject constructor( if (frozenStateJobHolder.isActive) return val message = if (isFrozen) { - TangemPayMessagesFactory.createUnfreezeCardMessage( - onUnfreezeClicked = ::unfreezeCard, - isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled, - ) + TangemPayMessagesFactory.createUnfreezeCardMessage(onUnfreezeClicked = ::unfreezeCard) } else { - TangemPayMessagesFactory.createFreezeCardMessage( - onFreezeClicked = ::freezeCard, - isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled, - ) + TangemPayMessagesFactory.createFreezeCardMessage(onFreezeClicked = ::freezeCard) } uiMessageSender.send(message) } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayChangePinModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayChangePinModel.kt index d529fcd2fd..3c130a60f8 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayChangePinModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayChangePinModel.kt @@ -13,7 +13,6 @@ import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher import com.tangem.domain.pay.model.SetPinResult import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository import com.tangem.domain.tangempay.TangemPayAnalyticsEvents -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.components.TangemPayChangePinComponent import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.TangemPayChangePinUM @@ -38,7 +37,6 @@ internal class TangemPayChangePinModel @Inject constructor( private val router: Router, private val cardDetailsRepository: TangemPayCardDetailsRepository, private val analytics: AnalyticsEventHandler, - private val featureToggles: TangemPayFeatureToggles, private val fetcher: PaymentAccountStatusFetcher, ) : Model() { @@ -50,13 +48,11 @@ internal class TangemPayChangePinModel @Inject constructor( analytics.send(TangemPayAnalyticsEvents.ChangePinScreenShown()) } - fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled - private fun onPinCodeChange(pin: String) { uiState.update(transformer = PinCodeChangeTransformer(newPin = pin)) val state = uiState.value - // In the redesign there is no submit button: a valid full PIN is submitted automatically. - if (featureToggles.isRedesignEnabled && state.submitButtonEnabled && !state.submitButtonLoading) { + // There is no submit button: a valid full PIN is submitted automatically. + if (state.submitButtonEnabled && !state.submitButtonLoading) { onClickSubmit() } } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt index 6d8ad20dc2..ca2672e524 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt @@ -115,7 +115,6 @@ internal class TangemPayDetailsModel @Inject constructor( onBack = router::pop, onOpenMenu = ::onOpenMenu, intents = this, - isRedesignEnabled = isRedesignEnabled(), isRemoveAccountEnabled = tangemPayFeatureToggles.isRemoveAccountEnabled, isTiersPlusPlanEnabled = tangemPayFeatureToggles.isTiersPlusPlanEnabled, ) @@ -198,8 +197,6 @@ internal class TangemPayDetailsModel @Inject constructor( } } - fun isRedesignEnabled(): Boolean = tangemPayFeatureToggles.isRedesignEnabled - override fun onClickAddFunds() { analytics.send(TangemPayAnalyticsEvents.AddFundsClicked()) val balance = currentStatus.value.balanceOrNull() diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayEditDisplayNameModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayEditDisplayNameModel.kt index f0419494f2..2973106a5c 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayEditDisplayNameModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayEditDisplayNameModel.kt @@ -18,7 +18,6 @@ import com.tangem.domain.models.account.requireCardWithId import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier import com.tangem.domain.pay.usecase.UpdateTangemPayCardNameUseCase -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.components.TangemPayEditDisplayNameComponent import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM @@ -39,7 +38,6 @@ internal class TangemPayEditDisplayNameModel @Inject constructor( private val updateCardNameUseCase: UpdateTangemPayCardNameUseCase, private val uiMessageSender: UiMessageSender, private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier, - private val featureToggles: TangemPayFeatureToggles, cardDetailsControllerFactory: TangemPayCardDetailsController.Factory, ) : Model() { @@ -80,8 +78,6 @@ internal class TangemPayEditDisplayNameModel @Inject constructor( subscribeToCardNameChanges(card.id, params.userWalletId) } - fun isRedesignEnabled() = featureToggles.isRedesignEnabled - private fun subscribeToCardNameChanges(cardId: String, userWalletId: UserWalletId) { paymentAccountStatusSupplier.invoke(userWalletId) .onEach { state -> diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayReissueCardModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayReissueCardModel.kt index 4435246ebe..444d6701da 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayReissueCardModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayReissueCardModel.kt @@ -15,7 +15,6 @@ import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository import com.tangem.domain.pay.repository.TangemPayReissueCardRepository import com.tangem.domain.pay.usecase.ReissueTangemPayCardUseCase import com.tangem.domain.tangempay.TangemPayAnalyticsEvents -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.components.TangemPayReissueCardComponent import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.TangemPayReissueCardError @@ -42,7 +41,6 @@ internal class TangemPayReissueCardModel @Inject constructor( private val reissueTangemPayCardUseCase: ReissueTangemPayCardUseCase, private val uiMessageSender: UiMessageSender, private val analytics: AnalyticsEventHandler, - private val featureToggles: TangemPayFeatureToggles, ) : Model() { private val params = paramsContainer.require() @@ -69,8 +67,6 @@ internal class TangemPayReissueCardModel @Inject constructor( loadData() } - fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled - fun onDismiss() { reissueJobHolder.cancel() params.listener.onDismissReissueCard() diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt index 7034bfdc3f..ed3dc5f02a 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt @@ -16,9 +16,8 @@ import com.tangem.domain.tangempay.TangemPayAnalyticsEvents import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository import com.tangem.domain.visa.model.TangemPayTxHistoryItem import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent -import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUiStates +import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUMV2 import com.tangem.features.tangempay.entity.TransactionLoadState -import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverter import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverterV2 import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.Job @@ -46,16 +45,16 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor( private val transactionLoadState = MutableStateFlow(TransactionLoadState.Loading) private var loadTransactionJob: Job? = null - val uiState: StateFlow = combine( + val uiState: StateFlow = combine( balanceHidingSettings.isBalanceHidden(), transaction, transactionLoadState, ) { isBalanceHidden, transaction, transactionLoadState -> - buildUiStates(isBalanceHidden, transaction, transactionLoadState) + buildUiState(isBalanceHidden, transaction, transactionLoadState) }.stateIn( scope = modelScope, started = SharingStarted.Eagerly, - initialValue = buildUiStates( + initialValue = buildUiState( isBalanceHidden = params.isBalanceHidden, transaction = params.transaction, transactionLoadState = transactionLoadState.value, @@ -88,30 +87,20 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor( } } - private fun buildUiStates( + private fun buildUiState( isBalanceHidden: Boolean, transaction: TangemPayTxHistoryItem, transactionLoadState: TransactionLoadState, - ): TangemPayTxHistoryDetailsUiStates { - val converterInput = TangemPayTxHistoryDetailsConverter.Input( - item = transaction, - isBalanceHidden = isBalanceHidden, - onExplorerClick = ::openExplorer, - onDisputeClick = { dispute(customerId = params.customerId) }, - onDismiss = ::dismiss, - ) - return TangemPayTxHistoryDetailsUiStates( - legacy = TangemPayTxHistoryDetailsConverter.convert(converterInput), - redesign = TangemPayTxHistoryDetailsConverterV2.convert( - value = TangemPayTxHistoryDetailsConverterV2.Input( - item = converterInput.item, - isBalanceHidden = converterInput.isBalanceHidden, - transactionLoadState = transactionLoadState, - onExplorerClick = converterInput.onExplorerClick, - onDisputeClick = converterInput.onDisputeClick, - onCardRefreshClick = ::loadTransaction, - onDismiss = converterInput.onDismiss, - ), + ): TangemPayTxHistoryDetailsUMV2 { + return TangemPayTxHistoryDetailsConverterV2.convert( + value = TangemPayTxHistoryDetailsConverterV2.Input( + item = transaction, + isBalanceHidden = isBalanceHidden, + transactionLoadState = transactionLoadState, + onExplorerClick = ::openExplorer, + onDisputeClick = { dispute(customerId = params.customerId) }, + onCardRefreshClick = ::loadTransaction, + onDismiss = ::dismiss, ), ) } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryModel.kt index 5cd1ea401f..47b229ce5d 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryModel.kt @@ -6,7 +6,6 @@ import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM import com.tangem.features.tangempay.utils.TangemPayTxHistoryListManager @@ -26,7 +25,6 @@ internal class TangemPayTxHistoryModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, private val txHistoryUpdateListener: TangemPayTxHistoryUpdateListener, - private val featureToggles: TangemPayFeatureToggles, ) : Model() { private val params: DefaultTangemPayTxHistoryComponent.Params = paramsContainer.require() @@ -46,8 +44,6 @@ internal class TangemPayTxHistoryModel @Inject constructor( subscribeToUpdateListener() } - fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled - private fun launchPagination() { modelScope.launch { listManager.launchPagination(params.userWalletId) } } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayViewPinModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayViewPinModel.kt index 9b02ad1ed5..a610d66541 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayViewPinModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayViewPinModel.kt @@ -7,7 +7,6 @@ import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository import com.tangem.domain.tangempay.TangemPayAnalyticsEvents -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.components.TangemPayViewPinComponent import com.tangem.features.tangempay.entity.TangemPayViewPinUM import com.tangem.features.tangempay.model.transformers.TangemPayViewPinErrorStateTransformer @@ -26,7 +25,6 @@ internal class TangemPayViewPinModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, private val cardDetailsRepository: TangemPayCardDetailsRepository, private val analytics: AnalyticsEventHandler, - private val featureToggles: TangemPayFeatureToggles, ) : Model() { private val params = paramsContainer.require() @@ -39,8 +37,6 @@ internal class TangemPayViewPinModel @Inject constructor( getCardPin() } - fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled - private fun getCardPin() { modelScope.launch { cardDetailsRepository.getPin(userWalletId = params.walletId, cardId = params.cardId) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayAddFundsUMConverter.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayAddFundsUMConverter.kt index dae806fdf8..85e45ff7ca 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayAddFundsUMConverter.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayAddFundsUMConverter.kt @@ -18,7 +18,6 @@ import kotlinx.collections.immutable.toPersistentList internal class TangemPayAddFundsUMConverter( val listener: AddFundsListener, - val isRedesignEnabled: Boolean, val shouldShowBankTransfer: Boolean, ) : Converter { @@ -27,41 +26,23 @@ internal class TangemPayAddFundsUMConverter( return TangemPayAddFundsUM( items = buildList { TangemPayAddFundsItemUM( - icon = if (isRedesignEnabled) { - TangemIconUM.Icon( - imageVector = Icons.ic_logo_tangem_20, - tintReference = { - TangemTheme.colors3.icon.brand - }, - ) - } else { - TangemIconUM.Icon( - iconRes = R.drawable.ic_exchange_vertical_24, - tintReference = { - TangemTheme.colors.icon.accent - }, - ) - }, + icon = TangemIconUM.Icon( + imageVector = Icons.ic_logo_tangem_20, + tintReference = { + TangemTheme.colors3.icon.brand + }, + ), title = resourceReference(R.string.tangempay_topup_swap_title), description = resourceReference(R.string.tangempay_topup_swap_body), onClick = { listener.onClickSwap(value) }, ).let(::add) TangemPayAddFundsItemUM( - icon = if (isRedesignEnabled) { - TangemIconUM.Icon( - imageVector = Icons.ic_card_20, - tintReference = { - TangemTheme.colors3.icon.brand - }, - ) - } else { - TangemIconUM.Icon( - iconRes = R.drawable.ic_arrow_down_24, - tintReference = { - TangemTheme.colors.icon.accent - }, - ) - }, + icon = TangemIconUM.Icon( + imageVector = Icons.ic_card_20, + tintReference = { + TangemTheme.colors3.icon.brand + }, + ), title = resourceReference(R.string.tangempay_topup_receive_title), description = resourceReference(R.string.tangempay_topup_receive_body), onClick = { listener.onClickReceive(value) }, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverter.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverter.kt deleted file mode 100644 index 29c444b3cc..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverter.kt +++ /dev/null @@ -1,313 +0,0 @@ -package com.tangem.features.tangempay.model.transformers - -import com.tangem.core.ui.components.label.entity.LabelStyle -import com.tangem.core.ui.components.label.entity.LabelUM -import com.tangem.core.ui.components.notifications.NotificationConfig -import com.tangem.core.ui.extensions.* -import com.tangem.core.ui.format.bigdecimal.fiat -import com.tangem.core.ui.format.bigdecimal.format -import com.tangem.core.ui.format.bigdecimal.price -import com.tangem.core.ui.res.TangemColorPalette -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.utils.DateTimeFormatters -import com.tangem.domain.visa.model.TangemPayTxHistoryItem -import com.tangem.features.tangempay.details.impl.R -import com.tangem.features.tangempay.entity.ButtonState -import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM -import com.tangem.utils.StringsSigns -import com.tangem.utils.converter.Converter -import com.tangem.utils.extensions.isPositive -import com.tangem.utils.extensions.isZero -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf - -internal object TangemPayTxHistoryDetailsConverter : - Converter { - private val dateFormatter = DateTimeFormatters.getBestFormatterBySkeleton("dd MMMM") - - private val paySpendSubtitleConverter = PayDetailsSpendSubtitleConverter - - override fun convert(value: Input): TangemPayTxHistoryDetailsUM { - val transaction = value.item - return TangemPayTxHistoryDetailsUM( - isBalanceHidden = value.isBalanceHidden, - title = transaction.extractDate(), - iconState = transaction.extractIcon(), - transactionTitle = transaction.extractTransactionTitle(), - transactionSubtitle = transaction.extractTransactionSubtitle(), - transactionAmount = transaction.extractAmount(), - transactionAmountColor = transaction.extractAmountColor(), - localTransactionText = transaction.extractLocalAmount(), - labelState = transaction.extractLabel(), - notification = transaction.extractNotification(), - buttons = value.extractButtonsState(), - dismiss = value.onDismiss, - ) - } - - private fun TangemPayTxHistoryItem.extractDate(): TextReference { - val date = DateTimeFormatters.formatDate(this.date, dateFormatter) - val time = DateTimeFormatters.formatDate(this.date, DateTimeFormatters.timeFormatter) - - return stringReference("$date ${StringsSigns.DOT} $time") - } - - private fun TangemPayTxHistoryItem.extractIcon(): ImageReference { - return when (this) { - is TangemPayTxHistoryItem.Collateral -> when (this.type) { - TangemPayTxHistoryItem.Type.Deposit -> ImageReference.Res(R.drawable.ic_arrow_down_24) - TangemPayTxHistoryItem.Type.Withdrawal -> ImageReference.Res(R.drawable.ic_arrow_up_24) - } - is TangemPayTxHistoryItem.Fee -> ImageReference.Res(R.drawable.ic_percent_24) - is TangemPayTxHistoryItem.Payment -> ImageReference.Res(R.drawable.ic_arrow_up_24) - is TangemPayTxHistoryItem.Spend -> { - val merchantIcon = this.enrichedMerchantIconUrl - if (!merchantIcon.isNullOrEmpty()) { - ImageReference.Url(merchantIcon) - } else { - ImageReference.Res(R.drawable.ic_category_24) - } - } - } - } - - private fun TangemPayTxHistoryItem.extractTransactionTitle(): TextReference { - return when (this) { - is TangemPayTxHistoryItem.Spend -> stringReference(this.enrichedMerchantName ?: this.merchantName) - is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.tangem_pay_withdrawal) - is TangemPayTxHistoryItem.Collateral -> when (this.type) { - TangemPayTxHistoryItem.Type.Deposit -> resourceReference(R.string.tangem_pay_deposit) - TangemPayTxHistoryItem.Type.Withdrawal -> resourceReference(R.string.tangem_pay_withdrawal) - } - is TangemPayTxHistoryItem.Fee -> { - this.description?.let(::stringReference) ?: resourceReference(R.string.tangem_pay_fee_title) - } - } - } - - private fun TangemPayTxHistoryItem.extractTransactionSubtitle(): TextReference { - return when (this) { - is TangemPayTxHistoryItem.Fee -> resourceReference(R.string.tangem_pay_fee_subtitle) - is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.common_transfer) - is TangemPayTxHistoryItem.Collateral -> resourceReference(R.string.common_transfer) - is TangemPayTxHistoryItem.Spend -> paySpendSubtitleConverter.convert(this) - } - } - - private fun TangemPayTxHistoryItem.extractAmount(): String { - return when (this) { - is TangemPayTxHistoryItem.Fee, - is TangemPayTxHistoryItem.Payment, - -> { - val amount = this.amount.format { - fiat( - fiatCurrencyCode = this@extractAmount.currency.currencyCode, - fiatCurrencySymbol = this@extractAmount.currency.symbol, - ) - } - StringsSigns.MINUS + amount - } - is TangemPayTxHistoryItem.Spend -> { - val amountPrefix = when { - this.amount.isZero() -> "" - this.status == TangemPayTxHistoryItem.Status.REVERSED -> StringsSigns.MINUS - this.status == TangemPayTxHistoryItem.Status.DECLINED || - this.amount.isPositive() -> StringsSigns.MINUS - else -> StringsSigns.PLUS - } - val amount = when (this.status) { - TangemPayTxHistoryItem.Status.DECLINED -> this.authorizedAmount - else -> this.amount - } - val formattedAmount = amount.abs().format { - fiat( - fiatCurrencyCode = this@extractAmount.currency.currencyCode, - fiatCurrencySymbol = this@extractAmount.currency.symbol, - ) - } - amountPrefix + formattedAmount - } - is TangemPayTxHistoryItem.Collateral -> { - val amountPrefix = when { - this.amount.isZero() -> "" - this.amount.isPositive() -> StringsSigns.PLUS - else -> StringsSigns.MINUS - } - val amount = this.amount.abs().format { - fiat( - fiatCurrencyCode = this@extractAmount.currency.currencyCode, - fiatCurrencySymbol = this@extractAmount.currency.symbol, - ) - } - amountPrefix + amount - } - } - } - - private fun TangemPayTxHistoryItem.extractAmountColor(): ColorReference { - return when (this) { - is TangemPayTxHistoryItem.Fee, - is TangemPayTxHistoryItem.Payment, - -> themedColor { TangemTheme.colors.text.primary1 } - is TangemPayTxHistoryItem.Collateral -> when (this.type) { - TangemPayTxHistoryItem.Type.Deposit -> themedColor { TangemTheme.colors.text.accent } - TangemPayTxHistoryItem.Type.Withdrawal -> themedColor { TangemTheme.colors.text.primary1 } - } - is TangemPayTxHistoryItem.Spend -> when (this.status) { - TangemPayTxHistoryItem.Status.DECLINED -> themedColor { TangemTheme.colors.text.warning } - else -> themedColor { TangemTheme.colors.text.primary1 } - } - } - } - - private fun TangemPayTxHistoryItem.extractLocalAmount(): String? { - return when (this) { - is TangemPayTxHistoryItem.Collateral, - is TangemPayTxHistoryItem.Fee, - is TangemPayTxHistoryItem.Payment, - -> null - is TangemPayTxHistoryItem.Spend -> { - val localCurrency = this.localCurrency - val localAmount = this.localAmount - if (localCurrency != null && localAmount != null && localCurrency != currency) { - val amountPrefix = when { - localAmount.isZero() -> "" - this.status == TangemPayTxHistoryItem.Status.DECLINED || - localAmount.isPositive() -> StringsSigns.MINUS - else -> StringsSigns.PLUS - } - val amount = localAmount.abs().format { - fiat( - fiatCurrencyCode = localCurrency.currencyCode, - fiatCurrencySymbol = localCurrency.symbol, - ).price() - } - amountPrefix + amount - } else { - null - } - } - } - } - - private fun TangemPayTxHistoryItem.extractLabel(): LabelUM? { - return when (this) { - is TangemPayTxHistoryItem.Fee, - is TangemPayTxHistoryItem.Payment, - is TangemPayTxHistoryItem.Collateral, - -> null - is TangemPayTxHistoryItem.Spend -> when (this.status) { - TangemPayTxHistoryItem.Status.COMPLETED -> LabelUM( - text = resourceReference(R.string.tangem_pay_status_completed), - style = LabelStyle.ACCENT, - ) - TangemPayTxHistoryItem.Status.PENDING -> LabelUM( - text = resourceReference(R.string.tangem_pay_status_pending), - style = LabelStyle.REGULAR, - icon = com.tangem.core.ui.R.drawable.ic_clock_24, - ) - TangemPayTxHistoryItem.Status.DECLINED -> LabelUM( - text = resourceReference(R.string.tangem_pay_status_declined), - style = LabelStyle.WARNING, - ) - TangemPayTxHistoryItem.Status.REVERSED -> LabelUM( - text = resourceReference(R.string.tangem_pay_status_reversed), - style = LabelStyle.REGULAR, - ) - TangemPayTxHistoryItem.Status.RESERVED, - TangemPayTxHistoryItem.Status.UNKNOWN, - -> null - } - } - } - - private fun TangemPayTxHistoryItem.extractNotification(): TangemPayTxHistoryDetailsUM.NotificationState? { - return when (this) { - is TangemPayTxHistoryItem.Payment -> null - is TangemPayTxHistoryItem.Collateral -> null - is TangemPayTxHistoryItem.Fee -> TangemPayTxHistoryDetailsUM.NotificationState( - config = NotificationConfig( - title = resourceReference(R.string.tangem_pay_transaction_fee_notification_text), - subtitle = TextReference.EMPTY, - iconResId = R.drawable.ic_token_info_24, - ), - titleColor = themedColor { TangemTheme.colors.text.tertiary }, - iconTint = themedColor { TangemTheme.colors.icon.secondary }, - containerColor = null, - ) - is TangemPayTxHistoryItem.Spend -> when (this.status) { - TangemPayTxHistoryItem.Status.DECLINED -> TangemPayTxHistoryDetailsUM.NotificationState( - config = NotificationConfig( - title = declinedReason.let { reason -> - if (reason.isNullOrEmpty()) { - resourceReference(R.string.tangem_pay_transaction_declined_notification_text) - } else { - resourceReference( - id = R.string.tangem_pay_history_item_spend_mc_declined_reason, - formatArgs = wrappedList(TangemPayDeclinedReasonMapper.map(reason)), - ) - } - }, - subtitle = TextReference.EMPTY, - iconResId = R.drawable.ic_token_info_24, - ), - titleColor = themedColor { TangemTheme.colors.text.warning }, - iconTint = themedColor { TangemTheme.colors.icon.warning }, - containerColor = themedColor { TangemColorPalette.Amaranth.copy(alpha = 0.1F) }, - ) - TangemPayTxHistoryItem.Status.REVERSED -> TangemPayTxHistoryDetailsUM.NotificationState( - config = NotificationConfig( - title = resourceReference(R.string.tangem_pay_transaction_reversed_notification_text), - subtitle = TextReference.EMPTY, - iconResId = R.drawable.ic_token_info_24, - ), - titleColor = themedColor { TangemTheme.colors.text.tertiary }, - iconTint = themedColor { TangemTheme.colors.icon.secondary }, - containerColor = null, - ) - TangemPayTxHistoryItem.Status.PENDING, - TangemPayTxHistoryItem.Status.COMPLETED, - TangemPayTxHistoryItem.Status.RESERVED, - TangemPayTxHistoryItem.Status.UNKNOWN, - -> null - } - } - } - - private fun Input.extractButtonsState(): ImmutableList { - return when (this.item) { - is TangemPayTxHistoryItem.Fee -> persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_get_help), - onClick = this.onDisputeClick, - ), - ) - is TangemPayTxHistoryItem.Spend -> persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_get_help), - onClick = this.onDisputeClick, - ), - ) - is TangemPayTxHistoryItem.Payment -> persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_get_help), - onClick = this.onDisputeClick, - ), - ) - is TangemPayTxHistoryItem.Collateral -> persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_get_help), - onClick = this.onDisputeClick, - ), - ) - } - } - - data class Input( - val item: TangemPayTxHistoryItem, - val isBalanceHidden: Boolean, - val onExplorerClick: (String?) -> Unit, - val onDisputeClick: () -> Unit, - val onDismiss: () -> Unit, - ) -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddFundsContent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddFundsContent.kt deleted file mode 100644 index 984595b25b..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddFundsContent.kt +++ /dev/null @@ -1,162 +0,0 @@ -package com.tangem.features.tangempay.ui - -import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.key -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.util.fastForEach -import com.tangem.core.ui.components.SpacerH16 -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent -import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetContent -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle -import com.tangem.core.ui.ds.image.TangemIcon -import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.extensions.TextReference.Res -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.features.tangempay.details.impl.R -import com.tangem.features.tangempay.entity.TangemPayAddFundsItemUM -import com.tangem.features.tangempay.entity.TangemPayAddFundsUM -import kotlinx.collections.immutable.persistentListOf - -@Composable -internal fun TangemPayAddFundsContent(state: TangemPayAddFundsUM) { - TangemModalBottomSheet( - config = TangemBottomSheetConfig( - isShown = true, - onDismissRequest = state.dismiss, - content = TangemBottomSheetConfigContent.Empty, - ), - onBack = state.dismiss, - containerColor = TangemTheme.colors.background.tertiary, - title = { - TangemModalBottomSheetTitle( - title = resourceReference(R.string.tangempay_card_details_add_funds), - endIconRes = R.drawable.ic_close_24, - onEndClick = state.dismiss, - ) - }, - ) { - if (state.errorMessage != null) { - MessageBottomSheetContent(state.errorMessage) - } else { - Surface( - modifier = Modifier - .padding(horizontal = 16.dp) - .fillMaxWidth(), - shape = TangemTheme.shapes.roundedCornersXMedium, - color = TangemTheme.colors.background.primary, - ) { - Column( - modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.Start, - ) { - Text( - modifier = Modifier.padding(top = 12.dp, start = 16.dp, end = 16.dp), - text = resourceReference(R.string.tangempay_card_details_add_funds_subtitle).resolveReference(), - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.subtitle2, - ) - state.items.fastForEach { - key(it.title) { - TangemPayTopUpItem(state = it) - } - } - } - } - SpacerH16() - } - } -} - -@Composable -private fun TangemPayTopUpItem(state: TangemPayAddFundsItemUM, modifier: Modifier = Modifier) { - Row( - modifier = modifier - .fillMaxWidth() - .clickable(onClick = state.onClick) - .padding(horizontal = 12.dp, vertical = 16.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp), - ) { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .background( - color = TangemTheme.colors.icon.accent.copy(alpha = 0.1f), - shape = CircleShape, - ) - .size(36.dp), - ) { - TangemIcon( - modifier = Modifier.size(16.dp), - tangemIconUM = state.icon, - ) - } - Column( - verticalArrangement = Arrangement.spacedBy(2.dp), - ) { - Text( - text = state.title.resolveReference(), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.primary1, - ) - Text( - text = state.description.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - } - } -} - -@Preview(showBackground = true) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun TangemPayAddFundsContentPreview() { - TangemThemePreview { - TangemPayAddFundsContent( - state = TangemPayAddFundsUM( - items = persistentListOf( - TangemPayAddFundsItemUM( - icon = TangemIconUM.Icon( - iconRes = R.drawable.ic_exchange_vertical_24, - tintReference = { - TangemTheme.colors.icon.accent - }, - ), - title = Res(R.string.common_exchange), - description = Res(R.string.exсhange_token_description), - onClick = {}, - ), - TangemPayAddFundsItemUM( - icon = TangemIconUM.Icon( - iconRes = R.drawable.ic_arrow_down_24, - tintReference = { - TangemTheme.colors.icon.accent - }, - ), - title = Res(R.string.common_receive), - description = Res(R.string.receive_token_description), - onClick = {}, - ), - ), - dismiss = {}, - errorMessage = null, - ), - ) - } -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletBlock.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletBlock.kt index b5b3374ac7..e1e6cdf045 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletBlock.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletBlock.kt @@ -1,120 +1,19 @@ package com.tangem.features.tangempay.ui import android.content.res.Configuration -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import com.tangem.core.ui.ds.message.TangemMessage import com.tangem.core.ui.ds.message.TangemMessageEffect import com.tangem.core.ui.extensions.clickableSingle import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalVisaRedesignEnabled -import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.AddToWalletBlockState -private const val GRADIENT_START_COLOR = 0xFF252934 -private const val GRADIENT_END_COLOR = 0xFF12141E -private const val GRADIENT_OFFSET_X = 0f -private const val GRADIENT_OFFSET_Y = 80F -private const val GRADIENT_RADIUS = 200F - @Composable internal fun TangemPayAddToWalletBlock(state: AddToWalletBlockState, modifier: Modifier = Modifier) { - if (LocalVisaRedesignEnabled.current) { - TangemPayAddToWalletBlockV2(state = state, modifier = modifier) - } else { - TangemPayAddToWalletBlockV1(state = state, modifier = modifier) - } -} - -@Composable -private fun TangemPayAddToWalletBlockV1(state: AddToWalletBlockState, modifier: Modifier = Modifier) { - Box( - modifier = modifier - .fillMaxWidth() - .clip(TangemTheme.shapes.roundedCornersXMedium) - .background( - brush = Brush.radialGradient( - colors = listOf(Color(GRADIENT_START_COLOR), Color(GRADIENT_END_COLOR)), - center = Offset(GRADIENT_OFFSET_X, GRADIENT_OFFSET_Y), - radius = GRADIENT_RADIUS, - ), - ) - .clickable(onClick = state.onClick), - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .height(IntrinsicSize.Min) - .padding(horizontal = 16.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Image( - painter = painterResource(R.drawable.img_google_wallet_48), - contentDescription = null, - modifier = Modifier - .size(36.dp) - .clip(CircleShape), - ) - - Spacer(Modifier.width(12.dp)) - - Column( - modifier = Modifier.weight(1f), - verticalArrangement = Arrangement.Center, - ) { - Text( - text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_notification_title), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.constantWhite, - ) - - Spacer(Modifier.height(6.dp)) - - Text( - text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_notification_subtitle), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - } - Box( - modifier = Modifier.fillMaxHeight(), - contentAlignment = Alignment.TopEnd, - ) { - Image( - modifier = Modifier - .clip(TangemTheme.shapes.roundedCornersXMedium) - .clickable(onClick = state.onClickClose) - .padding(4.dp) - .size(12.dp), - painter = painterResource(id = R.drawable.ic_close_24), - colorFilter = ColorFilter.tint(TangemTheme.colors.icon.inactive), - contentDescription = null, - ) - } - } - } -} - -@Composable -private fun TangemPayAddToWalletBlockV2(state: AddToWalletBlockState, modifier: Modifier = Modifier) { TangemMessage( modifier = modifier.clickableSingle(onClick = state.onClick), onCloseClick = state.onClickClose, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletScreen.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletScreen.kt deleted file mode 100644 index cfebd48a78..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayAddToWalletScreen.kt +++ /dev/null @@ -1,193 +0,0 @@ -package com.tangem.features.tangempay.ui - -import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.PrimaryButton -import com.tangem.core.ui.components.SecondaryButton -import com.tangem.core.ui.components.appbar.AppBarWithBackButton -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemColorPalette -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.domain.models.pay.TangemPayCardFrozenState -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.persistentListOf - -@Composable -internal fun TangemPayAddToWalletScreen( - state: TangemPayAddToWalletUM, - cardDetailsState: TangemPayCardDetailsUM, - modifier: Modifier = Modifier, -) { - val listState = rememberLazyListState() - val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } - - Column( - modifier = modifier - .fillMaxSize() - .navigationBarsPadding(), - ) { - AppBarWithBackButton( - modifier = Modifier.statusBarsPadding(), - iconRes = R.drawable.ic_close_24, - onBackClick = state.onBackClick, - ) - - LazyColumn( - modifier = Modifier - .fillMaxSize() - .weight(1f), - state = listState, - contentPadding = PaddingValues(bottom = TangemTheme.dimens.spacing16 + bottomBarHeight), - ) { - item(TangemPayCardDetailsUM::class.java) { - TangemPayCard( - state = cardDetailsState, - modifier = Modifier.padding(horizontal = 16.dp).padding(top = 8.dp), - ) - } - - item(key = TangemPayAddToWalletUM::class.java) { - Text( - modifier = Modifier - .padding(horizontal = 16.dp, vertical = 24.dp) - .fillMaxWidth(), - text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_title), - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - ) - } - itemsIndexed( - items = state.steps, - key = { _, step -> "${TangemPayAddToWalletStepItemUM::class.java}${step.count}" }, - ) { idx, step -> - StepItem( - modifier = Modifier.padding(bottom = if (idx < state.steps.lastIndex) 16.dp else 0.dp), - stepNumber = step.count, - title = step.text, - ) - } - } - - SecondaryButton( - modifier = Modifier - .imePadding() - .padding(start = 16.dp, end = 16.dp, bottom = 8.dp) - .fillMaxWidth(), - text = resourceReference(R.string.common_got_it).resolveReference(), - onClick = state.onBackClick, - - ) - if (state.showAddToWalletButton) { - PrimaryButton( - modifier = Modifier - .imePadding() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp) - .fillMaxWidth(), - text = resourceReference(R.string.tangempay_card_details_open_wallet_button).resolveReference(), - onClick = state.onClickOpenWallet, - ) - } - } -} - -@Composable -private fun StepItem(stepNumber: Int, title: TextReference, modifier: Modifier = Modifier) { - Row( - modifier = modifier - .background(color = Color.Transparent, shape = TangemTheme.shapes.roundedCorners8) - .padding(horizontal = 24.dp), - verticalAlignment = Alignment.Top, - ) { - Box( - modifier = Modifier - .size(24.dp) - .background(color = TangemColorPalette.Azure, shape = CircleShape), - contentAlignment = Alignment.Center, - ) { - Text( - text = stepNumber.toString(), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.primary2, - ) - } - - Spacer(modifier = Modifier.width(12.dp)) - - Text( - text = title.resolveReference(), - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - ) - } -} - -@Preview(showBackground = true) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PreviewTangemPayAddToWalletScreen() { - TangemThemePreview { - TangemPayAddToWalletScreen( - state = TangemPayAddToWalletUM( - steps = persistentListOf( - TangemPayAddToWalletStepItemUM( - count = 1, - text = resourceReference(R.string.tangempay_card_details_open_wallet_step_1), - ), - TangemPayAddToWalletStepItemUM( - count = 2, - text = resourceReference(R.string.tangempay_card_details_open_wallet_step_2), - ), - TangemPayAddToWalletStepItemUM( - count = 3, - text = resourceReference(R.string.tangempay_card_details_open_wallet_step_3), - ), - TangemPayAddToWalletStepItemUM( - count = 4, - text = resourceReference(R.string.tangempay_card_details_open_wallet_step_4), - ), - TangemPayAddToWalletStepItemUM( - count = 5, - text = resourceReference(R.string.tangempay_card_details_open_wallet_step_5), - ), - ), - showAddToWalletButton = true, - onBackClick = {}, - onClickOpenWallet = {}, - ), - cardDetailsState = TangemPayCardDetailsUM( - number = "", - numberShort = "*1245", - expiry = "••/••", - cvv = "•••", - onCopy = { _, _ -> }, - onClick = {}, - buttonText = TextReference.Res(R.string.tangempay_card_details_hide_text), - cardFrozenState = TangemPayCardFrozenState.Unfrozen, - displayNameState = null, - cardImageUrl = 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 e7ba2a0cd0..c80ae213d7 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 @@ -21,7 +21,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.graphicsLayer @@ -57,7 +56,6 @@ import com.tangem.core.ui.components.buttons.common.TangemButtonSize import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.ds2.button.TangemButton import com.tangem.core.ui.extensions.conditional -import com.tangem.core.ui.extensions.conditionalCompose import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.* @@ -118,7 +116,6 @@ internal fun TangemPayCard(state: TangemPayCardDetailsUM, modifier: Modifier = M @Suppress("LongMethod", "DestructuringDeclarationWithTooManyEntries") @Composable private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modifier: Modifier = Modifier) { - val isRedesignEnabled = LocalVisaRedesignEnabled.current Box(modifier = modifier.fillMaxSize()) { TangemPayCardBackground( modifier = Modifier @@ -163,24 +160,7 @@ private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modif ) when (state.cardFrozenState) { - TangemPayCardFrozenState.Frozen -> { - if (!isRedesignEnabled) { - Icon( - modifier = Modifier - .constrainAs(frozenIconRef) { - start.linkTo(cardNumberRef.end, margin = 4.dp) - top.linkTo(cardNumberRef.top) - bottom.linkTo(cardNumberRef.bottom) - } - .padding(bottom = 8.dp) - .size(16.dp) - .testTag(TangemPayTestTags.CARD_FROZEN_BADGE), - painter = painterResource(id = R.drawable.ic_snow_24), - contentDescription = null, - tint = TangemTheme.colors.icon.constant, - ) - } - } + TangemPayCardFrozenState.Frozen -> Unit TangemPayCardFrozenState.Pending -> CircularProgressIndicator( modifier = Modifier .constrainAs(frozenIconRef) { @@ -203,9 +183,7 @@ private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modif bottom.linkTo(parent.bottom) } .testTag(TangemPayTestTags.CARD_DETAILS_SHOW_BUTTON), - visible = !isRedesignEnabled || - state.isLoading || - state.shouldShowCardDetailsButtonOnCard, + visible = state.isLoading || state.shouldShowCardDetailsButtonOnCard, ) { TangemPayCardDetailsCustomButton( text = stringResourceSafe(id = R.string.tangempay_card_details_show_details), @@ -286,8 +264,7 @@ private fun CardBgWrapper( back: @Composable () -> Unit, front: @Composable () -> Unit, ) { - val isRedesignEnabled = LocalVisaRedesignEnabled.current - val shouldShowDetailsBg = shouldShowDetails && isRedesignEnabled + val shouldShowDetailsBg = shouldShowDetails Box( modifier = modifier .fillMaxWidth() @@ -295,32 +272,13 @@ private fun CardBgWrapper( rotationY = rotateCardY cameraDistance = zAxisDistance } - .conditionalCompose( - condition = isRedesignEnabled, - modifier = { - clip(RoundedCornerShape(TangemTheme.dimens2.x5)) - .border( - width = 1.dp, - shape = RoundedCornerShape(TangemTheme.dimens2.x5), - color = TangemTheme.colors3.border.secondary, - ) - .background(CardBackgroundColor) - }, - otherModifier = { - clip(RoundedCornerShape(16.dp)) - .background(CardBackgroundColor) - .border( - width = 1.dp, - brush = Brush.linearGradient( - colors = listOf( - TangemTheme.colors.text.constantWhite.copy(alpha = 0.1F), - TangemTheme.colors.text.constantWhite.copy(alpha = 0f), - ), - ), - shape = RoundedCornerShape(16.dp), - ) - }, - ), + .clip(RoundedCornerShape(TangemTheme.dimens2.x5)) + .border( + width = 1.dp, + shape = RoundedCornerShape(TangemTheme.dimens2.x5), + color = TangemTheme.colors3.border.secondary, + ) + .background(CardBackgroundColor), ) { EqualHeightCardSides( modifier = Modifier.fillMaxWidth(), @@ -400,30 +358,17 @@ private fun CardTopBlock(modifier: Modifier = Modifier) { verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp), ) { - if (LocalVisaRedesignEnabled.current) { - Text( - text = stringResourceSafe(R.string.tangempay_digital_card), - style = TangemTheme.typography3.body.medium, - color = TangemTheme.colors3.text.staticDark.primary, - ) - Icon( - modifier = Modifier.size(TangemTheme.dimens2.x5), - imageVector = ImageVector.vectorResource(R.drawable.ic_cloud_fill_16), - tint = TangemTheme.colors3.icon.staticDark, - contentDescription = null, - ) - } else { - Icon( - painter = painterResource(R.drawable.ic_cloud_fill_16), - tint = TangemTheme.colors.icon.constant, - contentDescription = null, - ) - Text( - text = stringResourceSafe(R.string.tangempay_digital_card), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.constantWhite, - ) - } + Text( + text = stringResourceSafe(R.string.tangempay_digital_card), + style = TangemTheme.typography3.body.medium, + color = TangemTheme.colors3.text.staticDark.primary, + ) + Icon( + modifier = Modifier.size(TangemTheme.dimens2.x5), + imageVector = ImageVector.vectorResource(R.drawable.ic_cloud_fill_16), + tint = TangemTheme.colors3.icon.staticDark, + contentDescription = null, + ) } } @@ -434,36 +379,22 @@ private fun ConstraintLayoutScope.CardNumberBlock( cardNumberRef: ConstrainedLayoutReference, modifier: Modifier = Modifier, ) { - if (LocalVisaRedesignEnabled.current) { - Text( - text = numberShort, - style = TangemTheme.typography3.body.medium, - color = if (isRenaming) { - TangemTheme.colors3.text.staticDark.secondary - } else { - TangemTheme.colors3.text.staticDark.primary - }, - modifier = modifier - .constrainAs(cardNumberRef) { - start.linkTo(parent.start) - bottom.linkTo(parent.bottom) - } - .padding(bottom = 8.dp) - .testTag(TangemPayTestTags.CARD_NUMBER_SHORT), - ) - } else { - Text( - text = numberShort, - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.constantWhite, - modifier = modifier - .constrainAs(cardNumberRef) { - start.linkTo(parent.start) - bottom.linkTo(parent.bottom) - } - .padding(bottom = 8.dp), - ) - } + Text( + text = numberShort, + style = TangemTheme.typography3.body.medium, + color = if (isRenaming) { + TangemTheme.colors3.text.staticDark.secondary + } else { + TangemTheme.colors3.text.staticDark.primary + }, + modifier = modifier + .constrainAs(cardNumberRef) { + start.linkTo(parent.start) + bottom.linkTo(parent.bottom) + } + .padding(bottom = 8.dp) + .testTag(TangemPayTestTags.CARD_NUMBER_SHORT), + ) } @Composable @@ -476,67 +407,37 @@ private fun CardDisplayName(state: DisplayNameState, modifier: Modifier = Modifi @Composable private fun DisplayOnlyCardDisplayName(state: DisplayNameState.Display, modifier: Modifier = Modifier) { - if (LocalVisaRedesignEnabled.current) { - Row( - modifier = modifier.conditional( - condition = state.isEditingEnabled, - modifier = { clickable(onClick = state.onClick) }, - ), - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = state.displayName, - style = TangemTheme.typography3.body.medium, - color = TangemTheme.colors3.text.staticDark.secondary, - maxLines = 1, + Row( + modifier = modifier.conditional( + condition = state.isEditingEnabled, + modifier = { clickable(onClick = state.onClick) }, + ), + horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = state.displayName, + style = TangemTheme.typography3.body.medium, + color = TangemTheme.colors3.text.staticDark.secondary, + maxLines = 1, + ) + if (state.isEditingEnabled) { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_edit_card_20), + contentDescription = null, + modifier = Modifier.size(TangemTheme.dimens2.x5), + tint = TangemTheme.colors3.icon.staticDark, ) - if (state.isEditingEnabled) { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_edit_card_20), - contentDescription = null, - modifier = Modifier.size(TangemTheme.dimens2.x5), - tint = TangemTheme.colors3.icon.staticDark, - ) - } - } - } else { - Row( - modifier = modifier.conditional( - condition = state.isEditingEnabled, - modifier = { clickable(onClick = state.onClick) }, - ), - horizontalArrangement = Arrangement.spacedBy(6.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = state.displayName, - style = TangemTheme.typography.caption1.copy(color = TangemTheme.colors.text.constantWhite), - maxLines = 1, - ) - if (state.isEditingEnabled) { - Icon( - painter = painterResource(id = R.drawable.ic_edit_new_12), - contentDescription = null, - modifier = Modifier.size(10.dp), - tint = TangemTheme.colors.text.constantWhite, - ) - } } } } @Composable private fun EditingCardDisplayName(state: DisplayNameState.Editing, modifier: Modifier = Modifier) { - val isRedesignEnabled = LocalVisaRedesignEnabled.current val focusRequester = remember { FocusRequester() } val placeholder = stringResourceSafe(R.string.tangempay_card_edit_name_placeholder) - val textStyle = if (isRedesignEnabled) { - TangemTheme.typography3.body.medium.copy(color = TangemTheme.colors3.text.staticDark.primary) - } else { - TangemTheme.typography.caption1.copy(color = TangemTheme.colors.text.constantWhite) - } + val textStyle = TangemTheme.typography3.body.medium.copy(color = TangemTheme.colors3.text.staticDark.primary) val textMeasurer = rememberTextMeasurer() val measuredText = state.editingValue.text.ifEmpty { placeholder } val textWidthDp = with(LocalDensity.current) { @@ -551,11 +452,7 @@ private fun EditingCardDisplayName(state: DisplayNameState.Editing, modifier: Mo .focusRequester(focusRequester), textStyle = textStyle, singleLine = true, - cursorBrush = if (isRedesignEnabled) { - SolidColor(TangemTheme.colors3.text.staticDark.primary) - } else { - SolidColor(TangemTheme.colors.text.constantWhite) - }, + cursorBrush = SolidColor(TangemTheme.colors3.text.staticDark.primary), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardActions = KeyboardActions( onDone = if (state.isSubmitEnabled) { @@ -569,13 +466,7 @@ private fun EditingCardDisplayName(state: DisplayNameState.Editing, modifier: Mo if (state.editingValue.text.isEmpty()) { Text( text = placeholder, - style = textStyle.copy( - color = if (isRedesignEnabled) { - TangemTheme.colors3.text.staticDark.secondary - } else { - TangemTheme.colors.text.tertiary - }, - ), + style = textStyle.copy(color = TangemTheme.colors3.text.staticDark.secondary), ) } innerTextField() @@ -640,30 +531,19 @@ private fun TangemPayCardDetailsShownBlock( Spacer(modifier = Modifier.weight(1f)) Row { SpacerWMax() - if (LocalVisaRedesignEnabled.current) { - // Must use dark theme locally for button cause card is dark - CompositionLocalProvider(LocalIsInDarkTheme provides true) { - TangemThemeRedesign { - TangemButton( - modifier = Modifier - .padding(end = 16.dp, bottom = 8.dp) - .testTag(TangemPayTestTags.CARD_DETAILS_HIDE_BUTTON), - variant = TangemButton.Variant.Material, - size = TangemButton.Size.X8, - onClick = onHideDetails, - iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_20), - ) - } + // Must use dark theme locally for button cause card is dark + CompositionLocalProvider(LocalIsInDarkTheme provides true) { + TangemThemeRedesign { + TangemButton( + modifier = Modifier + .padding(end = 16.dp, bottom = 8.dp) + .testTag(TangemPayTestTags.CARD_DETAILS_HIDE_BUTTON), + variant = TangemButton.Variant.Material, + size = TangemButton.Size.X8, + onClick = onHideDetails, + iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_20), + ) } - } else { - TangemPayCardDetailsCustomButton( - modifier = Modifier - .padding(end = 16.dp, bottom = 8.dp) - .testTag(TangemPayTestTags.CARD_DETAILS_HIDE_BUTTON), - text = stringResourceSafe(id = R.string.tangempay_card_details_hide_details), - onClick = onHideDetails, - showProgress = false, - ) } } } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardPageScreen.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardPageScreen.kt index 9ea6c1f59e..75784a1e20 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardPageScreen.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardPageScreen.kt @@ -6,8 +6,6 @@ import androidx.compose.animation.core.MutableTransitionState import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyItemScope @@ -16,7 +14,6 @@ import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.Scaffold import androidx.compose.material3.ScaffoldDefaults -import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment @@ -25,9 +22,7 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.util.fastForEach import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.tangem.core.ui.components.appbar.AppBarWithBackButton import com.tangem.core.ui.ds.TangemPagerIndicator import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.ds.topbar.TangemTopBar @@ -74,7 +69,6 @@ private fun TangemPayCardPageScreen( modifier: Modifier = Modifier, cardSection: @Composable () -> Unit, ) { - val isRedesignEnabled = LocalVisaRedesignEnabled.current Scaffold( modifier = modifier, topBar = { @@ -84,15 +78,11 @@ private fun TangemPayCardPageScreen( ) }, contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars), - containerColor = if (isRedesignEnabled) { - TangemTheme.colors3.bg.primary - } else { - TangemTheme.colors.background.secondary - }, + containerColor = TangemTheme.colors3.bg.primary, ) { scaffoldPaddings -> val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } val contentBottomPadding = TangemTheme.dimens.spacing16 + bottomBarHeight - val reissueTitle = reissueTitleOrNull(isRedesignEnabled = isRedesignEnabled, cardState = state.cardState) + val reissueTitle = reissueTitleOrNull(cardState = state.cardState) if (reissueTitle != null) { ReissueCardLayout( @@ -109,9 +99,7 @@ private fun TangemPayCardPageScreen( .fillMaxSize() .padding(scaffoldPaddings), contentPadding = PaddingValues(bottom = contentBottomPadding), - verticalArrangement = Arrangement.spacedBy( - if (isRedesignEnabled) 0.dp else TangemTheme.dimens.spacing16, - ), + verticalArrangement = Arrangement.spacedBy(0.dp), ) { item(key = "Card") { Box(modifier = Modifier.padding(top = TangemTheme.dimens.spacing8)) { @@ -119,7 +107,6 @@ private fun TangemPayCardPageScreen( } } if ( - isRedesignEnabled && state.settingsV2.isNotEmpty() && state.cardState == TangemPayCardState.Active ) { @@ -136,8 +123,7 @@ private fun TangemPayCardPageScreen( } } -private fun reissueTitleOrNull(isRedesignEnabled: Boolean, cardState: TangemPayCardState): TextReference? { - if (!isRedesignEnabled) return null +private fun reissueTitleOrNull(cardState: TangemPayCardState): TextReference? { return when (cardState) { TangemPayCardState.Reissuing -> combinedReference( resourceReference(R.string.tangempay_reissue_card_in_progress), @@ -243,95 +229,14 @@ private fun CardDetailsPage(controller: TangemPayCardDetailsController, modifier } private fun LazyListScope.cardState(state: TangemPayCardPageUM) { - when (state.cardState) { - TangemPayCardState.Active -> { - if (state.addToWalletBlockState != null) { - cardPageItem(key = "GooglePay") { - TangemPayAddToWalletBlock(state = state.addToWalletBlockState) - } - } - cardPageItem(key = "Limit") { - TangemPayDailyLimitBlock(state = state.dailyLimitState) - } - if (state.dailyLimitState is TangemPayDailyLimitBlockState.Error) { - cardPageItem(key = "LimitError") { - TangemPayDailyLimitErrorBlock() - } - } - cardPageItem(key = "Settings") { - TangemPayCardPageSettingsBlock(settings = state.settings) - } - } - TangemPayCardState.Reissuing -> cardPageItem(key = "Reissue") { - TangemPayReplacingCardBlock() - } - TangemPayCardState.Closing -> cardPageItem(key = "Closing") { - TangemPayReplacingCardBlock( - title = resourceReference(R.string.tangempay_card_page_closing_banner_title), - subtitle = resourceReference(R.string.tangempay_card_page_closing_banner_description), - ) - } - TangemPayCardState.Issuing -> cardPageItem(key = "Issuing") { - TangemPayReplacingCardBlock( - title = resourceReference(R.string.tangempay_issuing_new_digital_card_title), - subtitle = resourceReference(R.string.tangempay_reissue_card_in_progress_description), - ) + if (state.cardState != TangemPayCardState.Active) return + if (state.addToWalletBlockState != null) { + cardPageItem(key = "GooglePay") { + TangemPayAddToWalletBlock(state = state.addToWalletBlockState) } } -} - -@Composable -private fun TangemPayCardPageSettingsBlock( - settings: ImmutableList, - modifier: Modifier = Modifier, -) { - if (LocalVisaRedesignEnabled.current) return - Column( - modifier = modifier - .fillMaxWidth() - .background( - color = TangemTheme.colors.background.primary, - shape = TangemTheme.shapes.roundedCornersMedium, - ), - ) { - Text( - modifier = Modifier.padding( - start = TangemTheme.dimens.spacing12, - top = TangemTheme.dimens.spacing12, - bottom = TangemTheme.dimens.spacing4, - ), - text = stringResourceSafe(R.string.tangempay_card_page_settings_title), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - ) - settings.fastForEach { item -> - TangemPayCardPageSettingRow( - item = item, - onClick = item.onSettingClick, - ) - } - } -} - -@Composable -private fun TangemPayCardPageSettingRow( - item: TangemPayCardPageSetting, - onClick: () -> Unit, - modifier: Modifier = Modifier, -) { - Box( - modifier = modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(TangemTheme.dimens.spacing12) - .then(if (item.testTag != null) Modifier.testTag(item.testTag) else Modifier), - contentAlignment = Alignment.CenterStart, - ) { - Text( - text = item.title.resolveReference(), - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - ) + cardPageItem(key = "Limit") { + TangemPayDailyLimitBlock(state = state.dailyLimitState) } } @@ -341,41 +246,34 @@ private fun CardPageTopBar( items: ImmutableList, modifier: Modifier = Modifier, ) { - if (LocalVisaRedesignEnabled.current) { - var isDropdownMenuShown by rememberSaveable { mutableStateOf(false) } - TangemTopBar( - modifier = modifier.statusBarsPadding(), - startContent = { + var isDropdownMenuShown by rememberSaveable { mutableStateOf(false) } + TangemTopBar( + modifier = modifier.statusBarsPadding(), + startContent = { + TangemButton( + iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_arrow_back_28), + onClick = onBackClick, + size = TangemButton.Size.X11, + variant = TangemButton.Variant.Material, + ) + }, + endContent = { + Box { TangemButton( - iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_arrow_back_28), - onClick = onBackClick, + modifier = Modifier.testTag(TangemPayTestTags.CARD_PAGE_MORE_BUTTON), + iconStart = TangemIconUM.Icon(iconRes = CoreUiR.drawable.ic_more_default_24), + onClick = { isDropdownMenuShown = true }, size = TangemButton.Size.X11, variant = TangemButton.Variant.Material, ) - }, - endContent = { - Box { - TangemButton( - modifier = Modifier.testTag(TangemPayTestTags.CARD_PAGE_MORE_BUTTON), - iconStart = TangemIconUM.Icon(iconRes = CoreUiR.drawable.ic_more_default_24), - onClick = { isDropdownMenuShown = true }, - size = TangemButton.Size.X11, - variant = TangemButton.Variant.Material, - ) - PayContextMenuBlock( - items = items, - onMenuDismiss = { isDropdownMenuShown = false }, - isDropdownMenuShown = isDropdownMenuShown, - ) - } - }, - ) - } else { - AppBarWithBackButton( - modifier = modifier.statusBarsPadding(), - onBackClick = onBackClick, - ) - } + PayContextMenuBlock( + items = items, + onMenuDismiss = { isDropdownMenuShown = false }, + isDropdownMenuShown = isDropdownMenuShown, + ) + } + }, + ) } private fun LazyListScope.cardPageItem( @@ -400,23 +298,6 @@ private fun LazyListScope.cardPageItem( } } -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun TangemPayCardPageScreenPreviewV1() { - TangemThemePreview { - TangemPayCardPageScreen( - state = TangemPayCardPageUM.stub(), - cardSection = { - TangemPayCard( - state = previewCardDetailsState(), - modifier = Modifier.padding(horizontal = 16.dp), - ) - }, - ) - } -} - private fun previewCardDetailsState(): TangemPayCardDetailsUM = TangemPayCardDetailsUM( number = "•••• •••• •••• 1245", numberShort = "··1245", @@ -440,7 +321,6 @@ private fun TangemPayCardPageScreenPreviewV2() { TangemThemePreviewRedesign { CompositionLocalProvider( LocalRedesignEnabled provides true, - LocalVisaRedesignEnabled provides true, ) { TangemPayCardPageScreen( state = TangemPayCardPageUM.stub(), diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayChangePinCodeSuccessScreen.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayChangePinCodeSuccessScreen.kt deleted file mode 100644 index eda90333b9..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayChangePinCodeSuccessScreen.kt +++ /dev/null @@ -1,134 +0,0 @@ -package com.tangem.features.tangempay.ui - -import androidx.compose.foundation.layout.* -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.airbnb.lottie.compose.LottieAnimation -import com.airbnb.lottie.compose.LottieCompositionSpec -import com.airbnb.lottie.compose.animateLottieCompositionAsState -import com.airbnb.lottie.compose.rememberLottieComposition -import com.tangem.core.ui.components.* -import com.tangem.core.ui.components.appbar.TangemTopAppBar -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.test.TangemPayTestTags -import com.tangem.features.tangempay.details.impl.R - -@Composable -internal fun TangemPayChangePinCodeSuccessScreen(onClick: () -> Unit, modifier: Modifier = Modifier) { - val composition by rememberLottieComposition(spec = LottieCompositionSpec.RawRes(R.raw.anim_confetti)) - val progress by animateLottieCompositionAsState(composition) - var showConfetti by remember { mutableStateOf(false) } - - Column( - modifier = modifier - .fillMaxSize() - .navigationBarsPadding(), - ) { - TangemTopAppBar( - modifier = Modifier.statusBarsPadding(), - title = resourceReference(R.string.common_done).resolveReference(), - startButton = null, - titleAlignment = Alignment.CenterHorizontally, - ) - Column( - modifier = Modifier - .fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - SuccessContent( - modifier = Modifier - .fillMaxWidth() - .weight(1f), - ) - - PrimaryButton( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 16.dp) - .navigationBarsPadding() - .testTag(TangemPayTestTags.PIN_DONE_BUTTON), - text = stringResourceSafe(R.string.common_done), - onClick = onClick, - ) - } - - if (showConfetti) { - FullScreen(notTouchable = true) { - LottieAnimation( - composition = composition, - progress = { progress }, - ) - } - } - - LaunchedEffect(Unit) { - showConfetti = true - } - - LaunchedEffect(progress == 1f) { - if (progress == 1f) { - showConfetti = false - } - } - } -} - -@Composable -private fun SuccessContent(modifier: Modifier = Modifier) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_success_blue_76), - tint = Color.Unspecified, - contentDescription = null, - modifier = Modifier - .size(76.dp), - ) - SpacerH32() - Text( - modifier = Modifier - .padding(horizontal = 32.dp) - .testTag(TangemPayTestTags.PIN_SUCCESS_TITLE), - text = stringResourceSafe(R.string.tangempay_card_details_change_pin_success_title), - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - ) - SpacerH12() - Text( - modifier = Modifier - .padding(horizontal = 32.dp) - .testTag(TangemPayTestTags.PIN_SUCCESS_DESCRIPTION), - text = stringResourceSafe(R.string.tangempay_card_details_change_pin_success_description), - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.secondary, - textAlign = TextAlign.Center, - ) - SpacerH(72.dp) - } -} - -@Preview(showBackground = true) -@Composable -private fun Preview() { - TangemThemePreview { - TangemPayChangePinCodeSuccessScreen(onClick = {}) - } -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayChangePinScreen.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayChangePinScreen.kt deleted file mode 100644 index 88a3a9ca2e..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayChangePinScreen.kt +++ /dev/null @@ -1,192 +0,0 @@ -package com.tangem.features.tangempay.ui - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.graphics.Color.Companion.Transparent -import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import com.tangem.common.ui.navigationButtons.NavigationButton -import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton -import com.tangem.core.ui.components.SpacerH -import com.tangem.core.ui.components.SpacerH16 -import com.tangem.core.ui.components.SpacerH4 -import com.tangem.core.ui.components.appbar.AppBarWithBackButton -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.test.TangemPayTestTags -import com.tangem.features.tangempay.details.impl.R -import com.tangem.features.tangempay.entity.TangemPayChangePinUM -import kotlinx.coroutines.delay - -@Composable -internal fun TangemPayChangePinScreen( - state: TangemPayChangePinUM, - onBackClick: () -> Unit, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier - .fillMaxSize() - .navigationBarsPadding(), - ) { - AppBarWithBackButton( - modifier = Modifier.statusBarsPadding(), - onBackClick = onBackClick, - ) - - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 48.dp) - .padding(horizontal = 36.dp) - .weight(1f), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - text = stringResourceSafe(R.string.visa_onboarding_pin_code_title), - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - modifier = Modifier.testTag(TangemPayTestTags.PIN_SCREEN_TITLE), - ) - - SpacerH16() - - Text( - text = stringResourceSafe(R.string.visa_onboarding_pin_code_description), - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.secondary, - textAlign = TextAlign.Center, - modifier = Modifier.testTag(TangemPayTestTags.PIN_SCREEN_DESCRIPTION), - ) - - SpacerH(26.dp) - - PinCodeSection(state) - } - - NavigationPrimaryButton( - modifier = Modifier - .imePadding() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp) - .fillMaxWidth() - .testTag(TangemPayTestTags.PIN_SUBMIT_BUTTON), - primaryButton = NavigationButton( - textReference = resourceReference(R.string.common_submit), - onClick = state.onSubmitClick, - shouldShowProgress = state.submitButtonLoading, - isEnabled = state.submitButtonEnabled, - ), - ) - } -} - -@Composable -private fun PinCodeSection(state: TangemPayChangePinUM, modifier: Modifier = Modifier) { - val focusRequester = remember { FocusRequester() } - Column(horizontalAlignment = Alignment.CenterHorizontally) { - PinCode( - modifier = modifier, - value = state.pinCode, - onValueChange = state.onPinCodeChange, - focusRequester = focusRequester, - ) - - AnimatedVisibility( - visible = state.error != null, - ) { - val error = remember(this) { requireNotNull(state.error) } - Column { - SpacerH4() - Text( - text = error.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.warning, - textAlign = TextAlign.Center, - modifier = Modifier.testTag(TangemPayTestTags.PIN_ERROR_MESSAGE), - ) - } - } - } - - LaunchedEffect(Unit) { - delay(timeMillis = 300) - focusRequester.requestFocus() - } -} - -@Composable -private fun PinCode( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier = Modifier, - numbersCount: Int = 4, - focusRequester: FocusRequester = remember { FocusRequester() }, -) { - val keyboardController = LocalSoftwareKeyboardController.current - - BasicTextField( - value = value, - onValueChange = { text -> - if (text.length <= numbersCount) { - onValueChange(text) - } - }, - modifier = modifier - .focusRequester(focusRequester) - .clickable { - focusRequester.requestFocus() - keyboardController?.show() - } - .testTag(TangemPayTestTags.PIN_INPUT_FIELD), - textStyle = TangemTheme.typography.h1.copy(color = Transparent), - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.NumberPassword, - imeAction = ImeAction.Done, - ), - keyboardActions = KeyboardActions(onDone = { keyboardController?.hide() }), - cursorBrush = SolidColor(Transparent), - decorationBox = { innerTextField -> - Box( - modifier = Modifier.fillMaxWidth(), - contentAlignment = Alignment.Center, - ) { - Row( - horizontalArrangement = Arrangement.spacedBy(12.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - repeat(numbersCount) { index -> - val digit = value.getOrNull(index)?.toString() - PinDigitBox( - digit = digit, - backgroundColor = TangemTheme.colors.field.focused, - borderColor = TangemTheme.colors.stroke.primary, - textColor = TangemTheme.colors.text.primary1, - textStyle = TangemTheme.typography.h1, - ) - } - } - innerTextField() - } - }, - ) -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDailyLimitBlock.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDailyLimitBlock.kt index 8f8cf0f980..2454853469 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDailyLimitBlock.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDailyLimitBlock.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon -import androidx.compose.material3.LocalMinimumInteractiveComponentSize import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -16,15 +15,10 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.layoutId import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.* -import com.tangem.core.ui.components.buttons.common.TangemButtonSize -import com.tangem.core.ui.components.notifications.Notification -import com.tangem.core.ui.components.notifications.NotificationConfig import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.ds.row.TangemRowContainer import com.tangem.core.ui.ds.row.TangemRowLayoutId @@ -41,92 +35,7 @@ import com.tangem.features.tangempay.entity.TangemPayDailyLimitBlockState @Composable internal fun TangemPayDailyLimitBlock(state: TangemPayDailyLimitBlockState, modifier: Modifier = Modifier) { - if (LocalVisaRedesignEnabled.current) { - CurrentLimitBlockV2(state, modifier.padding(top = TangemTheme.dimens2.x2)) - } else { - TangemPayDailyLimitBlockV1(state, modifier) - } -} - -@Composable -private fun TangemPayDailyLimitBlockV1(state: TangemPayDailyLimitBlockState, modifier: Modifier = Modifier) { - Column( - modifier = modifier - .fillMaxWidth() - .background( - color = TangemTheme.colors.background.primary, - shape = TangemTheme.shapes.roundedCornersMedium, - ) - .padding(TangemTheme.dimens.spacing12), - ) { - Text( - text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_title), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - ) - SpacerH4() - CurrentLimitBlockV1(state) - } -} - -@Composable -private fun CurrentLimitBlockV1(state: TangemPayDailyLimitBlockState) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - ) { - Box( - modifier = Modifier - .size(36.dp) - .background( - color = TangemTheme.colors.icon.accent.copy(alpha = 0.1f), - shape = CircleShape, - ), - contentAlignment = Alignment.Center, - ) { - Icon( - painter = painterResource(R.drawable.ic_limit_20), - contentDescription = null, - tint = TangemTheme.colors.icon.accent, - ) - } - SpacerW12() - Column( - modifier = Modifier.weight(1f), - ) { - Text( - text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_current_limit), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - ) - when (state) { - is TangemPayDailyLimitBlockState.Error, - is TangemPayDailyLimitBlockState.Content, - -> Text( - text = if (state is TangemPayDailyLimitBlockState.Content) state.limit else "—", - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - TangemPayDailyLimitBlockState.Loading -> TextShimmer( - style = TangemTheme.typography.subtitle1, - text = "$50,000", - ) - } - } - SpacerW8() - if (state is TangemPayDailyLimitBlockState.Content) { - CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) { - SecondaryButton( - modifier = Modifier, - text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_change), - onClick = state.onChangeClick, - size = TangemButtonSize.Small, - ) - } - } - } + CurrentLimitBlockV2(state, modifier.padding(top = TangemTheme.dimens2.x2)) } @Composable @@ -279,36 +188,6 @@ private fun SubtitleLimit(state: TangemPayDailyLimitBlockState, modifier: Modifi } } -@Composable -internal fun TangemPayDailyLimitErrorBlock(modifier: Modifier = Modifier) { - if (LocalVisaRedesignEnabled.current) return - Notification( - config = NotificationConfig( - title = resourceReference(R.string.tangempay_card_page_daily_limit_error_title), - subtitle = resourceReference(R.string.tangempay_card_page_daily_limit_error_description), - iconResId = R.drawable.img_attention_20, - ), - containerColor = TangemTheme.colors.background.action, - modifier = modifier.fillMaxWidth(), - ) -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview() { - TangemThemePreview { - Column( - verticalArrangement = Arrangement.spacedBy(16.dp), - ) { - TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Content.stub()) - TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Error(onReloadClick = {})) - TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Loading) - TangemPayDailyLimitErrorBlock() - } - } -} - @Preview @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable @@ -316,7 +195,6 @@ private fun PreviewV2() { TangemThemePreviewRedesign { CompositionLocalProvider( LocalRedesignEnabled provides true, - LocalVisaRedesignEnabled provides true, ) { Column( verticalArrangement = Arrangement.spacedBy(16.dp), @@ -324,7 +202,6 @@ private fun PreviewV2() { TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Content.stub()) TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Error(onReloadClick = {})) TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Loading) - TangemPayDailyLimitErrorBlock() } } } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsPreviewProviders.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsPreviewProviders.kt new file mode 100644 index 0000000000..eddeb4296f --- /dev/null +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsPreviewProviders.kt @@ -0,0 +1,140 @@ +package com.tangem.features.tangempay.ui + +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig +import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig +import com.tangem.core.ui.components.notifications.NotificationConfig +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.combinedReference +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.extensions.styledStringReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.features.tangempay.components.txHistory.PreviewTangemPayTxHistoryComponent +import com.tangem.features.tangempay.details.impl.R +import com.tangem.features.tangempay.entity.AddToWalletBlockState +import com.tangem.features.tangempay.entity.CardsProgressBannerUM +import com.tangem.features.tangempay.entity.TangemPayAction +import com.tangem.features.tangempay.entity.TangemPayActionButtonUM +import com.tangem.features.tangempay.entity.TangemPayCardUiState +import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState +import com.tangem.features.tangempay.entity.TangemPayDetailsTopBarConfig +import com.tangem.features.tangempay.entity.TangemPayDetailsUM +import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM +import kotlinx.collections.immutable.persistentListOf + +internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider( + collection = listOf( + TangemPayDetailsUM( + topBarConfig = TangemPayDetailsTopBarConfig( + onBackClick = {}, + onOpenMenu = {}, + items = persistentListOf(), + itemsV2 = persistentListOf(), + ), + pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}), + balanceBlockState = TangemPayDetailsBalanceBlockState.Content( + actionButtons = persistentListOf( + TangemPayActionButtonUM( + action = TangemPayAction.AddFunds, + config = ActionButtonConfig( + text = resourceReference(id = R.string.common_receive), + iconResId = R.drawable.ic_arrow_down_24, + onClick = {}, + ), + ), + ), + fiatBalance = combinedReference( + stringReference("1,234"), + styledStringReference( + ".56", + { SpanStyle(color = TangemTheme.colors3.text.primary) }, + ), + stringReference(" $"), + ), + isBalanceFlickering = false, + cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState( + cards = persistentListOf( + TangemPayDetailsBalanceBlockState.Card( + lastDigits = "1234", + imageUrl = null, + onClick = {}, + isEnabled = false, + isFrozen = false, + state = TangemPayCardUiState.Active, + ), + TangemPayDetailsBalanceBlockState.Card( + lastDigits = "3456", + imageUrl = null, + onClick = {}, + isEnabled = true, + isFrozen = false, + state = TangemPayCardUiState.Active, + ), + ), + onAddCardClick = {}, + isAddCardEnabled = true, + ), + isNegative = false, + isInactive = false, + ), + isBalanceHidden = false, + addToWalletBlockState = AddToWalletBlockState( + onClick = {}, + onClickClose = {}, + ), + accountDeactivatedNotificationConfig = null, + errorNotificationConfig = null, + ), + TangemPayDetailsUM( + topBarConfig = TangemPayDetailsTopBarConfig( + onBackClick = {}, + onOpenMenu = {}, + items = persistentListOf(), + itemsV2 = persistentListOf(), + ), + pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}), + balanceBlockState = TangemPayDetailsBalanceBlockState.Loading( + actionButtons = persistentListOf(), + cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState( + cards = persistentListOf( + TangemPayDetailsBalanceBlockState.Card( + lastDigits = "1234", + imageUrl = null, + onClick = {}, + isFrozen = false, + isEnabled = true, + state = TangemPayCardUiState.InProgress, + ), + ), + onAddCardClick = {}, + isAddCardEnabled = true, + progressBanner = CardsProgressBannerUM.Reissuing, + ), + ), + isBalanceHidden = false, + addToWalletBlockState = null, + accountDeactivatedNotificationConfig = null, + errorNotificationConfig = NotificationConfig( + title = TextReference.Str("Error title"), + subtitle = TextReference.Str("Error subtitle"), + iconResId = R.drawable.ic_alert_circle_24, + buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( + text = TextReference.Str("Error btn text"), + onClick = {}, + iconResId = R.drawable.ic_tangem_24, + ), + ), + ), + ), +) + +internal class TangemPayDetailsTxHistoryProvider : CollectionPreviewParameterProvider( + collection = listOf( + PreviewTangemPayTxHistoryComponent.loadingUM, + PreviewTangemPayTxHistoryComponent.contentUM, + PreviewTangemPayTxHistoryComponent.emptyUM, + PreviewTangemPayTxHistoryComponent.errorUM, + ), +) \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreen.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreen.kt deleted file mode 100644 index a68b7a0a4a..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreen.kt +++ /dev/null @@ -1,587 +0,0 @@ -package com.tangem.features.tangempay.ui - -import android.content.res.Configuration -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -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 -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.tooling.preview.Devices -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.util.fastForEach -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.tangem.core.ui.components.RectangleShimmer -import com.tangem.core.ui.components.SpacerH12 -import com.tangem.core.ui.components.buttons.HorizontalActionChips -import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig -import com.tangem.core.ui.components.buttons.small.TangemIconButton -import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig -import com.tangem.core.ui.components.containers.pullToRefresh.TangemPullToRefreshContainer -import com.tangem.core.ui.components.dropdownmenu.TangemDropdownItem -import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenu -import com.tangem.core.ui.components.notifications.Notification -import com.tangem.core.ui.components.notifications.NotificationConfig -import com.tangem.core.ui.components.text.applyBladeBrush -import com.tangem.core.ui.extensions.* -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.test.TangemPayTestTags -import com.tangem.core.ui.test.TokenDetailsTopBarTestTags -import com.tangem.core.ui.test.WalletConnectBottomSheetTestTags -import com.tangem.features.tangempay.components.express.PreviewEmptyExpressTransactionsComponent -import com.tangem.features.tangempay.components.txHistory.PreviewTangemPayTxHistoryComponent -import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryComponent -import com.tangem.features.tangempay.details.impl.R -import com.tangem.features.tangempay.entity.* -import com.tangem.features.tokendetails.ExpressTransactionsComponent -import com.tangem.utils.StringsSigns.DASH_SIGN -import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList - -private const val DISABLED_ALPHA = 0.5f - -@Suppress("LongMethod") -@Composable -internal fun TangemPayDetailsScreen( - state: TangemPayDetailsUM, - txHistoryComponent: TangemPayTxHistoryComponent, - expressTransactionsComponent: ExpressTransactionsComponent, - modifier: Modifier = Modifier, -) { - Scaffold( - modifier = modifier, - topBar = { TangemPayDetailsTopAppBar(config = state.topBarConfig) }, - contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars), - containerColor = TangemTheme.colors.background.secondary, - ) { scaffoldPaddings -> - val listState = rememberLazyListState() - val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } - val txHistoryState by txHistoryComponent.state.collectAsStateWithLifecycle() - val expressState by expressTransactionsComponent.state.collectAsStateWithLifecycle() - val expressTransactionsBottomSheetState = expressState.bottomSheetSlot - - TangemPullToRefreshContainer( - config = state.pullToRefreshConfig, - modifier = Modifier.padding(scaffoldPaddings), - ) { - LazyColumn( - modifier = Modifier.fillMaxSize(), - state = listState, - contentPadding = PaddingValues( - bottom = TangemTheme.dimens.spacing16 + bottomBarHeight, - ), - ) { - item(key = "title") { - TangemPayTitle( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .padding(top = 4.dp) - .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 = { - TangemPayDetailsBalanceBlock( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .padding(top = 12.dp) - .fillMaxWidth(), - state = state.balanceBlockState, - isBalanceHidden = state.isBalanceHidden, - ) - SpacerH12() - }, - ) - - val progressBanner = state.balanceBlockState.cardsBlockState?.progressBanner - if (progressBanner == CardsProgressBannerUM.Reissuing) { - item( - key = "REISSUE_MESSAGE", - content = { - TangemPayReplacingCardBlock( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - ) - SpacerH12() - }, - ) - } else { - if (state.addToWalletBlockState != null) { - item( - key = AddToWalletBlockState::class.java, - content = { - TangemPayAddToWalletBlock( - state = state.addToWalletBlockState, - modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16), - ) - }, - ) - } - if (state.accountDeactivatedNotificationConfig != null) { - item( - key = "DEACTIVATION_MESSAGE", - content = { - Notification( - modifier = modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - config = state.accountDeactivatedNotificationConfig, - ) - SpacerH12() - }, - ) - } - } - if (state.accountDeactivatedNotificationConfig == null) { - with(expressTransactionsComponent) { - expressTransactionsContentLegacy( - state = expressState.transactionsToDisplay, - modifier = modifier - .padding(horizontal = 16.dp) - .padding(top = 12.dp) - .fillMaxWidth(), - ) - } - with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryState) } - } - } - } - expressTransactionsBottomSheetState?.content(null) - } -} - -@Composable -private fun TangemPayTitle(modifier: Modifier = Modifier) { - Column(modifier = modifier) { - Text( - text = stringResourceSafe(R.string.tangempay_payment_account), - style = TangemTheme.typography.head, - color = TangemTheme.colors.text.primary1, - maxLines = 1, - ) - TangemPaySubtitle() - } -} - -@Suppress("MagicNumber") -@Composable -private fun TangemPaySubtitle(modifier: Modifier = Modifier) { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(4.dp), - ) { - Box(modifier = Modifier.wrapContentWidth()) { - Icon( - painter = painterResource(id = R.drawable.ic_polygon_22), - contentDescription = null, - tint = TangemTheme.colors.text.constantWhite, - modifier = Modifier - .padding(start = TangemTheme.dimens.spacing12) - .border(width = 2.dp, color = TangemTheme.colors.background.secondary, shape = CircleShape) - .padding(2.dp) - .clip(CircleShape) - .background(Color(0xFF8247E5)) - .size(16.dp) - .testTag(WalletConnectBottomSheetTestTags.NETWORKS_ICONS), - ) - Image( - painter = painterResource(id = R.drawable.img_usdc_16), - contentDescription = null, - contentScale = ContentScale.Crop, - modifier = Modifier - .border(width = 2.dp, color = TangemTheme.colors.background.secondary, shape = CircleShape) - .padding(2.dp) - .clip(CircleShape) - .size(16.dp) - .testTag(WalletConnectBottomSheetTestTags.NETWORKS_ICONS), - ) - } - Text( - modifier = Modifier.align(Alignment.CenterVertically), - text = stringResourceSafe(R.string.tangempay_usdc_on_polygon_network), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - ) - } -} - -// region Balance block -@Composable -private fun TangemPayDetailsBalanceBlock( - state: TangemPayDetailsBalanceBlockState, - isBalanceHidden: Boolean, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier - .background( - color = TangemTheme.colors.background.primary, - shape = TangemTheme.shapes.roundedCornersMedium, - ) - .padding(vertical = 12.dp), - ) { - Text( - modifier = Modifier.padding(start = 12.dp), - text = stringResourceSafe(R.string.common_balance_title), - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.subtitle2, - ) - FiatBalance( - modifier = Modifier.padding(start = 12.dp, top = 8.dp), - state = state, - isBalanceHidden = isBalanceHidden, - ) - state.cardsBlockState?.let { cardsBlockState -> - CardsBlockRow( - modifier = Modifier - .wrapContentSize() - .padding(horizontal = 12.dp, vertical = 8.dp), - cardsBlockState = cardsBlockState, - ) - } - if (state.actionButtons.isNotEmpty()) { - HorizontalActionChips( - modifier = Modifier.padding(top = 12.dp), - buttons = state.actionButtons.map { it.config }.toImmutableList(), - containerColor = TangemTheme.colors.background.primary, - contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing12), - ) - } - } -} - -@Composable -private fun CardsBlockRow( - cardsBlockState: TangemPayDetailsBalanceBlockState.CardsBlockState, - modifier: Modifier = Modifier, -) { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(6.dp), - ) { - val itemsModifier = Modifier.size(width = 48.dp, height = 32.dp) - cardsBlockState.cards.fastForEach { card -> - TangemPayCardItem(modifier = itemsModifier, card = card) - } - TangemIconButton( - modifier = itemsModifier.alpha(if (cardsBlockState.isAddCardEnabled) 1f else DISABLED_ALPHA), - onClick = cardsBlockState.onAddCardClick, - iconRes = R.drawable.ic_plus_24, - shape = RoundedCornerShape(4.dp), - enabled = cardsBlockState.isAddCardEnabled, - ) - } -} - -@Composable -private fun TangemPayCardItem(card: TangemPayDetailsBalanceBlockState.Card, modifier: Modifier = Modifier) { - val isCardInProcess = card.state == TangemPayCardUiState.InProgress - Box( - modifier = modifier - .clip(RoundedCornerShape(4.dp)) - .clickable( - onClick = card.onClick, - enabled = card.isEnabled, - ) - .testTag(TangemPayTestTags.PAYMENT_ACCOUNT_CARD_BUTTON), - ) { - Image( - modifier = Modifier - .alpha(if (card.isEnabled) 1f else DISABLED_ALPHA) - .fillMaxSize(), - painter = painterResource( - if (isCardInProcess) { - R.drawable.img_visa_card_inactive_48_32 - } else { - R.drawable.img_visa_card_48_32 - }, - ), - contentDescription = null, - ) - if (!isCardInProcess) { - Text( - modifier = Modifier - .align(Alignment.BottomStart) - .padding(4.dp, bottom = 2.dp), - text = card.lastDigits, - style = TangemTheme.typography.overline.copy(letterSpacing = 0.sp), - color = TangemTheme.colors.text.constantWhite, - ) - } - } -} - -@Composable -private fun FiatBalance( - state: TangemPayDetailsBalanceBlockState, - isBalanceHidden: Boolean, - modifier: Modifier = Modifier, -) { - when (state) { - is TangemPayDetailsBalanceBlockState.Loading -> RectangleShimmer( - modifier = modifier.size( - width = TangemTheme.dimens.size102, - height = TangemTheme.dimens.size32, - ), - ) - is TangemPayDetailsBalanceBlockState.Content -> Text( - modifier = modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE), - text = state.fiatBalance.orMaskWithStars(isBalanceHidden).resolveReference(), - style = TangemTheme.typography.h2.applyBladeBrush( - isEnabled = state.isBalanceFlickering, - textColor = TangemTheme.colors.text.primary1, - ), - ) - is TangemPayDetailsBalanceBlockState.Error -> Text( - modifier = modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE), - text = DASH_SIGN.orMaskWithStars(isBalanceHidden), - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - ) - } -} -// endregion - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun TangemPayDetailsTopAppBar(config: TangemPayDetailsTopBarConfig, modifier: Modifier = Modifier) { - var showDropdownMenu by rememberSaveable { mutableStateOf(false) } - TopAppBar( - modifier = modifier, - navigationIcon = { - IconButton(onClick = config.onBackClick) { - Icon( - painter = painterResource(id = R.drawable.ic_back_24), - tint = TangemTheme.colors.icon.primary1, - contentDescription = "Back", - ) - } - }, - title = {}, - actions = { - AnimatedVisibility(visible = config.items.isNotEmpty()) { - IconButton( - onClick = { - config.onOpenMenu() - showDropdownMenu = true - }, - ) { - Icon( - painter = painterResource(id = R.drawable.ic_more_vertical_24), - tint = TangemTheme.colors.icon.primary1, - contentDescription = "More", - modifier = Modifier.testTag(TokenDetailsTopBarTestTags.MORE_BUTTON), - ) - } - } - - TangemDropdownMenu( - expanded = showDropdownMenu, - modifier = Modifier.background(TangemTheme.colors.background.primary), - onDismissRequest = { showDropdownMenu = false }, - content = { - config.items.fastForEach { item -> - TangemDropdownItem( - item = item, - dismissParent = { showDropdownMenu = false }, - ) - } - }, - ) - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = TangemTheme.colors.background.secondary, - titleContentColor = TangemTheme.colors.icon.primary1, - actionIconContentColor = TangemTheme.colors.icon.primary1, - ), - scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(), - ) -} - -@Preview(device = Devices.PIXEL_7_PRO) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_7_PRO) -@Composable -private fun TangemPayDetailsScreenPreview( - @PreviewParameter(TangemPayDetailsUMProvider::class) state: TangemPayDetailsUM, -) { - TangemThemePreview { - TangemPayDetailsScreen( - state = state, - txHistoryComponent = PreviewTangemPayTxHistoryComponent( - txHistoryUM = PreviewTangemPayTxHistoryComponent.contentUM, - ), - expressTransactionsComponent = PreviewEmptyExpressTransactionsComponent(), - ) - } -} - -internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider( - collection = listOf( - TangemPayDetailsUM( - topBarConfig = TangemPayDetailsTopBarConfig( - onBackClick = {}, - onOpenMenu = {}, - items = persistentListOf(), - itemsV2 = persistentListOf(), - ), - pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}), - balanceBlockState = TangemPayDetailsBalanceBlockState.Content( - actionButtons = persistentListOf( - TangemPayActionButtonUM( - action = TangemPayAction.AddFunds, - config = ActionButtonConfig( - text = resourceReference(id = R.string.common_receive), - iconResId = R.drawable.ic_arrow_down_24, - onClick = {}, - ), - ), - ), - fiatBalance = combinedReference( - stringReference("1,234"), - styledStringReference( - ".56", - { SpanStyle(color = TangemTheme.colors3.text.primary) }, - ), - stringReference(" $"), - ), - isBalanceFlickering = false, - cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState( - cards = persistentListOf( - TangemPayDetailsBalanceBlockState.Card( - lastDigits = "1234", - imageUrl = null, - onClick = {}, - isEnabled = false, - isFrozen = false, - state = TangemPayCardUiState.Active, - ), - TangemPayDetailsBalanceBlockState.Card( - lastDigits = "3456", - imageUrl = null, - onClick = {}, - isEnabled = true, - isFrozen = false, - state = TangemPayCardUiState.Active, - ), - ), - onAddCardClick = {}, - isAddCardEnabled = true, - ), - isNegative = false, - isInactive = false, - ), - isBalanceHidden = false, - addToWalletBlockState = AddToWalletBlockState( - onClick = {}, - onClickClose = {}, - ), - accountDeactivatedNotificationConfig = null, - errorNotificationConfig = null, - ), - TangemPayDetailsUM( - topBarConfig = TangemPayDetailsTopBarConfig( - onBackClick = {}, - onOpenMenu = {}, - items = persistentListOf(), - itemsV2 = persistentListOf(), - ), - pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}), - balanceBlockState = TangemPayDetailsBalanceBlockState.Loading( - actionButtons = persistentListOf(), - cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState( - cards = persistentListOf( - TangemPayDetailsBalanceBlockState.Card( - lastDigits = "1234", - imageUrl = null, - onClick = {}, - isFrozen = false, - isEnabled = true, - state = TangemPayCardUiState.InProgress, - ), - ), - onAddCardClick = {}, - isAddCardEnabled = true, - progressBanner = CardsProgressBannerUM.Reissuing, - ), - ), - isBalanceHidden = false, - addToWalletBlockState = null, - accountDeactivatedNotificationConfig = null, - errorNotificationConfig = NotificationConfig( - title = TextReference.Str("Error title"), - subtitle = TextReference.Str("Error subtitle"), - iconResId = R.drawable.ic_alert_circle_24, - buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( - text = TextReference.Str("Error btn text"), - onClick = {}, - iconResId = R.drawable.ic_tangem_24, - ), - ), - ), - ), -) - -@Preview(device = Devices.PIXEL_7_PRO) -@Composable -private fun TangemPayDetailsTxHistoryScreenPreview( - @PreviewParameter(TangemPayDetailsTxHistoryProvider::class) state: TangemPayTxHistoryUM, -) { - TangemThemePreview { - TangemPayDetailsScreen( - state = TangemPayDetailsUMProvider().values.first(), - txHistoryComponent = PreviewTangemPayTxHistoryComponent(txHistoryUM = state), - expressTransactionsComponent = PreviewEmptyExpressTransactionsComponent(), - ) - } -} - -internal class TangemPayDetailsTxHistoryProvider : CollectionPreviewParameterProvider( - collection = listOf( - PreviewTangemPayTxHistoryComponent.loadingUM, - PreviewTangemPayTxHistoryComponent.contentUM, - PreviewTangemPayTxHistoryComponent.emptyUM, - PreviewTangemPayTxHistoryComponent.errorUM, - ), -) \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayEditDisplayNameScreen.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayEditDisplayNameScreen.kt index 652b53d9f0..7f307f22a7 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayEditDisplayNameScreen.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayEditDisplayNameScreen.kt @@ -4,18 +4,12 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.PrimaryButton import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds2.button.TangemButton import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe 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_cross_20 @@ -23,80 +17,6 @@ import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM import com.tangem.features.tangempay.entity.TangemPayEditDisplayNameUM -@Composable -internal fun TangemPayEditDisplayNameScreen( - isRedesignEnabled: Boolean, - state: TangemPayEditDisplayNameUM, - cardDetailsState: TangemPayCardDetailsUM, - modifier: Modifier = Modifier, -) { - if (isRedesignEnabled) { - TangemPayEditDisplayNameScreenV2( - state = state, - cardDetailsState = cardDetailsState, - modifier = modifier, - ) - } else { - TangemPayEditDisplayNameScreenV1( - state = state, - cardDetailsState = cardDetailsState, - modifier = modifier, - ) - } -} - -@Composable -internal fun TangemPayEditDisplayNameScreenV1( - state: TangemPayEditDisplayNameUM, - cardDetailsState: TangemPayCardDetailsUM, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier - .fillMaxSize() - .background(TangemTheme.colors.background.secondary) - .navigationBarsPadding(), - ) { - Box( - modifier = Modifier - .statusBarsPadding() - .height(56.dp) - .fillMaxWidth(), - ) { - IconButton( - modifier = Modifier.padding(start = 4.dp, top = 4.dp), - onClick = state.onDismiss, - ) { - Icon( - painter = painterResource(id = com.tangem.core.ui.R.drawable.ic_close_24), - contentDescription = null, - tint = TangemTheme.colors.icon.primary1, - ) - } - } - - TangemPayCard( - state = cardDetailsState, - modifier = Modifier - .padding(horizontal = 16.dp) - .padding(top = 8.dp), - ) - - Spacer(modifier = Modifier.weight(1f)) - - PrimaryButton( - modifier = Modifier - .imePadding() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp) - .fillMaxWidth(), - text = stringResourceSafe(R.string.common_done), - onClick = state.onDoneClick, - showProgress = state.isLoading, - enabled = !state.isLoading && state.isDoneEnabled, - ) - } -} - @Composable internal fun TangemPayEditDisplayNameScreenV2( state: TangemPayEditDisplayNameUM, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReissueCardContent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReissueCardContent.kt deleted file mode 100644 index 9048249e1d..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReissueCardContent.kt +++ /dev/null @@ -1,218 +0,0 @@ -package com.tangem.features.tangempay.ui - -import android.content.res.Configuration -import androidx.compose.animation.AnimatedContent -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.PrimaryButton -import com.tangem.core.ui.components.SpacerH16 -import com.tangem.core.ui.components.SpacerH24 -import com.tangem.core.ui.components.SpacerH8 -import com.tangem.core.ui.components.TextShimmer -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle -import com.tangem.core.ui.components.notifications.Notification -import com.tangem.core.ui.components.notifications.NotificationConfig -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.features.tangempay.details.impl.R -import com.tangem.features.tangempay.entity.TangemPayReissueCardError -import com.tangem.features.tangempay.entity.TangemPayReissueCardUM - -@Composable -internal fun TangemPayReissueCardContent(state: TangemPayReissueCardUM) { - TangemModalBottomSheet( - config = TangemBottomSheetConfig( - isShown = true, - onDismissRequest = state.onDismissRequest, - content = TangemBottomSheetConfigContent.Empty, - ), - containerColor = TangemTheme.colors.background.tertiary, - onBack = state.onDismissRequest, - title = { - TangemModalBottomSheetTitle( - title = TextReference.EMPTY, - endIconRes = R.drawable.ic_close_24, - onEndClick = state.onDismissRequest, - ) - }, - ) { - Content(state) - } -} - -@Composable -private fun Content(state: TangemPayReissueCardUM) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = TangemTheme.dimens.spacing16), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Box( - modifier = Modifier - .size(TangemTheme.dimens.spacing56) - .clip(CircleShape) - .background(TangemTheme.colors.icon.accent.copy(alpha = 0.1f)), - contentAlignment = Alignment.Center, - ) { - Icon( - painter = painterResource(id = R.drawable.ic_update_32), - contentDescription = null, - tint = TangemTheme.colors.icon.accent, - modifier = Modifier.size(32.dp), - ) - } - - SpacerH24() - - Text( - text = stringResourceSafe(R.string.tangempay_reissue_card_title), - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), - ) - - SpacerH8() - - Text( - text = stringResourceSafe(R.string.tangempay_reissue_card_description), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.secondary, - textAlign = TextAlign.Center, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), - ) - - SpacerH24() - - FeeBlock(state) - - if (state.error != null) { - SpacerH16() - ErrorBlock( - error = state.error, - onRetryFee = state.onRetryFee, - onAddFundsClick = state.onAddFundsClick, - ) - } - - SpacerH24() - - PrimaryButton( - modifier = Modifier.fillMaxWidth(), - text = stringResourceSafe(R.string.tangempay_reissue_card_confirm), - enabled = state.error == null && !state.isFeeLoading, - showProgress = state.isReissuingInProgress, - onClick = state.onConfirmClick, - ) - - SpacerH16() - } -} - -@Composable -private fun FeeBlock(state: TangemPayReissueCardUM) { - Row( - modifier = Modifier - .fillMaxWidth() - .background( - color = TangemTheme.colors.background.action, - shape = TangemTheme.shapes.roundedCornersMedium, - ) - .padding(TangemTheme.dimens.spacing12), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = stringResourceSafe(R.string.tangempay_reissue_card_fee_label), - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.primary1, - ) - AnimatedContent( - targetState = when { - state.isFeeLoading -> null - state.error == TangemPayReissueCardError.InitialDataLoading -> "—" - else -> state.feeAmount - }, - ) { fee -> - if (fee != null) { - Text( - text = fee, - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.tertiary, - ) - } else { - TextShimmer(style = TangemTheme.typography.body1, text = "$0.00") - } - } - } -} - -@Composable -private fun ErrorBlock(error: TangemPayReissueCardError, onAddFundsClick: () -> Unit, onRetryFee: () -> Unit) { - when (error) { - TangemPayReissueCardError.InsufficientFunds -> Notification( - config = NotificationConfig( - title = resourceReference(R.string.tangempay_reissue_card_insufficient_funds_title), - subtitle = resourceReference(R.string.tangempay_reissue_card_insufficient_funds_subtitle), - iconResId = R.drawable.img_usdc_16, - buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( - text = resourceReference(R.string.tangempay_card_details_add_funds), - iconResId = R.drawable.ic_plus_24, - onClick = onAddFundsClick, - ), - ), - containerColor = TangemTheme.colors.background.action, - modifier = Modifier.fillMaxWidth(), - ) - TangemPayReissueCardError.InitialDataLoading -> Notification( - config = NotificationConfig( - title = resourceReference(R.string.tangempay_reissue_card_fee_unreachable_error_title), - subtitle = resourceReference(R.string.send_fee_unreachable_error_text), - iconResId = R.drawable.img_attention_20, - buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( - text = resourceReference(R.string.warning_button_refresh), - onClick = onRetryFee, - ), - ), - containerColor = TangemTheme.colors.background.action, - modifier = Modifier.fillMaxWidth(), - ) - } -} - -@Preview(showBackground = true) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun preview() = TangemThemePreview { - TangemPayReissueCardContent( - state = TangemPayReissueCardUM.stub(), - ) -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReplacingCardBlock.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReplacingCardBlock.kt deleted file mode 100644 index 7b1c3675d9..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReplacingCardBlock.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.tangem.features.tangempay.ui - -import android.content.res.Configuration -import androidx.compose.foundation.layout.Column -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import com.tangem.core.ui.components.SpacerH24 -import com.tangem.core.ui.components.notifications.Notification -import com.tangem.core.ui.components.notifications.NotificationConfig -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.res.LocalVisaRedesignEnabled -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.res.TangemThemePreviewRedesign -import com.tangem.features.tangempay.details.impl.R - -@Composable -internal fun TangemPayReplacingCardBlock( - modifier: Modifier = Modifier, - title: TextReference? = resourceReference(R.string.tangempay_reissue_card_in_progress), - subtitle: TextReference = resourceReference(R.string.tangempay_reissue_card_in_progress_description), -) { - if (LocalVisaRedesignEnabled.current) { - return - } else { - Block(title = title, subtitle = subtitle, modifier = modifier) - } -} - -@Composable -private fun Block( - modifier: Modifier = Modifier, - title: TextReference? = resourceReference(R.string.tangempay_reissue_card_in_progress), - subtitle: TextReference = resourceReference(R.string.tangempay_reissue_card_in_progress_description), -) { - Notification( - modifier = modifier, - config = NotificationConfig( - iconResId = R.drawable.ic_update_32, - iconTint = NotificationConfig.IconTint.Accent, - title = title, - subtitle = subtitle, - ), - containerColor = TangemTheme.colors.background.primary, - ) -} - -@Preview(showBackground = true) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview() { - Column { - TangemThemePreview { - TangemPayReplacingCardBlock() - } - SpacerH24() - CompositionLocalProvider(LocalVisaRedesignEnabled provides true) { - TangemThemePreviewRedesign { - TangemPayReplacingCardBlock() - } - } - } -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUi.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUi.kt deleted file mode 100644 index 0c5053794b..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUi.kt +++ /dev/null @@ -1,408 +0,0 @@ -package com.tangem.features.tangempay.ui - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material3.Icon -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.constraintlayout.compose.ChainStyle -import androidx.constraintlayout.compose.ConstraintLayout -import androidx.constraintlayout.compose.Dimension -import com.tangem.core.ui.R -import com.tangem.core.ui.components.CircleShimmer -import com.tangem.core.ui.components.RectangleShimmer -import com.tangem.core.ui.components.buttons.actions.ActionButton -import com.tangem.core.ui.components.list.InfiniteListHandler -import com.tangem.core.ui.components.transactions.TxHistoryGroupTitle -import com.tangem.core.ui.decorations.roundedShapeItemDecoration -import com.tangem.core.ui.extensions.ImageReference -import com.tangem.core.ui.extensions.orMaskWithStars -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.test.EmptyTransactionBlockTestTags -import com.tangem.core.ui.test.TransactionHistoryBlockTestTags -import com.tangem.features.tangempay.entity.TangemPayEmptyTransactionHistoryState -import com.tangem.features.tangempay.entity.TangemPayTransactionState -import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM - -private const val LOAD_ITEMS_BUFFER = 20 - -internal fun LazyListScope.tangemPayTxHistoryItems(listState: LazyListState, state: TangemPayTxHistoryUM) { - when (state) { - is TangemPayTxHistoryUM.Content -> contentItems(listState = listState, state = state) - is TangemPayTxHistoryUM.Empty -> nonContentItem(state = TangemPayEmptyTransactionHistoryState.Empty) - is TangemPayTxHistoryUM.Error -> nonContentItem( - state = TangemPayEmptyTransactionHistoryState.FailedToLoad(onReload = state.onReload), - ) - is TangemPayTxHistoryUM.Loading -> loadingItems(state = state) - } -} - -private fun LazyListScope.nonContentItem(state: TangemPayEmptyTransactionHistoryState, modifier: Modifier = Modifier) { - item(key = state::class.java, contentType = state::class.java) { - TangemPayEmptyTransactionBlock( - state = state, - modifier = modifier - .padding(horizontal = TangemTheme.dimens.spacing16, vertical = TangemTheme.dimens.spacing12) - .fillMaxWidth(), - ) - } -} - -private fun LazyListScope.contentItems(listState: LazyListState, state: TangemPayTxHistoryUM.Content) { - itemsIndexed( - items = state.items, - key = { index, item -> - when (item) { - is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle -> item.itemKey - is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title -> index + item.hashCode() - is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction -> - item.transaction.id + (item.transaction as? TangemPayTransactionState.Content)?.hashCode() - } - }, - contentType = { _, item -> item::class.java }, - itemContent = { index, item -> - TangemPayTxHistoryListItem( - state = item, - isBalanceHidden = state.isBalanceHidden, - modifier = Modifier.roundedShapeItemDecoration( - currentIndex = index, - lastIndex = state.items.lastIndex, - ), - ) - }, - ) - item { - InfiniteListHandler( - listState = listState, - buffer = LOAD_ITEMS_BUFFER, - onLoadMore = state.loadMore, - ) - } -} - -private fun LazyListScope.loadingItems(state: TangemPayTxHistoryUM.Loading) { - itemsIndexed( - items = state.items, - key = { _, item -> - when (item) { - is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle -> item.itemKey - is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title -> item.hashCode() - is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction -> - item.transaction.id + (item.transaction as? TangemPayTransactionState.Content)?.hashCode() - } - }, - contentType = { _, item -> item::class.java }, - itemContent = { index, item -> - TangemPayTxHistoryListItem( - state = item, - isBalanceHidden = true, - modifier = Modifier.roundedShapeItemDecoration( - currentIndex = index, - lastIndex = state.items.lastIndex, - ), - ) - }, - ) -} - -@Composable -private fun TangemPayTxHistoryListItem( - state: TangemPayTxHistoryUM.TangemPayTxHistoryItemUM, - isBalanceHidden: Boolean, - modifier: Modifier = Modifier, -) { - when (state) { - is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle -> { - if (state.isLoading) { - RectangleShimmer( - modifier = modifier - .fillMaxWidth() - .padding( - vertical = TangemTheme.dimens.spacing8, - horizontal = TangemTheme.dimens.spacing12, - ) - .height(TangemTheme.dimens.size12), - ) - } else { - TxHistoryGroupTitle(config = state.legacyGroupTitle, modifier = modifier) - } - } - is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title -> { - TangemPayTxHistoryTitle(modifier = modifier) - } - is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction -> { - TangemPayTransaction( - transactionState = state.transaction, - isBalanceHidden = isBalanceHidden, - modifier = modifier, - ) - } - } -} - -@Composable -private fun TangemPayTxHistoryTitle(modifier: Modifier = Modifier) { - Text( - text = stringResourceSafe(id = R.string.common_transactions), - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.subtitle2, - modifier = modifier - .background(TangemTheme.colors.background.primary) - .padding(top = TangemTheme.dimens.spacing12) - .padding(horizontal = TangemTheme.dimens.spacing12) - .fillMaxWidth() - .heightIn(min = TangemTheme.dimens.size24) - .testTag(TransactionHistoryBlockTestTags.TITLE_TEXT), - ) -} - -@Suppress("LongMethod") -@Composable -private fun TangemPayTransaction( - transactionState: TangemPayTransactionState, - isBalanceHidden: Boolean, - modifier: Modifier = Modifier, -) { - Surface( - modifier = modifier - .background(TangemTheme.colors.background.primary) - .clickable( - enabled = transactionState is TangemPayTransactionState.Content, - onClick = (transactionState as? TangemPayTransactionState.Content)?.onClick ?: {}, - ) - .fillMaxWidth() - .heightIn(min = TangemTheme.dimens.size56) - .padding( - vertical = TangemTheme.dimens.spacing8, - horizontal = TangemTheme.dimens.spacing12, - ), - color = TangemTheme.colors.background.primary, - ) { - @Suppress("DestructuringDeclarationWithTooManyEntries") - ConstraintLayout(modifier = Modifier.fillMaxWidth()) { - val (iconItem, titleItem, subtitleItem, amountItem, timestampItem) = createRefs() - - createVerticalChain(titleItem, subtitleItem, chainStyle = ChainStyle.Spread) - createVerticalChain(amountItem, timestampItem, chainStyle = ChainStyle.Spread) - - Icon( - state = transactionState, - modifier = Modifier - .size(TangemTheme.dimens.size40) - .constrainAs(iconItem) { - start.linkTo(parent.start) - centerVerticallyTo(parent) - }, - ) - - Title( - state = transactionState, - modifier = Modifier - .padding( - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing4, - ) - .constrainAs(titleItem) { - top.linkTo(parent.top) - bottom.linkTo(subtitleItem.top) - start.linkTo(iconItem.end) - end.linkTo(amountItem.start) - width = Dimension.fillToConstraints - }, - ) - - Subtitle( - state = transactionState, - modifier = Modifier - .padding( - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing4, - ) - .constrainAs(subtitleItem) { - top.linkTo(titleItem.bottom) - bottom.linkTo(parent.bottom) - start.linkTo(iconItem.end) - end.linkTo(timestampItem.start) - width = Dimension.fillToConstraints - }, - ) - - Amount( - state = transactionState, - isBalanceHidden = isBalanceHidden, - modifier = Modifier.constrainAs(amountItem) { - top.linkTo(parent.top) - bottom.linkTo(timestampItem.top) - start.linkTo(titleItem.end) - end.linkTo(parent.end) - width = Dimension.preferredWrapContent - }, - ) - - Timestamp( - state = transactionState, - modifier = Modifier.constrainAs(timestampItem) { - top.linkTo(amountItem.bottom) - bottom.linkTo(parent.bottom) - end.linkTo(parent.end) - }, - ) - } - } -} - -@Composable -private fun Icon(state: TangemPayTransactionState, modifier: Modifier = Modifier) { - when (state) { - is TangemPayTransactionState.Content -> when (val iconReference = state.icon) { - is ImageReference.Url -> RemoteIcon(modifier = modifier, url = iconReference.url) - is ImageReference.Res -> LocalStaticIcon( - modifier = modifier, - id = iconReference.resId, - iconSize = TangemTheme.dimens.size20, - ) - } - is TangemPayTransactionState.Loading -> CircleShimmer(modifier = modifier) - } -} - -@Composable -private fun Title(state: TangemPayTransactionState, modifier: Modifier = Modifier) { - when (state) { - is TangemPayTransactionState.Content -> { - Text( - modifier = modifier, - text = state.title.resolveReference(), - color = TangemTheme.colors.text.primary1, - style = TangemTheme.typography.subtitle2, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - ) - } - is TangemPayTransactionState.Loading -> { - RectangleShimmer( - modifier = modifier.size(width = TangemTheme.dimens.size70, height = TangemTheme.dimens.size12), - ) - } - } -} - -@Composable -private fun Subtitle(state: TangemPayTransactionState, modifier: Modifier = Modifier) { - when (state) { - is TangemPayTransactionState.Content -> { - Text( - text = state.subtitle.resolveReference(), - modifier = modifier, - textAlign = TextAlign.Start, - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.caption2, - ) - } - is TangemPayTransactionState.Loading -> { - RectangleShimmer( - modifier = modifier.size(width = TangemTheme.dimens.size52, height = TangemTheme.dimens.size12), - ) - } - } -} - -@Composable -private fun Amount(state: TangemPayTransactionState, isBalanceHidden: Boolean, modifier: Modifier = Modifier) { - when (state) { - is TangemPayTransactionState.Content -> { - Text( - text = state.amount.orMaskWithStars(isBalanceHidden), - modifier = modifier, - textAlign = TextAlign.End, - color = state.amountColor.resolveReference(), - style = TangemTheme.typography.body2, - ) - } - is TangemPayTransactionState.Loading -> { - RectangleShimmer( - modifier = modifier.size(width = TangemTheme.dimens.size72, height = TangemTheme.dimens.size12), - ) - } - } -} - -@Composable -private fun Timestamp(state: TangemPayTransactionState, modifier: Modifier = Modifier) { - when (state) { - is TangemPayTransactionState.Content -> { - Text( - text = state.time, - modifier = modifier, - textAlign = TextAlign.End, - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.caption2, - ) - } - is TangemPayTransactionState.Loading -> { - RectangleShimmer( - modifier = modifier.size(width = TangemTheme.dimens.size40, height = TangemTheme.dimens.size12), - ) - } - } -} - -@Composable -private fun TangemPayEmptyTransactionBlock( - state: TangemPayEmptyTransactionHistoryState, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier - .clip(TangemTheme.shapes.roundedCornersXMedium) - .background(color = TangemTheme.colors.background.primary) - .padding(vertical = TangemTheme.dimens.spacing24) - .testTag(EmptyTransactionBlockTestTags.BLOCK), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing24), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - modifier = Modifier - .size(TangemTheme.dimens.size64) - .testTag(EmptyTransactionBlockTestTags.ICON), - painter = painterResource(id = state.iconRes), - tint = TangemTheme.colors.icon.inactive, - contentDescription = null, - ) - - Text( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing32) - .testTag(EmptyTransactionBlockTestTags.TEXT), - textAlign = TextAlign.Center, - text = state.text.resolveReference(), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.tertiary, - ) - - when (state) { - is TangemPayEmptyTransactionHistoryState.Empty -> Unit - is TangemPayEmptyTransactionHistoryState.FailedToLoad -> ActionButton( - modifier = Modifier - .padding(horizontal = 24.dp) - .fillMaxWidth(), - config = state.actionButtonConfig, - ) - } - } -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayViewPinContent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayViewPinContent.kt deleted file mode 100644 index 945e9fd5e9..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayViewPinContent.kt +++ /dev/null @@ -1,204 +0,0 @@ -package com.tangem.features.tangempay.ui - -import android.content.res.Configuration -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color.Companion.Transparent -import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.SecondaryButton -import com.tangem.core.ui.components.SpacerH12 -import com.tangem.core.ui.components.SpacerH24 -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent -import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetContent -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.features.tangempay.details.impl.R -import com.tangem.features.tangempay.entity.TangemPayViewPinUM - -@Composable -internal fun TangemPayViewPinContent(state: TangemPayViewPinUM) { - TangemModalBottomSheet( - config = TangemBottomSheetConfig( - isShown = true, - onDismissRequest = state.onDismiss, - content = TangemBottomSheetConfigContent.Empty, - ), - onBack = state.onDismiss, - containerColor = TangemTheme.colors.background.tertiary, - title = { - TangemModalBottomSheetTitle( - title = TextReference.EMPTY, - endIconRes = R.drawable.ic_close_24, - onEndClick = state.onDismiss, - ) - }, - ) { - when (state) { - is TangemPayViewPinUM.Content -> { - PinSuccessContent(state) - } - is TangemPayViewPinUM.Error -> { - MessageBottomSheetContent(state.errorMessage) - } - is TangemPayViewPinUM.Loading -> { - PinLoadingContent() - } - } - } -} - -@Composable -private fun PinSuccessContent(state: TangemPayViewPinUM.Content, modifier: Modifier = Modifier) { - Column( - modifier = modifier - .padding(horizontal = 16.dp) - .fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - text = stringResourceSafe(R.string.tangempay_card_details_view_pin_code_title), - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - ) - - SpacerH12() - - Text( - text = stringResourceSafe(R.string.tangempay_card_details_view_pin_code_description), - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.secondary, - textAlign = TextAlign.Center, - ) - - SpacerH24() - - Box( - modifier = Modifier - .fillMaxWidth() - .height(200.dp), - contentAlignment = Alignment.Center, - ) { - PinCode( - modifier = Modifier - .align(Alignment.TopCenter), - value = state.pin, - ) - - SecondaryButton( - modifier = Modifier - .align(Alignment.BottomCenter) - .imePadding() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp) - .fillMaxWidth(), - text = stringResourceSafe(R.string.tangempay_change_pin_code), - onClick = state.onClickChangePin, - ) - } - } -} - -@Composable -private fun PinLoadingContent(modifier: Modifier = Modifier) { - Column( - modifier = modifier - .padding(horizontal = 16.dp) - .fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - text = stringResourceSafe(R.string.tangempay_card_details_view_pin_code_title), - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - ) - - SpacerH12() - - Text( - text = stringResourceSafe(R.string.tangempay_card_details_view_pin_code_description), - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.secondary, - textAlign = TextAlign.Center, - ) - - SpacerH24() - - Box( - modifier = Modifier - .fillMaxWidth() - .height(200.dp), - contentAlignment = Alignment.Center, - ) { - CircularProgressIndicator( - color = TangemTheme.colors.text.disabled, - modifier = Modifier - .align(Alignment.TopCenter) - .padding(top = 16.dp) - .size(TangemTheme.dimens.size24), - ) - } - } -} - -@Composable -private fun PinCode(value: String, modifier: Modifier = Modifier, numbersCount: Int = 4) { - BasicTextField( - value = value, - onValueChange = {}, - modifier = modifier, - textStyle = TangemTheme.typography.h1.copy(color = Transparent), - cursorBrush = SolidColor(Transparent), - decorationBox = { innerTextField -> - Box( - modifier = Modifier.fillMaxWidth(), - contentAlignment = Alignment.Center, - ) { - Row( - horizontalArrangement = Arrangement.spacedBy(12.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - repeat(numbersCount) { index -> - val digit = value.getOrNull(index)?.toString() - PinDigitBox( - digit = digit, - backgroundColor = TangemTheme.colors.background.action, - borderColor = TangemTheme.colors.stroke.primary, - textColor = TangemTheme.colors.text.primary1, - textStyle = TangemTheme.typography.h1, - ) - } - } - innerTextField() - } - }, - ) -} - -@Preview(showBackground = true) -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun TangemPayViewPinContentPreview() { - TangemThemePreview { - TangemPayViewPinContent( - state = TangemPayViewPinUM.Content( - pin = "1234", - onClickChangePin = {}, - onDismiss = {}, - ), - ) - } -} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt deleted file mode 100644 index 42f821bf8a..0000000000 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt +++ /dev/null @@ -1,307 +0,0 @@ -package com.tangem.features.tangempay.ui - -import android.content.res.Configuration -import androidx.compose.foundation.layout.* -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Devices -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import androidx.compose.ui.unit.dp -import androidx.compose.ui.util.fastForEach -import com.tangem.core.ui.components.SecondaryButton -import com.tangem.core.ui.components.SecondaryButtonIconStart -import com.tangem.core.ui.components.SpacerH32 -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle -import com.tangem.core.ui.components.label.Label -import com.tangem.core.ui.components.label.entity.LabelStyle -import com.tangem.core.ui.components.label.entity.LabelUM -import com.tangem.core.ui.components.notifications.Notification -import com.tangem.core.ui.components.notifications.NotificationConfig -import com.tangem.core.ui.extensions.* -import com.tangem.core.ui.res.TangemColorPalette -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.features.tangempay.details.impl.R -import com.tangem.features.tangempay.entity.ButtonState -import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf - -@Suppress("LongMethod") -@Composable -internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM) { - TangemModalBottomSheet( - config = TangemBottomSheetConfig( - isShown = true, - onDismissRequest = state.dismiss, - content = TangemBottomSheetConfigContent.Empty, - ), - onBack = state.dismiss, - containerColor = TangemTheme.colors.background.tertiary, - title = { - TangemModalBottomSheetTitle( - title = state.title, - endIconRes = R.drawable.ic_close_24, - onEndClick = state.dismiss, - ) - }, - ) { - Column( - modifier = Modifier - .padding(horizontal = 16.dp) - .fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - modifier = Modifier - .padding(top = 24.dp) - .size(88.dp), - iconState = state.iconState, - ) - Text( - modifier = Modifier.padding(top = 32.dp), - text = state.transactionTitle.resolveReference(), - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - ) - Text( - modifier = Modifier.padding(top = 2.dp), - text = state.transactionSubtitle.resolveReference(), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.tertiary, - textAlign = TextAlign.Center, - ) - Text( - modifier = Modifier.padding(top = 8.dp), - text = state.transactionAmount.orMaskWithStars(state.isBalanceHidden), - style = TangemTheme.typography.head, - color = state.transactionAmountColor.resolveReference(), - ) - if (state.localTransactionText != null) { - Text( - modifier = Modifier.padding(top = 4.dp), - text = state.localTransactionText.orMaskWithStars(state.isBalanceHidden), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.tertiary, - ) - } - if (state.labelState != null) { - Label(state = state.labelState, modifier = Modifier.padding(top = 12.dp)) - } - SpacerH32() - if (state.notification != null) { - Notification( - config = state.notification.config, - titleColor = state.notification.titleColor.resolveReference(), - iconTint = state.notification.iconTint.resolveReference(), - containerColor = state.notification.containerColor?.resolveReference(), - ) - } - ButtonsContainer( - modifier = Modifier - .padding(vertical = 16.dp) - .fillMaxWidth(), - buttons = state.buttons, - ) - } - } -} - -@Composable -private fun ButtonsContainer(buttons: ImmutableList, modifier: Modifier = Modifier) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - buttons.fastForEach { buttonState -> - if (buttonState.startIcon != null) { - SecondaryButtonIconStart( - modifier = Modifier.fillMaxWidth(), - text = buttonState.text.resolveReference(), - iconResId = buttonState.startIcon.resId, - onClick = buttonState.onClick, - ) - } else { - SecondaryButton( - modifier = Modifier.fillMaxWidth(), - text = buttonState.text.resolveReference(), - onClick = buttonState.onClick, - ) - } - } - } -} - -@Composable -private fun Icon(iconState: ImageReference, modifier: Modifier = Modifier) { - when (iconState) { - is ImageReference.Res -> LocalStaticIcon(modifier = modifier, id = iconState.resId, iconSize = 40.dp) - is ImageReference.Url -> RemoteIcon(modifier = modifier, url = iconState.url) - } -} - -@Preview(device = Devices.PIXEL_7_PRO) -@Preview(device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun TangemPayTxHistoryDetailsContentPreview( - @PreviewParameter(TangemPayTxHistoryDetailsUMProvider::class) state: TangemPayTxHistoryDetailsUM, -) { - TangemThemePreview { - TangemPayTxHistoryDetailsContent(state = state) - } -} - -private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterProvider( - listOf( - TangemPayTxHistoryDetailsUM( - isBalanceHidden = true, - title = stringReference("12 June • 12:40"), - iconState = ImageReference.Res(R.drawable.ic_category_24), - transactionTitle = stringReference("Starbucks"), - transactionSubtitle = stringReference("Food and drinks"), - transactionAmount = "-$5.86", - transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 }, - localTransactionText = null, - labelState = LabelUM( - text = resourceReference(R.string.tangem_pay_status_pending), - style = LabelStyle.REGULAR, - icon = R.drawable.ic_clock_24, - ), - notification = null, - buttons = persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_dispute), - onClick = {}, - ), - ), - dismiss = {}, - ), - TangemPayTxHistoryDetailsUM( - isBalanceHidden = true, - title = stringReference("12 June • 12:40"), - iconState = ImageReference.Res(R.drawable.ic_category_24), - transactionTitle = stringReference("Starbucks"), - transactionSubtitle = stringReference("Food and drinks"), - transactionAmount = "-$5.86", - transactionAmountColor = themedColor { TangemTheme.colors.text.warning }, - localTransactionText = null, - labelState = LabelUM( - text = resourceReference(R.string.tangem_pay_status_declined), - style = LabelStyle.WARNING, - ), - notification = TangemPayTxHistoryDetailsUM.NotificationState( - config = NotificationConfig( - title = stringReference("The bank rejected this transaction request."), - subtitle = TextReference.EMPTY, - iconResId = R.drawable.ic_token_info_24, - ), - titleColor = themedColor { TangemTheme.colors.text.warning }, - iconTint = themedColor { TangemTheme.colors.icon.warning }, - containerColor = themedColor { TangemColorPalette.Amaranth.copy(alpha = 0.1F) }, - ), - buttons = persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_dispute), - onClick = {}, - ), - ), - dismiss = {}, - ), - TangemPayTxHistoryDetailsUM( - isBalanceHidden = true, - title = stringReference("12 June • 12:40"), - iconState = ImageReference.Res(R.drawable.ic_category_24), - transactionTitle = stringReference("Starbucks"), - transactionSubtitle = stringReference("Food and drinks Food and drinks Food and drinks Food and drinks"), - transactionAmount = "-$5.86", - transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 }, - localTransactionText = "€ 5.36", - labelState = LabelUM( - text = resourceReference(R.string.tangem_pay_status_completed), - style = LabelStyle.ACCENT, - ), - notification = null, - buttons = persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_dispute), - onClick = {}, - ), - ), - dismiss = {}, - ), - TangemPayTxHistoryDetailsUM( - isBalanceHidden = false, - title = stringReference("12 June • 12:40"), - iconState = ImageReference.Res(R.drawable.ic_percent_24), - transactionTitle = stringReference("Fee"), - transactionSubtitle = stringReference("Service fee"), - transactionAmount = "-$5.86", - transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 }, - localTransactionText = null, - labelState = null, - notification = TangemPayTxHistoryDetailsUM.NotificationState( - config = NotificationConfig( - title = stringReference("This fee goes to cover the cost of handling your transfer."), - subtitle = TextReference.EMPTY, - iconResId = R.drawable.ic_token_info_24, - ), - titleColor = themedColor { TangemTheme.colors.text.tertiary }, - iconTint = themedColor { TangemTheme.colors.icon.secondary }, - containerColor = null, - ), - buttons = persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_dispute), - onClick = {}, - ), - ), - dismiss = {}, - ), - TangemPayTxHistoryDetailsUM( - isBalanceHidden = false, - title = stringReference("12 June • 12:40"), - iconState = ImageReference.Res(R.drawable.ic_arrow_down_24), - transactionTitle = stringReference("Deposit"), - transactionSubtitle = stringReference("Transfers"), - transactionAmount = "+$20", - transactionAmountColor = themedColor { TangemTheme.colors.text.accent }, - localTransactionText = null, - labelState = null, - notification = null, - buttons = persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_get_help), - onClick = {}, - ), - ), - dismiss = {}, - ), - TangemPayTxHistoryDetailsUM( - isBalanceHidden = false, - title = stringReference("12 June • 12:40"), - iconState = ImageReference.Res(R.drawable.ic_arrow_up_24), - transactionTitle = stringReference("Withdrawal"), - transactionSubtitle = stringReference("Transfers"), - transactionAmount = "-$5.86", - transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 }, - localTransactionText = null, - labelState = null, - notification = null, - buttons = persistentListOf( - ButtonState( - text = resourceReference(R.string.tangem_pay_get_help), - onClick = {}, - ), - ), - dismiss = {}, - ), - ), -) \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayMessagesFactory.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayMessagesFactory.kt index 20a0d16da4..4450dc8764 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayMessagesFactory.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayMessagesFactory.kt @@ -60,29 +60,20 @@ internal object TangemPayMessagesFactory { } } - fun createFreezeCardMessage(isRedesignEnabled: Boolean, onFreezeClicked: () -> Unit): BottomSheetMessage { + fun createFreezeCardMessage(onFreezeClicked: () -> Unit): BottomSheetMessage { return bottomSheetMessage { infoBlock { - if (isRedesignEnabled) { - vector(Icons.ic_snowflake_20) { - type = MessageBottomSheetUM.Vector.Type.Informative - backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Informative - } - } else { - icon(R.drawable.ic_snow_24) { - type = MessageBottomSheetUM.Icon.Type.Accent - backgroundType = MessageBottomSheetUM.Icon.BackgroundType.Accent - } + vector(Icons.ic_snowflake_20) { + type = MessageBottomSheetUM.Vector.Type.Informative + backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Informative } title = TextReference.Res(R.string.tangem_pay_freeze_card_alert_title) body = TextReference.Res(R.string.tangem_pay_freeze_card_alert_body) } - if (isRedesignEnabled) { - secondaryButton { - text = resourceReference(R.string.common_cancel) - onClick { - closeBs() - } + secondaryButton { + text = resourceReference(R.string.common_cancel) + onClick { + closeBs() } } primaryButton { @@ -95,29 +86,20 @@ internal object TangemPayMessagesFactory { } } - fun createUnfreezeCardMessage(isRedesignEnabled: Boolean, onUnfreezeClicked: () -> Unit): BottomSheetMessage { + fun createUnfreezeCardMessage(onUnfreezeClicked: () -> Unit): BottomSheetMessage { return bottomSheetMessage { infoBlock { - if (isRedesignEnabled) { - vector(Icons.ic_sun_20) { - type = MessageBottomSheetUM.Vector.Type.Attention - backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Attention - } - } else { - icon(R.drawable.ic_snow_24) { - type = MessageBottomSheetUM.Icon.Type.Accent - backgroundType = MessageBottomSheetUM.Icon.BackgroundType.Accent - } + vector(Icons.ic_sun_20) { + type = MessageBottomSheetUM.Vector.Type.Attention + backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Attention } title = TextReference.Res(R.string.tangem_pay_unfreeze_card_alert_title) body = TextReference.Res(R.string.tangem_pay_unfreeze_card_alert_body) } - if (isRedesignEnabled) { - secondaryButton { - text = resourceReference(R.string.common_cancel) - onClick { - closeBs() - } + secondaryButton { + text = resourceReference(R.string.common_cancel) + onClick { + closeBs() } } primaryButton { diff --git a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactoryTest.kt b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactoryTest.kt index d066aa49af..d434e48653 100644 --- a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactoryTest.kt +++ b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsStateFactoryTest.kt @@ -29,7 +29,6 @@ internal class TangemPayDetailsStateFactoryTest { onBack = {}, onOpenMenu = {}, intents = intents, - isRedesignEnabled = true, isRemoveAccountEnabled = true, isTiersPlusPlanEnabled = true, ) diff --git a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupModelTest.kt b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupModelTest.kt index 048c7a5396..7afb902d64 100644 --- a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupModelTest.kt +++ b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupModelTest.kt @@ -13,7 +13,6 @@ import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase import com.tangem.domain.tangempay.TangemPayAnalyticsEvents -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider import io.mockk.every import io.mockk.mockk @@ -36,7 +35,6 @@ internal class TangemPayCardLimitSetupModelTest { private val setLimitUseCase: SetTangemPayCardLimitUseCase = mockk(relaxed = true) private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier = mockk() private val analytics: AnalyticsEventHandler = mockk(relaxed = true) - private val featureToggles: TangemPayFeatureToggles = mockk() private val initialCard = TangemPayCard( id = cardId, @@ -98,7 +96,6 @@ internal class TangemPayCardLimitSetupModelTest { setTangemPayCardLimitUseCase = setLimitUseCase, uiMessageSender = uiMessageSender, analytics = analytics, - featureToggles = featureToggles, ) } diff --git a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/model/TangemPayEditDisplayNameModelTest.kt b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/model/TangemPayEditDisplayNameModelTest.kt index 3f80cc0a72..6ab7558056 100644 --- a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/model/TangemPayEditDisplayNameModelTest.kt +++ b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/model/TangemPayEditDisplayNameModelTest.kt @@ -14,7 +14,6 @@ import com.tangem.domain.models.pay.TangemPayCardState import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier import com.tangem.domain.pay.usecase.UpdateTangemPayCardNameUseCase -import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tangempay.components.TangemPayEditDisplayNameComponent import com.tangem.features.tangempay.model.controller.TangemPayCardDetailsController import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider @@ -36,7 +35,6 @@ internal class TangemPayEditDisplayNameModelTest { private val updateCardNameUseCase: UpdateTangemPayCardNameUseCase = mockk() private val uiMessageSender: UiMessageSender = mockk(relaxed = true) private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier = mockk() - private val featureToggles: TangemPayFeatureToggles = mockk(relaxed = true) private val cardDetailsControllerFactory: TangemPayCardDetailsController.Factory = mockk(relaxed = true) init { @@ -55,7 +53,6 @@ internal class TangemPayEditDisplayNameModelTest { updateCardNameUseCase = updateCardNameUseCase, uiMessageSender = uiMessageSender, paymentAccountStatusSupplier = paymentAccountStatusSupplier, - featureToggles = featureToggles, cardDetailsControllerFactory = cardDetailsControllerFactory, ) diff --git a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModelTest.kt b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModelTest.kt index e2d90be963..619380d0fb 100644 --- a/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModelTest.kt +++ b/features/tangempay/details/impl/src/test/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModelTest.kt @@ -67,7 +67,7 @@ internal class TangemPayTxHistoryDetailsModelTest { advanceUntilIdle() // Assert - assertThat(model.uiState.value.redesign.detail).isEqualTo(TransactionDetailUM.Loading) + assertThat(model.uiState.value.detail).isEqualTo(TransactionDetailUM.Loading) model.onDestroy() } @@ -85,7 +85,7 @@ internal class TangemPayTxHistoryDetailsModelTest { advanceUntilIdle() // Assert - assertThat(model.uiState.value.redesign.detail) + assertThat(model.uiState.value.detail) .isEqualTo( TransactionDetailUM.Content( cardNumber = stringReference("*4321"), @@ -106,7 +106,7 @@ internal class TangemPayTxHistoryDetailsModelTest { advanceUntilIdle() // Assert - assertThat(model.uiState.value.redesign.detail).isNull() + assertThat(model.uiState.value.detail).isNull() model.onDestroy() } @@ -120,7 +120,7 @@ internal class TangemPayTxHistoryDetailsModelTest { advanceUntilIdle() // Assert - assertThat(model.uiState.value.redesign.detail).isInstanceOf(TransactionDetailUM.Error::class.java) + assertThat(model.uiState.value.detail).isInstanceOf(TransactionDetailUM.Error::class.java) model.onDestroy() } @@ -136,7 +136,7 @@ internal class TangemPayTxHistoryDetailsModelTest { ) val model = createModel(testScope = this, transaction = spendTransaction()) advanceUntilIdle() - val errorState = model.uiState.value.redesign.detail + val errorState = model.uiState.value.detail assertThat(errorState).isInstanceOf(TransactionDetailUM.Error::class.java) // Act — tap refresh @@ -144,7 +144,7 @@ internal class TangemPayTxHistoryDetailsModelTest { advanceUntilIdle() // Assert - assertThat(model.uiState.value.redesign.detail) + assertThat(model.uiState.value.detail) .isEqualTo( TransactionDetailUM.Content( cardNumber = stringReference("*4321"), @@ -164,7 +164,7 @@ internal class TangemPayTxHistoryDetailsModelTest { advanceUntilIdle() // Assert - assertThat(model.uiState.value.redesign.detail).isNull() + assertThat(model.uiState.value.detail).isNull() coVerify(exactly = 0) { repository.getTransaction(any(), any()) } model.onDestroy() }