From b4e99d245976ec6d3040505efdbee5a6d44ce5d6 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 26 Nov 2024 17:54:31 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../ui/components/buttons/actions/Actions.kt | 9 ++-- .../swap/DefaultSwapSelectTokensComponent.kt | 17 ++++--- .../model/AvailableSwapPairsModel.kt | 1 + .../RemoveSelectedToTokenTransformer.kt | 29 ++++++++++++ .../swap/model/SwapSelectTokensModel.kt | 47 ++++++++++++++----- .../feature/swap/viewmodels/SwapViewModel.kt | 11 +---- 6 files changed, 82 insertions(+), 32 deletions(-) create mode 100644 features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/RemoveSelectedToTokenTransformer.kt diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt index 728eb3a49c..77e06f0358 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt @@ -96,7 +96,10 @@ private fun Button( .clip(shape) .background(color = backgroundColor), ) { - Content(config = config) + Content( + config = config, + modifier = Modifier.align(alignment = Alignment.Center), + ) if (config.isInProgress) { Loading( @@ -111,11 +114,11 @@ private fun Button( @OptIn(ExperimentalFoundationApi::class) @Composable -private fun Content(config: ActionButtonConfig) { +private fun Content(config: ActionButtonConfig, modifier: Modifier = Modifier) { val context = LocalContext.current Row( - modifier = Modifier + modifier = modifier .combinedClickable( enabled = config.enabled, onClick = config.onClick, diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/DefaultSwapSelectTokensComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/DefaultSwapSelectTokensComponent.kt index 457590ea6b..d49405a047 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/DefaultSwapSelectTokensComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/DefaultSwapSelectTokensComponent.kt @@ -37,15 +37,14 @@ internal class DefaultSwapSelectTokensComponent @AssistedInject constructor( ), ) - private val selectToTokenListComponent: AvailableSwapPairsComponent = - availableSwapPairsComponentFactory.create( - context = child(key = "select_to_token_list"), - params = AvailableSwapPairsComponent.Params( - userWalletId = params.userWalletId, - selectedStatus = model.fromCurrencyStatus, - onTokenClick = model::selectToToken, - ), - ) + private val selectToTokenListComponent: AvailableSwapPairsComponent = availableSwapPairsComponentFactory.create( + context = child(key = "select_to_token_list"), + params = AvailableSwapPairsComponent.Params( + userWalletId = params.userWalletId, + selectedStatus = model.fromCurrencyStatus, + onTokenClick = model::selectToToken, + ), + ) @Composable override fun Content(modifier: Modifier) { diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/model/AvailableSwapPairsModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/model/AvailableSwapPairsModel.kt index 1c9f0ecae6..4d639a5c46 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/model/AvailableSwapPairsModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/model/AvailableSwapPairsModel.kt @@ -81,6 +81,7 @@ internal class AvailableSwapPairsModel @Inject constructor( val (appCurrency, isBalanceHidden) = appCurrencyAndBalanceHiding val filterTokenList = currencies + .filter { it.currency != selectedStatus?.currency } .filterByQuery(query = query) .filterByAvailability(availablePairs = availablePairs) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/RemoveSelectedToTokenTransformer.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/RemoveSelectedToTokenTransformer.kt new file mode 100644 index 0000000000..971bf36fd8 --- /dev/null +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/RemoveSelectedToTokenTransformer.kt @@ -0,0 +1,29 @@ +package com.tangem.features.onramp.swap.entity.transformer + +import com.tangem.features.onramp.swap.entity.ExchangeCardUM +import com.tangem.features.onramp.swap.entity.SwapSelectTokensUM +import com.tangem.features.onramp.swap.entity.SwapSelectTokensUMTransformer +import com.tangem.features.onramp.swap.entity.utils.createEmptyExchangeTo + +/** + * Transformer for removing selected "to" token + * +[REDACTED_AUTHOR] + */ +internal class RemoveSelectedToTokenTransformer( + private val onRemoveFromTokenClick: () -> Unit, +) : SwapSelectTokensUMTransformer { + + override fun transform(prevState: SwapSelectTokensUM): SwapSelectTokensUM { + return prevState.copy( + exchangeFrom = prevState.exchangeFrom.showRemoveButton(onClick = onRemoveFromTokenClick), + exchangeTo = createEmptyExchangeTo(), + ) + } + + private fun ExchangeCardUM.showRemoveButton(onClick: () -> Unit): ExchangeCardUM { + return (this as? ExchangeCardUM.Filled) + ?.copy(removeButtonUM = ExchangeCardUM.RemoveButtonUM(onClick = onClick)) + ?: this + } +} \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/model/SwapSelectTokensModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/model/SwapSelectTokensModel.kt index 40a3b14a91..e86d202e54 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/model/SwapSelectTokensModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/model/SwapSelectTokensModel.kt @@ -10,11 +10,15 @@ import com.tangem.features.onramp.component.SwapSelectTokensComponent import com.tangem.features.onramp.swap.entity.SwapSelectTokensController import com.tangem.features.onramp.swap.entity.SwapSelectTokensUM import com.tangem.features.onramp.swap.entity.transformer.RemoveSelectedFromTokenTransformer +import com.tangem.features.onramp.swap.entity.transformer.RemoveSelectedToTokenTransformer import com.tangem.features.onramp.swap.entity.transformer.SelectFromTokenTransformer import com.tangem.features.onramp.swap.entity.transformer.SelectToTokenTransformer import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withTimeout import javax.inject.Inject @Suppress("LongParameterList") @@ -46,7 +50,7 @@ internal class SwapSelectTokensModel @Inject constructor( controller.update( transformer = SelectFromTokenTransformer( selectedTokenItemState = selectedTokenItemState, - onRemoveClick = ::onRemoveClick, + onRemoveClick = ::removeSelectedFromToken, ), ) } @@ -58,22 +62,43 @@ internal class SwapSelectTokensModel @Inject constructor( * @param status crypto currency status */ fun selectToToken(selectedTokenItemState: TokenItemState, status: CryptoCurrencyStatus) { - _toCurrencyStatus.value = status + modelScope.launch { + _toCurrencyStatus.value = status - controller.update(transformer = SelectToTokenTransformer(selectedTokenItemState)) + controller.update(transformer = SelectToTokenTransformer(selectedTokenItemState)) - router.push( - route = AppRoute.Swap( - currencyFrom = requireNotNull(fromCurrencyStatus.value).currency, - currencyTo = status.currency, - userWalletId = params.userWalletId, - ), - ) + // require some delay to show state with selected "from" and "to" tokens + delay(timeMillis = 500) + + router.push( + route = AppRoute.Swap( + currencyFrom = requireNotNull(fromCurrencyStatus.value).currency, + currencyTo = status.currency, + userWalletId = params.userWalletId, + ), + onComplete = { + modelScope.launch { + withTimeout(timeMillis = 500) { + // Return a state with selected only "from" token + removeSelectedToToken() + } + } + }, + ) + } } - private fun onRemoveClick() { + private fun removeSelectedFromToken() { _fromCurrencyStatus.value = null controller.update(transformer = RemoveSelectedFromTokenTransformer) } + + private fun removeSelectedToToken() { + _toCurrencyStatus.value = null + + controller.update( + transformer = RemoveSelectedToTokenTransformer(onRemoveFromTokenClick = ::removeSelectedFromToken), + ) + } } \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt index b3360ff214..431017f917 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/viewmodels/SwapViewModel.kt @@ -51,7 +51,6 @@ import com.tangem.feature.swap.router.SwapNavScreen import com.tangem.feature.swap.router.SwapRouter import com.tangem.feature.swap.ui.StateBuilder import com.tangem.feature.swap.utils.formatToUIRepresentation -import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles import com.tangem.utils.Provider import com.tangem.utils.coroutines.* import com.tangem.utils.isNullOrZero @@ -87,7 +86,6 @@ internal class SwapViewModel @Inject constructor( private val saveBlockchainErrorUseCase: SaveBlockchainErrorUseCase, private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, private val getMinimumTransactionAmountSyncUseCase: GetMinimumTransactionAmountSyncUseCase, - private val walletFeatureToggles: WalletFeatureToggles, swapInteractorFactory: SwapInteractor.Factory, private val savedStateHandle: SavedStateHandle, ) : ViewModel(), DefaultLifecycleObserver { @@ -99,13 +97,8 @@ internal class SwapViewModel @Inject constructor( ?: error("no expected parameter CryptoCurrency (from) found") } - private val initialCurrencyTo: CryptoCurrency? - get() = if (walletFeatureToggles.isMainActionButtonsEnabled) { - savedStateHandle.get(AppRoute.Swap.CURRENCY_TO_KEY) - ?.unbundle(CryptoCurrency.serializer()) - } else { - null - } + private val initialCurrencyTo: CryptoCurrency? = savedStateHandle.get(AppRoute.Swap.CURRENCY_TO_KEY) + ?.unbundle(CryptoCurrency.serializer()) private val userWalletId: UserWalletId = savedStateHandle.get(AppRoute.Swap.USER_WALLET_ID_KEY) ?.unbundle(UserWalletId.serializer())