Updated on 2026-08-14
This commit is contained in:
parent
ed6970db05
commit
207fe02586
15 changed files with 433 additions and 253 deletions
|
|
@ -16,6 +16,7 @@ import com.tangem.domain.wallets.models.UserWalletId
|
|||
import com.tangem.features.onramp.OnrampFeatureToggles
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.runCatching
|
||||
import com.tangem.utils.isNullOrZero
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -37,9 +38,13 @@ internal class DefaultRampManager(
|
|||
private val cryptoCurrencyConverter = CryptoCurrencyConverter(excludedBlockchains)
|
||||
|
||||
override fun isSellSupportedByService(cryptoCurrency: CryptoCurrency): Boolean {
|
||||
return exchangeService?.availableForSell(
|
||||
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
|
||||
) ?: false
|
||||
return runCatching {
|
||||
exchangeService?.availableForSell(
|
||||
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
|
||||
)
|
||||
}
|
||||
.getOrNull()
|
||||
?: false
|
||||
}
|
||||
|
||||
override suspend fun availableForBuy(
|
||||
|
|
@ -47,28 +52,38 @@ internal class DefaultRampManager(
|
|||
userWalletId: UserWalletId,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
): Boolean {
|
||||
return when {
|
||||
onrampFeatureToggles.isFeatureEnabled -> getOnrampAvailable(userWalletId, cryptoCurrency)
|
||||
exchangeService != null -> exchangeService.availableForBuy(
|
||||
scanResponse = scanResponse,
|
||||
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
|
||||
)
|
||||
else -> false
|
||||
return runCatching {
|
||||
when {
|
||||
onrampFeatureToggles.isFeatureEnabled -> getOnrampAvailable(userWalletId, cryptoCurrency)
|
||||
exchangeService != null -> exchangeService.availableForBuy(
|
||||
scanResponse = scanResponse,
|
||||
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
|
||||
)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
.getOrNull()
|
||||
?: false
|
||||
}
|
||||
|
||||
override suspend fun availableForSell(userWalletId: UserWalletId, status: CryptoCurrencyStatus): Boolean {
|
||||
val sellSupportedByService = isSellSupportedByService(cryptoCurrency = status.currency)
|
||||
return runCatching {
|
||||
val sellSupportedByService = isSellSupportedByService(cryptoCurrency = status.currency)
|
||||
|
||||
if (!sellSupportedByService) return false
|
||||
if (!sellSupportedByService) return false
|
||||
|
||||
val reason = getSendUnavailabilityReason(userWalletId, status)
|
||||
val reason = getSendUnavailabilityReason(userWalletId, status)
|
||||
|
||||
return reason == ScenarioUnavailabilityReason.None
|
||||
reason == ScenarioUnavailabilityReason.None
|
||||
}
|
||||
.getOrNull()
|
||||
?: false
|
||||
}
|
||||
|
||||
override suspend fun availableForSwap(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean {
|
||||
return getExchangeableFlag(userWalletId, cryptoCurrency) && !cryptoCurrency.isCustom
|
||||
return runCatching { getExchangeableFlag(userWalletId, cryptoCurrency) && !cryptoCurrency.isCustom }
|
||||
.getOrNull()
|
||||
?: false
|
||||
}
|
||||
|
||||
override fun getBuyInitializationStatus(): Flow<ExchangeServiceInitializationStatus> {
|
||||
|
|
@ -76,7 +91,7 @@ internal class DefaultRampManager(
|
|||
}
|
||||
|
||||
override suspend fun fetchBuyServiceData() {
|
||||
withContext(dispatchers.io) {
|
||||
runCatching(dispatchers.io) {
|
||||
buyService.invoke().update()
|
||||
}
|
||||
}
|
||||
|
|
@ -86,12 +101,12 @@ internal class DefaultRampManager(
|
|||
}
|
||||
|
||||
override suspend fun fetchSellServiceData() {
|
||||
withContext(dispatchers.io) {
|
||||
runCatching(dispatchers.io) {
|
||||
sellService.invoke().update()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSwapInitializationStatus(userWalletId: UserWalletId): Flow<ExchangeServiceInitializationStatus> {
|
||||
override fun getExpressInitializationStatus(userWalletId: UserWalletId): Flow<ExchangeServiceInitializationStatus> {
|
||||
return expressServiceLoader.getInitializationStatus(userWalletId)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -240,6 +240,11 @@ sealed class NotificationUM(val config: NotificationConfig) {
|
|||
onClick = onRefresh,
|
||||
),
|
||||
)
|
||||
|
||||
data object SwapNoAvailablePair : Warning(
|
||||
title = resourceReference(id = R.string.action_buttons_swap_no_available_pair_notification_title),
|
||||
subtitle = resourceReference(id = R.string.action_buttons_swap_no_available_pair_notification_message),
|
||||
)
|
||||
}
|
||||
|
||||
open class Info(
|
||||
|
|
|
|||
|
|
@ -39,5 +39,5 @@ interface RampStateManager {
|
|||
|
||||
fun getSellInitializationStatus(): Flow<Lce<Throwable, Any>>
|
||||
|
||||
fun getSwapInitializationStatus(userWalletId: UserWalletId): Flow<Lce<Throwable, Any>>
|
||||
fun getExpressInitializationStatus(userWalletId: UserWalletId): Flow<Lce<Throwable, Any>>
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.features.onramp.swap.availablepairs.entity.transformers
|
||||
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.feature.swap.domain.models.ExpressException
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class SetErrorWarningTransformer(
|
||||
private val cause: Throwable,
|
||||
private val onRefresh: () -> Unit,
|
||||
) : TokenListUMTransformer {
|
||||
|
||||
override fun transform(prevState: TokenListUM): TokenListUM {
|
||||
return prevState.copy(
|
||||
availableItems = persistentListOf(),
|
||||
unavailableItems = persistentListOf(),
|
||||
warning = NotificationUM.Warning.OnrampErrorNotification(
|
||||
errorCode = (cause as? ExpressException)?.expressDataError?.code?.toString(),
|
||||
onRefresh = onRefresh,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
|||
import com.tangem.features.onramp.swap.availablepairs.entity.converters.LoadingTokenListItemConverter
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
/**
|
||||
|
|
@ -18,6 +19,8 @@ internal class SetLoadingTokenItemsTransformer(
|
|||
override fun transform(prevState: TokenListUM): TokenListUM {
|
||||
return prevState.copy(
|
||||
availableItems = LoadingTokenListItemConverter.convertList(input = statuses).toImmutableList(),
|
||||
unavailableItems = persistentListOf(),
|
||||
warning = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.tangem.features.onramp.swap.availablepairs.entity.transformers
|
||||
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
||||
import com.tangem.features.onramp.tokenlist.entity.utils.OnrampTokenItemStateConverterFactory
|
||||
import com.tangem.features.onramp.tokenlist.entity.utils.addHeader
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class SetNoAvailablePairsTransformer(
|
||||
private val appCurrency: AppCurrency,
|
||||
private val unavailableStatuses: List<CryptoCurrencyStatus>,
|
||||
private val isBalanceHidden: Boolean,
|
||||
private val unavailableTokensHeaderReference: TextReference,
|
||||
) : TokenListUMTransformer {
|
||||
|
||||
override fun transform(prevState: TokenListUM): TokenListUM {
|
||||
val unavailableItems = OnrampTokenItemStateConverterFactory.createUnavailableItemConverter(appCurrency)
|
||||
.convertList(unavailableStatuses)
|
||||
.map(TokensListItemUM::Token)
|
||||
|
||||
return prevState.copy(
|
||||
availableItems = persistentListOf(),
|
||||
unavailableItems = unavailableItems.addHeader(textReference = unavailableTokensHeaderReference),
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
warning = NotificationUM.Warning.SwapNoAvailablePair,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,11 @@ import com.tangem.core.ui.extensions.wrappedList
|
|||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.core.utils.getOrElse
|
||||
import com.tangem.domain.core.utils.lceContent
|
||||
import com.tangem.domain.core.utils.lceError
|
||||
import com.tangem.domain.core.utils.lceLoading
|
||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
|
|
@ -19,9 +23,12 @@ import com.tangem.feature.swap.domain.models.domain.LeastTokenInfo
|
|||
import com.tangem.feature.swap.domain.models.domain.SwapPairLeast
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.swap.availablepairs.AvailableSwapPairsComponent
|
||||
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetErrorWarningTransformer
|
||||
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetLoadingTokenItemsTransformer
|
||||
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetNoAvailablePairsTransformer
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMController
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
||||
import com.tangem.features.onramp.tokenlist.entity.transformer.SetNothingToFoundStateTransformer
|
||||
import com.tangem.features.onramp.tokenlist.entity.transformer.UpdateTokenItemsTransformer
|
||||
import com.tangem.features.onramp.utils.InputManager
|
||||
|
|
@ -33,11 +40,13 @@ import kotlinx.coroutines.flow.*
|
|||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
private typealias AvailablePairsState = Lce<Throwable, List<SwapPairLeast>>
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class AvailableSwapPairsModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
getTokenListUseCase: GetTokenListUseCase,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val getTokenListUseCase: GetTokenListUseCase,
|
||||
private val tokenListUMController: TokenListUMController,
|
||||
private val searchManager: InputManager,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
|
|
@ -49,29 +58,37 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
|||
|
||||
private var params: AvailableSwapPairsComponent.Params = paramsContainer.require()
|
||||
|
||||
private val tokenListFlow = getTokenListUseCase.launch(userWalletId = params.userWalletId)
|
||||
.distinctUntilChanged()
|
||||
.map { maybeTokenList ->
|
||||
maybeTokenList.getOrElse(
|
||||
ifLoading = { it ?: TokenList.Empty },
|
||||
ifError = { TokenList.Empty },
|
||||
)
|
||||
.flattenCurrencies()
|
||||
}
|
||||
.shareIn(scope = modelScope, started = SharingStarted.Eagerly, replay = 1)
|
||||
private val tokenListFlow = getTokenListUseCaseFlow()
|
||||
|
||||
private val availablePairsByNetworkFlow = MutableStateFlow<Map<LeastTokenInfo, List<SwapPairLeast>>>(emptyMap())
|
||||
private val availablePairsByNetworkFlow = MutableStateFlow<Map<LeastTokenInfo, AvailablePairsState>>(emptyMap())
|
||||
|
||||
init {
|
||||
initializeSearchBardCallbacks()
|
||||
|
||||
subscribeOnUpdateState()
|
||||
subscribeOnAvailablePairsUpdates()
|
||||
}
|
||||
|
||||
private fun getTokenListUseCaseFlow(): SharedFlow<List<CryptoCurrencyStatus>> {
|
||||
return getTokenListUseCase.launch(userWalletId = params.userWalletId)
|
||||
.distinctUntilChanged()
|
||||
.map { maybeTokenList ->
|
||||
maybeTokenList.getOrElse(
|
||||
ifLoading = { it ?: TokenList.Empty },
|
||||
ifError = { TokenList.Empty },
|
||||
)
|
||||
.flattenCurrencies()
|
||||
}
|
||||
.shareIn(scope = modelScope, started = SharingStarted.Eagerly, replay = 1)
|
||||
}
|
||||
|
||||
private fun initializeSearchBardCallbacks() {
|
||||
tokenListUMController.update(
|
||||
transformer = UpdateSearchBarCallbacksTransformer(
|
||||
onQueryChange = ::onSearchQueryChange,
|
||||
onActiveChange = ::onSearchBarActiveChange,
|
||||
),
|
||||
)
|
||||
|
||||
subscribeOnUpdateState()
|
||||
subscribeOnAvailablePairsUpdates()
|
||||
}
|
||||
|
||||
private fun subscribeOnUpdateState() {
|
||||
|
|
@ -81,69 +98,143 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
|||
flow3 = params.selectedStatus,
|
||||
flow4 = searchManager.query,
|
||||
flow5 = availablePairsByNetworkFlow
|
||||
.map { it[params.selectedStatus.value?.toLeastTokenInfo()].orEmpty() }
|
||||
.map { it[params.selectedStatus.value?.toLeastTokenInfo()] }
|
||||
.distinctUntilChanged(),
|
||||
) { currencies, appCurrencyAndBalanceHiding, selectedStatus, query, availablePairs ->
|
||||
if (availablePairs.isEmpty()) {
|
||||
SetLoadingTokenItemsTransformer(currencies)
|
||||
} else {
|
||||
val (appCurrency, isBalanceHidden) = appCurrencyAndBalanceHiding
|
||||
|
||||
val filterByQueryTokenList = currencies
|
||||
.filter { it.currency != selectedStatus?.currency }
|
||||
.filterByQuery(query = query)
|
||||
|
||||
if (query.isNotEmpty() && filterByQueryTokenList.isEmpty()) {
|
||||
SetNothingToFoundStateTransformer(
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
emptySearchMessageReference = resourceReference(
|
||||
id = R.string.action_buttons_swap_empty_search_message,
|
||||
),
|
||||
) { currencies, appCurrencyAndBalanceHiding, selectedStatus, query, availablePairsState ->
|
||||
availablePairsState?.fold(
|
||||
ifLoading = { SetLoadingTokenItemsTransformer(currencies) },
|
||||
ifContent = { pairs ->
|
||||
handleContentState(
|
||||
appCurrencyAndBalanceHiding = appCurrencyAndBalanceHiding,
|
||||
currencies = currencies,
|
||||
selectedStatus = selectedStatus,
|
||||
query = query,
|
||||
availablePairs = pairs,
|
||||
)
|
||||
} else {
|
||||
UpdateTokenItemsTransformer(
|
||||
appCurrency = appCurrency,
|
||||
onItemClick = params.onTokenClick,
|
||||
statuses = filterByQueryTokenList.filterByAvailability(availablePairs = availablePairs),
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
unavailableTokensHeaderReference = resourceReference(
|
||||
id = R.string.tokens_list_unavailable_to_swap_header,
|
||||
wrappedList(selectedStatus?.currency?.name?.capitalize() ?: ""),
|
||||
),
|
||||
},
|
||||
ifError = {
|
||||
handleErrorState(
|
||||
cause = it,
|
||||
networkInfo = params.selectedStatus.value?.toLeastTokenInfo(),
|
||||
currencies = currencies,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
?: SetLoadingTokenItemsTransformer(currencies)
|
||||
}
|
||||
.onEach(tokenListUMController::update)
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun handleContentState(
|
||||
appCurrencyAndBalanceHiding: Pair<AppCurrency, Boolean>,
|
||||
currencies: List<CryptoCurrencyStatus>,
|
||||
selectedStatus: CryptoCurrencyStatus?,
|
||||
query: String,
|
||||
availablePairs: List<SwapPairLeast>,
|
||||
): TokenListUMTransformer {
|
||||
val (appCurrency, isBalanceHidden) = appCurrencyAndBalanceHiding
|
||||
|
||||
if (availablePairs.isEmpty()) {
|
||||
return SetNoAvailablePairsTransformer(
|
||||
appCurrency = appCurrency,
|
||||
unavailableStatuses = currencies,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
unavailableTokensHeaderReference = resourceReference(
|
||||
id = R.string.tokens_list_unavailable_to_swap_header,
|
||||
wrappedList(selectedStatus?.currency?.name?.capitalize() ?: ""),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val filterByQueryTokenList = currencies
|
||||
.filter { it.currency != selectedStatus?.currency }
|
||||
.filterByQuery(query = query)
|
||||
|
||||
return if (query.isNotEmpty() && filterByQueryTokenList.isEmpty()) {
|
||||
SetNothingToFoundStateTransformer(
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
emptySearchMessageReference = resourceReference(
|
||||
id = R.string.action_buttons_swap_empty_search_message,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
UpdateTokenItemsTransformer(
|
||||
appCurrency = appCurrency,
|
||||
onItemClick = params.onTokenClick,
|
||||
statuses = filterByQueryTokenList.filterByAvailability(availablePairs = availablePairs),
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
unavailableTokensHeaderReference = resourceReference(
|
||||
id = R.string.tokens_list_unavailable_to_swap_header,
|
||||
wrappedList(selectedStatus?.currency?.name?.capitalize() ?: ""),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleErrorState(
|
||||
cause: Throwable,
|
||||
networkInfo: LeastTokenInfo?,
|
||||
currencies: List<CryptoCurrencyStatus>,
|
||||
): SetErrorWarningTransformer {
|
||||
return SetErrorWarningTransformer(
|
||||
cause = cause,
|
||||
onRefresh = {
|
||||
modelScope.launch {
|
||||
if (networkInfo != null) {
|
||||
updateAvailablePairs(networkInfo, currencies)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun subscribeOnAvailablePairsUpdates() {
|
||||
modelScope.launch {
|
||||
params.selectedStatus
|
||||
.filterNotNull()
|
||||
.collectLatest { selectedStatus ->
|
||||
val initialCurrency = selectedStatus.toLeastTokenInfo()
|
||||
val tokenList = tokenListFlow.firstOrNull() ?: return@collectLatest
|
||||
val networkInfo = selectedStatus.toLeastTokenInfo()
|
||||
|
||||
val availablePairs = availablePairsByNetworkFlow.value[initialCurrency]
|
||||
if (!availablePairs.isNullOrEmpty()) return@collectLatest
|
||||
val isAlreadyLoaded = availablePairsByNetworkFlow.value[networkInfo]?.isContent() ?: false
|
||||
if (isAlreadyLoaded) return@collectLatest
|
||||
|
||||
val pairs = getAvailablePairsUseCase(
|
||||
initialCurrency = initialCurrency,
|
||||
currencies = tokenList.map(CryptoCurrencyStatus::currency),
|
||||
)
|
||||
val statuses = tokenListFlow.firstOrNull() ?: return@collectLatest
|
||||
|
||||
availablePairsByNetworkFlow.update {
|
||||
it.toMutableMap().apply {
|
||||
put(initialCurrency, pairs)
|
||||
}
|
||||
}
|
||||
updateAvailablePairs(networkInfo = networkInfo, statuses = statuses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateAvailablePairs(networkInfo: LeastTokenInfo, statuses: List<CryptoCurrencyStatus>) {
|
||||
runCatching {
|
||||
availablePairsByNetworkFlow.update(networkInfo = networkInfo, state = lceLoading())
|
||||
|
||||
getAvailablePairsUseCase(
|
||||
initialCurrency = networkInfo,
|
||||
currencies = statuses.map(CryptoCurrencyStatus::currency),
|
||||
)
|
||||
}
|
||||
.onSuccess { pairs ->
|
||||
availablePairsByNetworkFlow.update(networkInfo = networkInfo, state = pairs.lceContent())
|
||||
}
|
||||
.onFailure { cause ->
|
||||
availablePairsByNetworkFlow.update(networkInfo = networkInfo, state = cause.lceError())
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableStateFlow<Map<LeastTokenInfo, AvailablePairsState>>.update(
|
||||
networkInfo: LeastTokenInfo,
|
||||
state: AvailablePairsState,
|
||||
) {
|
||||
update {
|
||||
it.toMutableMap().apply {
|
||||
put(networkInfo, state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAppCurrencyAndBalanceHidingFlow(): Flow<Pair<AppCurrency, Boolean>> {
|
||||
return combine(
|
||||
flow = getSelectedAppCurrencyUseCase().map { it.getOrElse { AppCurrency.Default } }.distinctUntilChanged(),
|
||||
|
|
@ -186,7 +277,8 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
|||
|
||||
isAvailable &&
|
||||
status.value !is CryptoCurrencyStatus.MissedDerivation &&
|
||||
status.value !is CryptoCurrencyStatus.Unreachable
|
||||
status.value !is CryptoCurrencyStatus.Unreachable &&
|
||||
!status.currency.isCustom
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.onramp.tokenlist.entity
|
||||
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.fields.entity.SearchBarUM
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -19,4 +20,5 @@ internal data class TokenListUM(
|
|||
val availableItems: ImmutableList<TokensListItemUM>,
|
||||
val unavailableItems: ImmutableList<TokensListItemUM>,
|
||||
val isBalanceHidden: Boolean,
|
||||
val warning: NotificationUM? = null,
|
||||
)
|
||||
|
|
@ -1,22 +1,18 @@
|
|||
package com.tangem.features.onramp.tokenlist.entity.transformer
|
||||
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedCryptoAmount
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedFiatAmount
|
||||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import com.tangem.features.onramp.tokenlist.entity.utils.OnrampTokenItemStateConverterFactory
|
||||
import com.tangem.features.onramp.tokenlist.entity.utils.addHeader
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class UpdateTokenItemsTransformer(
|
||||
private val appCurrency: AppCurrency,
|
||||
private val onItemClick: (TokenItemState, CryptoCurrencyStatus) -> Unit,
|
||||
|
|
@ -27,36 +23,22 @@ internal class UpdateTokenItemsTransformer(
|
|||
|
||||
override fun transform(prevState: TokenListUM): TokenListUM {
|
||||
val availableItems = convertStatuses(
|
||||
converter = createAvailableTokenItemStateConverter(),
|
||||
converter = OnrampTokenItemStateConverterFactory.createAvailableItemConverter(appCurrency, onItemClick),
|
||||
statuses = statuses[true].orEmpty(),
|
||||
)
|
||||
|
||||
val unavailableItems = convertStatuses(
|
||||
converter = createUnavailableTokenItemStateConverter(),
|
||||
converter = OnrampTokenItemStateConverterFactory.createUnavailableItemConverter(appCurrency),
|
||||
statuses = statuses[false].orEmpty(),
|
||||
)
|
||||
|
||||
return prevState.copy(
|
||||
availableItems = buildList {
|
||||
if (availableItems.isNotEmpty()) {
|
||||
createGroupTitle(
|
||||
textReference = resourceReference(id = R.string.exchange_tokens_available_tokens_header),
|
||||
)
|
||||
.let(::add)
|
||||
}
|
||||
|
||||
addAll(availableItems)
|
||||
}
|
||||
.toImmutableList(),
|
||||
unavailableItems = buildList {
|
||||
if (unavailableItems.isNotEmpty()) {
|
||||
createGroupTitle(textReference = unavailableTokensHeaderReference).let(::add)
|
||||
}
|
||||
|
||||
addAll(unavailableItems)
|
||||
}
|
||||
.toImmutableList(),
|
||||
availableItems = availableItems.addHeader(
|
||||
textReference = resourceReference(id = R.string.exchange_tokens_available_tokens_header),
|
||||
),
|
||||
unavailableItems = unavailableItems.addHeader(textReference = unavailableTokensHeaderReference),
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
warning = null,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -67,88 +49,4 @@ internal class UpdateTokenItemsTransformer(
|
|||
return converter.convertList(statuses)
|
||||
.map(TokensListItemUM::Token)
|
||||
}
|
||||
|
||||
private fun createAvailableTokenItemStateConverter(): TokenItemStateConverter {
|
||||
return TokenItemStateConverter(
|
||||
appCurrency = appCurrency,
|
||||
subtitleStateProvider = { createSubtitleState(status = it, isAvailable = true) },
|
||||
subtitle2StateProvider = ::createSubtitle2State,
|
||||
fiatAmountStateProvider = { createFiatAmountStateProvider(status = it, isAvailable = true) },
|
||||
onItemClick = onItemClick,
|
||||
)
|
||||
}
|
||||
|
||||
private fun createUnavailableTokenItemStateConverter(): TokenItemStateConverter {
|
||||
return TokenItemStateConverter(
|
||||
appCurrency = appCurrency,
|
||||
iconStateProvider = { CryptoCurrencyToIconStateConverter(isAvailable = false).convert(it) },
|
||||
titleStateProvider = {
|
||||
TokenItemState.TitleState.Content(
|
||||
text = stringReference(value = it.currency.name),
|
||||
isAvailable = false,
|
||||
)
|
||||
},
|
||||
subtitleStateProvider = { createSubtitleState(status = it, isAvailable = false) },
|
||||
subtitle2StateProvider = ::createSubtitle2State,
|
||||
fiatAmountStateProvider = { createFiatAmountStateProvider(status = it, isAvailable = false) },
|
||||
)
|
||||
}
|
||||
|
||||
private fun createSubtitleState(status: CryptoCurrencyStatus, isAvailable: Boolean): TokenItemState.SubtitleState {
|
||||
return when (status.value) {
|
||||
CryptoCurrencyStatus.Loading -> TokenItemState.SubtitleState.Loading
|
||||
else -> {
|
||||
TokenItemState.SubtitleState.TextContent(
|
||||
value = stringReference(value = status.currency.symbol),
|
||||
isAvailable = isAvailable,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSubtitle2State(status: CryptoCurrencyStatus): TokenItemState.Subtitle2State? {
|
||||
return when (status.value) {
|
||||
is CryptoCurrencyStatus.Loaded,
|
||||
is CryptoCurrencyStatus.Custom,
|
||||
is CryptoCurrencyStatus.NoQuote,
|
||||
is CryptoCurrencyStatus.NoAccount,
|
||||
-> {
|
||||
TokenItemState.Subtitle2State.TextContent(
|
||||
text = status.getFormattedCryptoAmount(includeStaking = false),
|
||||
)
|
||||
}
|
||||
is CryptoCurrencyStatus.Loading,
|
||||
is CryptoCurrencyStatus.MissedDerivation,
|
||||
is CryptoCurrencyStatus.Unreachable,
|
||||
is CryptoCurrencyStatus.NoAmount,
|
||||
-> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFiatAmountStateProvider(
|
||||
status: CryptoCurrencyStatus,
|
||||
isAvailable: Boolean,
|
||||
): TokenItemState.FiatAmountState? {
|
||||
return when (status.value) {
|
||||
is CryptoCurrencyStatus.Loaded,
|
||||
is CryptoCurrencyStatus.Custom,
|
||||
is CryptoCurrencyStatus.NoQuote,
|
||||
is CryptoCurrencyStatus.NoAccount,
|
||||
-> {
|
||||
TokenItemState.FiatAmountState.TextContent(
|
||||
text = status.getFormattedFiatAmount(appCurrency = appCurrency, includeStaking = false),
|
||||
isAvailable = isAvailable,
|
||||
)
|
||||
}
|
||||
is CryptoCurrencyStatus.Unreachable,
|
||||
is CryptoCurrencyStatus.NoAmount,
|
||||
is CryptoCurrencyStatus.MissedDerivation,
|
||||
is CryptoCurrencyStatus.Loading,
|
||||
-> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createGroupTitle(textReference: TextReference): TokensListItemUM.GroupTitle {
|
||||
return TokensListItemUM.GroupTitle(id = textReference.hashCode(), text = textReference)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package com.tangem.features.onramp.tokenlist.entity.utils
|
||||
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedCryptoAmount
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormattedFiatAmount
|
||||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal object OnrampTokenItemStateConverterFactory {
|
||||
|
||||
fun createAvailableItemConverter(
|
||||
appCurrency: AppCurrency,
|
||||
onItemClick: (TokenItemState, CryptoCurrencyStatus) -> Unit,
|
||||
): TokenItemStateConverter {
|
||||
return TokenItemStateConverter(
|
||||
appCurrency = appCurrency,
|
||||
subtitleStateProvider = { createSubtitleState(status = it, isAvailable = true) },
|
||||
subtitle2StateProvider = ::createSubtitle2State,
|
||||
fiatAmountStateProvider = {
|
||||
createFiatAmountStateProvider(status = it, appCurrency = appCurrency, isAvailable = true)
|
||||
},
|
||||
onItemClick = onItemClick,
|
||||
)
|
||||
}
|
||||
|
||||
fun createUnavailableItemConverter(appCurrency: AppCurrency): TokenItemStateConverter {
|
||||
return TokenItemStateConverter(
|
||||
appCurrency = appCurrency,
|
||||
iconStateProvider = { CryptoCurrencyToIconStateConverter(isAvailable = false).convert(it) },
|
||||
titleStateProvider = {
|
||||
TokenItemState.TitleState.Content(
|
||||
text = stringReference(value = it.currency.name),
|
||||
isAvailable = false,
|
||||
)
|
||||
},
|
||||
subtitleStateProvider = { createSubtitleState(status = it, isAvailable = false) },
|
||||
subtitle2StateProvider = ::createSubtitle2State,
|
||||
fiatAmountStateProvider = {
|
||||
createFiatAmountStateProvider(status = it, appCurrency = appCurrency, isAvailable = false)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun createSubtitleState(status: CryptoCurrencyStatus, isAvailable: Boolean): TokenItemState.SubtitleState {
|
||||
return when (status.value) {
|
||||
CryptoCurrencyStatus.Loading -> TokenItemState.SubtitleState.Loading
|
||||
else -> {
|
||||
TokenItemState.SubtitleState.TextContent(
|
||||
value = stringReference(value = status.currency.symbol),
|
||||
isAvailable = isAvailable,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSubtitle2State(status: CryptoCurrencyStatus): TokenItemState.Subtitle2State? {
|
||||
return when (status.value) {
|
||||
is CryptoCurrencyStatus.Loaded,
|
||||
is CryptoCurrencyStatus.Custom,
|
||||
is CryptoCurrencyStatus.NoQuote,
|
||||
is CryptoCurrencyStatus.NoAccount,
|
||||
-> {
|
||||
TokenItemState.Subtitle2State.TextContent(
|
||||
text = status.getFormattedCryptoAmount(includeStaking = false),
|
||||
)
|
||||
}
|
||||
is CryptoCurrencyStatus.Loading,
|
||||
is CryptoCurrencyStatus.MissedDerivation,
|
||||
is CryptoCurrencyStatus.Unreachable,
|
||||
is CryptoCurrencyStatus.NoAmount,
|
||||
-> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFiatAmountStateProvider(
|
||||
status: CryptoCurrencyStatus,
|
||||
appCurrency: AppCurrency,
|
||||
isAvailable: Boolean,
|
||||
): TokenItemState.FiatAmountState? {
|
||||
return when (status.value) {
|
||||
is CryptoCurrencyStatus.Loaded,
|
||||
is CryptoCurrencyStatus.Custom,
|
||||
is CryptoCurrencyStatus.NoQuote,
|
||||
is CryptoCurrencyStatus.NoAccount,
|
||||
-> {
|
||||
TokenItemState.FiatAmountState.TextContent(
|
||||
text = status.getFormattedFiatAmount(appCurrency = appCurrency, includeStaking = false),
|
||||
isAvailable = isAvailable,
|
||||
)
|
||||
}
|
||||
is CryptoCurrencyStatus.Unreachable,
|
||||
is CryptoCurrencyStatus.NoAmount,
|
||||
is CryptoCurrencyStatus.MissedDerivation,
|
||||
is CryptoCurrencyStatus.Loading,
|
||||
-> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.features.onramp.tokenlist.entity.utils
|
||||
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
fun List<TokensListItemUM>.addHeader(textReference: TextReference): ImmutableList<TokensListItemUM> {
|
||||
val items = this@addHeader
|
||||
|
||||
return buildList {
|
||||
if (items.isNotEmpty()) {
|
||||
createGroupTitle(textReference = textReference).let(::add)
|
||||
}
|
||||
|
||||
addAll(items)
|
||||
}
|
||||
.toImmutableList()
|
||||
}
|
||||
|
||||
private fun createGroupTitle(textReference: TextReference): TokensListItemUM.GroupTitle {
|
||||
return TokensListItemUM.GroupTitle(id = textReference.hashCode(), text = textReference)
|
||||
}
|
||||
|
|
@ -14,9 +14,11 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastForEachIndexed
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.SpacerH12
|
||||
import com.tangem.core.ui.components.fields.SearchBar
|
||||
import com.tangem.core.ui.components.fields.entity.SearchBarUM
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.components.tokenlist.TokenListItem
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
||||
|
|
@ -37,15 +39,29 @@ import kotlinx.collections.immutable.ImmutableList
|
|||
@Composable
|
||||
internal fun TokenList(state: TokenListUM, modifier: Modifier = Modifier) {
|
||||
Column(modifier) {
|
||||
SearchBar(searchBarUM = state.searchBarUM)
|
||||
if (state.warning == null) {
|
||||
SearchBar(searchBarUM = state.searchBarUM)
|
||||
} else {
|
||||
when (state.warning) {
|
||||
is NotificationUM.Warning.OnrampErrorNotification -> {
|
||||
Notification(config = state.warning.config, containerColor = TangemTheme.colors.background.primary)
|
||||
}
|
||||
is NotificationUM.Warning.SwapNoAvailablePair -> {
|
||||
Notification(config = state.warning.config, containerColor = TangemTheme.colors.button.disabled)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
SpacerH12()
|
||||
if (state.availableItems.isNotEmpty()) {
|
||||
SpacerH12()
|
||||
ItemsBlock(items = state.availableItems, isBalanceHidden = state.isBalanceHidden)
|
||||
}
|
||||
|
||||
ItemsBlock(items = state.availableItems, isBalanceHidden = state.isBalanceHidden)
|
||||
|
||||
SpacerH12()
|
||||
|
||||
ItemsBlock(items = state.unavailableItems, isBalanceHidden = state.isBalanceHidden)
|
||||
if (state.unavailableItems.isNotEmpty()) {
|
||||
SpacerH12()
|
||||
ItemsBlock(items = state.unavailableItems, isBalanceHidden = state.isBalanceHidden)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.UpdateMultiWalletActionsTransformer
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
/**
|
||||
* Multi-currency wallet subscriber for actions state updating
|
||||
*
|
||||
* @property userWallet user wallet
|
||||
* @property rampStateManager ramp state manager
|
||||
* @property stateController state controller
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class MultiWalletActionsSubscriber(
|
||||
private val userWallet: UserWallet,
|
||||
private val rampStateManager: RampStateManager,
|
||||
private val stateController: WalletStateController,
|
||||
) : WalletSubscriber() {
|
||||
|
||||
override fun create(coroutineScope: CoroutineScope): Flow<*> {
|
||||
return combine(
|
||||
flow = rampStateManager.getBuyInitializationStatus(),
|
||||
flow2 = rampStateManager.getSellInitializationStatus(),
|
||||
flow3 = rampStateManager.getSwapInitializationStatus(userWalletId = userWallet.walletId),
|
||||
transform = ::RampStatuses,
|
||||
)
|
||||
.onEach { statuses ->
|
||||
stateController.update(
|
||||
UpdateMultiWalletActionsTransformer(
|
||||
userWalletId = userWallet.walletId,
|
||||
buyStatus = statuses.buy,
|
||||
sellStatus = statuses.sell,
|
||||
swapStatus = statuses.swap,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private data class RampStatuses(
|
||||
val buy: Lce<Throwable, Any>,
|
||||
val sell: Lce<Throwable, Any>,
|
||||
val swap: Lce<Throwable, Any>,
|
||||
)
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetRefreshStateTransformer
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTokenListErrorTransformer
|
||||
import com.tangem.features.onramp.OnrampFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.scopes.ViewModelScoped
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
@ -46,6 +47,7 @@ internal class WalletClickIntents @Inject constructor(
|
|||
private val neverToShowWalletsScrollPreview: NeverToShowWalletsScrollPreview,
|
||||
private val rampStateManager: RampStateManager,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val onrampFeatureToggles: OnrampFeatureToggles,
|
||||
) : BaseWalletClickIntents(),
|
||||
WalletCardClickIntents by walletCardClickIntentsImplementor,
|
||||
WalletWarningsClickIntents by warningsClickIntentsImplementer,
|
||||
|
|
@ -120,10 +122,13 @@ internal class WalletClickIntents @Inject constructor(
|
|||
fetchTokenListUseCase(userWalletId = userWallet.walletId, mode = RefreshMode.FULL)
|
||||
}
|
||||
|
||||
listOf(
|
||||
async { rampStateManager.fetchBuyServiceData() },
|
||||
async { rampStateManager.fetchSellServiceData() },
|
||||
)
|
||||
buildList {
|
||||
if (!onrampFeatureToggles.isFeatureEnabled) {
|
||||
async { rampStateManager.fetchBuyServiceData() }.let(::add)
|
||||
}
|
||||
|
||||
async { rampStateManager.fetchSellServiceData() }.let(::add)
|
||||
}
|
||||
.awaitAll()
|
||||
|
||||
maybeFetchResult.onLeft {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.model.*
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBottomSheetTransformer
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender
|
||||
import com.tangem.features.onramp.OnrampFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.scopes.ViewModelScoped
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
|
@ -119,6 +120,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
private val appRouter: AppRouter,
|
||||
private val rampStateManager: RampStateManager,
|
||||
private val getUserCountryUseCase: GetUserCountryUseCase,
|
||||
private val onrampFeatureToggles: OnrampFeatureToggles,
|
||||
) : BaseWalletClickIntents(), WalletCurrencyActionsClickIntents {
|
||||
|
||||
override fun onSendClick(
|
||||
|
|
@ -493,7 +495,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
|
||||
onMultiWalletActionClick(
|
||||
statusFlow = rampStateManager.getSwapInitializationStatus(userWalletId),
|
||||
statusFlow = rampStateManager.getExpressInitializationStatus(userWalletId),
|
||||
route = AppRoute.SwapCrypto(userWalletId = userWalletId),
|
||||
eventCreator = MainScreenAnalyticsEvent::ButtonSwap,
|
||||
)
|
||||
|
|
@ -501,7 +503,11 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
override fun onMultiWalletBuyClick(userWalletId: UserWalletId) {
|
||||
onMultiWalletActionClick(
|
||||
statusFlow = rampStateManager.getBuyInitializationStatus(),
|
||||
statusFlow = if (onrampFeatureToggles.isFeatureEnabled) {
|
||||
rampStateManager.getExpressInitializationStatus(userWalletId)
|
||||
} else {
|
||||
rampStateManager.getBuyInitializationStatus()
|
||||
},
|
||||
route = AppRoute.BuyCrypto(userWalletId = userWalletId),
|
||||
eventCreator = MainScreenAnalyticsEvent::ButtonBuy,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue