Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-19 17:16:47 +05:00
parent 2689850df0
commit c8e19f4cd6
6 changed files with 74 additions and 5 deletions

View file

@ -127,4 +127,13 @@ internal object NFTDomainModule {
fun provideGetWalletNFTEnabledUseCase(walletsRepository: WalletsRepository): GetWalletNFTEnabledUseCase {
return GetWalletNFTEnabledUseCase(walletsRepository)
}
@Provides
@Singleton
fun provideClearNFTCacheUseCase(
nftRepository: NFTRepository,
currenciesRepository: CurrenciesRepository,
): ObserveAndClearNFTCacheIfNeedUseCase {
return ObserveAndClearNFTCacheIfNeedUseCase(nftRepository, currenciesRepository)
}
}

View file

@ -0,0 +1,38 @@
package com.tangem.domain.nft
import com.tangem.domain.nft.repository.NFTRepository
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.flow.*
class ObserveAndClearNFTCacheIfNeedUseCase(
private val nftRepository: NFTRepository,
private val currenciesRepository: CurrenciesRepository,
) {
operator fun invoke(userWalletId: UserWalletId): Flow<Set<Network>> = currenciesRepository
.getWalletCurrenciesUpdates(userWalletId)
.map { it.map(CryptoCurrency::network) }
.mapDiff { old, new ->
// calculate networks sets difference to determine which networks were removed
old.toSet() - new.toSet()
}
.distinctUntilChanged()
.onEach { removedNetworks ->
if (removedNetworks.isNotEmpty()) {
nftRepository.clearCache(userWalletId, removedNetworks.toList())
}
}
private fun <T, R> Flow<T>.mapDiff(diff: (old: T, new: T) -> R): Flow<R> = flow {
var previous: T? = null
collect { current ->
val prev = previous
if (prev != null) {
emit(diff(prev, current))
}
previous = current
}
}
}

View file

@ -16,6 +16,7 @@ import com.tangem.core.deeplink.DeepLinksRegistry
import com.tangem.core.deeplink.global.ReferralDeepLink
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.nft.ObserveAndClearNFTCacheIfNeedUseCase
import com.tangem.domain.settings.*
import com.tangem.domain.tokens.FetchCurrencyStatusUseCase
import com.tangem.domain.tokens.RefreshMultiCurrencyWalletQuotesUseCase
@ -84,6 +85,7 @@ internal class WalletModel @Inject constructor(
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
private val appRouter: AppRouter,
private val routingFeatureToggle: RoutingFeatureToggle,
private val observeAndClearNFTCacheIfNeedUseCase: ObserveAndClearNFTCacheIfNeedUseCase,
val screenLifecycleProvider: ScreenLifecycleProvider,
val innerWalletRouter: InnerWalletRouter,
) : Model() {
@ -94,6 +96,7 @@ internal class WalletModel @Inject constructor(
private val walletsUpdateJobHolder = JobHolder()
private val refreshWalletJobHolder = JobHolder()
private val expressStatusJobHolder = JobHolder()
private val clearNFTCacheJobHolder = JobHolder()
private var needToRefreshWallet = false
private var expressTxStatusTaskScheduler = SingleTaskScheduler<Unit>()
@ -224,6 +227,7 @@ internal class WalletModel @Inject constructor(
}
subscribeOnExpressTransactionsUpdates(selectedWallet)
subscribeToScreenBackgroundState(selectedWallet)
observeAndClearNFTCacheIfNeedUseCase(selectedWallet)
}
.flowOn(dispatchers.main)
.launchIn(modelScope)
@ -283,6 +287,13 @@ internal class WalletModel @Inject constructor(
)
}
private fun observeAndClearNFTCacheIfNeedUseCase(selectedWallet: UserWallet) {
observeAndClearNFTCacheIfNeedUseCase
.invoke(selectedWallet.walletId)
.launchIn(modelScope)
.saveIn(clearNFTCacheJobHolder)
}
private fun needToRefreshTimer() {
modelScope.launch {
delay(REFRESH_WALLET_BACKGROUND_TIMER_MILLIS)

View file

@ -8,6 +8,7 @@ import com.tangem.domain.nft.GetNFTCollectionsUseCase
import com.tangem.domain.promo.GetStoryContentUseCase
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
@ -47,6 +48,7 @@ internal class MultiWalletContentLoader(
private val deepLinksRegistry: DeepLinksRegistry,
private val nftFeatureToggles: NFTFeatureToggles,
private val walletsRepository: WalletsRepository,
private val currenciesRepository: CurrenciesRepository,
private val routingFeatureToggle: RoutingFeatureToggle,
) : WalletContentLoader(id = userWallet.walletId) {
@ -72,6 +74,7 @@ internal class MultiWalletContentLoader(
stateHolder = stateHolder,
walletsRepository = walletsRepository,
clickIntents = clickIntents,
currenciesRepository = currenciesRepository,
).let(::add)
}
MultiWalletWarningsSubscriber(

View file

@ -8,6 +8,7 @@ import com.tangem.domain.nft.GetNFTCollectionsUseCase
import com.tangem.domain.promo.GetStoryContentUseCase
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
@ -42,6 +43,7 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
private val walletsRepository: WalletsRepository,
private val getNFTCollectionsUseCase: GetNFTCollectionsUseCase,
private val routingFeatureToggle: RoutingFeatureToggle,
private val currenciesRepository: CurrenciesRepository,
) {
fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): WalletContentLoader {
@ -65,6 +67,7 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
walletsRepository = walletsRepository,
getNFTCollectionsUseCase = getNFTCollectionsUseCase,
routingFeatureToggle = routingFeatureToggle,
currenciesRepository = currenciesRepository,
)
}
}

View file

@ -1,6 +1,7 @@
package com.tangem.feature.wallet.presentation.wallet.subscribers
import com.tangem.domain.nft.GetNFTCollectionsUseCase
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
@ -15,17 +16,21 @@ internal class WalletNFTListSubscriber(
private val userWallet: UserWallet,
private val stateHolder: WalletStateController,
private val walletsRepository: WalletsRepository,
private val currenciesRepository: CurrenciesRepository,
private val getNFTCollectionsUseCase: GetNFTCollectionsUseCase,
private val clickIntents: WalletClickIntents,
) : WalletSubscriber() {
@OptIn(ExperimentalCoroutinesApi::class)
override fun create(coroutineScope: CoroutineScope): Flow<*> = walletsRepository
.nftEnabledStatus(userWallet.walletId)
override fun create(coroutineScope: CoroutineScope): Flow<*> = combine(
walletsRepository.nftEnabledStatus(userWallet.walletId),
currenciesRepository.getWalletCurrenciesUpdates(userWallet.walletId),
) { nftEnabled, currencies -> nftEnabled to currencies }
.distinctUntilChanged()
.flatMapLatest { nftEnabled ->
// if NFT is enabled for this wallet, then start observing changes from store and apply transformer if need
if (nftEnabled) {
.flatMapLatest { (nftEnabled, currencies) ->
// if NFT is enabled for this wallet and there are currencies,
// then start observing changes from store and apply transformer if need
if (nftEnabled && currencies.isNotEmpty()) {
getNFTCollectionsUseCase(userWallet.walletId)
.shareIn(
scope = coroutineScope,