From 2d6bce9eb3a256ccb5202d0cc67297dc68c82380 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 24 Oct 2023 17:11:40 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/TokensDomainModule.kt | 12 +++++- .../tokens/GetCryptoCurrencyActionsUseCase.kt | 43 +++++++++++++++---- .../viewmodels/TokenDetailsViewModel.kt | 22 +++++----- .../wallet/viewmodels/WalletViewModel.kt | 18 +++++--- 4 files changed, 70 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt index e9a9087e06..925a5cf11c 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/TokensDomainModule.kt @@ -167,9 +167,19 @@ internal object TokensDomainModule { fun provideGetCryptoCurrencyActionsUseCase( rampStateManager: RampStateManager, marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository, + currenciesRepository: CurrenciesRepository, + quotesRepository: QuotesRepository, + networksRepository: NetworksRepository, dispatchers: CoroutineDispatcherProvider, ): GetCryptoCurrencyActionsUseCase { - return GetCryptoCurrencyActionsUseCase(rampStateManager, marketCryptoCurrencyRepository, dispatchers) + return GetCryptoCurrencyActionsUseCase( + rampManager = rampStateManager, + marketCryptoCurrencyRepository = marketCryptoCurrencyRepository, + currenciesRepository = currenciesRepository, + quotesRepository = quotesRepository, + networksRepository = networksRepository, + dispatchers = dispatchers, + ) } @Provides diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt index 718b412716..7c9c07eaf9 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt @@ -4,13 +4,16 @@ import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.TokenActionsState +import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations +import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.MarketCryptoCurrencyRepository +import com.tangem.domain.tokens.repository.NetworksRepository +import com.tangem.domain.tokens.repository.QuotesRepository import com.tangem.domain.wallets.models.UserWalletId import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.isNullOrZero -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.* /** * Use case to determine which TokenActions are available for a [CryptoCurrency] @@ -20,27 +23,48 @@ import kotlinx.coroutines.flow.flowOn class GetCryptoCurrencyActionsUseCase( private val rampManager: RampStateManager, private val marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository, + private val currenciesRepository: CurrenciesRepository, + private val quotesRepository: QuotesRepository, + private val networksRepository: NetworksRepository, private val dispatchers: CoroutineDispatcherProvider, ) { - operator fun invoke( + @OptIn(ExperimentalCoroutinesApi::class) + suspend operator fun invoke( userWalletId: UserWalletId, cryptoCurrencyStatus: CryptoCurrencyStatus, + isSingleWalletWithTokens: Boolean, ): Flow { - return flow { - val actionStates = createTokenActionsState(userWalletId, cryptoCurrencyStatus) - emit(actionStates) + val operations = CurrenciesStatusesOperations( + currenciesRepository = currenciesRepository, + quotesRepository = quotesRepository, + networksRepository = networksRepository, + userWalletId = userWalletId, + ) + val networkId = cryptoCurrencyStatus.currency.network.id + val networkFlow = if (isSingleWalletWithTokens) { + operations.getNetworkCoinForSingleWalletWithTokenFlow(networkId) + } else { + operations.getNetworkCoinFlow(networkId, cryptoCurrencyStatus.currency.network.derivationPath) + } + return networkFlow.mapLatest { maybeCoinStatus -> + createTokenActionsState( + userWalletId = userWalletId, + coinStatus = maybeCoinStatus.getOrNull(), + cryptoCurrencyStatus = cryptoCurrencyStatus, + ) }.flowOn(dispatchers.io) } private suspend fun createTokenActionsState( userWalletId: UserWalletId, + coinStatus: CryptoCurrencyStatus?, cryptoCurrencyStatus: CryptoCurrencyStatus, ): TokenActionsState { return TokenActionsState( walletId = userWalletId, cryptoCurrencyStatus = cryptoCurrencyStatus, - states = createListOfActions(userWalletId, cryptoCurrencyStatus), + states = createListOfActions(userWalletId, coinStatus, cryptoCurrencyStatus), ) } @@ -50,6 +74,7 @@ class GetCryptoCurrencyActionsUseCase( */ private suspend fun createListOfActions( userWalletId: UserWalletId, + coinStatus: CryptoCurrencyStatus?, cryptoCurrencyStatus: CryptoCurrencyStatus, ): List { val cryptoCurrency = cryptoCurrencyStatus.currency @@ -74,7 +99,7 @@ class GetCryptoCurrencyActionsUseCase( } // send - if (cryptoCurrencyStatus.value.amount.isNullOrZero()) { + if (cryptoCurrencyStatus.value.amount.isNullOrZero() || coinStatus?.value?.amount.isNullOrZero()) { disabledList.add(TokenActionsState.ActionState.Send(false)) } else { activeList.add(TokenActionsState.ActionState.Send(true)) diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt index 511b802dc1..5aedee9158 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt @@ -16,6 +16,7 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase import com.tangem.domain.balancehiding.ListenToFlipsUseCase +import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.tokens.* @@ -28,7 +29,6 @@ import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase import com.tangem.domain.walletmanager.WalletManagersFacade -import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase @@ -131,8 +131,14 @@ internal class TokenDetailsViewModel @Inject constructor( } } - private fun updateButtons(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus) { - getCryptoCurrencyActionsUseCase(userWalletId = userWalletId, cryptoCurrencyStatus = currencyStatus) + private suspend fun updateButtons(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus) { + val userWallet = getUserWalletUseCase(userWalletId).getOrElse { return } + getCryptoCurrencyActionsUseCase( + userWalletId = userWallet.walletId, + cryptoCurrencyStatus = currencyStatus, + isSingleWalletWithTokens = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), + ) + .conflate() .distinctUntilChanged() .onEach { uiState = stateFactory.getManageButtonsState(actions = it.states) } .flowOn(dispatchers.io) @@ -146,7 +152,7 @@ internal class TokenDetailsViewModel @Inject constructor( userWalletId = userWalletId, currencyStatus = cryptoCurrencyStatus, derivationPath = cryptoCurrency.network.derivationPath, - isSingleWalletWithTokens = isSingleWalletWithTokens(wallet), + isSingleWalletWithTokens = wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), ) .distinctUntilChanged() .onEach { uiState = stateFactory.getStateWithNotifications(it) } @@ -162,7 +168,7 @@ internal class TokenDetailsViewModel @Inject constructor( userWalletId = userWalletId, currencyId = cryptoCurrency.id, derivationPath = cryptoCurrency.network.derivationPath, - isSingleWalletWithTokens = isSingleWalletWithTokens(wallet), + isSingleWalletWithTokens = wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), ) .distinctUntilChanged() .onEach { either -> @@ -179,10 +185,6 @@ internal class TokenDetailsViewModel @Inject constructor( } } - private fun isSingleWalletWithTokens(userWallet: UserWallet): Boolean { - return userWallet.scanResponse.walletData?.token != null && !userWallet.isMultiCurrency - } - /** * @param refresh - invalidate cache and get data from remote * @param showItemsLoading - show loading items placeholder. @@ -283,7 +285,7 @@ internal class TokenDetailsViewModel @Inject constructor( userWalletId = userWalletId, networkId = status.currency.network.id, derivationPath = status.currency.network.derivationPath, - isSingleWalletWithTokens = isSingleWalletWithTokens(wallet), + isSingleWalletWithTokens = wallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), ).firstOrNull() maybeCoinStatus?.onRight { coinStatus -> diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt index e5fb404b49..cb4da3165e 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt @@ -882,10 +882,13 @@ internal class WalletViewModel @Inject constructor( } override fun onTokenItemLongClick(cryptoCurrencyStatus: CryptoCurrencyStatus) { - val state = uiState as? WalletState.ContentState ?: return - val userWallet = getWallet(state.walletsListConfig.selectedWalletIndex) + val userWallet = getSelectedWallet() viewModelScope.launch(dispatchers.io) { - getCryptoCurrencyActionsUseCase(userWallet.walletId, cryptoCurrencyStatus) + getCryptoCurrencyActionsUseCase( + userWalletId = userWallet.walletId, + cryptoCurrencyStatus = cryptoCurrencyStatus, + isSingleWalletWithTokens = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), + ) .take(count = 1) .collectLatest { uiState = stateFactory.getStateWithTokenActionBottomSheet(it) @@ -1262,8 +1265,13 @@ internal class WalletViewModel @Inject constructor( } } - private fun updateButtons(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus) { - getCryptoCurrencyActionsUseCase(userWalletId = userWalletId, cryptoCurrencyStatus = currencyStatus) + private suspend fun updateButtons(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus) { + val userWallet = getSelectedWallet() + getCryptoCurrencyActionsUseCase( + userWalletId = userWalletId, + cryptoCurrencyStatus = currencyStatus, + isSingleWalletWithTokens = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(), + ) .conflate() .distinctUntilChanged() .onEach { uiState = stateFactory.getSingleCurrencyManageButtonsState(actionsState = it) }