Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-24 17:11:40 +05:00
parent 14135be555
commit 2d6bce9eb3
4 changed files with 70 additions and 25 deletions

View file

@ -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

View file

@ -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<TokenActionsState> {
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<TokenActionsState.ActionState> {
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))

View file

@ -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 ->

View file

@ -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) }