Updated on 2026-08-14
This commit is contained in:
commit
7fe610ec37
26 changed files with 322 additions and 202 deletions
|
|
@ -36,11 +36,8 @@ internal class AccountTokenItemConverter(
|
|||
isExpanded = true,
|
||||
isCollapsable = false,
|
||||
tokens = value.currencyList.map { accountSwapCurrency ->
|
||||
if (accountSwapCurrency.isAvailable) {
|
||||
createAvailableItemConverter()
|
||||
} else {
|
||||
createUnavailableItemConverter()
|
||||
}.convert(accountSwapCurrency.cryptoCurrencyStatus)
|
||||
createAvailableItemConverter()
|
||||
.convert(accountSwapCurrency.cryptoCurrencyStatus)
|
||||
}.map(TokensListItemUM::Token).toPersistentList(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.tangem.feature.swap.models.TokenToSelectState
|
|||
import com.tangem.feature.swap.presentation.R
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
internal class TokensDataConverter(
|
||||
|
|
@ -31,14 +32,9 @@ internal class TokensDataConverter(
|
|||
val availableTitle = TokenToSelectState.Title(
|
||||
resourceReference(R.string.exchange_tokens_available_tokens_header),
|
||||
)
|
||||
val unavailableTitle = TokenToSelectState.Title(
|
||||
resourceReference(
|
||||
R.string.exchange_tokens_unavailable_tokens_header,
|
||||
wrappedList(value.fromCurrency.name),
|
||||
),
|
||||
)
|
||||
val allTokens = group.available + group.unavailable
|
||||
return SwapSelectTokenStateHolder(
|
||||
availableTokens = group.available.map { tokenWithBalanceToTokenToSelect(it, true) }
|
||||
availableTokens = allTokens.map { tokenWithBalanceToTokenToSelect(it, true) }
|
||||
.toMutableList()
|
||||
.apply {
|
||||
if (this.isNotEmpty()) {
|
||||
|
|
@ -46,14 +42,7 @@ internal class TokensDataConverter(
|
|||
}
|
||||
}
|
||||
.toImmutableList(),
|
||||
unavailableTokens = group.unavailable.map { tokenWithBalanceToTokenToSelect(it, false) }
|
||||
.toMutableList()
|
||||
.apply {
|
||||
if (this.isNotEmpty()) {
|
||||
this.add(0, unavailableTitle)
|
||||
}
|
||||
}
|
||||
.toImmutableList(),
|
||||
unavailableTokens = persistentListOf(),
|
||||
tokensListData = TokenListUMData.EmptyList,
|
||||
onSearchEntered = onSearchEntered,
|
||||
onTokenSelected = onTokenSelected,
|
||||
|
|
|
|||
|
|
@ -46,11 +46,8 @@ internal class TokensDataConverterV2(
|
|||
} else {
|
||||
val tokensList = accountList.flatMap { (_, currencyList) ->
|
||||
currencyList.asSequence().map { accountSwapCurrency ->
|
||||
if (accountSwapCurrency.isAvailable) {
|
||||
accountListItemConverter.createAvailableItemConverter()
|
||||
} else {
|
||||
accountListItemConverter.createUnavailableItemConverter()
|
||||
}.convert(accountSwapCurrency.cryptoCurrencyStatus)
|
||||
accountListItemConverter.createAvailableItemConverter()
|
||||
.convert(accountSwapCurrency.cryptoCurrencyStatus)
|
||||
}.map(TokensListItemUM::Token).toPersistentList()
|
||||
}.toPersistentList()
|
||||
|
||||
|
|
|
|||
|
|
@ -645,21 +645,14 @@ internal class SwapModel @Inject constructor(
|
|||
tokensDataState = state,
|
||||
)
|
||||
|
||||
if (!isTokenAvailableForSwap(state, selectedCurrency, isReverseFromTo)) {
|
||||
analyticsEventHandler.send(
|
||||
SwapEvents.NoticeUnavailableToSwapPair(
|
||||
sendToken = fromCurrencyStatus.currency.symbol,
|
||||
receiveToken = toCurrencyStatus.currency.symbol,
|
||||
sendBlockchain = fromCurrencyStatus.currency.network.name,
|
||||
receiveBlockchain = toCurrencyStatus.currency.network.name,
|
||||
),
|
||||
)
|
||||
uiState = stateBuilder.createSwapNotSupportedState(
|
||||
uiStateHolder = uiState,
|
||||
if (handleSwapNotSupported(
|
||||
state = state,
|
||||
fromToken = fromCurrencyStatus,
|
||||
toToken = toCurrencyStatus,
|
||||
fromAccount = fromAccount,
|
||||
toAccount = toAccount,
|
||||
)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -1397,6 +1390,17 @@ internal class SwapModel @Inject constructor(
|
|||
toAccount = toAccount,
|
||||
selectedProvider = null,
|
||||
)
|
||||
swapRouter.openScreen(SwapNavScreen.Main)
|
||||
if (handleSwapNotSupported(
|
||||
state = tokens,
|
||||
fromToken = fromToken,
|
||||
toToken = toToken,
|
||||
fromAccount = fromAccount,
|
||||
toAccount = toAccount,
|
||||
)
|
||||
) {
|
||||
return
|
||||
}
|
||||
modelScope.launch {
|
||||
updateFeePaidCryptoCurrencyFor(fromToken)
|
||||
}
|
||||
|
|
@ -1409,7 +1413,6 @@ internal class SwapModel @Inject constructor(
|
|||
reduceBalanceBy = lastReducedBalanceBy.value,
|
||||
toProvidersList = findSwapProviders(fromToken, toToken),
|
||||
)
|
||||
swapRouter.openScreen(SwapNavScreen.Main)
|
||||
updateTokensState(tokens)
|
||||
}
|
||||
}
|
||||
|
|
@ -2011,6 +2014,37 @@ internal class SwapModel @Inject constructor(
|
|||
.orEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if swap is not supported and UI was updated to show error state
|
||||
*/
|
||||
private fun handleSwapNotSupported(
|
||||
state: TokensDataStateExpress,
|
||||
fromToken: CryptoCurrencyStatus,
|
||||
toToken: CryptoCurrencyStatus,
|
||||
fromAccount: Account.CryptoPortfolio?,
|
||||
toAccount: Account.CryptoPortfolio?,
|
||||
): Boolean {
|
||||
val selectedCurrency = if (isOrderReversed) fromToken else toToken
|
||||
if (isTokenAvailableForSwap(state, selectedCurrency, isOrderReversed)) return false
|
||||
|
||||
analyticsEventHandler.send(
|
||||
SwapEvents.NoticeUnavailableToSwapPair(
|
||||
sendToken = fromToken.currency.symbol,
|
||||
receiveToken = toToken.currency.symbol,
|
||||
sendBlockchain = fromToken.currency.network.name,
|
||||
receiveBlockchain = toToken.currency.network.name,
|
||||
),
|
||||
)
|
||||
uiState = stateBuilder.createSwapNotSupportedState(
|
||||
uiStateHolder = uiState,
|
||||
fromToken = fromToken,
|
||||
toToken = toToken,
|
||||
fromAccount = fromAccount,
|
||||
toAccount = toAccount,
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isTokenAvailableForSwap(
|
||||
state: TokensDataStateExpress,
|
||||
selectedCurrency: CryptoCurrencyStatus,
|
||||
|
|
|
|||
|
|
@ -64,9 +64,9 @@ internal class SwapNotificationsFactory(
|
|||
)
|
||||
}
|
||||
|
||||
fun getSwapNotSupportedNotifications(tokenName: String): ImmutableList<NotificationUM> {
|
||||
fun getSwapNotSupportedNotifications(): ImmutableList<NotificationUM> {
|
||||
return persistentListOf(
|
||||
SwapNotificationUM.Warning.SwapNotSupported(tokenName),
|
||||
SwapNotificationUM.Warning.SwapNotSupported,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -132,15 +132,12 @@ internal object SwapNotificationUM {
|
|||
),
|
||||
)
|
||||
|
||||
data class SwapNotSupported(
|
||||
val tokenName: String,
|
||||
) : Warning(
|
||||
data object SwapNotSupported : Warning(
|
||||
title = resourceReference(
|
||||
id = com.tangem.feature.swap.presentation.R.string.express_swap_not_supported_title,
|
||||
formatArgs = wrappedList(tokenName),
|
||||
id = com.tangem.feature.swap.presentation.R.string.warning_express_unsupported_pair_title,
|
||||
),
|
||||
subtitle = resourceReference(
|
||||
com.tangem.feature.swap.presentation.R.string.express_swap_not_supported_text,
|
||||
com.tangem.feature.swap.presentation.R.string.warning_express_unsupported_pair_description,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -197,12 +197,15 @@ internal class StateBuilder(
|
|||
uiStateHolder: SwapStateHolder,
|
||||
fromToken: CryptoCurrencyStatus,
|
||||
toToken: CryptoCurrencyStatus,
|
||||
fromAccount: Account.CryptoPortfolio?,
|
||||
toAccount: Account.CryptoPortfolio?,
|
||||
): SwapStateHolder {
|
||||
if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
return uiStateHolder.copy(
|
||||
sendCardData = SwapCardState.SwapCardData(
|
||||
type = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.Inputtable),
|
||||
type = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.Inputtable).copy(
|
||||
accountTitleUM = getFromCardAccountTitle(fromAccount),
|
||||
),
|
||||
amountTextFieldValue = null,
|
||||
amountEquivalent = "0 ${appCurrencyProvider.invoke().symbol}",
|
||||
token = fromToken,
|
||||
|
|
@ -233,7 +236,7 @@ internal class StateBuilder(
|
|||
networkIconRes = getActiveIconRes(toToken.currency.network.rawId),
|
||||
isBalanceHidden = isBalanceHiddenProvider(),
|
||||
),
|
||||
notifications = notificationsFactory.getSwapNotSupportedNotifications(toToken.currency.name),
|
||||
notifications = notificationsFactory.getSwapNotSupportedNotifications(),
|
||||
fee = FeeItemState.Empty,
|
||||
swapButton = SwapButton(
|
||||
walletInteractionIcon = walletInterationIcon(userWalletProvider()),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue