Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-29 19:01:28 +03:00
parent c59048605c
commit 9b6a954ed0
21 changed files with 705 additions and 122 deletions

View file

@ -3,16 +3,17 @@ package com.tangem.feature.wallet.child.wallet.model.intents
import arrow.core.getOrElse
import com.tangem.common.TangemBlogUrlBuilder
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRoute.Onramp
import com.tangem.common.routing.AppRoute.ReferralProgram
import com.tangem.common.routing.AppRouter
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
import com.tangem.domain.card.SetCardWasScannedUseCase
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.models.currency.CryptoCurrency
@ -28,9 +29,11 @@ import com.tangem.domain.settings.NeverToSuggestRateAppUseCase
import com.tangem.domain.settings.RemindToRateAppLaterUseCase
import com.tangem.domain.staking.StakingIdFactory
import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher
import com.tangem.domain.tokens.model.analytics.TokenSwapPromoAnalyticsEvent
import com.tangem.domain.tokens.model.analytics.TokenSwapPromoAnalyticsEvent.Program
import com.tangem.domain.tokens.model.analytics.TokenSwapPromoAnalyticsEvent.PromotionBannerClicked
import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType
import com.tangem.domain.wallets.models.UnlockWalletsError
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.wallets.usecase.SeedPhraseNotificationUseCase
import com.tangem.domain.wallets.usecase.UnlockWalletsUseCase
@ -285,11 +288,12 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
analyticsEventHandler.send(
when (promoId) {
PromoId.Referral -> MainScreen.ReferralPromoButtonDismiss
PromoId.Sepa -> TokenSwapPromoAnalyticsEvent.PromotionBannerClicked(
PromoId.Sepa -> PromotionBannerClicked(
source = AnalyticsParam.ScreensSources.Main,
program = TokenSwapPromoAnalyticsEvent.Program.Sepa,
action = TokenSwapPromoAnalyticsEvent.PromotionBannerClicked.BannerAction.Closed,
program = Program.Sepa,
action = PromotionBannerClicked.BannerAction.Closed,
)
PromoId.VisaPresale -> MainScreen.VisaWaitlistPromoDismiss
},
)
@ -303,19 +307,19 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
when (promoId) {
PromoId.Referral -> {
analyticsEventHandler.send(MainScreen.ReferralPromoButtonParticipate)
appRouter.push(AppRoute.ReferralProgram(userWalletId = userWallet.walletId))
appRouter.push(ReferralProgram(userWalletId = userWallet.walletId))
}
PromoId.Sepa -> {
analyticsEventHandler.send(
TokenSwapPromoAnalyticsEvent.PromotionBannerClicked(
PromotionBannerClicked(
source = AnalyticsParam.ScreensSources.Main,
program = TokenSwapPromoAnalyticsEvent.Program.Sepa,
action = TokenSwapPromoAnalyticsEvent.PromotionBannerClicked.BannerAction.Clicked,
program = Program.Sepa,
action = PromotionBannerClicked.BannerAction.Clicked,
),
)
cryptoCurrency ?: return
appRouter.push(
AppRoute.Onramp(
Onramp(
userWalletId = userWallet.walletId,
currency = cryptoCurrency,
source = OnrampSource.SEPA_BANNER,
@ -323,6 +327,10 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
),
)
}
PromoId.VisaPresale -> {
analyticsEventHandler.send(MainScreen.VisaWaitlistPromoJoin)
urlOpener.openUrl(VISA_PROMO_LINK)
}
}
}
@ -472,4 +480,10 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
null
}
}
private companion object {
const val VISA_PROMO_LINK = "https://tangem.com/en/cardwaitlist/?utm_source=tangem-app-banner" +
"&utm_medium=banner" +
"&utm_campaign=tangempaywaitlist"
}
}

View file

@ -143,5 +143,11 @@ sealed class WalletScreenAnalyticsEvent {
data object ReferralPromoButtonParticipate : MainScreen(event = "Button - Referral Participate")
data object ReferralPromoButtonDismiss : MainScreen(event = "Button - Referral Dismiss")
//endregion
// region visa waitlist promo
data object VisaWaitlistPromo : MainScreen(event = "Visa Waitlist")
data object VisaWaitlistPromoJoin : MainScreen(event = "Button - Join Now")
data object VisaWaitlistPromoDismiss : MainScreen(event = "Button - Close")
//endregion
}
}

View file

@ -58,6 +58,7 @@ internal class WalletWarningsAnalyticsSender @Inject constructor(
program = Program.Sepa,
)
is WalletNotification.ReferralPromo -> MainScreen.ReferralPromo
is WalletNotification.VisaPresalePromo -> MainScreen.VisaWaitlistPromo
is WalletNotification.UnlockWallets -> null // See [SelectedWalletAnalyticsSender]
is WalletNotification.Informational.NoAccount,
is WalletNotification.Warning.LowSignatures,

View file

@ -63,9 +63,9 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
flow2 = isReadyToShowRateAppUseCase(),
flow3 = isNeedToBackupUseCase(userWallet.walletId),
flow4 = seedPhraseNotificationUseCase(userWalletId = userWallet.walletId),
flow5 = shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.Referral),
flow5 = shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.VisaPresale),
flow6 = shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.Sepa),
) { maybeTokenList, isReadyToShowRating, isNeedToBackup, seedPhraseIssueStatus, shouldShowReferralPromo, shouldShowSepaBanner ->
) { maybeTokenList, isReadyToShowRating, isNeedToBackup, seedPhraseIssueStatus, shouldShowVisaPresalePromo, shouldShowSepaBanner ->
buildList {
addUsedOutdatedDataNotification(maybeTokenList)
@ -73,7 +73,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
addFinishWalletActivationNotification(userWallet, maybeTokenList, clickIntents)
addReferralPromoNotification(cardTypesResolver, clickIntents, shouldShowReferralPromo)
addVisaPresalePromoNotification(clickIntents, shouldShowVisaPresalePromo)
addSepaPromoNotification(userWallet, clickIntents, shouldShowSepaBanner)
@ -220,17 +220,16 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
.map(CryptoCurrencyStatus::currency)
}
private fun MutableList<WalletNotification>.addReferralPromoNotification(
cardTypesResolver: CardTypesResolver?,
private fun MutableList<WalletNotification>.addVisaPresalePromoNotification(
clickIntents: WalletClickIntents,
shouldShowPromo: Boolean,
) {
addIf(
element = WalletNotification.ReferralPromo(
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.Referral) },
onClick = { clickIntents.onPromoClick(promoId = PromoId.Referral) },
element = WalletNotification.VisaPresalePromo(
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.VisaPresale) },
onClick = { clickIntents.onPromoClick(promoId = PromoId.VisaPresale) },
),
condition = shouldShowPromo && (cardTypesResolver == null || cardTypesResolver.isTangemWallet()),
condition = shouldShowPromo,
)
}

View file

@ -293,6 +293,23 @@ sealed class WalletNotification(val config: NotificationConfig) {
),
)
data class VisaPresalePromo(
val onCloseClick: () -> Unit,
val onClick: () -> Unit,
) : WalletNotification(
config = NotificationConfig(
title = resourceReference(R.string.notification_visa_waitlist_promo_title),
subtitle = resourceReference(R.string.notification_visa_waitlist_promo_text),
iconResId = R.drawable.img_visa_waitlist_promo,
onCloseClick = onCloseClick,
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
text = resourceReference(R.string.notification_referral_promo_button),
onClick = onClick,
),
iconSize = 54.dp,
),
)
data class Sepa(
val onCloseClick: () -> Unit,
val onClick: () -> Unit,