diff --git a/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt index 26161f3d76..07c16b3c3f 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt @@ -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) + } } \ No newline at end of file diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/ObserveAndClearNFTCacheIfNeedUseCase.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/ObserveAndClearNFTCacheIfNeedUseCase.kt new file mode 100644 index 0000000000..dec9562a2a --- /dev/null +++ b/domain/nft/src/main/kotlin/com/tangem/domain/nft/ObserveAndClearNFTCacheIfNeedUseCase.kt @@ -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> = 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 Flow.mapDiff(diff: (old: T, new: T) -> R): Flow = flow { + var previous: T? = null + collect { current -> + val prev = previous + if (prev != null) { + emit(diff(prev, current)) + } + previous = current + } + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt index 1fe0628b59..2360c86709 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt @@ -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() @@ -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) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt index 62325f8bfe..007c74fcc6 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt @@ -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( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt index 44aa146b20..9cdb3f5767 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt @@ -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, ) } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/WalletNFTListSubscriber.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/WalletNFTListSubscriber.kt index 57ed2a8b6d..329dc0268c 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/WalletNFTListSubscriber.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/WalletNFTListSubscriber.kt @@ -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,