From a1a82d3ece8b41d24b03050da87f0194b36af96f Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 1 Jun 2026 07:59:48 +0200 Subject: [PATCH] Updated on 2026-08-14 --- .../src/main/res/drawable/ic_replace_20.xml | 27 ++ .../ui/src/main/res/drawable/ic_visa_logo.xml | 29 ++ .../components/TangemPayDetailsComponent.kt | 23 +- .../tangempay/entity/TangemPayCardPageUM.kt | 2 + .../entity/TangemPayDetailsStateFactory.kt | 31 ++ .../entity/TangemPayDetailsTopBarConfig.kt | 1 + .../tangempay/entity/TangemPayDetailsUM.kt | 2 +- .../entity/TangemPayDropDownItemUM.kt | 10 + .../tangempay/model/TangemPayCardPageModel.kt | 20 +- .../transformers/DetailsBalanceTransformer.kt | 14 +- .../tangempay/ui/TangemPayCardPageScreen.kt | 56 ++- .../TangemPayCardPageSettingsButtonsBlock.kt | 45 +- .../tangempay/ui/TangemPayDetailsScreen.kt | 34 +- .../tangempay/ui/TangemPayDetailsScreenV2.kt | 404 ++++++++++++++++++ .../ui/components/PayContextMenuBlock.kt | 57 +++ .../ui/components/TangemPayActionButton.kt | 66 +++ .../ui/components/TangemPayCardView.kt | 215 ++++++++++ .../img_bg_pay_details.webp | Bin 0 -> 2136 bytes .../img_bg_pay_details.webp | Bin 0 -> 3052 bytes .../img_bg_pay_details.webp | Bin 0 -> 5644 bytes .../img_bg_pay_details.webp | Bin 0 -> 10094 bytes .../img_bg_pay_details.webp | Bin 0 -> 2678 bytes .../img_bg_pay_details.webp | Bin 0 -> 3956 bytes .../img_bg_pay_details.webp | Bin 0 -> 7808 bytes .../img_bg_pay_details.webp | Bin 0 -> 12528 bytes 25 files changed, 976 insertions(+), 60 deletions(-) create mode 100644 core/ui/src/main/res/drawable/ic_replace_20.xml create mode 100644 core/ui/src/main/res/drawable/ic_visa_logo.xml create mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDropDownItemUM.kt create mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreenV2.kt create mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/PayContextMenuBlock.kt create mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayActionButton.kt create mode 100644 features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayCardView.kt create mode 100644 features/tangempay/details/impl/src/main/res/drawable-night-hdpi/img_bg_pay_details.webp create mode 100644 features/tangempay/details/impl/src/main/res/drawable-night-xhdpi/img_bg_pay_details.webp create mode 100644 features/tangempay/details/impl/src/main/res/drawable-night-xxhdpi/img_bg_pay_details.webp create mode 100644 features/tangempay/details/impl/src/main/res/drawable-night-xxxhdpi/img_bg_pay_details.webp create mode 100644 features/tangempay/details/impl/src/main/res/drawable-notnight-hdpi/img_bg_pay_details.webp create mode 100644 features/tangempay/details/impl/src/main/res/drawable-notnight-xhdpi/img_bg_pay_details.webp create mode 100644 features/tangempay/details/impl/src/main/res/drawable-notnight-xxhdpi/img_bg_pay_details.webp create mode 100644 features/tangempay/details/impl/src/main/res/drawable-notnight-xxxhdpi/img_bg_pay_details.webp diff --git a/core/ui/src/main/res/drawable/ic_replace_20.xml b/core/ui/src/main/res/drawable/ic_replace_20.xml new file mode 100644 index 0000000000..3fdf7b9e3d --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_replace_20.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/core/ui/src/main/res/drawable/ic_visa_logo.xml b/core/ui/src/main/res/drawable/ic_visa_logo.xml new file mode 100644 index 0000000000..a03fb04772 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_visa_logo.xml @@ -0,0 +1,29 @@ + + + + + + + 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 a669eab012..abff694265 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 @@ -16,11 +16,13 @@ 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.LocalRedesignEnabled 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.requireLoaded import com.tangem.features.tangempay.utils.userWalletId import com.tangem.features.tokendetails.ExpressTransactionsComponent @@ -72,12 +74,21 @@ internal class TangemPayDetailsComponent( val bottomSheet by bottomSheetSlot.subscribeAsState() NavigationBar3ButtonsScrim() - TangemPayDetailsScreen( - state = state, - txHistoryComponent = txHistoryComponent, - expressTransactionsComponent = expressTransactionsComponent, - modifier = modifier, - ) + if (LocalRedesignEnabled.current) { + TangemPayDetailsScreenV2( + state = state, + txHistoryComponent = txHistoryComponent, + expressTransactionsComponent = expressTransactionsComponent, + modifier = modifier, + ) + } else { + TangemPayDetailsScreen( + state = state, + txHistoryComponent = txHistoryComponent, + expressTransactionsComponent = expressTransactionsComponent, + modifier = modifier, + ) + } bottomSheet.child?.instance?.BottomSheet() } 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 b4d70fd998..cb24f4b42d 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 @@ -17,6 +17,7 @@ internal data class TangemPayCardPageUM( val dailyLimitState: TangemPayDailyLimitBlockState, val addToWalletBlockState: AddToWalletBlockState? = null, val isReissueInProgress: Boolean = false, + val menuItems: ImmutableList, ) { companion object { fun stub( @@ -40,6 +41,7 @@ internal data class TangemPayCardPageUM( onBackClick = {}, isReissueInProgress = isReissueInProgress, dailyLimitState = dailyLimitState, + menuItems = persistentListOf(), ) } } 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 efabb31b08..8de4b0c86d 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 @@ -4,9 +4,12 @@ import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem import com.tangem.core.ui.components.notifications.NotificationConfig +import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.themedColor import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.generated.icons.Icons +import com.tangem.core.ui.res.generated.icons.ic_document_20 import com.tangem.domain.models.pay.TangemPayCardFrozenState import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.utils.TangemPayDetailIntents @@ -31,6 +34,7 @@ internal class TangemPayDetailsStateFactory( onBackClick = onBack, onOpenMenu = onOpenMenu, items = getTopBarMenuItems(isTangemPayDeactivated), + itemsV2 = getTopBarMenuItemsV2(isTangemPayDeactivated), ), pullToRefreshConfig = PullToRefreshConfig( isRefreshing = false, @@ -89,4 +93,31 @@ internal class TangemPayDetailsStateFactory( ), ) } + + private fun getTopBarMenuItemsV2(isTangemPayDeactivated: Boolean): ImmutableList { + if (isTangemPayDeactivated) return persistentListOf() + + return persistentListOf( + TangemPayDropDownItemUM( + title = resourceReference(R.string.tangem_pay_terms_limits), + onClick = intents::onClickTermsAndLimits, + icon = TangemIconUM.Icon( + imageVector = Icons.ic_document_20, + tintReference = { + TangemTheme.colors3.icon.primary + }, + ), + ), + TangemPayDropDownItemUM( + title = resourceReference(R.string.tangempay_pay_support), + onClick = intents::onContactSupportClicked, + icon = TangemIconUM.Icon( + imageVector = Icons.ic_document_20, + tintReference = { + TangemTheme.colors3.icon.primary + }, + ), // TODO change when the icon will be ready in design + ), + ) + } } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsTopBarConfig.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsTopBarConfig.kt index 9675f1b31d..f25f792ca5 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsTopBarConfig.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsTopBarConfig.kt @@ -7,4 +7,5 @@ internal data class TangemPayDetailsTopBarConfig( val onBackClick: () -> Unit, val onOpenMenu: () -> Unit, val items: ImmutableList, + val itemsV2: ImmutableList, ) \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsUM.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsUM.kt index e51533434b..706d875d26 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsUM.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDetailsUM.kt @@ -77,7 +77,7 @@ internal sealed class TangemPayDetailsBalanceBlockState { data class Content( override val actionButtons: ImmutableList, override val cardsBlockState: CardsBlockState?, - val fiatBalance: String, + val fiatBalance: TextReference, val isBalanceFlickering: Boolean, ) : TangemPayDetailsBalanceBlockState() diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDropDownItemUM.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDropDownItemUM.kt new file mode 100644 index 0000000000..71d30e3f2e --- /dev/null +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayDropDownItemUM.kt @@ -0,0 +1,10 @@ +package com.tangem.features.tangempay.entity + +import com.tangem.core.ui.ds.image.TangemIconUM +import com.tangem.core.ui.extensions.TextReference + +internal data class TangemPayDropDownItemUM( + val onClick: () -> Unit, + val title: TextReference, + val icon: TangemIconUM, +) \ No newline at end of file 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 0694b3694b..9db19e4817 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 @@ -13,6 +13,7 @@ import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.navigation.Router import com.tangem.core.decompose.ui.UiMessageSender import com.tangem.core.ui.DesignFeatureToggles +import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.format.bigdecimal.fiat @@ -20,6 +21,7 @@ import com.tangem.core.ui.format.bigdecimal.format import com.tangem.core.ui.format.bigdecimal.getJavaCurrencyByCode import com.tangem.core.ui.format.bigdecimal.optionalDecimals import com.tangem.core.ui.message.SnackbarMessage +import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.test.TangemPayTestTags import com.tangem.domain.models.StatusSource import com.tangem.domain.models.TokenReceiveConfig @@ -53,7 +55,7 @@ import kotlinx.coroutines.launch import javax.inject.Inject import com.tangem.core.ui.R as CoreUiR -@Suppress("LongParameterList") +@Suppress("LongParameterList", "LargeClass") @Stable @ModelScoped internal class TangemPayCardPageModel @Inject constructor( @@ -89,6 +91,7 @@ internal class TangemPayCardPageModel @Inject constructor( dailyLimitState = TangemPayDailyLimitBlockState.Loading, settings = persistentListOf(), settingsV2 = persistentListOf(), + menuItems = buildMenuItems(), ), ) @@ -210,6 +213,21 @@ internal class TangemPayCardPageModel @Inject constructor( ) } + private fun buildMenuItems(): ImmutableList { + return persistentListOf( + TangemPayDropDownItemUM( + title = TextReference.Res(R.string.tangempay_card_details_reissue_card), + onClick = ::onClickReissueCard, + icon = TangemIconUM.Icon( + iconRes = CoreUiR.drawable.ic_replace_20, + tintReference = { + TangemTheme.colors3.icon.primary + }, + ), + ), + ) + } + private fun onClickViewDetails() { modelScope.launch(dispatchers.default) { cardDetailsEventListener.send(CardDetailsEvent.Show) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/DetailsBalanceTransformer.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/DetailsBalanceTransformer.kt index d2a9482577..eca90fdbb4 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/DetailsBalanceTransformer.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/DetailsBalanceTransformer.kt @@ -2,8 +2,10 @@ package com.tangem.features.tangempay.model.transformers import arrow.core.Either import com.tangem.core.error.UniversalError +import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.format.bigdecimal.fiat -import com.tangem.core.ui.format.bigdecimal.format +import com.tangem.core.ui.format.bigdecimal.formatStyled +import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.pay.model.TangemPayCardBalance import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState import com.tangem.features.tangempay.entity.TangemPayDetailsUM @@ -35,10 +37,14 @@ internal class DetailsBalanceTransformer( return prevState.copy(balanceBlockState = balance) } - private fun getFiatBalanceText(balance: TangemPayCardBalance): String { + private fun getFiatBalanceText(balance: TangemPayCardBalance): TextReference { val currency = Currency.getInstance(balance.currencyCode) - return balance.fiatBalance.format { - fiat(fiatCurrencyCode = currency.currencyCode, fiatCurrencySymbol = currency.symbol) + return balance.fiatBalance.formatStyled { + fiat( + fiatCurrencyCode = currency.currencyCode, + fiatCurrencySymbol = currency.symbol, + spanStyleReference = { TangemTheme.typography3.heading.medium.toSpanStyle() }, + ) } } } \ No newline at end of file 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 6b2374624b..6793c51dd5 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 @@ -15,9 +15,8 @@ import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.material3.Scaffold import androidx.compose.material3.ScaffoldDefaults import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.remember +import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalDensity @@ -25,6 +24,9 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.util.fastForEach import com.tangem.core.ui.components.appbar.AppBarWithBackButton +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.resolveReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.LocalRedesignEnabled @@ -36,7 +38,9 @@ import com.tangem.features.tangempay.components.cardDetails.PreviewTangemPayCard import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.* +import com.tangem.features.tangempay.ui.components.PayContextMenuBlock import kotlinx.collections.immutable.ImmutableList +import com.tangem.core.ui.R as CoreUiR private const val CONTENT_FADE_DURATION_MS = 300 @@ -51,8 +55,8 @@ internal fun TangemPayCardPageScreen( Scaffold( modifier = modifier, topBar = { - AppBarWithBackButton( - modifier = Modifier.statusBarsPadding(), + CardPageTopBar( + items = state.menuItems, onBackClick = state.onBackClick, ) }, @@ -170,6 +174,48 @@ private fun TangemPayCardPageSettingRow( } } +@Composable +private fun CardPageTopBar( + onBackClick: () -> Unit, + items: ImmutableList, + modifier: Modifier = Modifier, +) { + if (LocalRedesignEnabled.current) { + 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 = 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, + onBackClick = onBackClick, + ) + } +} + private fun LazyListScope.cardPageItem( key: Any? = null, contentType: Any? = null, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardPageSettingsButtonsBlock.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardPageSettingsButtonsBlock.kt index ce36ac6ad5..ca0e75ed12 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardPageSettingsButtonsBlock.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayCardPageSettingsButtonsBlock.kt @@ -2,20 +2,20 @@ package com.tangem.features.tangempay.ui import android.content.res.Configuration import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material3.Text +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.util.fastForEach -import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.ds2.button.TangemButton -import com.tangem.core.ui.extensions.resolveAnnotatedReference import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.features.tangempay.entity.TangemPayCardPageSettingV2 +import com.tangem.features.tangempay.ui.components.TangemPayActionButton import kotlinx.collections.immutable.ImmutableList @Composable @@ -30,41 +30,18 @@ internal fun TangemPayCardPageSettingsButtonsBlock( horizontalArrangement = Arrangement.Center, ) { settings.fastForEach { setting -> - TangemPaySettingButton( - setting = setting, + TangemPayActionButton( modifier = Modifier.then(if (setting.testTag != null) Modifier.testTag(setting.testTag) else Modifier), + title = setting.title, + iconRes = setting.iconRes, + onClick = setting.onClick, + isEnabled = setting.isEnabled, + isLoading = setting.isLoading, ) } } } -@Composable -private fun TangemPaySettingButton(setting: TangemPayCardPageSettingV2, modifier: Modifier = Modifier) { - Column( - modifier = modifier.padding(horizontal = TangemTheme.dimens2.x6), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - TangemButton( - variant = TangemButton.Variant.Material, - size = TangemButton.Size.X14, - onClick = setting.onClick, - iconStart = TangemIconUM.Icon( - iconRes = setting.iconRes, - tintReference = { TangemTheme.colors3.icon.primary }, - ), - isLoading = setting.isLoading, - isEnabled = setting.isEnabled, - ) - - Text( - text = setting.title.resolveAnnotatedReference(), - style = TangemTheme.typography3.subheading.medium, - color = TangemTheme.colors3.text.primary, - ) - } -} - @Preview(showBackground = true) @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable 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 index 55d6159978..3371d0dcdb 100644 --- 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 @@ -25,6 +25,7 @@ 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 @@ -45,9 +46,7 @@ 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.text.applyBladeBrush -import com.tangem.core.ui.extensions.orMaskWithStars -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe +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 @@ -343,7 +342,7 @@ private fun FiatBalance( ) is TangemPayDetailsBalanceBlockState.Content -> Text( modifier = modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE), - text = state.fiatBalance.orMaskWithStars(isBalanceHidden), + text = state.fiatBalance.orMaskWithStars(isBalanceHidden).resolveReference(), style = TangemTheme.typography.h2.applyBladeBrush( isEnabled = state.isBalanceFlickering, textColor = TangemTheme.colors.text.primary1, @@ -432,10 +431,15 @@ private fun TangemPayDetailsScreenPreview( } } -private class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider( +internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider( collection = listOf( TangemPayDetailsUM( - topBarConfig = TangemPayDetailsTopBarConfig(onBackClick = {}, onOpenMenu = {}, items = persistentListOf()), + topBarConfig = TangemPayDetailsTopBarConfig( + onBackClick = {}, + onOpenMenu = {}, + items = persistentListOf(), + itemsV2 = persistentListOf(), + ), pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}), balanceBlockState = TangemPayDetailsBalanceBlockState.Content( actionButtons = persistentListOf( @@ -445,7 +449,14 @@ private class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider( +internal class TangemPayDetailsTxHistoryProvider : CollectionPreviewParameterProvider( collection = listOf( PreviewTangemPayTxHistoryComponent.loadingUM, PreviewTangemPayTxHistoryComponent.contentUM, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreenV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreenV2.kt new file mode 100644 index 0000000000..8be30b01d3 --- /dev/null +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreenV2.kt @@ -0,0 +1,404 @@ +package com.tangem.features.tangempay.ui + +import android.content.res.Configuration +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.togetherWith +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.* +import androidx.compose.foundation.text.TextAutoSize +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextOverflow +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.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.util.fastAny +import androidx.compose.ui.util.fastForEach +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.tangem.core.ui.components.SpacerW +import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig +import com.tangem.core.ui.components.containers.pullToRefresh.TangemPullToRefreshSlidingContainer +import com.tangem.core.ui.components.text.applyBladeBrush +import com.tangem.core.ui.components.topFade +import com.tangem.core.ui.ds.image.TangemIconUM +import com.tangem.core.ui.ds.message.TangemMessage +import com.tangem.core.ui.ds.message.TangemMessageEffect +import com.tangem.core.ui.ds.topbar.TangemTopBar +import com.tangem.core.ui.ds2.button.TangemButton +import com.tangem.core.ui.ds2.shimmers.TextShimmer +import com.tangem.core.ui.ds2.shimmers.TextShimmerStyle +import com.tangem.core.ui.extensions.clickableSingle +import com.tangem.core.ui.extensions.orMaskWithStars +import com.tangem.core.ui.extensions.resolveAnnotatedReference +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreviewRedesign +import com.tangem.core.ui.test.TangemPayTestTags +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.TangemPayDetailsBalanceBlockState +import com.tangem.features.tangempay.entity.TangemPayDetailsTopBarConfig +import com.tangem.features.tangempay.entity.TangemPayDetailsUM +import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM +import com.tangem.features.tangempay.ui.components.PayContextMenuBlock +import com.tangem.features.tangempay.ui.components.TangemPayActionButton +import com.tangem.features.tangempay.ui.components.TangemPayAddCardView +import com.tangem.features.tangempay.ui.components.TangemPayCardView +import com.tangem.features.tokendetails.ExpressTransactionsComponent +import com.tangem.utils.StringsSigns.DASH_SIGN +import kotlinx.collections.immutable.ImmutableList +import com.tangem.core.ui.R as CoreUiR + +private val InitialTopBarHeight: Dp = 64.dp +private val BgImageFadeDistance: Dp = 96.dp +private const val TOP_FADE_MID_STOP = 0.8f +private const val TOP_FADE_MID_ALPHA = 0.8f + +@Suppress("LongMethod") +@Composable +internal fun TangemPayDetailsScreenV2( + state: TangemPayDetailsUM, + txHistoryComponent: TangemPayTxHistoryComponent, + expressTransactionsComponent: ExpressTransactionsComponent, + modifier: Modifier = Modifier, +) { + val listState = rememberLazyListState() + val density = LocalDensity.current + val statusBarHeight = with(density) { WindowInsets.systemBars.getTop(this).toDp() } + val bottomBarHeight = with(density) { WindowInsets.systemBars.getBottom(this).toDp() } + var topBarTotalHeight by remember { mutableStateOf(InitialTopBarHeight + statusBarHeight) } + val rootBackground = TangemTheme.colors3.bg.primary + val fadeDistancePx = with(LocalDensity.current) { BgImageFadeDistance.toPx() } + val bgImageAlpha by remember(fadeDistancePx) { + derivedStateOf { + val scrollOffsetPx = when (listState.firstVisibleItemIndex) { + 0 -> listState.firstVisibleItemScrollOffset.toFloat() + else -> fadeDistancePx + }.coerceAtLeast(0f) + (1f - scrollOffsetPx / fadeDistancePx).coerceIn(0f, 1f) + } + } + + val txHistoryState by txHistoryComponent.state.collectAsStateWithLifecycle() + val expressState by expressTransactionsComponent.state.collectAsStateWithLifecycle() + val expressTransactionsBottomSheetState = expressState.bottomSheetSlot + + Box( + modifier = modifier + .fillMaxSize() + .background(rootBackground), + ) { + Image( + modifier = Modifier + .fillMaxWidth(), + painter = painterResource(R.drawable.img_bg_pay_details), + contentDescription = null, + contentScale = ContentScale.FillWidth, + alpha = bgImageAlpha, + ) + + TangemPullToRefreshSlidingContainer( + config = state.pullToRefreshConfig, + indicatorOffset = topBarTotalHeight, + ) { + LazyColumn( + modifier = Modifier + .fillMaxSize() + .topFade( + height = topBarTotalHeight, + 0f to rootBackground.copy(alpha = 1f - bgImageAlpha), + TOP_FADE_MID_STOP to rootBackground.copy(alpha = TOP_FADE_MID_ALPHA * (1f - bgImageAlpha)), + 1f to Color.Transparent, + ), + horizontalAlignment = Alignment.CenterHorizontally, + state = listState, + contentPadding = PaddingValues( + top = topBarTotalHeight, + bottom = TangemTheme.dimens2.x4 + bottomBarHeight, + ), + ) { + payDetailsBody(state) + with(expressTransactionsComponent) { + expressTransactionsContent( + state = expressState.transactionsToDisplay, + modifier = Modifier + .padding(horizontal = 16.dp) + .padding(top = 12.dp) + .fillMaxWidth(), + ) + } + with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryState) } + } + } + + PayDetailsTopBar( + config = state.topBarConfig, + onHeightChange = { measuredHeight -> + if (topBarTotalHeight != measuredHeight) topBarTotalHeight = measuredHeight + }, + ) + } + expressTransactionsBottomSheetState?.content(null) +} + +private fun LazyListScope.payDetailsBody(state: TangemPayDetailsUM) { + item("balanceBlock") { + BalanceBlock( + state = state.balanceBlockState, + isBalanceHidden = state.isBalanceHidden, + ) + } + state.balanceBlockState.cardsBlockState?.let { cardsState -> + item("cardsBlock") { + CardsBlock(cardsBlockState = cardsState) + } + } + if (state.balanceBlockState.actionButtons.isNotEmpty()) { + item("actionButtonsBlock") { + ActionBlock(actionButtons = state.balanceBlockState.actionButtons) + } + } + when { + state.balanceBlockState.cardsBlockState?.cards?.fastAny { it.isReissuing } == true -> { + item("reissuingBannerBlock") { + TangemMessage( + modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x4), + title = resourceReference(R.string.tangempay_reissue_card_in_progress), + subtitle = resourceReference(R.string.tangempay_reissue_card_in_progress_description), + ) + } + } + else -> { + if (state.addToWalletBlockState != null) { + item("addToWalletBannerBlock") { + TangemPayAddToWalletBlock( + state = state.addToWalletBlockState, + modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x4), + ) + } + } + if (state.accountDeactivatedNotificationConfig != null) { + item("deactivationBannerBlock") { + TangemMessage( + modifier = Modifier + .padding(horizontal = TangemTheme.dimens2.x4) + .clickableSingle( + onClick = { state.accountDeactivatedNotificationConfig.onClick?.invoke() }, + ), + title = state.accountDeactivatedNotificationConfig.title, + subtitle = state.accountDeactivatedNotificationConfig.subtitle, + messageEffect = TangemMessageEffect.Warning, + ) + } + } + } + } +} + +@Composable +private fun PayDetailsTopBar( + config: TangemPayDetailsTopBarConfig, + onHeightChange: (Dp) -> Unit, + modifier: Modifier = Modifier, +) { + val density = LocalDensity.current + TangemTopBar( + modifier = modifier + .onSizeChanged { size -> + onHeightChange(with(density) { size.height.toDp() }) + } + .statusBarsPadding(), + title = resourceReference(R.string.tangempay_payment_account), + subtitle = resourceReference(R.string.tangempay_usdc_on_polygon_network), + startContent = { + TangemButton( + iconStart = TangemIconUM.Icon(iconRes = CoreUiR.drawable.ic_arrow_back_28), + onClick = config.onBackClick, + size = TangemButton.Size.X11, + variant = TangemButton.Variant.Material, + ) + }, + endContent = if (config.itemsV2.isNotEmpty()) { + { + var isDropdownMenuShown by rememberSaveable { mutableStateOf(false) } + Box { + TangemButton( + iconStart = TangemIconUM.Icon(iconRes = CoreUiR.drawable.ic_more_default_24), + onClick = { + config.onOpenMenu() + isDropdownMenuShown = true + }, + size = TangemButton.Size.X11, + variant = TangemButton.Variant.Material, + ) + PayContextMenuBlock( + items = config.itemsV2, + onMenuDismiss = { isDropdownMenuShown = false }, + isDropdownMenuShown = isDropdownMenuShown, + ) + } + } + } else { + null + }, + ) +} + +@Composable +private fun BalanceBlock( + state: TangemPayDetailsBalanceBlockState, + isBalanceHidden: Boolean, + modifier: Modifier = Modifier, +) { + Column( + modifier + .fillMaxWidth() + .padding(horizontal = TangemTheme.dimens2.x4) + .padding(top = TangemTheme.dimens2.x12), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + AnimatedContent( + targetState = state, + label = "Updating the balance", + transitionSpec = { + fadeIn(animationSpec = tween(durationMillis = 220, delayMillis = 90)) togetherWith + fadeOut(animationSpec = tween(durationMillis = 90)) + }, + ) { animatedState -> + when (animatedState) { + is TangemPayDetailsBalanceBlockState.Loading -> TextShimmer( + modifier = Modifier.size(width = 160.dp, height = 56.dp), + text = "1234.00", + style = TextShimmerStyle.HEADING_MEDIUM, + radius = TangemTheme.dimens2.x25, + ) + is TangemPayDetailsBalanceBlockState.Content -> Text( + modifier = Modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE), + text = animatedState.fiatBalance.orMaskWithStars(isBalanceHidden).resolveAnnotatedReference(), + style = TangemTheme.typography3.display.medium.applyBladeBrush( + isEnabled = animatedState.isBalanceFlickering, + textColor = TangemTheme.colors3.text.primary, + ), + color = TangemTheme.colors3.text.primary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + autoSize = TextAutoSize.StepBased( + minFontSize = TangemTheme.typography3.heading.medium.fontSize, + maxFontSize = TangemTheme.typography3.display.medium.fontSize, + ), + ) + is TangemPayDetailsBalanceBlockState.Error -> Text( + modifier = Modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE), + text = DASH_SIGN.orMaskWithStars(isBalanceHidden), + style = TangemTheme.typography3.display.medium, + color = TangemTheme.colors3.text.primary, + ) + } + } + } +} + +@Composable +private fun CardsBlock( + cardsBlockState: TangemPayDetailsBalanceBlockState.CardsBlockState, + modifier: Modifier = Modifier, +) { + LazyRow( + modifier = modifier.fillMaxWidth(), + state = rememberLazyListState(), + contentPadding = PaddingValues( + horizontal = TangemTheme.dimens2.x4, + vertical = TangemTheme.dimens2.x6, + ), + horizontalArrangement = Arrangement.Center, + ) { + items(items = cardsBlockState.cards) { item -> + TangemPayCardView( + isReissuing = item.isReissuing, + lastDigits = item.lastDigits, + onClick = item.onClick, + ) + SpacerW(TangemTheme.dimens2.x2) + } + item { + TangemPayAddCardView(onClick = cardsBlockState.onAddCardClick) + } + } +} + +@Composable +private fun LazyItemScope.ActionBlock( + actionButtons: ImmutableList, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier + .fillMaxWidth() + .padding(vertical = TangemTheme.dimens2.x6), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + ) { + actionButtons.fastForEach { actionConfig -> + TangemPayActionButton( + iconRes = actionConfig.iconResId, + onClick = actionConfig.onClick, + isEnabled = actionConfig.isEnabled, + isLoading = actionConfig.isInProgress, + title = actionConfig.text, + ) + } + } +} + +// region preview + +@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, +) { + TangemThemePreviewRedesign { + TangemPayDetailsScreenV2( + state = state, + txHistoryComponent = PreviewTangemPayTxHistoryComponent( + txHistoryUM = PreviewTangemPayTxHistoryComponent.contentUM, + ), + expressTransactionsComponent = PreviewEmptyExpressTransactionsComponent(), + ) + } +} + +@Preview(device = Devices.PIXEL_7_PRO) +@Composable +private fun TangemPayDetailsTxHistoryScreenPreview( + @PreviewParameter(TangemPayDetailsTxHistoryProvider::class) state: TangemPayTxHistoryUM, +) { + TangemThemePreviewRedesign { + TangemPayDetailsScreenV2( + state = TangemPayDetailsUMProvider().values.first(), + txHistoryComponent = PreviewTangemPayTxHistoryComponent(txHistoryUM = state), + expressTransactionsComponent = PreviewEmptyExpressTransactionsComponent(), + ) + } +} + +// end region preview \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/PayContextMenuBlock.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/PayContextMenuBlock.kt new file mode 100644 index 0000000000..88dd7ca342 --- /dev/null +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/PayContextMenuBlock.kt @@ -0,0 +1,57 @@ +package com.tangem.features.tangempay.ui.components + +import androidx.compose.foundation.layout.* +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.DpOffset +import androidx.compose.ui.util.fastForEach +import com.tangem.core.ui.ds.contextmenu.TangemContextMenu +import com.tangem.core.ui.ds.image.TangemIcon +import com.tangem.core.ui.extensions.clickableSingle +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.features.tangempay.entity.TangemPayDropDownItemUM +import kotlinx.collections.immutable.ImmutableList + +@Composable +internal fun PayContextMenuBlock( + items: ImmutableList, + isDropdownMenuShown: Boolean, + onMenuDismiss: () -> Unit, + modifier: Modifier = Modifier, +) { + TangemContextMenu( + expanded = isDropdownMenuShown, + onDismissRequest = onMenuDismiss, + offset = DpOffset.Zero, + modifier = modifier, + ) { + items.fastForEach { item -> + Column { + Row( + horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2), + modifier = Modifier + .clickableSingle( + onClick = { + item.onClick() + onMenuDismiss() + }, + ) + .padding(vertical = TangemTheme.dimens2.x3, horizontal = TangemTheme.dimens2.x4), + ) { + TangemIcon( + modifier = Modifier.size(TangemTheme.dimens2.x5), + tangemIconUM = item.icon, + ) + Text( + text = item.title.resolveReference(), + style = TangemTheme.typography3.body.medium, + color = TangemTheme.colors3.text.primary, + maxLines = 1, + ) + } + } + } + } +} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayActionButton.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayActionButton.kt new file mode 100644 index 0000000000..924d154d90 --- /dev/null +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayActionButton.kt @@ -0,0 +1,66 @@ +package com.tangem.features.tangempay.ui.components + +import android.content.res.Configuration +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.R +import com.tangem.core.ui.ds.image.TangemIconUM +import com.tangem.core.ui.ds2.button.TangemButton +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveAnnotatedReference +import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreviewRedesign + +@Composable +internal fun TangemPayActionButton( + title: TextReference, + @DrawableRes iconRes: Int, + onClick: () -> Unit, + modifier: Modifier = Modifier, + isEnabled: Boolean = true, + isLoading: Boolean = false, +) { + Column( + modifier = modifier.padding(horizontal = TangemTheme.dimens2.x4), + verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + TangemButton( + variant = TangemButton.Variant.Material, + size = TangemButton.Size.X14, + onClick = onClick, + iconStart = TangemIconUM.Icon( + iconRes = iconRes, + tintReference = { TangemTheme.colors3.icon.primary }, + ), + isLoading = isLoading, + isEnabled = isEnabled, + ) + + Text( + text = title.resolveAnnotatedReference(), + style = TangemTheme.typography3.subheading.medium, + color = TangemTheme.colors3.text.primary, + ) + } +} + +@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun TangemPayActionButtonPreview() { + TangemThemePreviewRedesign { + TangemPayActionButton( + title = stringReference("Action"), + iconRes = R.drawable.ic_arrow_down_24, + onClick = {}, + ) + } +} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayCardView.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayCardView.kt new file mode 100644 index 0000000000..0663d4bd6d --- /dev/null +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayCardView.kt @@ -0,0 +1,215 @@ +package com.tangem.features.tangempay.ui.components + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.TileMode +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.tooling.preview.Devices +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.tangem.core.ui.R +import com.tangem.core.ui.components.SpacerH +import com.tangem.core.ui.extensions.clickableSingle +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreviewRedesign +import com.tangem.core.ui.res.generated.icons.Icons +import com.tangem.core.ui.res.generated.icons.ic_clock_12 +import com.tangem.core.ui.res.generated.icons.ic_cloud_12 +import com.tangem.core.ui.test.TangemPayTestTags + +private const val DEFAULT_CARD_BG = 0xFF1C1F29 +private const val REISSUING_CARD_BG = 0xFF1E1E1E + +@Composable +internal fun TangemPayCardView( + isReissuing: Boolean, + lastDigits: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + CardBackground( + modifier = modifier + .size( + height = TangemTheme.dimens2.x10, + width = TangemTheme.dimens2.x14, + ) + .testTag(TangemPayTestTags.PAYMENT_ACCOUNT_CARD_BUTTON), + isReissuing = isReissuing, + onClick = onClick, + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = TangemTheme.dimens2.x1) + .padding(top = TangemTheme.dimens2.x1), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Icon( + modifier = Modifier.size(TangemTheme.dimens2.x3), + imageVector = if (isReissuing) { + Icons.ic_clock_12 + } else { + Icons.ic_cloud_12 + }, + tint = TangemTheme.colors3.icon.staticDark, + contentDescription = null, + ) + + Icon( + modifier = Modifier.size(height = TangemTheme.dimens2.x2, width = 22.dp), + imageVector = ImageVector.vectorResource(R.drawable.ic_visa_logo), + tint = TangemTheme.colors3.icon.staticDark, + contentDescription = null, + ) + } + + Text( + modifier = Modifier + .align(Alignment.BottomEnd) + .padding(end = TangemTheme.dimens2.x1, bottom = TangemTheme.dimens2.x1), + text = lastDigits, + style = TangemTheme.typography3.caption.medium.copy(fontSize = 10.sp), + color = TangemTheme.colors3.text.staticDark.primary, + ) + } +} + +@Composable +internal fun TangemPayAddCardView(onClick: () -> Unit, modifier: Modifier = Modifier) { + Box( + modifier = modifier + .size( + height = TangemTheme.dimens2.x10, + width = TangemTheme.dimens2.x14, + ) + .clip(RoundedCornerShape(TangemTheme.dimens3.borderRadius.b075)) + .background(TangemTheme.colors3.bg.opaque.primary) + .clickableSingle(onClick = onClick), + contentAlignment = Alignment.Center, + ) { + Icon( + modifier = Modifier.size(20.dp), + imageVector = ImageVector.vectorResource(R.drawable.ic_plus_default_24), + contentDescription = null, + tint = TangemTheme.colors3.icon.secondary, + ) + } +} + +@Suppress("MagicNumber") +@Composable +private fun CardBackground( + isReissuing: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable BoxScope.() -> Unit, +) { + val bgColor = remember(isReissuing) { + if (isReissuing) { + Color(REISSUING_CARD_BG) + } else { + Color(DEFAULT_CARD_BG) + } + } + + Box( + modifier = modifier + .clip(RoundedCornerShape(TangemTheme.dimens3.borderRadius.b075)) + .drawBehind { + drawRect(bgColor) + + val w = size.width + val h = size.height + val radiusScaleRightCorner = h / 2f + val radiusScaleLeftCorner = h / 1.27f + + drawRect( + brush = Brush.radialGradient( + colors = listOf( + Color( + if (isReissuing) 0xFFB0B4BC else 0xFF38587F, + ).copy( + if (isReissuing) .1f else .41f, + ), + Color.Transparent, + ), + center = Offset(w - 20f, h * .05f), + radius = radiusScaleRightCorner, + tileMode = TileMode.Clamp, + ), + ) + + if (!isReissuing) { + drawRect( + brush = Brush.radialGradient( + colors = listOf( + Color(0xFF2881FF).copy(.25f), + Color.Transparent, + ), + center = Offset(0f, h + h * .1f), + radius = radiusScaleLeftCorner, + ), + ) + } + } + .border( + width = 1.dp, + color = TangemTheme.colors3.border.primary, + shape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.b075), + ) + .clickableSingle(onClick = onClick), + content = content, + ) +} + +@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_7_PRO) +@Composable +private fun CardBackgroundPreview() { + TangemThemePreviewRedesign { + Column(modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.Center) { + CardBackground( + modifier = Modifier.size( + height = TangemTheme.dimens2.x10, + width = TangemTheme.dimens2.x14, + ), + isReissuing = false, + onClick = {}, + content = {}, + ) + SpacerH(TangemTheme.dimens2.x4) + CardBackground( + modifier = Modifier.size( + height = TangemTheme.dimens2.x10, + width = TangemTheme.dimens2.x14, + ), + isReissuing = true, + onClick = {}, + content = {}, + ) + SpacerH(TangemTheme.dimens2.x4) + TangemPayCardView(isReissuing = false, onClick = {}, lastDigits = "1234") + SpacerH(TangemTheme.dimens2.x4) + TangemPayCardView(isReissuing = true, onClick = {}, lastDigits = "") + SpacerH(TangemTheme.dimens2.x4) + TangemPayAddCardView(onClick = {}) + } + } +} \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/res/drawable-night-hdpi/img_bg_pay_details.webp b/features/tangempay/details/impl/src/main/res/drawable-night-hdpi/img_bg_pay_details.webp new file mode 100644 index 0000000000000000000000000000000000000000..190f51ba02e0e40450717de578cde948a94b427b GIT binary patch literal 2136 zcmV-e2&eZ_Nk&Fc2mk|KUIUhyU>3-wyoO@6vr+XK~Z$#i`Nn++Fa4@7#8}V7i)sn9*)HGrF845V^lCzZ5jR zs~o`uaQPVOlr}qb)aGehk&duzc3v*liDXO(1qethv;CG8IF6Gk_C^%QD1*^(>sSEK zGN=TAkao}l3<8>(fB{G~z|%z&K$z!LY(IMurR3A@uw%G1YsFS0s#PSPJ}1<(4f~>bhJF!%L$|t^n(7EiV*&g z?=P*#ah!;s8dt4I&lD$UsxrRw3bhsOx#N6%j3f>q0s!BDnr6g~#oF9i$a1IOo}zU{ zY`BZCTV+h{tw|O6B;C=Ac;BoN$3Iy%A@OJpxGFmH2FsJj=fRg+`WFGs92}fhTKOcfo&^^suVsOn+reJ_9*2#?kZkAO}e+tiDa?Zc_-+3z&f|}km4`Q%CUuqk6+$NQ;qh=OQ#}FhSGR^rh*H6a7 zMP8&3D#GphGl;li!M)9!B7hv6d6+)u)G}^6)@HNZ@vFJ$%T5<>Icu=@9tfGW729#z z_5du1XGx4pjANuyV-&%GPAWI)3Xy?I;})IpMZZasgzr7rTw+3WqC4@mYPxE7$s=iu z*Yp9Z?YN_K!GDZ>_&$BUPC-b#z7}1!{9eFlecWvsI}xNH$y2Ojj=9SSB&cL_v3v9= z@OD7R!m{}<^`WaWnEGqAQmVAc}arSw_50{^`|@+KG34XBVY6I2?b`Uhs7hwJO{|Ywzss>nb*?FUv8!5*k#ev(V-2NC3znzD)z%*$wf}64Y-(Vm-+uCr$f-Q_H#wkAvLg z_mA94{yEy;>A&2rM?M~*-m5Y9nxbV5uwEiU{K>;jhe{941XSiN+P@)>ecL4*L76cX zd5_e~=-0BTspJWjD=2-S(QNJ_^9B;M(dY+*+(My~EPsuUE_^Z5yVa?_#469rPg9Ai zUPx6j!D^3u<3z1*V0Az-2!5XiX`A7+CNm(<__o<9(w?7 zZ(sD<3ivr$xpD&3H8W+3$78~t0zC{}{&=l3DHyo`6SqQ7lxLH!I)x*~ua|H(K;(9F zNFf+8N*igdyk4tC$gJRgo9*!*s7`7$6W3ADWx&aCrepPo)onfvF(@s}r8j zE7w9{9?5{?KuUWOl`9Ue~uwA z03CSS#eI5QP`G;Y*E>_2sr=i->D0F1j)3zjk!Lvk)aG8(*&RMSNiHy248%Tf@niW+ zO7cGc*V3RMIesV>6x;wf;?TDQ;iI5Uz$8?|MF=qB+r3fX5@Evm-%&IG005{!#Q@2G OKJVq9$1%Z#0001D3lCQS literal 0 HcmV?d00001 diff --git a/features/tangempay/details/impl/src/main/res/drawable-night-xhdpi/img_bg_pay_details.webp b/features/tangempay/details/impl/src/main/res/drawable-night-xhdpi/img_bg_pay_details.webp new file mode 100644 index 0000000000000000000000000000000000000000..c9b40847346af7604027df0efdcc0af8368e7338 GIT binary patch literal 3052 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 literal 0 HcmV?d00001 diff --git a/features/tangempay/details/impl/src/main/res/drawable-night-xxhdpi/img_bg_pay_details.webp b/features/tangempay/details/impl/src/main/res/drawable-night-xxhdpi/img_bg_pay_details.webp new file mode 100644 index 0000000000000000000000000000000000000000..d8aedcf855464580f4ee797e80ab5efe796b802e GIT binary patch literal 5644 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 G;r{}1gzE7C literal 0 HcmV?d00001 diff --git a/features/tangempay/details/impl/src/main/res/drawable-night-xxxhdpi/img_bg_pay_details.webp b/features/tangempay/details/impl/src/main/res/drawable-night-xxxhdpi/img_bg_pay_details.webp new file mode 100644 index 0000000000000000000000000000000000000000..7671f73787cf681b4eb8a2a2541151b26fbde4f8 GIT binary patch literal 10094 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 TpwR+aXlqQ_FrO~@=ktF6Z}CY@ literal 0 HcmV?d00001 diff --git a/features/tangempay/details/impl/src/main/res/drawable-notnight-hdpi/img_bg_pay_details.webp b/features/tangempay/details/impl/src/main/res/drawable-notnight-hdpi/img_bg_pay_details.webp new file mode 100644 index 0000000000000000000000000000000000000000..dcc819b5672a61f6a7a68082f2ba0b0792997759 GIT binary patch literal 2678 zcmV-+3W@bnNk&F)3IG6CMM6+kP&il$0000G000150sxx=06|PpNP7SP009@Ue-RM{ z+eng}{QZNkmL!Nm`!ACuRtl4e=)ZuV$N@W^k7~t#_z(Z#Km3RP@E`uefA|mo;XnL` z|L`CF!+-b>|KUIUhyU>3-wyoO@6vr+XK~Z$#08pL)odGIa0-ORqkwl$LtE#D`p;QS$a1se=Zv0OC zRBrXUyGJB(!+)s_ar7Tw-@jPC_UV`3^IyL}1r{U7h(>4`V!!9Ov%fyzs?U~p=iC>7 zb~@rS3ei#^U@!m-OB|w+Sm(il%mqp)`-@$h@pNJutAYn0YU52v3QA<}VhmiIJ1zqz z*9%73k~7|5CUv*tFL7ti-T)q7e?ZcWgluU9Bp}k=CE!v3e}ABF(M`z!BqOi``xQO7r#W~1Qf_^pxSGmq z+X;Ww0mmw+1Ic|L<6@lKKHw z3`sp`()=_NRJ0NgVnrp0p@20(uVXUgdP;49yd#5Fkpl^IY{ICLSPliwFMeYr+KhPI zsp@$=35~XA#6etGbBsE*`MlRcG5=S?Vs*x%E=WXHLVsq2U*q`oWM%!&hMAb;i584t z1P=HALd#>7Wq18jul)U(tbKimqBvo1tzSnrB!gud6_sxAti-?*wBY~66a6&=ox6b` zQ9vL8mi2;s7E-@DJ&`WbC-0jM+(&Xi0jdzD6s2I289g)L_|u=vC|UP`&v0O`n1 zvQng3w~>d-bzN<4SnHZ~;r*Kp*OFCw|L}h1^+O%Gc#<$bw?GZ zTGGVssrt3iei_-;#D)QJynqsaa2nVRD`O#}g#;e*lc$<}40j5|hC38anKCngk|D*y z1K08D{KsEU%6w3eyBEwxJP-xX;urgl$uKaqke5W9B zJJ25xcv~>b4Zd${xK<&ErS1el0~h#Te&c*Y)vf^0D79a&d(t8@A{Bs(!DIGD;+`r1 zjZwb!zddRSNla?G)F}1u+$zyy-)fs{OTDCVj^R!A3TnT8`DNeZ@*NfKz#uox}u|yk4J+J~`C_|^XRwLm%whC7ikAmrM2%kZY z-p%6I*9v@4kh@O+aYg;bn}id`$1CdKC`evF&qgh7tXQm8+GBAwF!6deP{T(YAW zp~v4neCqIk5H}?k3O01DPVs8TVZOJ6Yb?8CTqT+IA`h*h&6OgFYZ*+(yOgQ5* zDLw=K;ny-fGki^wrS+Is)FF$AIuahlMPJjfJ*RG~>(tn1&F^rs3&b@&*3UH-6TA$Q z80L$d8EbgKUr#Oyqm2Up4ms4ZXq`I{gB%^ojR60GUrAd5+4R1FhCSz}+uhMYB4m*A zQFCfWaY);SIXM{Svltrc1gQTUZ=QE@mL{=`U75G^+)Vt03UEXXHYJ&ZD4jPmCmy6J zgpV|5C%z-$r;Ut}(~W4>Sh(66?0#z`Razzy7g3Q@{JGRotpZ{eGFd za6^XNSp;S*J`UX9Y0KQp9<9*6(omU%-rqEEeP ziGl1+0`@IIh9QYhNHs+=ljj7bsIgIU57D!a;x_K+nzlF*{4JVYE(1^CbDrWl&cT=D zc68*hX78dr5irNQ-d~2NB1u?mQ9?M8zAL?rC8OpwZ@hZBXX?J*dz*S-E3dD0mAGY< zw3Y9l&yM)~=Z1)ER!YqB5nh>%`rBPZEUZ_Se-9@#X6mEdEE=eoamM1HK)m196w``d=&7qMFBxo+;VwNf78-y;oU zk4V|O9x5yi_XFY44UYbUH895J4k6QKHl>=5LwyhV9Io z5?}og(_=pcBUe!8yDd&!Rss->dwOHc)Dla zcQ*L?^?!-m5e&4EhL*$q4)dXpT_i62$YD|=NU|m|I|pxqIgLbA9o-d zs9@l_pL?-*kL`U(kvt2H>-?l?EKV0#a}wP@jJ&^+=~wN-p0_hP2CNS(gJAPPjFk12 z3klXF9<6FFE{{pd5D)z>u@DeXFq-o^vfrt0eF2H8r+S-X0iHj)P@PSF*i6I^{CR8x ktVnH+Ql+>X+5|r_oV>^bvSnoCC_*4P(F{-k000000MYFL;Q#;t literal 0 HcmV?d00001 diff --git a/features/tangempay/details/impl/src/main/res/drawable-notnight-xhdpi/img_bg_pay_details.webp b/features/tangempay/details/impl/src/main/res/drawable-notnight-xhdpi/img_bg_pay_details.webp new file mode 100644 index 0000000000000000000000000000000000000000..8f47020f267ec48b9cd9e8a25ebb443e61a837e3 GIT binary patch literal 3956 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 Oir@se001N|0002Qdw+uf literal 0 HcmV?d00001 diff --git a/features/tangempay/details/impl/src/main/res/drawable-notnight-xxhdpi/img_bg_pay_details.webp b/features/tangempay/details/impl/src/main/res/drawable-notnight-xxhdpi/img_bg_pay_details.webp new file mode 100644 index 0000000000000000000000000000000000000000..1a91ca2907900fc9e5c9e8ee32cf9bdac38bd36c GIT binary patch literal 7808 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 literal 0 HcmV?d00001 diff --git a/features/tangempay/details/impl/src/main/res/drawable-notnight-xxxhdpi/img_bg_pay_details.webp b/features/tangempay/details/impl/src/main/res/drawable-notnight-xxxhdpi/img_bg_pay_details.webp new file mode 100644 index 0000000000000000000000000000000000000000..0122654158ceddf4d34f1911cb9535dac4236b3d GIT binary patch literal 12528 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