Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-02 13:28:07 +03:00
commit 687a67632d
23 changed files with 206 additions and 63 deletions

View file

@ -5,6 +5,8 @@ import com.tangem.domain.card.repository.CardRepository
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.wallets.legacy.WalletsStateHolder
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
import com.tangem.tap.domain.TangemSdkManager
import com.tangem.tap.domain.card.DefaultDerivePublicKeysUseCase
import dagger.Module
@ -62,4 +64,10 @@ internal object CardDomainModule {
fun provideDerivePublicKeysUseCase(tangemSdkManager: TangemSdkManager): DerivePublicKeysUseCase {
return DefaultDerivePublicKeysUseCase(tangemSdkManager = tangemSdkManager)
}
@Provides
@ViewModelScoped
fun provideIsNeedToBackupUseCase(walletStateHolder: WalletsStateHolder): IsNeedToBackupUseCase {
return IsNeedToBackupUseCase(walletStateHolder)
}
}

View file

@ -450,6 +450,23 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
Analytics.send(Onboarding.Backup.Finished(backupState.backupCardsNumber))
}
userWalletsListManager.selectedUserWalletSync?.walletId?.let {
scope.launch {
userWalletsListManager.update(
userWalletId = it,
update = { wallet ->
wallet.copy(
scanResponse = updateScanResponseAfterBackup(
scanResponse = wallet.scanResponse,
backupState = backupState,
),
)
},
)
store.dispatchOnMain(GlobalAction.UpdateUserWalletsListManager(userWalletsListManager))
}
}
val notActivatedCardIds = gatherCardIds(backupState, card)
.mapNotNull { if (cardActivationIsFinished(it)) null else it }

View file

@ -40,7 +40,6 @@ internal class DefaultNetworksRepository(
override fun getNetworkStatusesUpdates(
userWalletId: UserWalletId,
networks: Set<Network>,
refresh: Boolean,
): Flow<Set<NetworkStatus>> = channelFlow {
launch(dispatchers.io) {
networksStatusesStore.get(userWalletId)
@ -48,7 +47,7 @@ internal class DefaultNetworksRepository(
}
withContext(dispatchers.io) {
fetchNetworksStatusesIfCacheExpired(userWalletId, networks, refresh)
fetchNetworksStatusesIfCacheExpired(userWalletId, networks, false)
}
}.cancellable()

View file

@ -37,17 +37,15 @@ class GetCurrencyStatusUpdatesUseCase(
operator fun invoke(
userWalletId: UserWalletId,
currencyId: CryptoCurrency.ID,
refresh: Boolean,
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
return flow {
emitAll(getCurrency(userWalletId, currencyId, refresh))
emitAll(getCurrency(userWalletId, currencyId))
}.flowOn(dispatchers.io)
}
private suspend fun getCurrency(
userWalletId: UserWalletId,
currencyId: CryptoCurrency.ID,
refresh: Boolean,
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
val operations = CurrenciesStatusesOperations(
currenciesRepository = currenciesRepository,
@ -56,7 +54,7 @@ class GetCurrencyStatusUpdatesUseCase(
userWalletId = userWalletId,
)
return operations.getCurrencyStatusFlow(currencyId, refresh).map { maybeCurrency ->
return operations.getCurrencyStatusFlow(currencyId).map { maybeCurrency ->
maybeCurrency.mapLeft(CurrenciesStatusesOperations.Error::mapToCurrencyError)
}
}

View file

@ -67,16 +67,13 @@ internal class CurrenciesStatusesOperations(
}
}
suspend fun getCurrencyStatusFlow(
currencyId: CryptoCurrency.ID,
refresh: Boolean = false,
): Flow<Either<Error, CryptoCurrencyStatus>> {
suspend fun getCurrencyStatusFlow(currencyId: CryptoCurrency.ID): Flow<Either<Error, CryptoCurrencyStatus>> {
val currency = recover(
block = { getMultiCurrencyWalletCurrency(currencyId) },
recover = { return flowOf(it.left()) },
)
return getCurrencyStatusFlow(currency, refresh)
return getCurrencyStatusFlow(currency)
}
suspend fun getNetworkCoinFlow(networkId: Network.ID): Flow<Either<Error, CryptoCurrencyStatus>> {
@ -97,10 +94,7 @@ internal class CurrenciesStatusesOperations(
return getCurrencyStatusFlow(currency)
}
private fun getCurrencyStatusFlow(
currency: CryptoCurrency,
refresh: Boolean = false,
): Flow<Either<Error, CryptoCurrencyStatus>> {
private fun getCurrencyStatusFlow(currency: CryptoCurrency): Flow<Either<Error, CryptoCurrencyStatus>> {
val (networks, currenciesIds) = getIds(nonEmptyListOf(currency))
val quoteFlow = getQuotes(currenciesIds)
@ -111,7 +105,7 @@ internal class CurrenciesStatusesOperations(
}
}
val statusFlow = getNetworksStatuses(networks, refresh)
val statusFlow = getNetworksStatuses(networks)
.map { maybeStatuses ->
maybeStatuses.flatMap { statuses ->
statuses.singleOrNull { it.network == currency.network }?.right()
@ -210,11 +204,8 @@ internal class CurrenciesStatusesOperations(
.onEmpty { emit(Error.EmptyQuotes.left()) }
}
private fun getNetworksStatuses(
networks: NonEmptySet<Network>,
refresh: Boolean = false,
): Flow<Either<Error, Set<NetworkStatus>>> {
return networksRepository.getNetworkStatusesUpdates(userWalletId, networks, refresh)
private fun getNetworksStatuses(networks: NonEmptySet<Network>): Flow<Either<Error, Set<NetworkStatus>>> {
return networksRepository.getNetworkStatusesUpdates(userWalletId, networks)
.map<Set<NetworkStatus>, Either<Error, Set<NetworkStatus>>> { it.right() }
.catch { emit(Error.DataError(it).left()) }
.onEmpty { emit(Error.EmptyNetworksStatuses.left()) }

View file

@ -16,14 +16,9 @@ interface NetworksRepository {
*
* @param userWalletId The unique identifier of the user wallet.
* @param networks A set of network which statuses are to be retrieved.
* @param refresh A boolean flag indicating whether the data should be refreshed from remote.
* @return A [Flow] emitting a set of [NetworkStatus] objects corresponding to the specified networks.
*/
fun getNetworkStatusesUpdates(
userWalletId: UserWalletId,
networks: Set<Network>,
refresh: Boolean = false,
): Flow<Set<NetworkStatus>>
fun getNetworkStatusesUpdates(userWalletId: UserWalletId, networks: Set<Network>): Flow<Set<NetworkStatus>>
/**
* Retrieves network statuses of specified blockchain networks for a specific user wallet.

View file

@ -17,7 +17,6 @@ internal class MockNetworksRepository(
override fun getNetworkStatusesUpdates(
userWalletId: UserWalletId,
networks: Set<Network>,
refresh: Boolean,
): Flow<Set<NetworkStatus>> {
return statuses.map { it.getOrElse { e -> throw e } }
}

View file

@ -0,0 +1,27 @@
package com.tangem.domain.wallets.usecase
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.wallets.legacy.WalletsStateHolder
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
/**
* Use case that checks if wallet need backup cards
*/
class IsNeedToBackupUseCase(private val walletsStateHolder: WalletsStateHolder) {
operator fun invoke(id: UserWalletId): Flow<Boolean> {
val userWalletsListManager = requireNotNull(walletsStateHolder.userWalletsListManager)
return userWalletsListManager.userWallets
.map { wallets ->
val wallet = wallets.firstOrNull { it.walletId == id }
if (wallet == null) {
false
} else {
wallet.scanResponse.card.backupStatus is CardDTO.BackupStatus.NoBackup
}
}
}
}

View file

@ -11,14 +11,12 @@ import com.tangem.features.tokendetails.impl.R
// TODO: Finalize notification strings [REDACTED_JIRA]
@Immutable
sealed class TokenDetailsNotification(
open val isVisible: Boolean = true,
open val config: NotificationConfig,
) {
data class RentInfo(
private val rentInfo: CryptoCurrencyWarning.Rent,
private val onCloseClick: () -> Unit,
override val isVisible: Boolean = true,
) : TokenDetailsNotification(
config = NotificationConfig(
title = TextReference.Res(R.string.send_network_fee_title),

View file

@ -1,11 +1,11 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
import com.tangem.common.extensions.cast
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
import com.tangem.utils.converter.Converter
import com.tangem.utils.extensions.removeBy
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@ -17,15 +17,9 @@ internal class TokenDetailsNotificationConverter(
return value.map(::mapToNotification).toImmutableList()
}
fun getStateRentInfoVisibility(
currentState: TokenDetailsState,
isVisible: Boolean,
): ImmutableList<TokenDetailsNotification> {
fun removeRentInfo(currentState: TokenDetailsState): ImmutableList<TokenDetailsNotification> {
val newNotifications = currentState.notifications.toMutableList()
val oldNotification = newNotifications.find { it is TokenDetailsNotification.RentInfo }
oldNotification?.let {
newNotifications.add(it.cast<TokenDetailsNotification.RentInfo>().copy(isVisible = isVisible))
}
newNotifications.removeBy { it is TokenDetailsNotification.RentInfo }
return newNotifications.toImmutableList()
}

View file

@ -139,9 +139,7 @@ internal class TokenDetailsStateFactory(
}
fun getRefreshedState(): TokenDetailsState {
val state = currentStateProvider()
return refreshStateConverter.convert(false)
.copy(notifications = notificationConverter.getStateRentInfoVisibility(state, true))
}
fun getStateWithReceiveBottomSheet(
@ -212,6 +210,6 @@ internal class TokenDetailsStateFactory(
fun getStateWithRemovedRentNotification(): TokenDetailsState {
val state = currentStateProvider()
return state.copy(notifications = notificationConverter.getStateRentInfoVisibility(state, false))
return state.copy(notifications = notificationConverter.removeRentInfo(state))
}
}

View file

@ -87,7 +87,7 @@ internal fun TokenDetailsScreen(state: TokenDetailsState) {
)
}
items(
items = state.notifications.filter { it.isVisible },
items = state.notifications,
key = { it.config::class.java },
contentType = { it.config::class.java },
itemContent = { Notification(config = it.config, modifier = itemModifier.animateItemPlacement()) },

View file

@ -35,6 +35,7 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import timber.log.Timber
@ -71,6 +72,7 @@ internal class TokenDetailsViewModel @Inject constructor(
private val marketPriceJobHolder = JobHolder()
private val refreshStateJobHolder = JobHolder()
private val networkStatusAutoUpdateStateJobHolder = JobHolder()
private var cryptoCurrencyStatus: CryptoCurrencyStatus? = null
private var wallet by Delegates.notNull<UserWallet>()
@ -148,7 +150,6 @@ internal class TokenDetailsViewModel @Inject constructor(
getCurrencyStatusUpdatesUseCase(
userWalletId = selectedWallet.walletId,
currencyId = cryptoCurrency.id,
refresh = true,
)
.distinctUntilChanged()
.onEach { either ->
@ -161,6 +162,17 @@ internal class TokenDetailsViewModel @Inject constructor(
.flowOn(dispatchers.io)
.launchIn(viewModelScope)
.saveIn(marketPriceJobHolder)
viewModelScope.launch(dispatchers.io) {
// Wait for blockchain updates pending transactions.
// Immediate update doesn't receive any changes.
delay(NETWORK_STATUS_AUTO_UPDATE_DELAY)
fetchCurrencyStatusUseCase.invoke(
userWalletId = wallet.walletId,
id = cryptoCurrency.id,
refresh = true,
)
}.saveIn(networkStatusAutoUpdateStateJobHolder)
}
private fun updateTxHistory(refresh: Boolean = false) {
@ -365,7 +377,7 @@ internal class TokenDetailsViewModel @Inject constructor(
refresh = true,
)
updateTxHistory(refresh = true)
updateWarnings(wallet)
uiState = stateFactory.getRefreshedState()
}.saveIn(refreshStateJobHolder)
}
@ -377,4 +389,8 @@ internal class TokenDetailsViewModel @Inject constructor(
override fun onCloseRentInfoNotification() {
uiState = stateFactory.getStateWithRemovedRentNotification()
}
companion object {
private const val NETWORK_STATUS_AUTO_UPDATE_DELAY = 1000L
}
}

View file

@ -43,6 +43,7 @@ internal object WalletPreviewData {
imageResId = R.drawable.ill_businessman_3d,
onRenameClick = { _, _ -> },
onDeleteClick = {},
cardCount = 1,
)
}
@ -65,6 +66,7 @@ internal object WalletPreviewData {
onDeleteClick = {},
balance = "8923,05 $",
additionalInfo = TextReference.Str("3 cards • Seed phrase"),
cardCount = 1,
)
}

View file

@ -34,6 +34,7 @@ internal sealed interface WalletCardState {
* @property onRenameClick lambda be invoked when Rename button is clicked
* @property onDeleteClick lambda be invoked when Delete button is clicked
* @property additionalInfo wallet additional info
* @property cardCount number of cards in the wallet
* @property balance wallet balance
*/
data class Content(
@ -43,6 +44,7 @@ internal sealed interface WalletCardState {
override val onRenameClick: (UserWalletId, String) -> Unit,
override val onDeleteClick: (UserWalletId) -> Unit,
val additionalInfo: TextReference,
val cardCount: Int?,
val balance: String,
) : WalletCardState
@ -55,6 +57,7 @@ internal sealed interface WalletCardState {
* @property onRenameClick lambda be invoked when Rename button is clicked
* @property onDeleteClick lambda be invoked when Delete button is clicked
* @property additionalInfo wallet additional info
* @property cardCount number of cards in the wallet
* @property balance wallet balance
*/
data class HiddenContent(
@ -65,6 +68,7 @@ internal sealed interface WalletCardState {
override val onDeleteClick: (UserWalletId) -> Unit,
val additionalInfo: TextReference,
val balance: String,
val cardCount: Int?,
) : WalletCardState
/**

View file

@ -11,6 +11,7 @@ import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
import com.tangem.feature.wallet.presentation.wallet.domain.getCardsCount
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
@ -96,6 +97,7 @@ internal class WalletSingleCurrencyLoadedBalanceConverter(
onRenameClick = selectedWallet.onRenameClick,
onDeleteClick = selectedWallet.onDeleteClick,
balance = formatFiatAmount(status = status, appCurrency = appCurrencyProvider()),
cardCount = currentWalletProvider().getCardsCount(),
)
}
is CryptoCurrencyStatus.Loading -> {

View file

@ -61,6 +61,13 @@ internal class WalletStateFactory(
private val hiddenStateConverter by lazy { HiddenStateConverter(currentStateProvider) }
private val walletUpdateCardCountConverter by lazy {
WalletUpdateCardCountConverter(
currentStateProvider,
currentWalletProvider,
)
}
private val tokenListErrorConverter by lazy {
TokenListErrorConverter(currentStateProvider)
}
@ -134,6 +141,8 @@ internal class WalletStateFactory(
fun getStateWithUpdatedWalletName(name: String): WalletState = walletRenameStateConverter.convert(value = name)
fun getStateWithUpdatedWalletCardCount(): WalletState = walletUpdateCardCountConverter.convert(Unit)
fun getUnlockedState(action: WalletsUpdateActionResolver.Action.UnlockWallet): WalletState {
return walletsUnlockStateConverter.convert(value = action)
}

View file

@ -0,0 +1,56 @@
package com.tangem.feature.wallet.presentation.wallet.state.factory
import com.tangem.common.Provider
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
import com.tangem.feature.wallet.presentation.wallet.domain.getCardsCount
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCardState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletsListConfig
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.toImmutableList
internal class WalletUpdateCardCountConverter(
private val currentStateProvider: Provider<WalletState>,
private val currentWalletProvider: Provider<UserWallet>,
) : Converter<Unit, WalletState> {
override fun convert(value: Unit): WalletState {
return when (val state = currentStateProvider()) {
is WalletState.ContentState -> {
state.copySealed(
walletsListConfig = state.walletsListConfig.refreshCardCount(),
)
}
is WalletState.Initial -> state
}
}
private fun WalletsListConfig.refreshCardCount(): WalletsListConfig {
return copy(
wallets = wallets
.mapIndexed { index, walletCard ->
if (index == selectedWalletIndex) {
when (walletCard) {
is WalletCardState.Content -> walletCard.copy(
additionalInfo = WalletAdditionalInfoFactory.resolve(
wallet = currentWalletProvider(),
),
cardCount = currentWalletProvider().getCardsCount(),
)
is WalletCardState.HiddenContent -> walletCard.copy(
additionalInfo = WalletAdditionalInfoFactory.resolve(
wallet = currentWalletProvider(),
),
cardCount = currentWalletProvider().getCardsCount(),
)
else -> walletCard
}
} else {
walletCard
}
}
.toImmutableList(),
)
}
}

View file

@ -6,6 +6,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.TokenList.FiatBalance
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
import com.tangem.feature.wallet.presentation.wallet.domain.getCardsCount
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCardState
import com.tangem.utils.converter.Converter
@ -54,6 +55,7 @@ internal class FiatBalanceToWalletCardConverter(
fiatCurrencySymbol = appCurrency.symbol,
),
additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = currentWalletProvider()),
cardCount = currentWalletProvider().getCardsCount(),
)
} else {
WalletCardState.Content(
@ -68,6 +70,7 @@ internal class FiatBalanceToWalletCardConverter(
fiatCurrencyCode = appCurrency.code,
fiatCurrencySymbol = appCurrency.symbol,
),
cardCount = currentWalletProvider().getCardsCount(),
)
}
}

View file

@ -25,6 +25,7 @@ internal class WalletHiddenBalanceStateConverter {
onRenameClick = content.onRenameClick,
onDeleteClick = content.onDeleteClick,
balance = content.balance,
cardCount = content.cardCount,
)
}
@ -37,6 +38,7 @@ internal class WalletHiddenBalanceStateConverter {
onRenameClick = hiddenContent.onRenameClick,
onDeleteClick = hiddenContent.onDeleteClick,
balance = hiddenContent.balance,
cardCount = hiddenContent.cardCount,
)
}
}

View file

@ -6,6 +6,8 @@ import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@ -16,9 +18,10 @@ import kotlin.collections.count
/**
* Wallet notifications list factory
*
* @property isDemoCardUseCase use case that check if card is demo
* @property isReadyToShowRateAppUseCase use case that check if card is user already rate app
* @property wasCardScannedUseCase use case that check if card was scanned
* @property isDemoCardUseCase use case that checks if card is demo
* @property isReadyToShowRateAppUseCase use case that checks if card is user already rate app
* @property wasCardScannedUseCase use case that checks if card was scanned
* @property isNeedToBackupUseCase use case that checks if wallet need backup cards
* @property clickIntents screen click intents
*
[REDACTED_AUTHOR]
@ -27,17 +30,20 @@ internal class WalletNotificationsListFactory(
private val isDemoCardUseCase: IsDemoCardUseCase,
private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
private val wasCardScannedUseCase: WasCardScannedUseCase,
private val isNeedToBackupUseCase: IsNeedToBackupUseCase,
private val clickIntents: WalletClickIntents,
) {
fun create(
selectedWalletId: UserWalletId,
cardTypesResolver: CardTypesResolver,
cryptoCurrencyList: List<CryptoCurrencyStatus>,
): Flow<ImmutableList<WalletNotification>> {
return combine(
flow = wasCardScannedUseCase(cardTypesResolver.getCardId()),
flow2 = isReadyToShowRateAppUseCase(),
) { wasCardScanned, isReadyToShowRating ->
flow3 = isNeedToBackupUseCase(selectedWalletId),
) { wasCardScanned, isReadyToShowRating, isNeedToBackup ->
buildList {
addCriticalNotifications(cardTypesResolver)
@ -45,7 +51,7 @@ internal class WalletNotificationsListFactory(
addRateTheAppNotification(isReadyToShowRating)
addWarningNotifications(cardTypesResolver, cryptoCurrencyList, wasCardScanned)
addWarningNotifications(cardTypesResolver, cryptoCurrencyList, wasCardScanned, isNeedToBackup)
}.toImmutableList()
}
}
@ -116,12 +122,13 @@ internal class WalletNotificationsListFactory(
cardTypesResolver: CardTypesResolver,
cryptoCurrencyList: List<CryptoCurrencyStatus>,
wasCardScanned: Boolean,
isNeedToBackup: Boolean,
) {
addIf(
element = WalletNotification.Warning.MissingBackup(
onStartBackupClick = clickIntents::onBackupCardClick,
),
condition = !cardTypesResolver.isBackupForbidden() && !cardTypesResolver.hasBackup(),
condition = isNeedToBackup,
)
val isDemo = isDemoCardUseCase(cardId = cardTypesResolver.getCardId())

View file

@ -122,6 +122,7 @@ internal class WalletViewModel @Inject constructor(
wasCardScannedUseCase: WasCardScannedUseCase,
isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
isDemoCardUseCase: IsDemoCardUseCase,
isNeedToBackupUseCase: IsNeedToBackupUseCase,
// endregion Parameters
) : ViewModel(), DefaultLifecycleObserver, WalletClickIntents {
@ -135,6 +136,7 @@ internal class WalletViewModel @Inject constructor(
wasCardScannedUseCase = wasCardScannedUseCase,
isReadyToShowRateAppUseCase = isReadyToShowRateAppUseCase,
isDemoCardUseCase = isDemoCardUseCase,
isNeedToBackupUseCase = isNeedToBackupUseCase,
clickIntents = this,
)
@ -227,6 +229,9 @@ internal class WalletViewModel @Inject constructor(
is WalletsUpdateActionResolver.Action.AddWallet -> {
scrollAndUpdateState(action.selectedWalletIndex)
}
is WalletsUpdateActionResolver.Action.UpdateWalletCardCount -> {
uiState = stateFactory.getStateWithUpdatedWalletCardCount()
}
is WalletsUpdateActionResolver.Action.Unknown -> Unit
}
}
@ -983,6 +988,7 @@ internal class WalletViewModel @Inject constructor(
private fun updateNotifications(index: Int, tokenList: TokenList? = null) {
notificationsListFactory.create(
selectedWalletId = getWallet(index).walletId,
cardTypesResolver = getCardTypeResolver(index = index),
cryptoCurrencyList = if (tokenList != null) {
when (tokenList) {

View file

@ -4,6 +4,7 @@ import com.tangem.common.Provider
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
import com.tangem.feature.wallet.presentation.wallet.domain.getCardsCount
import com.tangem.feature.wallet.presentation.wallet.state.WalletLockedState
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCardState
@ -110,20 +111,29 @@ internal class WalletsUpdateActionResolver(
selectedWallet: UserWallet,
): Action {
val selectedWalletName = selectedWallet.name
val previousWalletState = state.getPrevSelectedWallet()
return when {
previousWalletState.title != selectedWalletName -> {
Action.UpdateWalletName(selectedWalletName)
}
if (state.getPrevSelectedWallet().title != selectedWalletName) {
return Action.UpdateWalletName(selectedWalletName)
state is WalletLockedState && !selectedWallet.isLocked -> {
Action.UnlockWallet(
selectedWalletIndex = wallets.indexOfWallet(id = selectedWallet.walletId),
selectedWallet = selectedWallet,
unlockedWallets = wallets.filterNot(UserWallet::isLocked),
)
}
previousWalletState is WalletCardState.Content &&
previousWalletState.cardCount != selectedWallet.getCardsCount() ||
previousWalletState is WalletCardState.HiddenContent &&
previousWalletState.cardCount != selectedWallet.getCardsCount() -> {
Action.UpdateWalletCardCount
}
else -> Action.Unknown
}
if (state is WalletLockedState && !selectedWallet.isLocked) {
return Action.UnlockWallet(
selectedWalletIndex = wallets.indexOfWallet(id = selectedWallet.walletId),
selectedWallet = selectedWallet,
unlockedWallets = wallets.filterNot(UserWallet::isLocked),
)
}
return Action.Unknown
}
private fun WalletState.ContentState.getPrevSelectedWallet(): WalletCardState {
@ -163,6 +173,8 @@ internal class WalletsUpdateActionResolver(
data class AddWallet(val selectedWalletIndex: Int) : Action()
object UpdateWalletCardCount : Action()
object Unknown : Action()
}
}