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,
)
}
}