Updated on 2026-08-14

This commit is contained in:
Tangem 2023-09-04 13:31:17 +08:00
parent 1061426e87
commit 343c3ad9fb
16 changed files with 340 additions and 37 deletions

View file

@ -117,6 +117,22 @@ internal object TokensDomainModule {
return GetCryptoCurrencyActionsUseCase(rampStateManager, marketCryptoCurrencyRepository, dispatchers)
}
@Provides
@ViewModelScoped
fun provideGetCurrencyStatusByNetworkUseCase(
currenciesRepository: CurrenciesRepository,
quotesRepository: QuotesRepository,
networksRepository: NetworksRepository,
dispatchers: CoroutineDispatcherProvider,
): GetNetworkCoinStatusUseCase {
return GetNetworkCoinStatusUseCase(
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
networksRepository = networksRepository,
dispatchers = dispatchers,
)
}
@Provides
@ViewModelScoped
fun provideGetCurrenciesUseCase(currenciesRepository: CurrenciesRepository): GetCryptoCurrenciesUseCase {

View file

@ -18,9 +18,11 @@ import com.tangem.feature.swap.presentation.SwapFragment
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Token
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
import com.tangem.tap.common.extensions.dispatchErrorNotification
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchOpenUrl
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.tokens.getIconUrl
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
@ -39,7 +41,10 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import com.tangem.feature.swap.domain.models.domain.Currency as SwapCurrency
@Suppress("LargeClass")
class TradeCryptoMiddleware {
@Suppress("LongMethod", "CyclomaticComplexMethod")
fun handle(state: () -> AppState?, action: TradeCryptoAction) {
if (DemoHelper.tryHandle(state, action)) return
@ -52,11 +57,10 @@ class TradeCryptoMiddleware {
openSwap(currency = store.state.walletState.selectedWalletData?.currency?.toSwapCurrency())
}
is TradeCryptoAction.New.Buy -> proceedNewBuyAction(state, action)
TradeCryptoAction.New.Send -> store.dispatch(WalletAction.Send())
is TradeCryptoAction.New.Sell -> proceedNewSellAction(action)
is TradeCryptoAction.New.Swap -> {
openSwap(currency = action.cryptoCurrency.toSwapCurrency())
}
is TradeCryptoAction.New.Swap -> openSwap(currency = action.cryptoCurrency.toSwapCurrency())
is TradeCryptoAction.New.SendToken -> handleNewSendToken(action = action)
is TradeCryptoAction.New.SendCoin -> handleNewSendCoin(action = action)
}
}
@ -301,4 +305,98 @@ class TradeCryptoMiddleware {
)
}
}
private fun handleNewSendToken(action: TradeCryptoAction.New.SendToken) {
val cryptoStatus = action.tokenStatus
val currency = cryptoStatus.currency
val blockchain = Blockchain.fromId(currency.network.id.value)
scope.launch {
val walletManager = store.state.daggerGraphState
.get(DaggerGraphState::walletManagersFacade)
.getOrCreateWalletManager(
userWallet = action.userWallet,
blockchain = blockchain,
derivationPath = blockchain.derivationPath(
style = action.userWallet.scanResponse.derivationStyleProvider.getDerivationStyle(),
),
)
if (walletManager == null) {
val error = TapError.UnsupportedState(stateError = "WalletManager is null")
FirebaseCrashlytics.getInstance().recordException(IllegalStateException(error.stateError))
store.dispatchErrorNotification(error)
return@launch
}
val sendableAmounts = walletManager.wallet.amounts.values.filter { it.type is AmountType.Token }
when (currency) {
is CryptoCurrency.Coin -> error("Action.tokenStatus.currency is Coin")
is CryptoCurrency.Token -> {
store.dispatchOnMain(
action = PrepareSendScreen(
walletManager = walletManager,
coinAmount = walletManager.wallet.amounts[AmountType.Coin],
coinRate = action.coinFiatRate,
tokenAmount = sendableAmounts.first(),
tokenRate = cryptoStatus.value.fiatRate,
),
)
}
}
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Send))
}
}
private fun handleNewSendCoin(action: TradeCryptoAction.New.SendCoin) {
val cryptoStatus = action.coinStatus
val currency = cryptoStatus.currency
val blockchain = Blockchain.fromId(currency.network.id.value)
scope.launch {
val walletManager = store.state.daggerGraphState
.get(DaggerGraphState::walletManagersFacade)
.getOrCreateWalletManager(
userWallet = action.userWallet,
blockchain = blockchain,
derivationPath = blockchain.derivationPath(
style = action.userWallet.scanResponse.derivationStyleProvider.getDerivationStyle(),
),
)
if (walletManager == null) {
val error = TapError.UnsupportedState(stateError = "WalletManager is null")
FirebaseCrashlytics.getInstance().recordException(IllegalStateException(error.stateError))
store.dispatchErrorNotification(error)
return@launch
}
val sendableAmounts = walletManager.wallet.amounts.values.filter { it.type == AmountType.Coin }
when (currency) {
is CryptoCurrency.Coin -> {
val amountToSend = sendableAmounts.find { it.currencySymbol == currency.symbol }
if (amountToSend == null) {
val error = TapError.UnsupportedState(stateError = "Amount to send is null")
FirebaseCrashlytics.getInstance()
.recordException(IllegalStateException(error.stateError))
store.dispatchErrorNotification(error)
return@launch
}
store.dispatchOnMain(
action = PrepareSendScreen(
walletManager = walletManager,
coinAmount = amountToSend,
coinRate = cryptoStatus.value.fiatRate,
),
)
}
is CryptoCurrency.Token -> error("Action.tokenStatus.currency is Token")
}
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Send))
}
}
}

View file

@ -1,5 +1,6 @@
package com.tangem.data.tokens.repository
import com.tangem.blockchain.common.Blockchain
import com.tangem.data.common.cache.CacheRegistry
import com.tangem.data.tokens.utils.*
import com.tangem.datasource.api.tangemTech.TangemTechApi
@ -7,10 +8,12 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.local.token.UserMarketCoinsStore
import com.tangem.datasource.local.token.UserTokensStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.extensions.toNetworkId
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.core.error.DataError
import com.tangem.domain.demo.DemoConfig
import com.tangem.domain.tokens.models.CryptoCurrency
import com.tangem.domain.tokens.models.Network
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
@ -190,6 +193,27 @@ internal class DefaultCurrenciesRepository(
responseCurrenciesFactory.createCurrency(id, response, userWallet.scanResponse.card)
}
override suspend fun getNetworkCoin(userWalletId: UserWalletId, networkId: Network.ID): CryptoCurrency.Coin {
val userWallet = getUserWallet(userWalletId)
ensureIsCorrectUserWallet(userWallet = userWallet, isMultiCurrencyWalletExpected = true)
fetchTokensIfCacheExpired(userWallet = userWallet, refresh = false)
val storedTokens = requireNotNull(userTokensStore.getSyncOrNull(userWallet.walletId)) {
"Unable to find tokens response for user wallet with provided ID: $userWalletId"
}
val storedCoin = storedTokens.tokens.find { it.networkId == Blockchain.fromId(networkId.value).toNetworkId() }
?: error("Coin in this network $networkId not found")
val coin = responseCurrenciesFactory.createCurrency(
responseToken = storedCoin,
card = userWallet.scanResponse.card,
)
return coin as? CryptoCurrency.Coin ?: error("Unable to create currency")
}
override fun isTokensGrouped(userWalletId: UserWalletId): Flow<Boolean> {
return channelFlow {
ensureIsCorrectUserWallet(userWalletId, isMultiCurrencyWalletExpected = true)

View file

@ -28,7 +28,7 @@ internal class ResponseCurrenciesFactory(private val demoConfig: DemoConfig) {
return response.tokens.mapNotNull { createCurrency(it, card) }
}
private fun createCurrency(responseToken: UserTokensResponse.Token, card: CardDTO): CryptoCurrency? {
fun createCurrency(responseToken: UserTokensResponse.Token, card: CardDTO): CryptoCurrency? {
var blockchain = Blockchain.fromNetworkId(responseToken.networkId)
if (blockchain == null || blockchain == Blockchain.Unknown) {
Timber.e("Unable to find a blockchain with the network ID: ${responseToken.networkId}")

View file

@ -0,0 +1,53 @@
package com.tangem.domain.tokens
import arrow.core.Either
import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.domain.tokens.error.mapper.mapToCurrencyError
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.models.Network
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
import com.tangem.domain.tokens.repository.CurrenciesRepository
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 kotlinx.coroutines.flow.*
class GetNetworkCoinStatusUseCase(
private val currenciesRepository: CurrenciesRepository,
private val quotesRepository: QuotesRepository,
private val networksRepository: NetworksRepository,
private val dispatchers: CoroutineDispatcherProvider,
) {
operator fun invoke(
userWalletId: UserWalletId,
networkId: Network.ID,
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
return flow {
emitAll(
flow = getCurrency(
userWalletId = userWalletId,
networkId = networkId,
),
)
}
.flowOn(dispatchers.io)
}
private suspend fun getCurrency(
userWalletId: UserWalletId,
networkId: Network.ID,
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
val operations = CurrenciesStatusesOperations(
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
networksRepository = networksRepository,
userWalletId = userWalletId,
)
return operations.getNetworkCoinFlow(networkId).map { maybeCurrency ->
maybeCurrency.mapLeft(CurrenciesStatusesOperations.Error::mapToCurrencyError)
}
}
}

View file

@ -4,6 +4,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.models.CryptoCurrency
import com.tangem.domain.wallets.models.UserWallet
import org.rekotlin.Action
import java.math.BigDecimal
sealed class TradeCryptoAction : Action {
@ -36,7 +37,13 @@ sealed class TradeCryptoAction : Action {
val appCurrencyCode: String,
) : New()
object Send : New()
data class SendToken(
val userWallet: UserWallet,
val tokenStatus: CryptoCurrencyStatus,
val coinFiatRate: BigDecimal?,
) : New()
data class SendCoin(val userWallet: UserWallet, val coinStatus: CryptoCurrencyStatus) : New()
data class Swap(val cryptoCurrency: CryptoCurrency) : New()
}

View file

@ -80,6 +80,15 @@ internal class CurrenciesStatusesOperations(
return getCurrencyStatusFlow(currency)
}
suspend fun getNetworkCoinFlow(networkId: Network.ID): Flow<Either<Error, CryptoCurrencyStatus>> {
val currency = recover(
block = { getNetworkCoin(networkId) },
recover = { return flowOf(it.left()) },
)
return getCurrencyStatusFlow(currency)
}
suspend fun getPrimaryCurrencyStatusFlow(): Flow<Either<Error, CryptoCurrencyStatus>> {
val currency = recover(
block = { getPrimaryCurrency() },
@ -177,6 +186,12 @@ internal class CurrenciesStatusesOperations(
.bind()
}
private suspend fun Raise<Error>.getNetworkCoin(networkId: Network.ID): CryptoCurrency {
return Either.catch { currenciesRepository.getNetworkCoin(userWalletId, networkId) }
.mapLeft { Error.DataError(it) }
.bind()
}
private suspend fun Raise<Error>.getPrimaryCurrency(): CryptoCurrency {
return catch(
block = { currenciesRepository.getSingleCurrencyWalletPrimaryCurrency(userWalletId) },

View file

@ -1,6 +1,7 @@
package com.tangem.domain.tokens.repository
import com.tangem.domain.tokens.models.CryptoCurrency
import com.tangem.domain.tokens.models.Network
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.flow.Flow
@ -103,6 +104,14 @@ interface CurrenciesRepository {
*/
suspend fun getMultiCurrencyWalletCurrency(userWalletId: UserWalletId, id: CryptoCurrency.ID): CryptoCurrency
/**
* Get the coin for a specific network.
*
* @param userWalletId The unique identifier of the user wallet.
* @param networkId The unique identifier of the network.
*/
suspend fun getNetworkCoin(userWalletId: UserWalletId, networkId: Network.ID): CryptoCurrency.Coin
/**
* Determines whether the tokens within a specific multi-currency user wallet are grouped.
*

View file

@ -4,6 +4,7 @@ import arrow.core.Either
import arrow.core.getOrElse
import com.tangem.domain.core.error.DataError
import com.tangem.domain.tokens.models.CryptoCurrency
import com.tangem.domain.tokens.models.Network
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
@ -74,6 +75,10 @@ internal class MockCurrenciesRepository(
return token
}
override suspend fun getNetworkCoin(userWalletId: UserWalletId, networkId: Network.ID): CryptoCurrency.Coin {
TODO("Not yet implemented")
}
override fun isTokensGrouped(userWalletId: UserWalletId): Flow<Boolean> {
return isGrouped.map { it.getOrElse { e -> throw e } }
}

View file

@ -11,8 +11,9 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
import com.tangem.domain.tokens.RemoveCurrencyUseCase
import com.tangem.domain.tokens.GetCurrencyStatusUpdatesUseCase
import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
import com.tangem.domain.tokens.RemoveCurrencyUseCase
import com.tangem.domain.tokens.legacy.TradeCryptoAction
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.models.CryptoCurrency
@ -48,6 +49,7 @@ internal class TokenDetailsViewModel @Inject constructor(
private val getExploreUrlUseCase: GetExploreUrlUseCase,
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
private val removeCurrencyUseCase: RemoveCurrencyUseCase,
private val getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
private val reduxStateHolder: ReduxStateHolder,
savedStateHandle: SavedStateHandle,
) : ViewModel(), DefaultLifecycleObserver, TokenDetailsClickIntents {
@ -169,7 +171,40 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onSendClick() {
reduxStateHolder.dispatch(TradeCryptoAction.New.Send)
val cryptoCurrencyStatus = cryptoCurrencyStatus ?: return
when (cryptoCurrencyStatus.currency) {
is CryptoCurrency.Coin -> {
reduxStateHolder.dispatch(
action = TradeCryptoAction.New.SendCoin(
userWallet = wallet,
coinStatus = cryptoCurrencyStatus,
),
)
}
is CryptoCurrency.Token -> sendToken(status = cryptoCurrencyStatus)
}
}
private fun sendToken(status: CryptoCurrencyStatus) {
viewModelScope.launch(dispatchers.io) {
getNetworkCoinStatusUseCase(
userWalletId = wallet.walletId,
networkId = status.currency.network.id,
)
.take(count = 1)
.collectLatest {
it.onRight { coinStatus ->
reduxStateHolder.dispatch(
action = TradeCryptoAction.New.SendToken(
userWallet = wallet,
tokenStatus = status,
coinFiatRate = coinStatus.value.fiatRate,
),
)
}
}
}
}
override fun onReceiveClick() {

View file

@ -1,36 +1,32 @@
package com.tangem.feature.wallet.presentation.wallet.state.factory
import com.tangem.common.Provider
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.common.state.TokenItemState
import com.tangem.feature.wallet.presentation.wallet.state.TokenActionButtonConfig
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
/**
* Converter from loaded [TokenItemState.Content] to ImmutableList<[TokenActionButtonConfig]>
*
* @property currentStateProvider current ui state provider
* @property clickIntents screen click intents
*
*/
@Suppress("UnusedPrivateMember")
internal class TokenActionsProvider(
private val currentStateProvider: Provider<WalletState>,
) {
internal class TokenActionsProvider(private val clickIntents: WalletClickIntents) {
@Suppress("UnusedPrivateMember")
fun provideActions(tokenId: String): ImmutableList<TokenActionButtonConfig> {
fun provideActions(cryptoCurrencyStatus: CryptoCurrencyStatus): ImmutableList<TokenActionButtonConfig> {
// TODO: [REDACTED_JIRA]
return mockTokenActionButtonConfig().toImmutableList()
return mockTokenActionButtonConfig(cryptoCurrencyStatus).toImmutableList()
}
private fun mockTokenActionButtonConfig(): List<TokenActionButtonConfig> {
private fun mockTokenActionButtonConfig(cryptoCurrencyStatus: CryptoCurrencyStatus): List<TokenActionButtonConfig> {
return listOf(
TokenActionButtonConfig(
text = "Send",
iconResId = R.drawable.ic_plus_24,
onClick = {},
onClick = { clickIntents.onMultiCurrencySendClick(cryptoCurrencyStatus) },
),
TokenActionButtonConfig(
text = "Buy",

View file

@ -40,7 +40,10 @@ internal class WalletCryptoCurrencyActionsConverter(
WalletManageButton.Sell(enabled = action.enabled, onClick = clickIntents::onSellClick)
}
is TokenActionsState.ActionState.Send -> {
WalletManageButton.Send(enabled = action.enabled, onClick = clickIntents::onSendClick)
WalletManageButton.Send(
enabled = action.enabled,
onClick = clickIntents::onSingleCurrencySendClick,
)
}
is TokenActionsState.ActionState.Swap -> null
}

View file

@ -44,7 +44,7 @@ internal class WalletStateFactory(
private val clickIntents: WalletClickIntents,
) {
private val tokenActionsProvider by lazy { TokenActionsProvider(currentStateProvider = currentStateProvider) }
private val tokenActionsProvider by lazy { TokenActionsProvider(clickIntents) }
private val skeletonConverter by lazy { WalletSkeletonStateConverter(currentStateProvider, clickIntents) }
private val tokenListErrorConverter by lazy {
@ -185,12 +185,12 @@ internal class WalletStateFactory(
}
}
fun getStateWithTokenActionBottomSheet(tokenId: String): WalletState {
fun getStateWithTokenActionBottomSheet(currencyStatus: CryptoCurrencyStatus): WalletState {
return when (val state = currentStateProvider() as WalletState.ContentState) {
is WalletMultiCurrencyState.Content -> state.copy(
tokenActionsBottomSheet = ActionsBottomSheetConfig(
isShow = true,
actions = tokenActionsProvider.provideActions(tokenId = tokenId),
actions = tokenActionsProvider.provideActions(currencyStatus),
onDismissRequest = clickIntents::onDismissActionsBottomSheet,
),
)

View file

@ -50,7 +50,7 @@ internal class CryptoCurrencyStatusToTokenItemConverter(
)
},
onItemClick = { clickIntents.onTokenItemClick(currency) },
onItemLongClick = { clickIntents.onTokenItemLongClick(currency) },
onItemLongClick = { clickIntents.onTokenItemLongClick(cryptoCurrencyStatus = this) },
)
}

View file

@ -1,6 +1,7 @@
package com.tangem.feature.wallet.presentation.wallet.viewmodels
import com.tangem.core.ui.components.transactions.intents.TxHistoryClickIntents
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.models.CryptoCurrency
import com.tangem.domain.wallets.models.UserWalletId
@ -39,7 +40,7 @@ internal interface WalletClickIntents : TxHistoryClickIntents {
fun onTokenItemClick(currency: CryptoCurrency)
fun onTokenItemLongClick(currency: CryptoCurrency)
fun onTokenItemLongClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
fun onDismissActionsBottomSheet()
@ -47,7 +48,9 @@ internal interface WalletClickIntents : TxHistoryClickIntents {
fun onDeleteClick(userWalletId: UserWalletId)
fun onSendClick()
fun onSingleCurrencySendClick(cryptoCurrencyStatus: CryptoCurrencyStatus? = null)
fun onMultiCurrencySendClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
fun onReceiveClick()

View file

@ -74,6 +74,7 @@ internal class WalletViewModel @Inject constructor(
private val fetchTokenListUseCase: FetchTokenListUseCase,
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
private val getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
private val getCardWasScannedUseCase: GetCardWasScannedUseCase,
private val isUserAlreadyRateAppUseCase: IsUserAlreadyRateAppUseCase,
private val isDemoCardUseCase: IsDemoCardUseCase,
@ -121,7 +122,7 @@ internal class WalletViewModel @Inject constructor(
var uiState: WalletState by uiStateHolder(initialState = stateFactory.getInitialState())
private var wallets: List<UserWallet> by Delegates.notNull()
private var cryptoCurrencyStatus: CryptoCurrencyStatus? = null
private var singleWalletCryptoCurrencyStatus: CryptoCurrencyStatus? = null
private val tokensJobHolder = JobHolder()
private val marketPriceJobHolder = JobHolder()
@ -300,7 +301,7 @@ internal class WalletViewModel @Inject constructor(
override fun onBuyClick() {
val state = uiState as? WalletState.ContentState ?: return
val status = cryptoCurrencyStatus ?: return
val status = singleWalletCryptoCurrencyStatus ?: return
val wallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
reduxStateHolder.dispatch(
@ -312,8 +313,48 @@ internal class WalletViewModel @Inject constructor(
)
}
override fun onSendClick() {
reduxStateHolder.dispatch(TradeCryptoAction.New.Send)
override fun onSingleCurrencySendClick(cryptoCurrencyStatus: CryptoCurrencyStatus?) {
val state = uiState as? WalletState.ContentState ?: return
val userWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
val coinStatus = if (userWallet.isMultiCurrency) cryptoCurrencyStatus else singleWalletCryptoCurrencyStatus
reduxStateHolder.dispatch(
action = TradeCryptoAction.New.SendCoin(
userWallet = userWallet,
coinStatus = coinStatus ?: return,
),
)
}
override fun onMultiCurrencySendClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
if (cryptoCurrencyStatus.currency is CryptoCurrency.Coin) {
onSingleCurrencySendClick(cryptoCurrencyStatus = cryptoCurrencyStatus)
return
}
val state = uiState as? WalletState.ContentState ?: return
viewModelScope.launch(dispatchers.io) {
val userWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
getNetworkCoinStatusUseCase(
userWalletId = userWallet.walletId,
networkId = cryptoCurrencyStatus.currency.network.id,
)
.take(count = 1)
.collectLatest {
it.onRight { coinStatus ->
reduxStateHolder.dispatch(
action = TradeCryptoAction.New.SendToken(
userWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex),
tokenStatus = cryptoCurrencyStatus,
coinFiatRate = coinStatus.value.fiatRate,
),
)
}
}
}
}
override fun onReceiveClick() {
@ -321,7 +362,7 @@ internal class WalletViewModel @Inject constructor(
}
override fun onSellClick() {
val status = cryptoCurrencyStatus ?: return
val status = singleWalletCryptoCurrencyStatus ?: return
reduxStateHolder.dispatch(
TradeCryptoAction.New.Sell(
@ -384,10 +425,8 @@ internal class WalletViewModel @Inject constructor(
router.openTokenDetails(currency = currency)
}
override fun onTokenItemLongClick(currency: CryptoCurrency) {
uiState = stateFactory.getStateWithTokenActionBottomSheet(
tokenId = currency.id.value,
)
override fun onTokenItemLongClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
uiState = stateFactory.getStateWithTokenActionBottomSheet(cryptoCurrencyStatus)
}
override fun onRenameClick(userWalletId: UserWalletId, name: String) {
@ -504,7 +543,7 @@ internal class WalletViewModel @Inject constructor(
uiState = stateFactory.getSingleCurrencyLoadedBalanceState(maybeCryptoCurrencyStatus)
maybeCryptoCurrencyStatus.onRight { status ->
cryptoCurrencyStatus = status
singleWalletCryptoCurrencyStatus = status
updateButtons(userWalletId = userWalletId, currency = status.currency)
}
}