diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index a6478e3318..4df1c486bf 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -1420,9 +1420,14 @@ あなたの住所や資産を開示することなく、個別の支払い用アカウントが作成されます。 他に類を見ないプライバシー 無料のTangem Payカードを数分でゲットしましょう + 支払いアカウント + 支払いアカウントの同期が必要です 技術的な問題を修正しています。後でもう一度お試しください。 サービスは一時的に利用できません + 現在サービスに接続できません。後ほどもう一度お試しください。 + Tangem Payは一時的に利用できません Tangem Pay + カードまたはリングを使用して、支払いアカウントへのアクセスを復元してください。 これは私のウォレットです 残高非表示 残高表示 diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 5971b8288b..74afe57a95 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -139,10 +139,17 @@ Balances are hidden According to the blockchain developers, Kaspa tokens are currently in beta. Stay tuned for updates! Beta Mode + Biometrics are turned off on your device, so you can’t use them to unlock your wallets. Enable biometrics in your device settings to use this method again. + Biometric authentication disabled Please scan the card or ring + You’ve reached the limit of biometric attempts. Please unlock your wallet with a device tap or enter your access code. + Biometric authentication locked Please try again in 30 seconds or scan the card or ring + Biometric login is temporarily locked. Please try again in 30 seconds, or unlock your wallet with a device tap or access code. Too many attempts You have disabled biometric authentication on your phone and will not be able to save wallets in the app. To save wallets, please enable the biometric authentication function in your phone settings. + Biometrics on your device have been updated. Please select your wallet and enter its access code to enable biometric login again. + Attention required An error occurred while processing your promo code. Please try again later. Activation error Your promo code was successfully activated. The reward will be credited to your Bitcoin account within 14 days. @@ -835,6 +842,8 @@ Destination account is not active. Send %s or more to activate the account. To create account send funds to this address The destination account does not have a trustline for the asset being sent. + Plus rewards in BTC per set.\nHurry up! + Black Friday: up to 25% OFF Join Now Share your code - earn 5 USDT per sale. Your friend gets 10% OFF. Get REWARDS for every friend! @@ -1445,9 +1454,14 @@ A separate payment account will be created without disclosing your addresses and assets Unrivaled privacy Get your free Tangem Pay Card in minutes + Payment account + Payment account sync needed We’re fixing a technical issue. Please try again later. Service temporarily unavailable + The service is currently unreachable. Please try again later. + Tangem Pay is temporarily unavailable Tangem Pay + Use your card or ring to restore access to your payment account This is my wallet Balances hidden Balances shown diff --git a/core/ui/src/main/res/drawable/img_black_friday_promo.webp b/core/ui/src/main/res/drawable/img_black_friday_promo.webp new file mode 100644 index 0000000000..18ad834359 Binary files /dev/null and b/core/ui/src/main/res/drawable/img_black_friday_promo.webp differ diff --git a/data/promo/src/main/java/com/tangem/data/promo/DefaultPromoRepository.kt b/data/promo/src/main/java/com/tangem/data/promo/DefaultPromoRepository.kt index a0dada9a61..bfdffde151 100644 --- a/data/promo/src/main/java/com/tangem/data/promo/DefaultPromoRepository.kt +++ b/data/promo/src/main/java/com/tangem/data/promo/DefaultPromoRepository.kt @@ -54,6 +54,11 @@ internal class DefaultPromoRepository( PromoId.VisaPresale -> { val isActive = getVisaPromoBanner()?.isActive ?: false + isActive && shouldShow + } + PromoId.BlackFriday -> { + val isActive = getBlackFridayPromoBanner()?.isActive ?: false + isActive && shouldShow } } @@ -65,6 +70,7 @@ internal class DefaultPromoRepository( PromoId.Referral -> flowOf(false) PromoId.Sepa -> flowOf(false) PromoId.VisaPresale -> flowOf(false) + PromoId.BlackFriday -> flowOf(false) } } @@ -148,9 +154,18 @@ internal class DefaultPromoRepository( }.getOrNull() } + private suspend fun getBlackFridayPromoBanner(): PromoBanner? { + return runCatching(dispatchers.io) { + promoBannerConverter.convert( + tangemApi.getPromoBanner(BLACK_FRIDAY_NAME).getOrThrow(), + ) + }.getOrNull() + } + private companion object { const val SEPA_NAME = "sepa" const val VISA_NAME = "visa-waitlist" + const val BLACK_FRIDAY_NAME = "black-friday" const val STORIES_LOAD_DELAY = 1000L } } \ No newline at end of file diff --git a/domain/promo/models/src/main/java/com/tangem/domain/promo/models/PromoBanner.kt b/domain/promo/models/src/main/java/com/tangem/domain/promo/models/PromoBanner.kt index 452445b991..764871ed95 100644 --- a/domain/promo/models/src/main/java/com/tangem/domain/promo/models/PromoBanner.kt +++ b/domain/promo/models/src/main/java/com/tangem/domain/promo/models/PromoBanner.kt @@ -29,4 +29,5 @@ enum class PromoId { Referral, Sepa, VisaPresale, + BlackFriday, } \ No newline at end of file diff --git a/domain/promo/src/main/java/com/tangem/domain/promo/ShouldShowPromoWalletUseCase.kt b/domain/promo/src/main/java/com/tangem/domain/promo/ShouldShowPromoWalletUseCase.kt index 396e1d8e90..d5b48a464e 100644 --- a/domain/promo/src/main/java/com/tangem/domain/promo/ShouldShowPromoWalletUseCase.kt +++ b/domain/promo/src/main/java/com/tangem/domain/promo/ShouldShowPromoWalletUseCase.kt @@ -31,6 +31,7 @@ class ShouldShowPromoWalletUseCase( return when (promoId) { PromoId.Referral, PromoId.VisaPresale, + PromoId.BlackFriday, -> true PromoId.Sepa -> { val walletFirstUsageDate = settingsRepository.getWalletFirstUsageDate() diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/PromoAnalyticsEvent.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/PromoAnalyticsEvent.kt index 1dcd4490f4..4056e2bdae 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/PromoAnalyticsEvent.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/PromoAnalyticsEvent.kt @@ -58,5 +58,6 @@ sealed class PromoAnalyticsEvent( enum class Program(val programName: String) { Empty("Empty"), Sepa("Sepa"), + BlackFriday("Black Friday"), } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt index 945d0dff0c..3db9bd5d2c 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt @@ -335,6 +335,11 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( action = PromotionBannerClicked.BannerAction.Closed, ) PromoId.VisaPresale -> PromoAnalyticsEvent.VisaWaitlistPromoDismiss + PromoId.BlackFriday -> PromotionBannerClicked( + source = AnalyticsParam.ScreensSources.Main, + program = Program.BlackFriday, + action = PromotionBannerClicked.BannerAction.Closed, + ) }, ) @@ -372,6 +377,16 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( analyticsEventHandler.send(PromoAnalyticsEvent.VisaWaitlistPromoJoin) urlOpener.openUrl(VISA_PROMO_LINK) } + PromoId.BlackFriday -> { + analyticsEventHandler.send( + PromotionBannerClicked( + source = AnalyticsParam.ScreensSources.Main, + program = Program.BlackFriday, + action = PromotionBannerClicked.BannerAction.Clicked, + ), + ) + urlOpener.openUrl(BLACK_FRIDAY_PROMO_LINK) + } } } @@ -587,5 +602,10 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( const val VISA_PROMO_LINK = "https://tangem.com/en/cardwaitlist/?utm_source=tangem-app-banner" + "&utm_medium=banner" + "&utm_campaign=tangempaywaitlist" + const val BLACK_FRIDAY_PROMO_LINK = "https://tangem.com/en/pricing/" + + "?promocode=BF2025" + + "&utm_source=tangem-app-banner" + + "&utm_medium=banner" + + "&utm_campaign=BlackFriday2025" } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsAnalyticsSender.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsAnalyticsSender.kt index 1f136f0dc3..9a99c824ef 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsAnalyticsSender.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsAnalyticsSender.kt @@ -58,6 +58,10 @@ internal class WalletWarningsAnalyticsSender @Inject constructor( source = AnalyticsParam.ScreensSources.Main, program = Program.Sepa, ) + is WalletNotification.BlackFridayPromo -> PromoAnalyticsEvent.NoticePromotionBanner( + source = AnalyticsParam.ScreensSources.Main, + program = Program.BlackFriday, + ) is WalletNotification.ReferralPromo -> MainScreen.ReferralPromo is WalletNotification.VisaPresalePromo -> PromoAnalyticsEvent.VisaWaitlistPromo is WalletNotification.UnlockWallets -> null // See [SelectedWalletAnalyticsSender] diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt index e21b971fe1..7699a9346e 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt @@ -97,6 +97,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( seedPhraseNotificationUseCase(userWalletId = userWallet.walletId), shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.VisaPresale), shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.Sepa), + shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.BlackFriday), notificationsRepository.getShouldShowNotification(NotificationId.EnablePushesReminderNotification.key), ) { array -> array } .combine(tokenListFlow()) { array, any: Any -> arrayOf(any).plus(elements = array) } @@ -109,7 +110,8 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( val seedPhraseIssueStatus = array[3] as SeedPhraseNotificationsStatus val shouldShowVisaPromo = array[4] as Boolean val shouldShowSepaBanner = array[5] as Boolean - val shouldShowEnablePushesReminderNotification = array[6] as Boolean + val shouldShowBlackFridayPromo = array[6] as Boolean + val shouldShowEnablePushesReminderNotification = array[7] as Boolean buildList { addUsedOutdatedDataNotification(totalFiatBalance) @@ -118,6 +120,8 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( addFinishWalletActivationNotification(userWallet, totalFiatBalance, clickIntents) + addBlackFridayPromoNotification(clickIntents, shouldShowBlackFridayPromo) + addVisaPresalePromoNotification(clickIntents, shouldShowVisaPromo) addSepaPromoNotification(userWallet, clickIntents, shouldShowSepaBanner) @@ -286,6 +290,19 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( ) } + private fun MutableList.addBlackFridayPromoNotification( + clickIntents: WalletClickIntents, + shouldShowPromo: Boolean, + ) { + addIf( + element = WalletNotification.BlackFridayPromo( + onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.BlackFriday) }, + onClick = { clickIntents.onPromoClick(promoId = PromoId.BlackFriday) }, + ), + condition = shouldShowPromo, + ) + } + private suspend fun MutableList.addSepaPromoNotification( userWallet: UserWallet, clickIntents: WalletClickIntents, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotification.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotification.kt index 62e29d2cac..b035f46c10 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotification.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotification.kt @@ -332,6 +332,23 @@ sealed class WalletNotification(val config: NotificationConfig) { ), ) + data class BlackFridayPromo( + val onCloseClick: () -> Unit, + val onClick: () -> Unit, + ) : WalletNotification( + config = NotificationConfig( + title = resourceReference(R.string.notification_black_friday_title), + subtitle = resourceReference(R.string.notification_black_friday_text), + iconResId = R.drawable.img_black_friday_promo, + onCloseClick = onCloseClick, + buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( + text = resourceReference(R.string.common_claim), + onClick = onClick, + ), + iconSize = 54.dp, + ), + ) + data class PushNotifications( val onCloseClick: () -> Unit, val onEnabledClick: () -> Unit, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt index 172ab84fbe..785eebe9c6 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt @@ -52,6 +52,7 @@ internal fun LazyListScope.notifications(configs: ImmutableList TangemTheme.colors.text.attention else -> null }, + subtitleColor = TangemTheme.colors.text.secondary, ) } }