Updated on 2026-08-14
This commit is contained in:
parent
8aba7b07d1
commit
57fc519d5f
3 changed files with 63 additions and 33 deletions
|
|
@ -2,6 +2,7 @@ package com.tangem.domain.account.models
|
||||||
|
|
||||||
import com.tangem.domain.models.TotalFiatBalance
|
import com.tangem.domain.models.TotalFiatBalance
|
||||||
import com.tangem.domain.models.account.AccountStatus
|
import com.tangem.domain.models.account.AccountStatus
|
||||||
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|
@ -29,4 +30,8 @@ data class AccountStatusList(
|
||||||
is AccountStatus.CryptoPortfolio -> accountStatus.account.isMainAccount
|
is AccountStatus.CryptoPortfolio -> accountStatus.account.isMainAccount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun flattenCurrencies(): List<CryptoCurrencyStatus> = accountStatuses
|
||||||
|
.map { accountStatus -> accountStatus.flattenCurrencies() }
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.domain.models.account
|
package com.tangem.domain.models.account
|
||||||
|
|
||||||
import com.tangem.domain.core.lce.Lce
|
import com.tangem.domain.core.lce.Lce
|
||||||
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.models.quote.PriceChange
|
import com.tangem.domain.models.quote.PriceChange
|
||||||
import com.tangem.domain.models.tokenlist.TokenList
|
import com.tangem.domain.models.tokenlist.TokenList
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
@ -29,4 +30,8 @@ sealed interface AccountStatus {
|
||||||
val tokenList: TokenList,
|
val tokenList: TokenList,
|
||||||
val priceChangeLce: Lce<Unit, PriceChange>,
|
val priceChangeLce: Lce<Unit, PriceChange>,
|
||||||
) : AccountStatus
|
) : AccountStatus
|
||||||
|
|
||||||
|
fun flattenCurrencies(): List<CryptoCurrencyStatus> = when (this) {
|
||||||
|
is CryptoPortfolio -> tokenList.flattenCurrencies()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,6 +9,8 @@ import com.tangem.core.decompose.di.ModelScoped
|
||||||
import com.tangem.core.ui.components.notifications.NotificationConfig.ButtonsState
|
import com.tangem.core.ui.components.notifications.NotificationConfig.ButtonsState
|
||||||
import com.tangem.core.ui.components.notifications.NotificationConfig.IconTint
|
import com.tangem.core.ui.components.notifications.NotificationConfig.IconTint
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
|
import com.tangem.domain.account.models.AccountStatusList
|
||||||
|
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
||||||
import com.tangem.domain.card.CardTypesResolver
|
import com.tangem.domain.card.CardTypesResolver
|
||||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.core.lce.Lce
|
import com.tangem.domain.core.lce.Lce
|
||||||
|
|
@ -33,6 +35,7 @@ import com.tangem.domain.wallets.usecase.SeedPhraseNotificationUseCase
|
||||||
import com.tangem.feature.wallet.child.wallet.model.WalletActivationBannerType
|
import com.tangem.feature.wallet.child.wallet.model.WalletActivationBannerType
|
||||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||||
import com.tangem.feature.wallet.impl.R
|
import com.tangem.feature.wallet.impl.R
|
||||||
|
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
|
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
|
||||||
import com.tangem.features.yield.supply.api.YieldSupplyFeatureToggles
|
import com.tangem.features.yield.supply.api.YieldSupplyFeatureToggles
|
||||||
import com.tangem.lib.crypto.BlockchainUtils.isBitcoin
|
import com.tangem.lib.crypto.BlockchainUtils.isBitcoin
|
||||||
|
|
@ -60,14 +63,21 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
private val getOnrampCountryUseCase: GetOnrampCountryUseCase,
|
private val getOnrampCountryUseCase: GetOnrampCountryUseCase,
|
||||||
private val notificationsRepository: NotificationsRepository,
|
private val notificationsRepository: NotificationsRepository,
|
||||||
private val yieldSupplyFeatureToggles: YieldSupplyFeatureToggles,
|
private val yieldSupplyFeatureToggles: YieldSupplyFeatureToggles,
|
||||||
|
private val accountDependencies: AccountDependencies,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST", "MagicNumber")
|
@Suppress("UNCHECKED_CAST", "MagicNumber")
|
||||||
fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): Flow<ImmutableList<WalletNotification>> {
|
fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): Flow<ImmutableList<WalletNotification>> {
|
||||||
val cardTypesResolver = (userWallet as? UserWallet.Cold)?.scanResponse?.cardTypesResolver
|
val cardTypesResolver = (userWallet as? UserWallet.Cold)?.scanResponse?.cardTypesResolver
|
||||||
|
|
||||||
|
val tokenListFlow = if (accountDependencies.accountsFeatureToggles.isFeatureEnabled) {
|
||||||
|
val params = SingleAccountStatusListProducer.Params(userWallet.walletId)
|
||||||
|
accountDependencies.singleAccountStatusListSupplier(params)
|
||||||
|
} else {
|
||||||
|
tokenListStore.getOrThrow(userWallet.walletId)
|
||||||
|
}
|
||||||
return combine(
|
return combine(
|
||||||
tokenListStore.getOrThrow(userWallet.walletId),
|
tokenListFlow,
|
||||||
isReadyToShowRateAppUseCase(),
|
isReadyToShowRateAppUseCase(),
|
||||||
isNeedToBackupUseCase(userWallet.walletId),
|
isNeedToBackupUseCase(userWallet.walletId),
|
||||||
seedPhraseNotificationUseCase(userWalletId = userWallet.walletId),
|
seedPhraseNotificationUseCase(userWalletId = userWallet.walletId),
|
||||||
|
|
@ -75,7 +85,18 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.Sepa),
|
shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.Sepa),
|
||||||
notificationsRepository.getShouldShowNotification(NotificationId.EnablePushesReminderNotification.key),
|
notificationsRepository.getShouldShowNotification(NotificationId.EnablePushesReminderNotification.key),
|
||||||
) { array ->
|
) { array ->
|
||||||
val maybeTokenList = array[0] as Lce<TokenListError, TokenList>
|
val totalFiatBalance: Lce<TokenListError, TotalFiatBalance>
|
||||||
|
val flattenCurrencies: Lce<TokenListError, List<CryptoCurrencyStatus>>
|
||||||
|
if (accountDependencies.accountsFeatureToggles.isFeatureEnabled) {
|
||||||
|
val accountStatusList = array[0] as AccountStatusList
|
||||||
|
totalFiatBalance = Lce.Content(accountStatusList.totalFiatBalance)
|
||||||
|
flattenCurrencies = Lce.Content(accountStatusList.flattenCurrencies())
|
||||||
|
} else {
|
||||||
|
val maybeTokenList = array[0] as Lce<TokenListError, TokenList>
|
||||||
|
totalFiatBalance = maybeTokenList.map { it.totalFiatBalance }
|
||||||
|
flattenCurrencies = maybeTokenList.map { it.flattenCurrencies() }
|
||||||
|
}
|
||||||
|
|
||||||
val isReadyToShowRating = array[1] as Boolean
|
val isReadyToShowRating = array[1] as Boolean
|
||||||
val isNeedToBackup = array[2] as Boolean
|
val isNeedToBackup = array[2] as Boolean
|
||||||
val seedPhraseIssueStatus = array[3] as SeedPhraseNotificationsStatus
|
val seedPhraseIssueStatus = array[3] as SeedPhraseNotificationsStatus
|
||||||
|
|
@ -84,19 +105,19 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
val shouldShowEnablePushesReminderNotification = array[6] as Boolean
|
val shouldShowEnablePushesReminderNotification = array[6] as Boolean
|
||||||
|
|
||||||
buildList {
|
buildList {
|
||||||
addUsedOutdatedDataNotification(maybeTokenList)
|
addUsedOutdatedDataNotification(totalFiatBalance)
|
||||||
|
|
||||||
addCriticalNotifications(userWallet, seedPhraseIssueStatus, clickIntents)
|
addCriticalNotifications(userWallet, seedPhraseIssueStatus, clickIntents)
|
||||||
|
|
||||||
addFinishWalletActivationNotification(userWallet, maybeTokenList, clickIntents)
|
addFinishWalletActivationNotification(userWallet, totalFiatBalance, clickIntents)
|
||||||
|
|
||||||
addReferralPromoNotification(cardTypesResolver, clickIntents, shouldShowReferralPromo)
|
addReferralPromoNotification(cardTypesResolver, clickIntents, shouldShowReferralPromo)
|
||||||
|
|
||||||
addSepaPromoNotification(userWallet, clickIntents, shouldShowSepaBanner)
|
addSepaPromoNotification(userWallet, clickIntents, shouldShowSepaBanner)
|
||||||
|
|
||||||
addInformationalNotifications(userWallet, cardTypesResolver, maybeTokenList, clickIntents)
|
addInformationalNotifications(userWallet, cardTypesResolver, flattenCurrencies, clickIntents)
|
||||||
|
|
||||||
addWarningNotifications(cardTypesResolver, maybeTokenList, isNeedToBackup, clickIntents)
|
addWarningNotifications(cardTypesResolver, flattenCurrencies, isNeedToBackup, clickIntents)
|
||||||
|
|
||||||
addPushReminderNotification(
|
addPushReminderNotification(
|
||||||
clickIntents = clickIntents,
|
clickIntents = clickIntents,
|
||||||
|
|
@ -104,7 +125,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
!notificationsRepository.isUserAllowToSubscribeOnPushNotifications(),
|
!notificationsRepository.isUserAllowToSubscribeOnPushNotifications(),
|
||||||
)
|
)
|
||||||
|
|
||||||
addYieldSupplyNotifications(maybeTokenList)
|
addYieldSupplyNotifications(flattenCurrencies)
|
||||||
|
|
||||||
val hasCriticalOrWarning = any { notification ->
|
val hasCriticalOrWarning = any { notification ->
|
||||||
notification is WalletNotification.Critical || notification is WalletNotification.Warning
|
notification is WalletNotification.Critical || notification is WalletNotification.Warning
|
||||||
|
|
@ -118,16 +139,16 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableList<WalletNotification>.addUsedOutdatedDataNotification(
|
private fun MutableList<WalletNotification>.addUsedOutdatedDataNotification(
|
||||||
maybeTokenList: Lce<TokenListError, TokenList>,
|
totalFiatBalance: Lce<TokenListError, TotalFiatBalance>,
|
||||||
) {
|
) {
|
||||||
addIf(
|
addIf(
|
||||||
element = WalletNotification.UsedOutdatedData,
|
element = WalletNotification.UsedOutdatedData,
|
||||||
condition = maybeTokenList.fold(
|
condition = totalFiatBalance.fold(
|
||||||
ifLoading = {
|
ifLoading = {
|
||||||
(it?.totalFiatBalance as? TotalFiatBalance.Loaded)?.source == StatusSource.ONLY_CACHE
|
(it as? TotalFiatBalance.Loaded)?.source == StatusSource.ONLY_CACHE
|
||||||
},
|
},
|
||||||
ifContent = {
|
ifContent = {
|
||||||
(it.totalFiatBalance as? TotalFiatBalance.Loaded)?.source == StatusSource.ONLY_CACHE
|
(it as? TotalFiatBalance.Loaded)?.source == StatusSource.ONLY_CACHE
|
||||||
},
|
},
|
||||||
ifError = { false },
|
ifError = { false },
|
||||||
),
|
),
|
||||||
|
|
@ -205,7 +226,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
private fun MutableList<WalletNotification>.addInformationalNotifications(
|
private fun MutableList<WalletNotification>.addInformationalNotifications(
|
||||||
userWallet: UserWallet,
|
userWallet: UserWallet,
|
||||||
cardTypesResolver: CardTypesResolver?,
|
cardTypesResolver: CardTypesResolver?,
|
||||||
maybeTokenList: Lce<TokenListError, TokenList>,
|
flattenCurrencies: Lce<TokenListError, List<CryptoCurrencyStatus>>,
|
||||||
clickIntents: WalletClickIntents,
|
clickIntents: WalletClickIntents,
|
||||||
) {
|
) {
|
||||||
addIf(
|
addIf(
|
||||||
|
|
@ -213,15 +234,15 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
condition = cardTypesResolver != null && isDemoCardUseCase(cardId = cardTypesResolver.getCardId()),
|
condition = cardTypesResolver != null && isDemoCardUseCase(cardId = cardTypesResolver.getCardId()),
|
||||||
)
|
)
|
||||||
|
|
||||||
addMissingAddressesNotification(userWallet, maybeTokenList, clickIntents)
|
addMissingAddressesNotification(userWallet, flattenCurrencies, clickIntents)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableList<WalletNotification>.addMissingAddressesNotification(
|
private fun MutableList<WalletNotification>.addMissingAddressesNotification(
|
||||||
userWallet: UserWallet,
|
userWallet: UserWallet,
|
||||||
maybeTokenList: Lce<TokenListError, TokenList>,
|
flattenCurrencies: Lce<TokenListError, List<CryptoCurrencyStatus>>,
|
||||||
clickIntents: WalletClickIntents,
|
clickIntents: WalletClickIntents,
|
||||||
) {
|
) {
|
||||||
val currencies = maybeTokenList.getMissingAddressCurrencies()
|
val currencies = flattenCurrencies.getMissingAddressCurrencies()
|
||||||
.ifEmpty { return }
|
.ifEmpty { return }
|
||||||
|
|
||||||
addIf(
|
addIf(
|
||||||
|
|
@ -236,11 +257,10 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Lce<TokenListError, TokenList>.getMissingAddressCurrencies(): List<CryptoCurrency> {
|
private fun Lce<TokenListError, List<CryptoCurrencyStatus>>.getMissingAddressCurrencies(): List<CryptoCurrency> {
|
||||||
val tokenList = getOrNull(isPartialContentAccepted = true) ?: return emptyList()
|
val flattenCurrencies = getOrNull(isPartialContentAccepted = true) ?: return emptyList()
|
||||||
|
|
||||||
return tokenList
|
return flattenCurrencies
|
||||||
.flattenCurrencies()
|
|
||||||
.filter { it.value is CryptoCurrencyStatus.MissedDerivation }
|
.filter { it.value is CryptoCurrencyStatus.MissedDerivation }
|
||||||
.map(CryptoCurrencyStatus::currency)
|
.map(CryptoCurrencyStatus::currency)
|
||||||
}
|
}
|
||||||
|
|
@ -292,17 +312,17 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableList<WalletNotification>.addYieldSupplyNotifications(
|
private fun MutableList<WalletNotification>.addYieldSupplyNotifications(
|
||||||
tokenList: Lce<TokenListError, TokenList>,
|
flattenCurrencies: Lce<TokenListError, List<CryptoCurrencyStatus>>,
|
||||||
) {
|
) {
|
||||||
addIf(
|
addIf(
|
||||||
element = WalletNotification.Warning.YeildSupplyApprove,
|
element = WalletNotification.Warning.YeildSupplyApprove,
|
||||||
condition = tokenList.hasTokensWithActivatedSupplyWithoutApprove(),
|
condition = flattenCurrencies.hasTokensWithActivatedSupplyWithoutApprove(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableList<WalletNotification>.addWarningNotifications(
|
private fun MutableList<WalletNotification>.addWarningNotifications(
|
||||||
cardTypesResolver: CardTypesResolver?,
|
cardTypesResolver: CardTypesResolver?,
|
||||||
tokenList: Lce<TokenListError, TokenList>,
|
flattenCurrencies: Lce<TokenListError, List<CryptoCurrencyStatus>>,
|
||||||
isNeedToBackup: Boolean,
|
isNeedToBackup: Boolean,
|
||||||
clickIntents: WalletClickIntents,
|
clickIntents: WalletClickIntents,
|
||||||
) {
|
) {
|
||||||
|
|
@ -320,7 +340,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
|
|
||||||
addIf(
|
addIf(
|
||||||
element = WalletNotification.Warning.SomeNetworksUnreachable,
|
element = WalletNotification.Warning.SomeNetworksUnreachable,
|
||||||
condition = tokenList.hasUnreachableNetworks(),
|
condition = flattenCurrencies.hasUnreachableNetworks(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,16 +357,16 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Lce<TokenListError, TokenList>.hasUnreachableNetworks(): Boolean {
|
private fun Lce<TokenListError, List<CryptoCurrencyStatus>>.hasUnreachableNetworks(): Boolean {
|
||||||
val tokenList = getOrNull(isPartialContentAccepted = false) ?: return false
|
val flattenCurrencies = getOrNull(isPartialContentAccepted = false) ?: return false
|
||||||
|
|
||||||
return tokenList.flattenCurrencies().any { it.value is CryptoCurrencyStatus.Unreachable }
|
return flattenCurrencies.any { it.value is CryptoCurrencyStatus.Unreachable }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Lce<TokenListError, TokenList>.hasTokensWithActivatedSupplyWithoutApprove(): Boolean {
|
private fun Lce<TokenListError, List<CryptoCurrencyStatus>>.hasTokensWithActivatedSupplyWithoutApprove(): Boolean {
|
||||||
val tokenList = getOrNull(isPartialContentAccepted = false) ?: return false
|
val flattenCurrencies = getOrNull(isPartialContentAccepted = false) ?: return false
|
||||||
val yieldSupplyEnabled = yieldSupplyFeatureToggles.isYieldSupplyFeatureEnabled
|
val yieldSupplyEnabled = yieldSupplyFeatureToggles.isYieldSupplyFeatureEnabled
|
||||||
return yieldSupplyEnabled && tokenList.flattenCurrencies().any {
|
return yieldSupplyEnabled && flattenCurrencies.any {
|
||||||
it.value.yieldSupplyStatus?.isAllowedToSpend == false
|
it.value.yieldSupplyStatus?.isAllowedToSpend == false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -365,8 +385,8 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TokenList?.getFinishWalletActivationType(): WalletActivationBannerType {
|
private fun TotalFiatBalance?.getFinishWalletActivationType(): WalletActivationBannerType {
|
||||||
return if ((this?.totalFiatBalance as? TotalFiatBalance.Loaded)?.amount?.isPositive() == true) {
|
return if ((this as? TotalFiatBalance.Loaded)?.amount?.isPositive() == true) {
|
||||||
WalletActivationBannerType.Warning
|
WalletActivationBannerType.Warning
|
||||||
} else {
|
} else {
|
||||||
WalletActivationBannerType.Attention
|
WalletActivationBannerType.Attention
|
||||||
|
|
@ -375,14 +395,14 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
|
|
||||||
private fun MutableList<WalletNotification>.addFinishWalletActivationNotification(
|
private fun MutableList<WalletNotification>.addFinishWalletActivationNotification(
|
||||||
userWallet: UserWallet,
|
userWallet: UserWallet,
|
||||||
maybeTokenList: Lce<TokenListError, TokenList>,
|
totalFiatBalance: Lce<TokenListError, TotalFiatBalance>,
|
||||||
clickIntents: WalletClickIntents,
|
clickIntents: WalletClickIntents,
|
||||||
) {
|
) {
|
||||||
if (userWallet !is UserWallet.Hot) return
|
if (userWallet !is UserWallet.Hot) return
|
||||||
|
|
||||||
val shouldShowFinishActivation = !userWallet.backedUp
|
val shouldShowFinishActivation = !userWallet.backedUp
|
||||||
|
|
||||||
val type = maybeTokenList.fold(
|
val type = totalFiatBalance.fold(
|
||||||
ifLoading = { it.getFinishWalletActivationType() },
|
ifLoading = { it.getFinishWalletActivationType() },
|
||||||
ifContent = { it.getFinishWalletActivationType() },
|
ifContent = { it.getFinishWalletActivationType() },
|
||||||
ifError = { WalletActivationBannerType.Attention },
|
ifError = { WalletActivationBannerType.Attention },
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue