Updated on 2026-08-14
This commit is contained in:
parent
e16b84a3d9
commit
210f392373
10 changed files with 146 additions and 17 deletions
|
|
@ -135,6 +135,10 @@
|
|||
"name": "AND_15364_VISA_PAY_CARD_CLOSE",
|
||||
"version": "undefined"
|
||||
},
|
||||
{
|
||||
"name": "AND_15741_VISA_PAY_REMOVE_ACCOUNT",
|
||||
"version": "undefined"
|
||||
},
|
||||
{
|
||||
"name": "TWI_83_ADDRESS_BOOK_ENABLED",
|
||||
"version": "undefined"
|
||||
|
|
|
|||
|
|
@ -1930,6 +1930,9 @@
|
|||
<string name="tangempay_reissue_card_insufficient_funds_subtitle">Deposit USDC to payment account to cover the issuing fee</string>
|
||||
<string name="tangempay_reissue_card_insufficient_funds_title">Unable to cover fee</string>
|
||||
<string name="tangempay_reissue_card_title">Replace your card?</string>
|
||||
<string name="tangempay_remove_account">Remove account</string>
|
||||
<string name="tangempay_remove_account_alert_description">Tangem Pay will be removed from the main screen and won\'t appear again, even after reinstalling the app.</string>
|
||||
<string name="tangempay_remove_account_alert_title">Remove account?</string>
|
||||
<string name="tangempay_service_unavailable_description">We’re fixing a technical issue. Please try again later.</string>
|
||||
<string name="tangempay_service_unavailable_title">Service temporarily unavailable</string>
|
||||
<string name="tangempay_service_unreachable_try_later">Service unreachable. However, card payments are still working.</string>
|
||||
|
|
|
|||
|
|
@ -3,4 +3,5 @@ package com.tangem.features.tangempay
|
|||
interface TangemPayFeatureToggles {
|
||||
val isRedesignEnabled: Boolean
|
||||
val isCloseCardEnabled: Boolean
|
||||
val isRemoveAccountEnabled: Boolean
|
||||
}
|
||||
|
|
@ -12,4 +12,7 @@ internal class DefaultTangemPayFeatureToggles(
|
|||
|
||||
override val isCloseCardEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15364_VISA_PAY_CARD_CLOSE)
|
||||
|
||||
override val isRemoveAccountEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15741_VISA_PAY_REMOVE_ACCOUNT)
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@ import com.tangem.features.tangempay.details.impl.R
|
|||
import com.tangem.features.tangempay.utils.TangemPayDetailIntents
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import com.tangem.core.ui.R as CoreUiR
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class TangemPayDetailsStateFactory(
|
||||
|
|
@ -25,6 +27,7 @@ internal class TangemPayDetailsStateFactory(
|
|||
private val onOpenMenu: () -> Unit,
|
||||
private val intents: TangemPayDetailIntents,
|
||||
private val isRedesignEnabled: Boolean,
|
||||
private val isRemoveAccountEnabled: Boolean,
|
||||
) {
|
||||
fun getLoadingState(): TangemPayDetailsUM {
|
||||
return TangemPayDetailsUM(
|
||||
|
|
@ -102,8 +105,8 @@ internal class TangemPayDetailsStateFactory(
|
|||
topBarConfig = TangemPayDetailsTopBarConfig(
|
||||
onBackClick = onBack,
|
||||
onOpenMenu = onOpenMenu,
|
||||
items = persistentListOf(),
|
||||
itemsV2 = persistentListOf(),
|
||||
items = getDeactivatedMenuItems(),
|
||||
itemsV2 = getDeactivatedMenuItemsV2(),
|
||||
),
|
||||
pullToRefreshConfig = PullToRefreshConfig(
|
||||
isRefreshing = false,
|
||||
|
|
@ -131,6 +134,14 @@ internal class TangemPayDetailsStateFactory(
|
|||
title = resourceReference(R.string.tangempay_account_deactivated_message_title),
|
||||
subtitle = resourceReference(R.string.tangempay_account_deactivated_message_subtitle),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
buttonsState = if (isRemoveAccountEnabled) {
|
||||
NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.tangempay_remove_account),
|
||||
onClick = intents::onRemoveAccount,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
|
||||
private fun createRenewSessionNotificationConfig() = NotificationConfig(
|
||||
|
|
@ -159,6 +170,55 @@ internal class TangemPayDetailsStateFactory(
|
|||
)
|
||||
}
|
||||
|
||||
private fun getDeactivatedMenuItems(): ImmutableList<TangemDropdownMenuItem> {
|
||||
return buildList {
|
||||
add(
|
||||
TangemDropdownMenuItem(
|
||||
title = resourceReference(R.string.tangempay_pay_support),
|
||||
textColor = themedColor { TangemTheme.colors.text.primary1 },
|
||||
onClick = intents::onContactSupportClicked,
|
||||
),
|
||||
)
|
||||
if (isRemoveAccountEnabled) {
|
||||
add(
|
||||
TangemDropdownMenuItem(
|
||||
title = resourceReference(R.string.tangempay_remove_account),
|
||||
textColor = themedColor { TangemTheme.colors.text.warning },
|
||||
onClick = intents::onRemoveAccount,
|
||||
),
|
||||
)
|
||||
}
|
||||
}.toImmutableList()
|
||||
}
|
||||
|
||||
private fun getDeactivatedMenuItemsV2(): ImmutableList<TangemPayDropDownItemUM> {
|
||||
return buildList {
|
||||
add(
|
||||
TangemPayDropDownItemUM(
|
||||
title = resourceReference(R.string.tangempay_pay_support),
|
||||
onClick = intents::onContactSupportClicked,
|
||||
icon = TangemIconUM.Icon(
|
||||
iconRes = R.drawable.ic_mail_20,
|
||||
tintReference = { TangemTheme.colors3.icon.primary },
|
||||
),
|
||||
),
|
||||
)
|
||||
if (isRemoveAccountEnabled) {
|
||||
add(
|
||||
TangemPayDropDownItemUM(
|
||||
title = resourceReference(R.string.tangempay_remove_account),
|
||||
onClick = intents::onRemoveAccount,
|
||||
icon = TangemIconUM.Icon(
|
||||
iconRes = CoreUiR.drawable.ic_trash_24,
|
||||
tintReference = { TangemTheme.colors3.icon.status.error },
|
||||
),
|
||||
titleColor = { TangemTheme.colors3.text.status.error },
|
||||
),
|
||||
)
|
||||
}
|
||||
}.toImmutableList()
|
||||
}
|
||||
|
||||
private fun getTopBarMenuItemsV2(): ImmutableList<TangemPayDropDownItemUM> {
|
||||
return persistentListOf(
|
||||
TangemPayDropDownItemUM(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.tangempay.entity
|
||||
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.extensions.ColorReference2
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
internal data class TangemPayDropDownItemUM(
|
||||
|
|
@ -9,4 +10,5 @@ internal data class TangemPayDropDownItemUM(
|
|||
val icon: TangemIconUM,
|
||||
val subtitle: TextReference? = null,
|
||||
val isEnabled: Boolean = true,
|
||||
val titleColor: ColorReference2? = null,
|
||||
)
|
||||
|
|
@ -16,6 +16,8 @@ import com.tangem.core.decompose.ui.UiMessageSender
|
|||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig.ShowRefreshState
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
|
|
@ -27,6 +29,7 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
|||
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||
import com.tangem.domain.pay.model.TangemPayTopUpData
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||
import com.tangem.domain.pay.repository.TangemPayWithdrawRepository
|
||||
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
|
||||
|
|
@ -75,6 +78,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
private val produceTangemPayInitialDataUseCase: ProduceTangemPayInitialDataUseCase,
|
||||
private val onboardingRepository: OnboardingRepository,
|
||||
) : Model(), TangemPayTxHistoryUiActions, TangemPayDetailIntents, AddFundsListener {
|
||||
|
||||
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
|
||||
|
|
@ -92,6 +96,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
onOpenMenu = ::onOpenMenu,
|
||||
intents = this,
|
||||
isRedesignEnabled = isRedesignEnabled(),
|
||||
isRemoveAccountEnabled = tangemPayFeatureToggles.isRemoveAccountEnabled,
|
||||
)
|
||||
|
||||
val uiState: StateFlow<TangemPayDetailsUM>
|
||||
|
|
@ -374,6 +379,36 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onRemoveAccount() {
|
||||
uiMessageSender.send(
|
||||
DialogMessage(
|
||||
title = resourceReference(R.string.tangempay_remove_account_alert_title),
|
||||
message = resourceReference(R.string.tangempay_remove_account_alert_description),
|
||||
firstActionBuilder = {
|
||||
EventMessageAction(
|
||||
isWarning = true,
|
||||
title = resourceReference(R.string.tangempay_remove_account),
|
||||
onClick = ::removeAccount,
|
||||
)
|
||||
},
|
||||
secondActionBuilder = { cancelAction() },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun removeAccount() {
|
||||
modelScope.launch {
|
||||
onboardingRepository.disableTangemPay(userWalletId)
|
||||
.onRight {
|
||||
paymentAccountStatusFetcher.invoke(userWalletId)
|
||||
router.pop()
|
||||
}
|
||||
.onLeft {
|
||||
uiMessageSender.send(SnackbarMessage(resourceReference(R.string.common_error)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showBottomSheetError(type: TangemPayDetailsErrorType) {
|
||||
uiMessageSender.send(message = TangemPayMessagesFactory.createErrorMessage(errorType = type))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,12 @@ 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.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.components.text.applyBladeBrush
|
||||
import com.tangem.core.ui.components.topFade
|
||||
import com.tangem.core.ui.ds.button.PrimaryInverseTangemButton
|
||||
import com.tangem.core.ui.ds.button.TangemButtonShape
|
||||
import com.tangem.core.ui.ds.button.TangemButtonSize
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.ds.message.TangemMessage
|
||||
import com.tangem.core.ui.ds.message.TangemMessageEffect
|
||||
|
|
@ -43,7 +47,10 @@ 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.*
|
||||
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.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.test.TangemPayTestTags
|
||||
|
|
@ -202,22 +209,35 @@ private fun LazyListScope.payDetailsBody(state: TangemPayDetailsUM) {
|
|||
}
|
||||
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,
|
||||
)
|
||||
DeactivationBannerBlock(notificationConfig = state.accountDeactivatedNotificationConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DeactivationBannerBlock(notificationConfig: NotificationConfig) {
|
||||
val removeAccountButton = notificationConfig.buttonsState as? NotificationConfig.ButtonsState.SecondaryButtonConfig
|
||||
TangemMessage(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x4),
|
||||
title = notificationConfig.title,
|
||||
subtitle = notificationConfig.subtitle,
|
||||
messageEffect = TangemMessageEffect.Warning,
|
||||
buttons = removeAccountButton?.let { button ->
|
||||
{
|
||||
PrimaryInverseTangemButton(
|
||||
text = button.text,
|
||||
onClick = button.onClick,
|
||||
size = TangemButtonSize.X9,
|
||||
shape = TangemButtonShape.Rounded,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PayDetailsTopBar(
|
||||
config: TangemPayDetailsTopBarConfig,
|
||||
|
|
|
|||
|
|
@ -71,10 +71,10 @@ private fun PayContextMenuItem(item: TangemPayDropDownItemUM, onMenuDismiss: ()
|
|||
Text(
|
||||
text = item.title.resolveReference(),
|
||||
style = TangemTheme.typography3.body.medium,
|
||||
color = if (item.isEnabled) {
|
||||
TangemTheme.colors3.text.primary
|
||||
} else {
|
||||
TangemTheme.colors3.text.tertiary
|
||||
color = when {
|
||||
!item.isEnabled -> TangemTheme.colors3.text.tertiary
|
||||
item.titleColor != null -> item.titleColor.invoke()
|
||||
else -> TangemTheme.colors3.text.primary
|
||||
},
|
||||
maxLines = 1,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,4 +11,5 @@ internal interface TangemPayDetailIntents {
|
|||
fun onClickTermsAndLimits()
|
||||
fun onCardClick()
|
||||
fun onAddCardClick()
|
||||
fun onRemoveAccount()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue