Updated on 2026-08-14
This commit is contained in:
parent
4c12570008
commit
97f41bd800
38 changed files with 768 additions and 163 deletions
|
|
@ -38,6 +38,8 @@ import com.tangem.domain.settings.*
|
|||
import com.tangem.domain.tokens.RefreshMultiCurrencyWalletQuotesUseCase
|
||||
import com.tangem.domain.walletconnect.WcPairService
|
||||
import com.tangem.domain.walletconnect.model.WcPairRequest
|
||||
import com.tangem.domain.tokensync.usecase.StartTokenSyncUseCase
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyUpdateUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
|
|
@ -123,6 +125,8 @@ internal class WalletModel @Inject constructor(
|
|||
private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val startTokenSyncUseCase: StartTokenSyncUseCase,
|
||||
val screenLifecycleProvider: ScreenLifecycleProvider,
|
||||
val innerWalletRouter: InnerWalletRouter,
|
||||
) : Model() {
|
||||
|
|
@ -155,6 +159,7 @@ internal class WalletModel @Inject constructor(
|
|||
subscribeTangemPayOnWalletState()
|
||||
subscribeToMainScreenQrScanning()
|
||||
enableNotificationsIfNeeded()
|
||||
applyPendingTokenSyncs()
|
||||
|
||||
clickIntents.initialize(innerWalletRouter, modelScope)
|
||||
|
||||
|
|
@ -819,6 +824,12 @@ internal class WalletModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun applyPendingTokenSyncs() {
|
||||
if (hotWalletFeatureToggles.isTokenSyncEnabled) {
|
||||
startTokenSyncUseCase.applyPendingSyncs()
|
||||
}
|
||||
}
|
||||
|
||||
private fun enableNotificationsIfNeeded() {
|
||||
modelScope.launch {
|
||||
val isUserAllowToEnableNotifications = notificationsRepository.isUserAllowToSubscribeOnPushNotifications()
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
|||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.hotwallet.CloseHotWalletUpgradeBannerUseCase
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -39,6 +40,7 @@ import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent
|
|||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.Program
|
||||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.PromotionBannerClicked
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.tokensync.usecase.AcknowledgeTokenSyncCompletionUseCase
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.Basic
|
||||
|
|
@ -94,6 +96,10 @@ internal interface WalletWarningsClickIntents {
|
|||
fun onUpgradeHotWalletClick(userWalletId: UserWalletId)
|
||||
|
||||
fun onCloseUpgradeBannerClick(userWalletId: UserWalletId)
|
||||
|
||||
fun onDismissTokenSyncNotification(userWalletId: UserWalletId)
|
||||
|
||||
fun onTokenSyncManageClick(userWalletId: UserWalletId)
|
||||
}
|
||||
|
||||
@Suppress("LargeClass", "LongParameterList", "TooManyFunctions")
|
||||
|
|
@ -126,6 +132,7 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
private val uiMessageSender: UiMessageSender,
|
||||
private val reviewManager: ReviewManager,
|
||||
private val closeHotWalletUpgradeBannerUseCase: CloseHotWalletUpgradeBannerUseCase,
|
||||
private val acknowledgeTokenSyncCompletionUseCase: AcknowledgeTokenSyncCompletionUseCase,
|
||||
) : BaseWalletClickIntents(), WalletWarningsClickIntents {
|
||||
|
||||
override fun onAddBackupCardClick() {
|
||||
|
|
@ -501,6 +508,17 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onDismissTokenSyncNotification(userWalletId: UserWalletId) {
|
||||
acknowledgeTokenSyncCompletionUseCase(userWalletId)
|
||||
}
|
||||
|
||||
override fun onTokenSyncManageClick(userWalletId: UserWalletId) {
|
||||
acknowledgeTokenSyncCompletionUseCase(userWalletId)
|
||||
router.openManageTokensScreen(
|
||||
AccountId.forMainCryptoPortfolio(userWalletId),
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val VISA_PROMO_LINK = "https://tangem.com/en/cardwaitlist/?utm_source=tangem-app-banner" +
|
||||
"&utm_medium=banner" +
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ internal object WalletPreviewDataLegacy {
|
|||
balance = "8923,05312312312312312312331231231233432423423424234 $",
|
||||
additionalInfo = WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = TextReference.Str("3 cards • Seed phrase3 cards • Seed phrasephrasephrasephrase"),
|
||||
content = WalletAdditionalInfo.Content.Text(
|
||||
TextReference.Str("3 cards • Seed phrase3 cards • Seed phrasephrasephrasephrase"),
|
||||
),
|
||||
),
|
||||
imageResId = R.drawable.ill_wallet2_cards3_120_106,
|
||||
dropDownItems = persistentListOf(),
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ internal object WalletScreenPreviewDataLegacy {
|
|||
title = "Note",
|
||||
additionalInfo = WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = TextReference.Str("Locked"),
|
||||
content = WalletAdditionalInfo.Content.Text(TextReference.Str("Locked")),
|
||||
),
|
||||
imageResId = R.drawable.ill_note_btc_120_106,
|
||||
dropDownItems = persistentListOf(),
|
||||
|
|
@ -172,7 +172,7 @@ internal object WalletScreenPreviewDataLegacy {
|
|||
title = "Wallet 1",
|
||||
additionalInfo = WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = TextReference.Str("Seed phrase"),
|
||||
content = WalletAdditionalInfo.Content.Text(TextReference.Str("Seed phrase")),
|
||||
),
|
||||
imageResId = R.drawable.ill_wallet2_cards3_120_106,
|
||||
cardCount = 3,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ import com.tangem.domain.notifications.repository.NotificationsRepository
|
|||
import com.tangem.domain.promo.ShouldShowPromoWalletUseCase
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
||||
import com.tangem.domain.tokensync.model.TokenSyncProgress
|
||||
import com.tangem.domain.tokensync.usecase.ObserveTokenSyncUseCase
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.WalletActivationBannerType
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
|
|
@ -43,6 +46,7 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -61,6 +65,8 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
private val shouldShowUpgradeHotWalletBannerUseCase: ShouldShowUpgradeHotWalletBannerUseCase,
|
||||
private val getUpgradeBannerClosureTimestampUseCase: GetUpgradeBannerClosureTimestampUseCase,
|
||||
private val checkHotWalletUpgradeBannerUseCase: CheckHotWalletUpgradeBannerUseCase,
|
||||
private val observeTokenSyncUseCase: ObserveTokenSyncUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) {
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "MagicNumber", "LongMethod", "CastNullableToNonNullableType")
|
||||
|
|
@ -69,6 +75,12 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
val params = SingleAccountStatusListProducer.Params(userWallet.walletId)
|
||||
val accountStatusListFlow = accountDependencies.singleAccountStatusListSupplier(params)
|
||||
|
||||
val tokenSyncProgressFlow = if (hotWalletFeatureToggles.isTokenSyncEnabled && userWallet is UserWallet.Hot) {
|
||||
observeTokenSyncUseCase(userWallet.walletId).distinctUntilChanged()
|
||||
} else {
|
||||
flowOf(TokenSyncProgress.Idle)
|
||||
}
|
||||
|
||||
return combine(
|
||||
accountStatusListFlow,
|
||||
isReadyToShowRateAppUseCase().distinctUntilChanged(),
|
||||
|
|
@ -84,6 +96,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
.distinctUntilChanged(),
|
||||
getUpgradeBannerClosureTimestampUseCase(userWallet.walletId)
|
||||
.distinctUntilChanged(),
|
||||
tokenSyncProgressFlow,
|
||||
) { array -> array }
|
||||
.map { array ->
|
||||
val accountStatusList = array[0] as AccountStatusList
|
||||
|
|
@ -95,6 +108,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
val shouldShowYieldPromo = array[6] as Boolean
|
||||
val shouldShowUpgradeBanner = array[7] as Boolean
|
||||
val closureTimestamp = array[8] as? Long
|
||||
val tokenSyncProgress = array[9] as TokenSyncProgress
|
||||
|
||||
val flattenCurrencies = accountStatusList.flattenCurrencies()
|
||||
val paymentAccountStatus = accountStatusList.accountStatuses
|
||||
|
|
@ -139,6 +153,12 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
clickIntents = clickIntents,
|
||||
)
|
||||
|
||||
addTokenSyncCompletedNotification(
|
||||
userWallet = userWallet,
|
||||
tokenSyncProgress = tokenSyncProgress,
|
||||
clickIntents = clickIntents,
|
||||
)
|
||||
|
||||
addPushReminderNotification(
|
||||
clickIntents = clickIntents,
|
||||
shouldShowPushReminderBanner = shouldShowEnablePushesReminderNotification &&
|
||||
|
|
@ -384,6 +404,20 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
// }
|
||||
// }
|
||||
|
||||
private fun MutableList<WalletNotification>.addTokenSyncCompletedNotification(
|
||||
userWallet: UserWallet,
|
||||
tokenSyncProgress: TokenSyncProgress,
|
||||
clickIntents: WalletClickIntents,
|
||||
) {
|
||||
addIf(
|
||||
element = WalletNotification.TokenSyncCompleted(
|
||||
onCloseClick = { clickIntents.onDismissTokenSyncNotification(userWallet.walletId) },
|
||||
onManageTokensClick = { clickIntents.onTokenSyncManageClick(userWallet.walletId) },
|
||||
),
|
||||
condition = tokenSyncProgress is TokenSyncProgress.Completed,
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addRateTheAppNotification(
|
||||
isReadyToShowRating: Boolean,
|
||||
clickIntents: WalletClickIntents,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.domain.card.common.util.cardTypesResolver
|
|||
import com.tangem.domain.card.common.util.getCardsCount
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TokenSyncProgressUM
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditionalInfo
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -28,7 +29,11 @@ internal object WalletAdditionalInfoFactory {
|
|||
* @param wallet current wallet
|
||||
* @param currencyAmount amount of currency
|
||||
*/
|
||||
fun resolve(wallet: UserWallet, currencyAmount: BigDecimal? = null): WalletAdditionalInfo {
|
||||
fun resolve(
|
||||
wallet: UserWallet,
|
||||
currencyAmount: BigDecimal? = null,
|
||||
syncProgress: TokenSyncProgressUM = TokenSyncProgressUM.Idle,
|
||||
): WalletAdditionalInfo {
|
||||
return when (wallet) {
|
||||
is UserWallet.Cold -> {
|
||||
if (wallet.isMultiCurrency) {
|
||||
|
|
@ -37,19 +42,26 @@ internal object WalletAdditionalInfoFactory {
|
|||
wallet.resolveSingleCurrencyInfo(currencyAmount)
|
||||
}
|
||||
}
|
||||
is UserWallet.Hot -> wallet.resolveAdditionalInfo()
|
||||
is UserWallet.Hot -> wallet.resolveAdditionalInfo(syncProgress)
|
||||
}
|
||||
}
|
||||
|
||||
private fun UserWallet.Hot.resolveAdditionalInfo(): WalletAdditionalInfo {
|
||||
private fun UserWallet.Hot.resolveAdditionalInfo(syncProgress: TokenSyncProgressUM): WalletAdditionalInfo {
|
||||
val content = if (syncProgress is TokenSyncProgressUM.InProgress) {
|
||||
WalletAdditionalInfo.Content.SyncProgress(syncProgress.progressPercent)
|
||||
} else {
|
||||
WalletAdditionalInfo.Content.Text(
|
||||
TextReference.Res(R.string.hw_mobile_wallet) +
|
||||
when {
|
||||
isLocked -> DIVIDER + TextReference.Res(R.string.common_locked)
|
||||
backedUp.not() -> DIVIDER + TextReference.Res(R.string.hw_backup_no_backup)
|
||||
else -> TextReference.Str("")
|
||||
},
|
||||
)
|
||||
}
|
||||
return WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = TextReference.Res(R.string.hw_mobile_wallet) +
|
||||
when {
|
||||
isLocked -> DIVIDER + TextReference.Res(R.string.common_locked)
|
||||
backedUp.not() -> DIVIDER + TextReference.Res(R.string.hw_backup_no_backup)
|
||||
else -> TextReference.Str("")
|
||||
},
|
||||
content = content,
|
||||
isHotBackedUp = backedUp,
|
||||
)
|
||||
}
|
||||
|
|
@ -58,9 +70,11 @@ internal object WalletAdditionalInfoFactory {
|
|||
return if (isLocked) {
|
||||
WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = getBackupInfoWithDivider(
|
||||
backupCardsCount = getCardsCount(),
|
||||
) + TextReference.Res(R.string.common_locked),
|
||||
content = WalletAdditionalInfo.Content.Text(
|
||||
getBackupInfoWithDivider(
|
||||
backupCardsCount = getCardsCount(),
|
||||
) + TextReference.Res(R.string.common_locked),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
val cardTypeResolver = scanResponse.cardTypesResolver
|
||||
|
|
@ -76,8 +90,10 @@ internal object WalletAdditionalInfoFactory {
|
|||
return if (isImported) {
|
||||
WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = getBackupInfoWithDivider(backupCardsCount = getCardsCount()) + TextReference.Res(
|
||||
id = R.string.common_seed_phrase,
|
||||
content = WalletAdditionalInfo.Content.Text(
|
||||
getBackupInfoWithDivider(backupCardsCount = getCardsCount()) + TextReference.Res(
|
||||
id = R.string.common_seed_phrase,
|
||||
),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
|
|
@ -94,7 +110,7 @@ internal object WalletAdditionalInfoFactory {
|
|||
}
|
||||
|
||||
private fun getBackupInfo(backupCardsCount: Int?): WalletAdditionalInfo {
|
||||
val content = if (backupCardsCount != null) {
|
||||
val ref = if (backupCardsCount != null) {
|
||||
getBackupInfoTextReference(count = backupCardsCount)
|
||||
} else {
|
||||
TextReference.EMPTY
|
||||
|
|
@ -102,7 +118,7 @@ internal object WalletAdditionalInfoFactory {
|
|||
|
||||
return WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = content,
|
||||
content = WalletAdditionalInfo.Content.Text(ref),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +134,7 @@ internal object WalletAdditionalInfoFactory {
|
|||
return if (isLocked) {
|
||||
WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = TextReference.Res(R.string.common_locked),
|
||||
content = WalletAdditionalInfo.Content.Text(TextReference.Res(R.string.common_locked)),
|
||||
)
|
||||
} else {
|
||||
val blockchain = scanResponse.cardTypesResolver.getBlockchain()
|
||||
|
|
@ -126,7 +142,7 @@ internal object WalletAdditionalInfoFactory {
|
|||
|
||||
WalletAdditionalInfo(
|
||||
hideable = true,
|
||||
content = TextReference.Str(value = amount.orEmpty()),
|
||||
content = WalletAdditionalInfo.Content.Text(TextReference.Str(value = amount.orEmpty())),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
|||
import com.tangem.core.ui.DesignFeatureToggles
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
|
@ -17,10 +18,12 @@ internal class MultiWalletContentLoader @AssistedInject constructor(
|
|||
private val walletNotificationsSubscriberFactory: WalletNotificationsSubscriber.Factory,
|
||||
private val multiWalletActionButtonsSubscriberFactory: MultiWalletActionButtonsSubscriber.Factory,
|
||||
private val tangemPayMainSubscriberFactory: TangemPayMainSubscriber.Factory,
|
||||
private val tokenSyncSubscriberFactory: TokenSyncSubscriber.Factory,
|
||||
private val designFeatureToggles: DesignFeatureToggles,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
||||
override fun create(): List<WalletSubscriber> = listOf(
|
||||
override fun create(): List<WalletSubscriber> = listOfNotNull(
|
||||
accountListSubscriberFactory.create(userWallet),
|
||||
walletNFTListSubscriberFactory.create(userWallet),
|
||||
checkWalletWithFundsSubscriberFactory.create(userWallet),
|
||||
|
|
@ -31,6 +34,11 @@ internal class MultiWalletContentLoader @AssistedInject constructor(
|
|||
},
|
||||
multiWalletActionButtonsSubscriberFactory.create(userWallet),
|
||||
tangemPayMainSubscriberFactory.create(userWallet),
|
||||
if (hotWalletFeatureToggles.isTokenSyncEnabled && userWallet is UserWallet.Hot) {
|
||||
tokenSyncSubscriberFactory.create(userWallet)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
|
||||
@AssistedFactory
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.model
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
internal sealed class TokenSyncProgressUM {
|
||||
|
||||
data object Idle : TokenSyncProgressUM()
|
||||
|
||||
data class InProgress(val progressPercent: Int) : TokenSyncProgressUM()
|
||||
|
||||
data object Completed : TokenSyncProgressUM()
|
||||
}
|
||||
|
|
@ -6,7 +6,12 @@ import com.tangem.core.ui.extensions.TextReference
|
|||
@Immutable
|
||||
data class WalletAdditionalInfo(
|
||||
val hideable: Boolean,
|
||||
val content: TextReference,
|
||||
val content: Content,
|
||||
val isHotBackedUp: Boolean = false,
|
||||
val shouldShowProgress: Boolean = false,
|
||||
)
|
||||
) {
|
||||
@Immutable
|
||||
sealed interface Content {
|
||||
data class Text(val text: TextReference) : Content
|
||||
data class SyncProgress(val progressPercent: Int) : Content
|
||||
}
|
||||
}
|
||||
|
|
@ -85,7 +85,10 @@ internal sealed interface WalletCardState {
|
|||
|
||||
private companion object {
|
||||
val defaultAdditionalInfo: WalletAdditionalInfo
|
||||
get() = WalletAdditionalInfo(hideable = true, content = EMPTY_BALANCE_TEXT)
|
||||
get() = WalletAdditionalInfo(
|
||||
hideable = true,
|
||||
content = WalletAdditionalInfo.Content.Text(EMPTY_BALANCE_TEXT),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ internal sealed interface WalletState : WalletStateHolder {
|
|||
abstract val tangemPayState: TangemPayState
|
||||
abstract val tangemPayMainUM: TangemPayMainUM
|
||||
abstract val isTangemPayRefactorEnabled: Boolean // TANGEM_PAY_ACCOUNTS_REFACTOR_ENABLED
|
||||
abstract val tokenSyncProgressUM: TokenSyncProgressUM
|
||||
|
||||
data class Content(
|
||||
override val pullToRefreshConfig: PullToRefreshConfig,
|
||||
|
|
@ -40,6 +41,7 @@ internal sealed interface WalletState : WalletStateHolder {
|
|||
override val tangemPayState: TangemPayState,
|
||||
override val tangemPayMainUM: TangemPayMainUM,
|
||||
override val isTangemPayRefactorEnabled: Boolean,
|
||||
override val tokenSyncProgressUM: TokenSyncProgressUM = TokenSyncProgressUM.Idle,
|
||||
) : MultiCurrency()
|
||||
|
||||
data class Locked(
|
||||
|
|
@ -61,6 +63,7 @@ internal sealed interface WalletState : WalletStateHolder {
|
|||
override val tangemPayState: TangemPayState = TangemPayState.Empty
|
||||
override val tangemPayMainUM: TangemPayMainUM = TangemPayMainUM.Empty
|
||||
override val isTangemPayRefactorEnabled: Boolean = false
|
||||
override val tokenSyncProgressUM: TokenSyncProgressUM = TokenSyncProgressUM.Idle
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ internal class SetTokenListErrorTransformer(
|
|||
walletsBalanceUM = walletUM.walletsBalanceUM.toLoadedState(),
|
||||
tokensListUM = WalletTokensListUM.Empty(
|
||||
onEmptyClick = {
|
||||
clickIntents.onManageTokensClick(walletUM.walletsBalanceUM.id)
|
||||
clickIntents.onTokenSyncManageClick(walletUM.walletsBalanceUM.id)
|
||||
},
|
||||
),
|
||||
buttons = walletUM.disableButtons(),
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ internal class SetTokenListTransformer(
|
|||
if (params !is TokenConverterParams.Account) {
|
||||
return WalletTokensListUM.Empty(
|
||||
onEmptyClick = {
|
||||
clickIntents.onManageTokensClick(userWallet.walletId)
|
||||
clickIntents.onTokenSyncManageClick(userWallet.walletId)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,51 +1,34 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditionalInfo
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TokenSyncProgressUM
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
|
||||
internal class SetTokenSyncProgressTransformer(
|
||||
userWalletId: UserWalletId,
|
||||
private val progressPercent: Int,
|
||||
) : WalletStateTransformer(userWalletId) {
|
||||
private val userWallet: UserWallet,
|
||||
private val progress: TokenSyncProgressUM,
|
||||
) : WalletStateTransformer(userWallet.walletId) {
|
||||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
return when (prevState) {
|
||||
is WalletState.MultiCurrency.Content -> {
|
||||
val updatedCardState = updateCardState(prevState.walletCardState)
|
||||
prevState.copy(walletCardState = updatedCardState)
|
||||
}
|
||||
else -> {
|
||||
prevState
|
||||
}
|
||||
is WalletState.MultiCurrency.Content -> prevState.copy(
|
||||
walletCardState = updateCardState(prevState.walletCardState),
|
||||
tokenSyncProgressUM = progress,
|
||||
)
|
||||
else -> prevState
|
||||
}
|
||||
}
|
||||
|
||||
override fun transform(walletUM: WalletUM): WalletUM {
|
||||
return walletUM
|
||||
}
|
||||
override fun transform(walletUM: WalletUM): WalletUM = walletUM
|
||||
|
||||
private fun updateCardState(cardState: WalletCardState): WalletCardState {
|
||||
val additionalInfo = WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = resourceReference(
|
||||
id = R.string.initial_wallet_sync_restore_progress,
|
||||
formatArgs = wrappedList(progressPercent),
|
||||
),
|
||||
shouldShowProgress = true,
|
||||
)
|
||||
val additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet, syncProgress = progress)
|
||||
return when (cardState) {
|
||||
is WalletCardState.Loading -> {
|
||||
cardState.copy(additionalInfo = additionalInfo)
|
||||
}
|
||||
is WalletCardState.Content -> {
|
||||
cardState.copy(additionalInfo = additionalInfo)
|
||||
}
|
||||
is WalletCardState.Loading -> cardState.copy(additionalInfo = additionalInfo)
|
||||
is WalletCardState.Content -> cardState.copy(additionalInfo = additionalInfo)
|
||||
else -> cardState
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.tangem.domain.card.common.util.getCardsCount
|
|||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TokenSyncProgressUM
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
|
|
@ -17,7 +18,9 @@ internal class UpdateWalletCardsCountTransformer(
|
|||
override fun transform(prevState: WalletState): WalletState {
|
||||
return when (prevState) {
|
||||
is WalletState.MultiCurrency.Content -> {
|
||||
prevState.copy(walletCardState = prevState.walletCardState.toUpdatedState())
|
||||
prevState.copy(
|
||||
walletCardState = prevState.walletCardState.toUpdatedState(prevState.tokenSyncProgressUM),
|
||||
)
|
||||
}
|
||||
is WalletState.SingleCurrency.Content -> {
|
||||
prevState.copy(walletCardState = prevState.walletCardState.toUpdatedState())
|
||||
|
|
@ -35,10 +38,12 @@ internal class UpdateWalletCardsCountTransformer(
|
|||
return walletUM // todo redesign main
|
||||
}
|
||||
|
||||
private fun WalletCardState.toUpdatedState(): WalletCardState {
|
||||
private fun WalletCardState.toUpdatedState(
|
||||
syncProgress: TokenSyncProgressUM = TokenSyncProgressUM.Idle,
|
||||
): WalletCardState {
|
||||
return when (this) {
|
||||
is WalletCardState.Content -> copy(
|
||||
additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet),
|
||||
additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet, syncProgress = syncProgress),
|
||||
imageResId = walletImageResolver.resolve(userWallet = userWallet),
|
||||
cardCount = (userWallet as? UserWallet.Cold)?.getCardsCount(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.tokensync.model.TokenSyncProgress
|
||||
import com.tangem.domain.tokensync.usecase.ObserveTokenSyncUseCase
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TokenSyncProgressUM
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTokenSyncProgressTransformer
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
internal class TokenSyncSubscriber @AssistedInject constructor(
|
||||
@Assisted private val userWallet: UserWallet,
|
||||
private val stateController: WalletStateController,
|
||||
private val observeTokenSyncUseCase: ObserveTokenSyncUseCase,
|
||||
) : WalletSubscriber() {
|
||||
|
||||
override fun create(coroutineScope: CoroutineScope): Flow<*> {
|
||||
return observeTokenSyncUseCase(userWallet.walletId)
|
||||
.onEach { current -> handleProgress(userWallet, current) }
|
||||
}
|
||||
|
||||
private fun handleProgress(userWallet: UserWallet, current: TokenSyncProgress) {
|
||||
val progressUM = when (current) {
|
||||
is TokenSyncProgress.InProgress -> TokenSyncProgressUM.InProgress(current.progressPercent)
|
||||
is TokenSyncProgress.Completed -> TokenSyncProgressUM.Completed
|
||||
is TokenSyncProgress.Idle -> TokenSyncProgressUM.Idle
|
||||
}
|
||||
stateController.update(
|
||||
SetTokenSyncProgressTransformer(
|
||||
userWallet = userWallet,
|
||||
progress = progressUM,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(userWallet: UserWallet): TokenSyncSubscriber
|
||||
}
|
||||
}
|
||||
|
|
@ -41,6 +41,9 @@ import com.tangem.core.ui.extensions.TextReference
|
|||
import com.tangem.core.ui.extensions.conditional
|
||||
import com.tangem.core.ui.extensions.orMaskWithStars
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.core.ui.res.TangemDimens
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -156,16 +159,10 @@ private fun CardContainer(state: WalletCardState, isBalanceHidden: Boolean, item
|
|||
.padding(vertical = TangemTheme.dimens.spacing8),
|
||||
)
|
||||
|
||||
val additionalText by remember(state.additionalInfo, isBalanceHidden) {
|
||||
mutableStateOf(
|
||||
state.additionalInfo?.content?.orMaskWithStars(
|
||||
maskWithStars = state.additionalInfo?.hideable == true && isBalanceHidden,
|
||||
),
|
||||
)
|
||||
}
|
||||
AdditionalInfo(
|
||||
text = additionalText,
|
||||
showProgress = state.additionalInfo?.shouldShowProgress == true,
|
||||
content = state.additionalInfo?.content,
|
||||
hideable = state.additionalInfo?.hideable == true,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
modifier = Modifier.conditional(
|
||||
state.imageResId == null,
|
||||
) { fillMaxWidth() },
|
||||
|
|
@ -300,28 +297,53 @@ private fun Modifier.nonContentBalanceSize(dimens: TangemDimens): Modifier {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun AdditionalInfo(text: TextReference?, showProgress: Boolean, modifier: Modifier = Modifier) {
|
||||
private fun AdditionalInfo(
|
||||
content: WalletAdditionalInfo.Content?,
|
||||
hideable: Boolean,
|
||||
isBalanceHidden: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = text,
|
||||
targetState = content,
|
||||
contentKey = { con ->
|
||||
when (con) {
|
||||
is WalletAdditionalInfo.Content.Text -> con
|
||||
is WalletAdditionalInfo.Content.SyncProgress -> WalletAdditionalInfo.Content.SyncProgress::class
|
||||
null -> null
|
||||
}
|
||||
},
|
||||
label = "Update the additional text",
|
||||
modifier = modifier,
|
||||
transitionSpec = {
|
||||
fadeIn(animationSpec = tween(durationMillis = 220, delayMillis = 90)) togetherWith
|
||||
fadeOut(animationSpec = tween(durationMillis = 90))
|
||||
},
|
||||
) { animatedText ->
|
||||
if (animatedText != null) {
|
||||
) { animatedContent ->
|
||||
if (animatedContent != null) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
AdditionalInfoText(text = animatedText)
|
||||
if (showProgress) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size16),
|
||||
color = TangemTheme.colors.icon.accent,
|
||||
strokeWidth = TangemTheme.dimens.size2,
|
||||
)
|
||||
when (animatedContent) {
|
||||
is WalletAdditionalInfo.Content.Text -> {
|
||||
AdditionalInfoText(
|
||||
text = animatedContent.text.orMaskWithStars(
|
||||
maskWithStars = hideable && isBalanceHidden,
|
||||
),
|
||||
)
|
||||
}
|
||||
is WalletAdditionalInfo.Content.SyncProgress -> {
|
||||
AdditionalInfoText(
|
||||
text = resourceReference(
|
||||
id = R.string.initial_wallet_sync_restore_progress,
|
||||
formatArgs = wrappedList(animatedContent.progressPercent),
|
||||
),
|
||||
)
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size16),
|
||||
color = TangemTheme.colors.icon.accent,
|
||||
strokeWidth = TangemTheme.dimens.size2,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -396,7 +418,7 @@ private class WalletCardStateProvider : CollectionPreviewParameterProvider<Walle
|
|||
title = "Title",
|
||||
additionalInfo = WalletAdditionalInfo(
|
||||
hideable = false,
|
||||
content = TextReference.Str("3 cards"),
|
||||
content = WalletAdditionalInfo.Content.Text(TextReference.Str("3 cards")),
|
||||
),
|
||||
),
|
||||
WalletPreviewDataLegacy.walletCardContentState.copy(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue