Updated on 2026-08-14
This commit is contained in:
parent
930693b301
commit
5bdb9513aa
18 changed files with 249 additions and 44 deletions
|
|
@ -24,5 +24,9 @@ object TangemBlogUrlBuilder {
|
|||
data object SeedNotify : Post {
|
||||
override val path: String = "seed-notify"
|
||||
}
|
||||
|
||||
data object SeedNotifySecond : Post {
|
||||
override val path: String = "tangem-resolves-log-issue"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -123,6 +123,17 @@ interface TangemTechApi {
|
|||
@Body body: SeedPhraseNotificationDTO,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@GET("seedphrase-notification/{wallet_id}/confirmed")
|
||||
suspend fun getSeedPhraseSecondNotificationStatus(
|
||||
@Path("wallet_id") walletId: String,
|
||||
): ApiResponse<SeedPhraseNotificationDTO>
|
||||
|
||||
@PUT("seedphrase-notification/{wallet_id}/confirmed")
|
||||
suspend fun updateSeedPhraseSecondNotificationStatus(
|
||||
@Path("wallet_id") walletId: String,
|
||||
@Body body: SeedPhraseNotificationDTO,
|
||||
): ApiResponse<Unit>
|
||||
|
||||
@GET("hot_crypto")
|
||||
suspend fun getHotCrypto(@Query("currency") currencyId: String): ApiResponse<HotCryptoResponse>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@ data class SeedPhraseNotificationDTO(val status: Status) {
|
|||
@Json(name = "confirmed")
|
||||
CONFIRMED,
|
||||
|
||||
@Json(name = "rejected")
|
||||
REJECTED,
|
||||
|
||||
@Json(name = "accepted")
|
||||
ACCEPTED,
|
||||
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -119,6 +119,8 @@ object PreferencesKeys {
|
|||
|
||||
val WAS_LOG_FILE_CLEARED by lazy { booleanPreferencesKey(name = "wasLogFileCleared") }
|
||||
|
||||
val SEED_FIRST_NOTIFICATION_SHOW_TIME by lazy { longPreferencesKey("seedFirstNotificationTime") }
|
||||
|
||||
fun getShouldShowStoriesKey(storyId: String) = booleanPreferencesKey("shouldShowStories_$storyId")
|
||||
|
||||
// region Permission
|
||||
|
|
|
|||
|
|
@ -881,13 +881,13 @@
|
|||
<string name="swap_give_permission_fee_footer">Le réseau facturera des frais d\'approbation de jeton pour vérifier que vous autorisez l\'utilisation de votre jeton pour l\'échange.</string>
|
||||
<string name="swap_promo_text">Échangez plus de jetons à de meilleurs taux directement dans votre portefeuille.</string>
|
||||
<string name="swap_promo_title">Nouveau fournisseur d\'échange disponible !</string>
|
||||
<string name="swap_story_fifth_subtitle">Ayez confiance en bénéficiant d\'un support constant, garantissant que vos transactions se déroulent sans problème à tout moment</string>
|
||||
<string name="swap_story_fifth_subtitle">Ayez confiance en notre assistance 24 heures sur 24 pour vous aider à résoudre tous vos problèmes</string>
|
||||
<string name="swap_story_fifth_title">Assistance 24 heures sur 24</string>
|
||||
<string name="swap_story_first_subtitle">Les fournisseurs d\'échange de confiance vous permettent d\'échanger des actifs sans effort, en gardant tout en sécurité dans votre portefeuille</string>
|
||||
<string name="swap_story_first_subtitle">Plusieurs fournisseurs de confiance en un seul endroit : échangez n\'importe quel actif facilement</string>
|
||||
<string name="swap_story_first_title">Échangez Avec Nous</string>
|
||||
<string name="swap_story_forth_subtitle">Une sécurité de haut niveau et des fournisseurs vérifiés garantissant que vos actifs sont protégés à chaque échange</string>
|
||||
<string name="swap_story_forth_title">Plus Sûr Que Jamais</string>
|
||||
<string name="swap_story_second_subtitle">Maximisez votre valeur avec des tarifs provenant d\'un large réseau de fournisseurs de confiance, en choisissant toujours le meilleur</string>
|
||||
<string name="swap_story_second_subtitle">Maximisez votre valeur avec des tarifs d\'un large réseau de fournisseurs de confiance</string>
|
||||
<string name="swap_story_second_title">Meilleurs Tarifs</string>
|
||||
<string name="swap_story_third_subtitle">Simple et intuitif, vous permettant d\'échanger des jetons en quelques clics</string>
|
||||
<string name="swap_story_third_title">Plus Simple Que Jamais</string>
|
||||
|
|
|
|||
|
|
@ -871,16 +871,16 @@
|
|||
<string name="swap_give_permission_fee_footer">ネットワークは、あなたがトークンのスワップを承認していることを確認するために、トークン承認手数料を請求します。</string>
|
||||
<string name="swap_promo_text">より多くのトークンをより良いレートで、ウォレット内にて直接交換します。</string>
|
||||
<string name="swap_promo_title">新しいスワッププロバイダーが利用可能になりました!</string>
|
||||
<string name="swap_story_fifth_subtitle">継続的なサポートで、いつでもスムーズに取引を行うことができます</string>
|
||||
<string name="swap_story_fifth_title">24時間体制のサポート</string>
|
||||
<string name="swap_story_first_subtitle">信頼できる交換プロバイダーは、ウォレット内の資産を安全に保管しながら、簡単に交換できるようにします。</string>
|
||||
<string name="swap_story_first_title">当社の交換機能をご利用ください</string>
|
||||
<string name="swap_story_forth_subtitle">トップレベルのセキュリティと認証済みプロバイダーが、スワップ時にユーザーの資産を確実に保護します。</string>
|
||||
<string name="swap_story_forth_title">最高に安全</string>
|
||||
<string name="swap_story_fifth_subtitle">24時間体制のサポートであらゆる問題に対応します。</string>
|
||||
<string name="swap_story_fifth_title">いつもここに</string>
|
||||
<string name="swap_story_first_subtitle">複数の信頼できるプロバイダーが一箇所に集結。ウォレット内で様々な暗号資産を簡単に交換できます。</string>
|
||||
<string name="swap_story_first_title">ぜひスワップしてください</string>
|
||||
<string name="swap_story_forth_subtitle">失敗も死角もありません。取引は常に保護されます。</string>
|
||||
<string name="swap_story_forth_title">難攻不落の防御</string>
|
||||
<string name="swap_story_second_subtitle">幅広いネットワークの中から、常に最適なプロバイダーと料金レートを選択します</string>
|
||||
<string name="swap_story_second_title">ベストレート</string>
|
||||
<string name="swap_story_second_title">破格のレート</string>
|
||||
<string name="swap_story_third_subtitle">手間がかからず直感的に操作でき、数回タップするだけでトークンを交換できます。</string>
|
||||
<string name="swap_story_third_title">最高に簡単</string>
|
||||
<string name="swap_story_third_title">とにかく便利</string>
|
||||
<string name="swapping_alert_cex_description">この金額には以下が含まれます:\n- サービスプロバイダーの手数料\n- 取引所からユーザーのアドレスに%s を送り返すためのネットワーク手数料。</string>
|
||||
<string name="swapping_alert_cex_description_with_slippage">金額には以下が含まれます: \n • サービス プロバイダーの手数料\n • 取引所からユーザーのアドレスに%1$sを送金するためのネットワーク手数料。 \n\nプロバイダーのスリッページは最大%2$sです</string>
|
||||
<string name="swapping_alert_dex_description">この金額には、サービスプロバイダーの手数料が含まれています。</string>
|
||||
|
|
|
|||
|
|
@ -674,6 +674,8 @@
|
|||
<string name="scan_card_settings_message">Scan the card or ring to change its settings. The changes will impact only the card or ring you\'ve scanned and will not affect other devices tied to your wallet.</string>
|
||||
<string name="scan_card_settings_title">Get your Tangem ready!</string>
|
||||
<string name="security_alert_title">Security Alert</string>
|
||||
<string name="seed_warning_no">No, I did not</string>
|
||||
<string name="seed_warning_yes">Yes, guide me</string>
|
||||
<string name="selling_insufficient_balance_alert_message">You don’t have enough funds in your balance to sell cryptocurrency. Please deposit the desired asset to proceed.</string>
|
||||
<string name="selling_insufficient_balance_alert_title">Insufficient Balance</string>
|
||||
<string name="selling_regional_restriction_alert_message">Selling cryptocurrency is unavailable in your region at the moment. We’re actively working to bring this option to you soon—stay tuned!</string>
|
||||
|
|
@ -1089,6 +1091,8 @@
|
|||
<string name="warning_rate_app_title">Enjoying Tangem?</string>
|
||||
<string name="warning_receive_blocked_hedera_token_association_required_message">You must associate your token before receiving tokens</string>
|
||||
<string name="warning_rent_fee_title">Network rent fee required</string>
|
||||
<string name="warning_seedphrase_action_required_title">Action required</string>
|
||||
<string name="warning_seedphrase_contacted_support">Did you contact support via the app or email within 7 days of creating a wallet? If you did or are unsure, follow and complete the instructions.</string>
|
||||
<string name="warning_seedphrase_issue_answer_no">Thank you! All set! No further actions required.</string>
|
||||
<string name="warning_seedphrase_issue_answer_yes">You will now be redirected to the official Tangem website. Please read and follow instructions there.</string>
|
||||
<string name="warning_seedphrase_issue_message">Have you ever contacted the Tangem support team directly through this application?</string>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
package com.tangem.utils
|
||||
|
||||
const val H24_MILLIS = 24L * 60 * 60 * 1000
|
||||
const val WEEK_MILLIS = 7L * H24_MILLIS
|
||||
|
|
@ -9,12 +9,15 @@ import com.tangem.datasource.api.tangemTech.models.SeedPhraseNotificationDTO.Sta
|
|||
import com.tangem.datasource.local.datastore.RuntimeStateStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys.SEED_FIRST_NOTIFICATION_SHOW_TIME
|
||||
import com.tangem.datasource.local.preferences.utils.get
|
||||
import com.tangem.datasource.local.preferences.utils.getSyncOrDefault
|
||||
import com.tangem.datasource.local.preferences.utils.store
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.wallets.models.SeedPhraseNotificationsStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.utils.WEEK_MILLIS
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.runCatching
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -23,11 +26,13 @@ import kotlinx.coroutines.flow.collectLatest
|
|||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
typealias SeedPhraseNotificationsStatuses = Map<UserWalletId, SeedPhraseNotificationsStatus>
|
||||
|
||||
internal class DefaultWalletsRepository(
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val tangemTechApi: TangemTechApi,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val seedPhraseNotificationVisibilityStore: RuntimeStateStore<Map<UserWalletId, Boolean>>,
|
||||
private val seedPhraseNotificationVisibilityStore: RuntimeStateStore<SeedPhraseNotificationsStatuses>,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : WalletsRepository {
|
||||
|
||||
|
|
@ -57,11 +62,16 @@ internal class DefaultWalletsRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override fun seedPhraseNotificationStatus(userWalletId: UserWalletId): Flow<Boolean> {
|
||||
override fun seedPhraseNotificationStatus(userWalletId: UserWalletId): Flow<SeedPhraseNotificationsStatus> {
|
||||
return channelFlow {
|
||||
launch {
|
||||
seedPhraseNotificationVisibilityStore.get()
|
||||
.map { it.getOrDefault(key = userWalletId, defaultValue = false) }
|
||||
.map {
|
||||
it.getOrDefault(
|
||||
key = userWalletId,
|
||||
defaultValue = SeedPhraseNotificationsStatus.NOT_NEEDED,
|
||||
)
|
||||
}
|
||||
.collectLatest(::send)
|
||||
}
|
||||
|
||||
|
|
@ -73,18 +83,53 @@ internal class DefaultWalletsRepository(
|
|||
val userWallet = userWalletsStore.getSyncOrNull(key = userWalletId)
|
||||
|
||||
val status = if (userWallet?.isImported == false) {
|
||||
false
|
||||
Status.NOT_NEEDED
|
||||
} else {
|
||||
runCatching(dispatchers.io) {
|
||||
tangemTechApi.getSeedPhraseNotificationStatus(walletId = userWalletId.stringValue).getOrThrow()
|
||||
}
|
||||
.fold(
|
||||
onSuccess = { it.status == Status.NOTIFIED },
|
||||
onFailure = { it is HttpException && it.code == HttpException.Code.NOT_FOUND },
|
||||
)
|
||||
}.fold(
|
||||
onSuccess = { it.status },
|
||||
onFailure = {
|
||||
if (it is HttpException && it.code == HttpException.Code.NOT_FOUND) {
|
||||
Status.NOTIFIED
|
||||
} else {
|
||||
Status.NOT_NEEDED
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
updateNotificationVisibility(id = userWalletId, value = status)
|
||||
when {
|
||||
status == Status.NOTIFIED -> updateNotificationVisibility(
|
||||
id = userWalletId,
|
||||
value = SeedPhraseNotificationsStatus.SHOW_FIRST,
|
||||
)
|
||||
status == Status.CONFIRMED && checkNeedFetchSecondNotification() ->
|
||||
fetchSeedPhraseSecondNotificationStatus(userWalletId)
|
||||
else -> updateNotificationVisibility(id = userWalletId, value = SeedPhraseNotificationsStatus.NOT_NEEDED)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchSeedPhraseSecondNotificationStatus(userWalletId: UserWalletId) {
|
||||
val status = runCatching(dispatchers.io) {
|
||||
tangemTechApi.getSeedPhraseSecondNotificationStatus(walletId = userWalletId.stringValue).getOrThrow()
|
||||
}.fold(
|
||||
onSuccess = { it.status },
|
||||
onFailure = { Status.NOT_NEEDED },
|
||||
)
|
||||
|
||||
val showStatus = when (status) {
|
||||
Status.CONFIRMED -> SeedPhraseNotificationsStatus.SHOW_SECOND
|
||||
else -> SeedPhraseNotificationsStatus.NOT_NEEDED
|
||||
}
|
||||
|
||||
updateNotificationVisibility(id = userWalletId, value = showStatus)
|
||||
}
|
||||
|
||||
private suspend fun checkNeedFetchSecondNotification(): Boolean {
|
||||
val firstNotificationTime =
|
||||
appPreferencesStore.getSyncOrDefault(SEED_FIRST_NOTIFICATION_SHOW_TIME, default = 0L)
|
||||
return System.currentTimeMillis() - firstNotificationTime > WEEK_MILLIS
|
||||
}
|
||||
|
||||
override suspend fun notifiedSeedPhraseNotification(userWalletId: UserWalletId) {
|
||||
|
|
@ -102,9 +147,10 @@ internal class DefaultWalletsRepository(
|
|||
walletId = userWalletId.stringValue,
|
||||
body = SeedPhraseNotificationDTO(status = Status.CONFIRMED),
|
||||
).getOrThrow()
|
||||
appPreferencesStore.store(key = SEED_FIRST_NOTIFICATION_SHOW_TIME, value = System.currentTimeMillis())
|
||||
}
|
||||
|
||||
updateNotificationVisibility(id = userWalletId, value = false)
|
||||
updateNotificationVisibility(id = userWalletId, value = SeedPhraseNotificationsStatus.NOT_NEEDED)
|
||||
}
|
||||
|
||||
override suspend fun declineSeedPhraseNotification(userWalletId: UserWalletId) {
|
||||
|
|
@ -113,9 +159,10 @@ internal class DefaultWalletsRepository(
|
|||
walletId = userWalletId.stringValue,
|
||||
body = SeedPhraseNotificationDTO(status = Status.DECLINED),
|
||||
).getOrThrow()
|
||||
appPreferencesStore.store(key = SEED_FIRST_NOTIFICATION_SHOW_TIME, value = System.currentTimeMillis())
|
||||
}
|
||||
|
||||
updateNotificationVisibility(id = userWalletId, value = false)
|
||||
updateNotificationVisibility(id = userWalletId, value = SeedPhraseNotificationsStatus.NOT_NEEDED)
|
||||
}
|
||||
|
||||
override suspend fun markWallet2WasCreated(userWalletId: UserWalletId) {
|
||||
|
|
@ -126,7 +173,29 @@ internal class DefaultWalletsRepository(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun updateNotificationVisibility(id: UserWalletId, value: Boolean) {
|
||||
override suspend fun rejectSeedPhraseSecondNotification(userWalletId: UserWalletId) {
|
||||
runCatching(dispatchers.io) {
|
||||
tangemTechApi.updateSeedPhraseSecondNotificationStatus(
|
||||
walletId = userWalletId.stringValue,
|
||||
body = SeedPhraseNotificationDTO(status = Status.REJECTED),
|
||||
).getOrThrow()
|
||||
}
|
||||
|
||||
updateNotificationVisibility(id = userWalletId, value = SeedPhraseNotificationsStatus.NOT_NEEDED)
|
||||
}
|
||||
|
||||
override suspend fun acceptSeedPhraseSecondNotification(userWalletId: UserWalletId) {
|
||||
runCatching(dispatchers.io) {
|
||||
tangemTechApi.updateSeedPhraseSecondNotificationStatus(
|
||||
walletId = userWalletId.stringValue,
|
||||
body = SeedPhraseNotificationDTO(status = Status.ACCEPTED),
|
||||
).getOrThrow()
|
||||
}
|
||||
|
||||
updateNotificationVisibility(id = userWalletId, value = SeedPhraseNotificationsStatus.NOT_NEEDED)
|
||||
}
|
||||
|
||||
private suspend fun updateNotificationVisibility(id: UserWalletId, value: SeedPhraseNotificationsStatus) {
|
||||
return seedPhraseNotificationVisibilityStore.update {
|
||||
it.toMutableMap().apply {
|
||||
this[id] = value
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.domain.wallets.models
|
||||
|
||||
enum class SeedPhraseNotificationsStatus {
|
||||
|
||||
SHOW_FIRST,
|
||||
SHOW_SECOND,
|
||||
NOT_NEEDED,
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.domain.wallets.repository
|
||||
|
||||
import com.tangem.domain.wallets.models.SeedPhraseNotificationsStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
|
@ -15,7 +16,7 @@ interface WalletsRepository {
|
|||
|
||||
suspend fun setHasWalletsWithRing(userWalletId: UserWalletId)
|
||||
|
||||
fun seedPhraseNotificationStatus(userWalletId: UserWalletId): Flow<Boolean>
|
||||
fun seedPhraseNotificationStatus(userWalletId: UserWalletId): Flow<SeedPhraseNotificationsStatus>
|
||||
|
||||
suspend fun notifiedSeedPhraseNotification(userWalletId: UserWalletId)
|
||||
|
||||
|
|
@ -23,5 +24,9 @@ interface WalletsRepository {
|
|||
|
||||
suspend fun declineSeedPhraseNotification(userWalletId: UserWalletId)
|
||||
|
||||
suspend fun rejectSeedPhraseSecondNotification(userWalletId: UserWalletId)
|
||||
|
||||
suspend fun acceptSeedPhraseSecondNotification(userWalletId: UserWalletId)
|
||||
|
||||
suspend fun markWallet2WasCreated(userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.domain.wallets.usecase
|
||||
|
||||
import com.tangem.domain.wallets.models.SeedPhraseNotificationsStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -8,7 +9,7 @@ class SeedPhraseNotificationUseCase(
|
|||
private val walletsRepository: WalletsRepository,
|
||||
) {
|
||||
|
||||
operator fun invoke(userWalletId: UserWalletId): Flow<Boolean> {
|
||||
operator fun invoke(userWalletId: UserWalletId): Flow<SeedPhraseNotificationsStatus> {
|
||||
return walletsRepository.seedPhraseNotificationStatus(userWalletId)
|
||||
}
|
||||
|
||||
|
|
@ -23,4 +24,12 @@ class SeedPhraseNotificationUseCase(
|
|||
suspend fun decline(userWalletId: UserWalletId) {
|
||||
walletsRepository.declineSeedPhraseNotification(userWalletId)
|
||||
}
|
||||
|
||||
suspend fun acceptSecond(userWalletId: UserWalletId) {
|
||||
walletsRepository.acceptSeedPhraseSecondNotification(userWalletId)
|
||||
}
|
||||
|
||||
suspend fun rejectSecond(userWalletId: UserWalletId) {
|
||||
walletsRepository.rejectSeedPhraseSecondNotification(userWalletId)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,15 +8,14 @@ import com.tangem.core.ui.utils.DateTimeFormatters
|
|||
import com.tangem.core.ui.utils.formatAsDateTime
|
||||
import com.tangem.domain.markets.PriceChangeInterval
|
||||
import com.tangem.features.markets.impl.R
|
||||
import com.tangem.utils.H24_MILLIS
|
||||
import com.tangem.utils.WEEK_MILLIS
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.DateTimeZone
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal object MarketsDateTimeFormatters {
|
||||
|
||||
private const val H24_MILLIS = 24L * 60 * 60 * 1000
|
||||
private const val WEEK_MILLIS = 7L * H24_MILLIS
|
||||
|
||||
private val dateTimeMMMFormatter by lazy {
|
||||
DateTimeFormatters.getBestFormatterBySkeleton("dd MMM Hm")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,8 +129,14 @@ sealed class WalletScreenAnalyticsEvent {
|
|||
|
||||
data object NoticeSeedPhraseSupport : MainScreen(event = "Notice - Seed Phrase Support")
|
||||
|
||||
data object NoticeSeedPhraseSupportSecond : MainScreen(event = "Notice - Seed Phrase Support2")
|
||||
|
||||
data object NoticeSeedPhraseSupportButtonNo : MainScreen(event = "Button - Support No")
|
||||
|
||||
data object NoticeSeedPhraseSupportButtonYes : MainScreen(event = "Button - Support Yes")
|
||||
|
||||
data object NoticeSeedPhraseSupportButtonUsed : MainScreen(event = "Button - Support Used")
|
||||
|
||||
data object NoticeSeedPhraseSupportButtonDeclined : MainScreen(event = "Button - Support Declined")
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ internal class WalletWarningsAnalyticsSender @Inject constructor(
|
|||
is WalletNotification.NoteMigration -> MainScreen.NotePromo
|
||||
is WalletNotification.SwapPromo -> TokenSwapPromoAnalyticsEvent.NoticePromotionBanner(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
programName = TokenSwapPromoAnalyticsEvent.ProgramName.Empty, // Use it on new promo action
|
||||
programName = ProgramName.Empty, // Use it on new promo action
|
||||
)
|
||||
is WalletNotification.UnlockWallets -> null // See [SelectedWalletAnalyticsSender]
|
||||
is WalletNotification.Informational.NoAccount,
|
||||
|
|
@ -60,6 +60,7 @@ internal class WalletWarningsAnalyticsSender @Inject constructor(
|
|||
is WalletNotification.Warning.NetworksUnreachable,
|
||||
-> null
|
||||
is WalletNotification.Critical.SeedPhraseNotification -> MainScreen.NoticeSeedPhraseSupport
|
||||
is WalletNotification.Critical.SeedPhraseSecondNotification -> MainScreen.NoticeSeedPhraseSupportSecond
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import com.tangem.domain.tokens.error.TokenListError
|
|||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.TokenList
|
||||
import com.tangem.domain.wallets.models.SeedPhraseNotificationsStatus
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
|
||||
import com.tangem.domain.wallets.usecase.SeedPhraseNotificationUseCase
|
||||
|
|
@ -63,21 +64,10 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
|
||||
private fun MutableList<WalletNotification>.addCriticalNotifications(
|
||||
userWallet: UserWallet,
|
||||
seedPhraseIssueStatus: Boolean,
|
||||
seedPhraseIssueStatus: SeedPhraseNotificationsStatus,
|
||||
clickIntents: WalletClickIntents,
|
||||
) {
|
||||
addIf(
|
||||
element = WalletNotification.Critical.SeedPhraseNotification(
|
||||
onDeclineClick = clickIntents::onSeedPhraseNotificationDecline,
|
||||
onConfirmClick = clickIntents::onSeedPhraseNotificationConfirm,
|
||||
),
|
||||
condition = with(userWallet) {
|
||||
val isDemo = isDemoCardUseCase(cardId = userWallet.cardId)
|
||||
val isWalletWithSeedPhrase = scanResponse.cardTypesResolver.isWallet2() && userWallet.isImported
|
||||
|
||||
!isDemo && isWalletWithSeedPhrase && seedPhraseIssueStatus
|
||||
},
|
||||
)
|
||||
addSeedNotificationIfNeeded(userWallet, seedPhraseIssueStatus, clickIntents)
|
||||
|
||||
val cardTypesResolver = userWallet.scanResponse.cardTypesResolver
|
||||
addIf(
|
||||
|
|
@ -103,6 +93,39 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addSeedNotificationIfNeeded(
|
||||
userWallet: UserWallet,
|
||||
seedPhraseIssueStatus: SeedPhraseNotificationsStatus,
|
||||
clickIntents: WalletClickIntents,
|
||||
) {
|
||||
val isNotificationAvailable = with(userWallet) {
|
||||
val isDemo = isDemoCardUseCase(cardId = userWallet.cardId)
|
||||
val isWalletWithSeedPhrase = scanResponse.cardTypesResolver.isWallet2() && userWallet.isImported
|
||||
|
||||
!isDemo && isWalletWithSeedPhrase
|
||||
}
|
||||
|
||||
when (seedPhraseIssueStatus) {
|
||||
SeedPhraseNotificationsStatus.SHOW_FIRST -> addIf(
|
||||
element = WalletNotification.Critical.SeedPhraseNotification(
|
||||
onDeclineClick = clickIntents::onSeedPhraseNotificationDecline,
|
||||
onConfirmClick = clickIntents::onSeedPhraseNotificationConfirm,
|
||||
),
|
||||
condition = isNotificationAvailable,
|
||||
)
|
||||
SeedPhraseNotificationsStatus.SHOW_SECOND -> addIf(
|
||||
element = WalletNotification.Critical.SeedPhraseSecondNotification(
|
||||
onDeclineClick = clickIntents::onSeedPhraseSecondNotificationReject,
|
||||
onConfirmClick = clickIntents::onSeedPhraseSecondNotificationAccept,
|
||||
),
|
||||
condition = isNotificationAvailable,
|
||||
)
|
||||
SeedPhraseNotificationsStatus.NOT_NEEDED -> {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addInformationalNotifications(
|
||||
cardTypesResolver: CardTypesResolver,
|
||||
maybeTokenList: Lce<TokenListError, TokenList>,
|
||||
|
|
|
|||
|
|
@ -51,7 +51,10 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
),
|
||||
)
|
||||
|
||||
data class SeedPhraseNotification(val onDeclineClick: () -> Unit, val onConfirmClick: () -> Unit) : Critical(
|
||||
data class SeedPhraseNotification(
|
||||
val onDeclineClick: () -> Unit,
|
||||
val onConfirmClick: () -> Unit,
|
||||
) : Critical(
|
||||
title = resourceReference(R.string.warning_seedphrase_issue_title),
|
||||
subtitle = resourceReference(R.string.warning_seedphrase_issue_message),
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryPairButtonsConfig(
|
||||
|
|
@ -61,6 +64,20 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
onRightClick = onConfirmClick,
|
||||
),
|
||||
)
|
||||
|
||||
data class SeedPhraseSecondNotification(
|
||||
val onDeclineClick: () -> Unit,
|
||||
val onConfirmClick: () -> Unit,
|
||||
) : Critical(
|
||||
title = resourceReference(R.string.warning_seedphrase_action_required_title),
|
||||
subtitle = resourceReference(R.string.warning_seedphrase_contacted_support),
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryPairButtonsConfig(
|
||||
leftText = resourceReference(R.string.seed_warning_no),
|
||||
onLeftClick = onDeclineClick,
|
||||
rightText = resourceReference(R.string.seed_warning_yes),
|
||||
onRightClick = onConfirmClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
sealed class Warning(
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ internal interface WalletWarningsClickIntents {
|
|||
fun onSeedPhraseNotificationConfirm()
|
||||
|
||||
fun onSeedPhraseNotificationDecline()
|
||||
|
||||
fun onSeedPhraseSecondNotificationAccept()
|
||||
|
||||
fun onSeedPhraseSecondNotificationReject()
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -312,6 +316,39 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
override fun onSeedPhraseSecondNotificationAccept() {
|
||||
val userWallet = getSelectedUserWallet() ?: return
|
||||
|
||||
analyticsEventHandler.send(MainScreen.NoticeSeedPhraseSupportButtonUsed)
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.SimpleOkAlert(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_yes),
|
||||
onOkClick = {
|
||||
viewModelScope.launch {
|
||||
seedPhraseNotificationUseCase.acceptSecond(userWalletId = userWallet.walletId)
|
||||
|
||||
urlOpener.openUrl(
|
||||
url = TangemBlogUrlBuilder.build(post = TangemBlogUrlBuilder.Post.SeedNotifySecond),
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun onSeedPhraseSecondNotificationReject() {
|
||||
val userWallet = getSelectedUserWallet() ?: return
|
||||
|
||||
analyticsEventHandler.send(MainScreen.NoticeSeedPhraseSupportButtonDeclined)
|
||||
|
||||
viewModelScope.launch {
|
||||
seedPhraseNotificationUseCase.rejectSecond(userWalletId = userWallet.walletId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSelectedUserWallet(): UserWallet? {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
return getUserWalletUseCase(userWalletId).getOrElse {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue