From 64c7ee661861e6a5fcbbb48f8602bff2eef77595 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 22 Dec 2023 12:53:20 +0300 Subject: [PATCH 1/7] Updated on 2026-08-14 --- .../api/express/models/response/ExchangeDataResponse.kt | 3 +++ .../main/java/com/tangem/feature/swap/DefaultSwapRepository.kt | 3 +++ .../java/com/tangem/feature/swap/domain/models/DataError.kt | 2 ++ 3 files changed, 8 insertions(+) diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/express/models/response/ExchangeDataResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/express/models/response/ExchangeDataResponse.kt index 40c3483f16..7496a0a8e2 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/express/models/response/ExchangeDataResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/express/models/response/ExchangeDataResponse.kt @@ -31,6 +31,9 @@ data class ExchangeDataResponse( ) data class TxDetails( + @Json(name = "payoutAddress") + val payoutAddress: String, + @Json(name = "requestId") val requestId: String, diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt index 7a4c0df381..772502d688 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapRepository.kt @@ -292,6 +292,9 @@ internal class DefaultSwapRepository @Inject constructor( if (txDetails.requestId != requestId) { return@withContext DataError.InvalidRequestIdError().left() } + if (toAddress != txDetails.payoutAddress) { + return@withContext DataError.InvalidPayoutAddressError().left() + } expressDataConverter.convert( ExchangeDataResponseWithTxDetails( dataResponse = response, diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/DataError.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/DataError.kt index 9c0ca6b268..0da33b0bcf 100644 --- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/DataError.kt +++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/DataError.kt @@ -36,6 +36,8 @@ sealed class DataError { data class InvalidRequestIdError(override val code: Int = 991) : DataError() + data class InvalidPayoutAddressError(override val code: Int = 992) : DataError() + object UnknownError : DataError() { override val code: Int = -1 } From bd9ecb82cef4684be45019f06110684d65aeafc6 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 22 Dec 2023 13:01:30 +0300 Subject: [PATCH 2/7] Updated on 2026-08-14 --- .../feature/swap/viewmodels/SwapViewModel.kt | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) 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 a511e6ab43..84cde6431c 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 @@ -12,8 +12,11 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase +import com.tangem.domain.tokens.UpdateDelayedNetworkStatusUseCase import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.swap.analytics.SwapEvents import com.tangem.feature.swap.domain.BlockchainInteractor import com.tangem.feature.swap.domain.SwapInteractor @@ -32,6 +35,7 @@ import com.tangem.feature.swap.ui.StateBuilder import com.tangem.utils.coroutines.* import com.tangem.utils.isNullOrZero import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -57,6 +61,7 @@ internal class SwapViewModel @Inject constructor( private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val getCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusSyncUseCase, + private val updateDelayedCurrencyStatusUseCase: UpdateDelayedNetworkStatusUseCase, savedStateHandle: SavedStateHandle, ) : ViewModel(), DefaultLifecycleObserver { @@ -448,6 +453,7 @@ internal class SwapViewModel @Inject constructor( }.onSuccess { when (it) { is TxState.TxSent -> { + updateWalletBalance() uiState = stateBuilder.createSuccessState( uiState = uiState, txState = it, @@ -957,10 +963,32 @@ internal class SwapViewModel @Inject constructor( } } + private fun updateWalletBalance() { + swapInteractor.getSelectedWallet()?.let { userWallet -> + dataState.fromCryptoCurrency?.currency?.network?.let { network -> + viewModelScope.launch { + withContext(NonCancellable) { + updateForBalance(userWallet, network) + } + } + } + } + } + + private suspend fun updateForBalance(userWallet: UserWallet, network: Network) { + updateDelayedCurrencyStatusUseCase( + userWalletId = userWallet.walletId, + network = network, + delayMillis = UPDATE_BALANCE_DELAY_MILLIS, + refresh = true, + ) + } + companion object { private const val loggingTag = "SwapViewModel" private const val INITIAL_AMOUNT = "" private const val UPDATE_DELAY = 10000L private const val DEBOUNCE_AMOUNT_DELAY = 1000L + private const val UPDATE_BALANCE_DELAY_MILLIS = 11000L } } \ No newline at end of file From 950aafe4edbfdca9bd3ee60627316c69a7e0da2a Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 22 Dec 2023 19:00:55 +0200 Subject: [PATCH 3/7] Updated on 2026-08-14 --- .../src/main/java/com/tangem/feature/swap/ui/TransactionCard.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/TransactionCard.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/TransactionCard.kt index 0aec67858b..45d37e07de 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/TransactionCard.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/TransactionCard.kt @@ -418,7 +418,7 @@ private fun TokenIcon( contentAlignment = Alignment.Center, ) { Image( - modifier = Modifier.padding(all = TangemTheme.dimens.spacing0_5), + modifier = Modifier.padding(all = TangemTheme.dimens.spacing2), painter = painterResource(id = networkIconRes), contentDescription = null, ) From e0bc66f30c19abb44c77d8ebf352e5fddaf18146 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 25 Dec 2023 09:19:37 +0200 Subject: [PATCH 4/7] Updated on 2026-08-14 --- core/res/src/main/res/values-ru/strings.xml | 1 + core/res/src/main/res/values/strings.xml | 1 + .../models/ui/TokensDataStateExpress.kt | 5 +-- .../feature/swap/domain/SwapInteractorImpl.kt | 1 + .../swap/converters/TokensDataConverter.kt | 1 + .../swap/models/SwapSelectTokenStateHolder.kt | 1 + .../feature/swap/ui/SwapSelectTokenScreen.kt | 35 ++++++++++++++++--- .../feature/swap/viewmodels/SwapViewModel.kt | 3 ++ 8 files changed, 42 insertions(+), 6 deletions(-) diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 42f9f8b591..c2cdf27727 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -193,6 +193,7 @@ Вы отправляете Мои токены У вас нет добавленных токенов. Добавьте токены для обмена + Токены не найдены. Пожалуйста, попробуйте другой запрос Недоступен для обмена с %s Кроме того, в курс обмена включена комиссия сети за отправку обмененных средств на ваш адрес Статус diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 1150c0349b..94f6ed4c2e 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -192,6 +192,7 @@ You send My tokens You haven\'t added any tokens yet. Add tokens via Market to swap + No tokens found. Please try another request Cannot be swapped for %s Additionally, the network fee for sending the exchanged funds back to your address is included in the rate Status diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt index 60c8e749bd..d761ad97fb 100644 --- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt +++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt @@ -11,8 +11,8 @@ data class TokensDataStateExpress( companion object { val EMPTY = TokensDataStateExpress( - fromGroup = CurrenciesGroup(emptyList(), emptyList()), - toGroup = CurrenciesGroup(emptyList(), emptyList()), + fromGroup = CurrenciesGroup(emptyList(), emptyList(), false), + toGroup = CurrenciesGroup(emptyList(), emptyList(), false), allProviders = emptyList(), ) } @@ -21,4 +21,5 @@ data class TokensDataStateExpress( data class CurrenciesGroup( val available: List, val unavailable: List, + val afterSearch: Boolean, ) \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index 19a88c1d4a..d38fc7f54a 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -148,6 +148,7 @@ internal class SwapInteractorImpl @Inject constructor( return CurrenciesGroup( available = availableCryptoCurrencies, unavailable = unavailableCryptoCurrencies.map { CryptoCurrencySwapInfo(it, emptyList()) }, + afterSearch = false ) } diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt index 895fcb1ea5..d475bad6f2 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt @@ -49,6 +49,7 @@ class TokensDataConverter( .toImmutableList(), onSearchEntered = onSearchEntered, onTokenSelected = onTokenSelected, + afterSearch = value.afterSearch, ) } diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapSelectTokenStateHolder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapSelectTokenStateHolder.kt index ac6762d7b7..585afb1921 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapSelectTokenStateHolder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapSelectTokenStateHolder.kt @@ -7,6 +7,7 @@ import kotlinx.collections.immutable.ImmutableList data class SwapSelectTokenStateHolder( val availableTokens: ImmutableList, val unavailableTokens: ImmutableList, + val afterSearch: Boolean, val onSearchEntered: (String) -> Unit, val onTokenSelected: (String) -> Unit, ) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapSelectTokenScreen.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapSelectTokenScreen.kt index 4057aba9af..87a82413f1 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapSelectTokenScreen.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapSelectTokenScreen.kt @@ -42,10 +42,16 @@ fun SwapSelectTokenScreen(state: SwapSelectTokenStateHolder, onBack: () -> Unit) .background(color = TangemTheme.colors.background.secondary), content = { padding -> val modifier = Modifier.padding(padding) - if (state.availableTokens.isEmpty() && state.unavailableTokens.isEmpty()) { - EmptyTokensList(modifier) - } else { - ListOfTokens(state = state, modifier = modifier) + when { + state.availableTokens.isEmpty() && state.unavailableTokens.isEmpty() && state.afterSearch -> { + TokensNotFound(modifier) + } + state.availableTokens.isEmpty() && state.unavailableTokens.isEmpty() && !state.afterSearch -> { + EmptyTokensList(modifier) + } + else -> { + ListOfTokens(state = state, modifier = modifier) + } } }, topBar = { @@ -91,6 +97,26 @@ private fun EmptyTokensList(modifier: Modifier = Modifier) { } } +@Composable +private fun TokensNotFound(modifier: Modifier = Modifier) { + Box( + modifier = modifier + .background(TangemTheme.colors.background.secondary) + .fillMaxSize(), + ) { + Text( + modifier = Modifier + .padding(top = TangemTheme.dimens.spacing32) + .padding(horizontal = TangemTheme.dimens.spacing30) + .align(Alignment.TopCenter), + text = stringResource(id = R.string.express_token_list_empty_search), + style = TangemTheme.typography.subtitle1, + color = TangemTheme.colors.text.tertiary, + textAlign = TextAlign.Center, + ) + } +} + @Composable private fun ListOfTokens(state: SwapSelectTokenStateHolder, modifier: Modifier = Modifier) { val screenBackgroundColor = TangemTheme.colors.background.secondary @@ -283,6 +309,7 @@ private fun TokenScreenPreview() { state = SwapSelectTokenStateHolder( availableTokens = listOf(title, token, token, token).toImmutableList(), unavailableTokens = listOf(title, token, token, token).toImmutableList(), + afterSearch = false, onSearchEntered = {}, onTokenSelected = {}, ), 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 84cde6431c..f021a40ab2 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 @@ -586,13 +586,16 @@ internal class SwapViewModel @Inject constructor( fromGroup = tokenDataState.fromGroup.copy( available = available, unavailable = unavailable, + afterSearch = true, ), + ) } else { tokenDataState.copy( toGroup = tokenDataState.toGroup.copy( available = available, unavailable = unavailable, + afterSearch = true, ), ) } From d0869cc149abadc02df7696e0a8030ea43df04fc Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 25 Dec 2023 10:03:27 +0200 Subject: [PATCH 5/7] Updated on 2026-08-14 --- .../domain/models/ui/TokensDataStateExpress.kt | 2 +- .../feature/swap/domain/SwapInteractorImpl.kt | 2 +- .../feature/swap/viewmodels/SwapViewModel.kt | 17 +++++++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt index d761ad97fb..1aa9ba51d1 100644 --- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt +++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/ui/TokensDataStateExpress.kt @@ -12,7 +12,7 @@ data class TokensDataStateExpress( val EMPTY = TokensDataStateExpress( fromGroup = CurrenciesGroup(emptyList(), emptyList(), false), - toGroup = CurrenciesGroup(emptyList(), emptyList(), false), + toGroup = CurrenciesGroup(emptyList(), emptyList(), false), allProviders = emptyList(), ) } diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt index d38fc7f54a..55d82743e6 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapInteractorImpl.kt @@ -148,7 +148,7 @@ internal class SwapInteractorImpl @Inject constructor( return CurrenciesGroup( available = availableCryptoCurrencies, unavailable = unavailableCryptoCurrencies.map { CryptoCurrencySwapInfo(it, emptyList()) }, - afterSearch = false + afterSearch = false, ) } 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 f021a40ab2..ee03e66695 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 @@ -98,6 +98,11 @@ internal class SwapViewModel @Inject constructor( private var isOrderReversed = false private val lastAmount = mutableStateOf(INITIAL_AMOUNT) private var swapRouter: SwapRouter by Delegates.notNull() + + private val isExchangeTooSmallAmountError: (SwapState) -> Boolean = { + it is SwapState.SwapError && it.error is DataError.ExchangeTooSmallAmountError + } + val currentScreen: SwapNavScreen get() = swapRouter.currentScreen @@ -385,13 +390,17 @@ internal class SwapViewModel @Inject constructor( } private fun selectProvider(state: Map): SwapProvider { - val stateSuccess = state.getLastLoadedSuccessStates() - return if (stateSuccess.isNotEmpty()) { + val consideredProviders = state.filter { + it.value is SwapState.QuotesLoadedState || isExchangeTooSmallAmountError(it.value) + } + + return if (consideredProviders.isNotEmpty()) { val currentSelected = dataState.selectedProvider - if (currentSelected != null && stateSuccess.keys.contains(currentSelected)) { + if (currentSelected != null && consideredProviders.keys.contains(currentSelected)) { currentSelected } else { - findBestQuoteProvider(stateSuccess) ?: stateSuccess.keys.first() + findBestQuoteProvider(consideredProviders.getLastLoadedSuccessStates()) + ?: consideredProviders.keys.first() } } else { state.keys.first() From f03f9d1b0dcd0ff442b7db79bfd7a497a9637880 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 25 Dec 2023 10:37:24 +0200 Subject: [PATCH 6/7] Updated on 2026-08-14 --- .../com/tangem/feature/swap/models/SwapStateHolder.kt | 1 - .../main/java/com/tangem/feature/swap/ui/ProviderItem.kt | 4 +++- .../main/java/com/tangem/feature/swap/ui/StateBuilder.kt | 9 ++------- .../java/com/tangem/feature/swap/ui/SwapScreenContent.kt | 5 +---- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt index 83d86eee5b..577c2e96af 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/models/SwapStateHolder.kt @@ -72,7 +72,6 @@ sealed class SwapCardState { data class SwapButton( val enabled: Boolean, - val loading: Boolean = false, val onClick: () -> Unit, ) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/ProviderItem.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/ProviderItem.kt index 4a217bcbfe..c1a94da8f7 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/ProviderItem.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/ProviderItem.kt @@ -260,7 +260,9 @@ private fun ProviderLoadingState(modifier: Modifier = Modifier) { ), ) { CircularProgressIndicator( - modifier = Modifier.size(TangemTheme.dimens.size16), + modifier = Modifier + .size(TangemTheme.dimens.size16) + .align(Alignment.CenterVertically), color = TangemTheme.colors.icon.informative, strokeWidth = TangemTheme.dimens.size2, ) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt index f02e5006fe..fab1b174c2 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt @@ -79,7 +79,7 @@ internal class StateBuilder( ), fee = FeeItemState.Empty, networkCurrency = networkInfo.blockchainCurrency, - swapButton = SwapButton(enabled = false, loading = true, onClick = {}), + swapButton = SwapButton(enabled = false, onClick = {}), onRefresh = {}, onBackClicked = actions.onBackClicked, onChangeCardsClicked = actions.onChangeCardsClicked, @@ -138,7 +138,6 @@ internal class StateBuilder( fee = FeeItemState.Empty, swapButton = SwapButton( enabled = false, - loading = false, onClick = { }, ), changeCardsButtonState = ChangeCardsButtonState.DISABLED, @@ -187,7 +186,7 @@ internal class StateBuilder( ), warnings = emptyList(), fee = FeeItemState.Empty, - swapButton = SwapButton(enabled = false, loading = true, onClick = {}), + swapButton = SwapButton(enabled = false, onClick = {}), providerState = ProviderState.Loading(), permissionState = uiStateHolder.permissionState, changeCardsButtonState = ChangeCardsButtonState.UPDATE_IN_PROGRESS, @@ -260,7 +259,6 @@ internal class StateBuilder( fee = feeState, swapButton = SwapButton( enabled = getSwapButtonEnabled(quoteModel.preparedSwapConfigState), - loading = false, onClick = actions.onSwapClick, ), changeCardsButtonState = if (isReverseSwapPossible) { @@ -454,7 +452,6 @@ internal class StateBuilder( fee = FeeItemState.Empty, swapButton = SwapButton( enabled = false, - loading = false, onClick = actions.onSwapClick, ), changeCardsButtonState = if (isReverseSwapPossible) { @@ -566,7 +563,6 @@ internal class StateBuilder( fee = FeeItemState.Empty, swapButton = SwapButton( enabled = false, - loading = false, onClick = { }, ), changeCardsButtonState = if (isReverseSwapPossible) { @@ -582,7 +578,6 @@ internal class StateBuilder( fun createSwapInProgressState(uiState: SwapStateHolder): SwapStateHolder { return uiState.copy( swapButton = uiState.swapButton.copy( - loading = true, enabled = false, ), ) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt index b211130172..571a1b51f1 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreenContent.kt @@ -399,7 +399,6 @@ private fun MainButton(state: SwapStateHolder, onPermissionWarningClick: () -> U modifier = Modifier.fillMaxWidth(), text = stringResource(id = R.string.swapping_insufficient_funds), enabled = false, - showProgress = state.swapButton.loading, onClick = state.swapButton.onClick, ) } @@ -408,7 +407,6 @@ private fun MainButton(state: SwapStateHolder, onPermissionWarningClick: () -> U modifier = Modifier.fillMaxWidth(), text = stringResource(id = R.string.swapping_give_permission), enabled = true, - showProgress = state.swapButton.loading, onClick = onPermissionWarningClick, ) } @@ -418,7 +416,6 @@ private fun MainButton(state: SwapStateHolder, onPermissionWarningClick: () -> U text = stringResource(id = R.string.common_swap), iconResId = R.drawable.ic_tangem_24, enabled = state.swapButton.enabled, - showProgress = state.swapButton.loading, onClick = state.swapButton.onClick, ) } @@ -487,7 +484,7 @@ private val state = SwapStateHolder( ), ), networkCurrency = "MATIC", - swapButton = SwapButton(enabled = true, loading = false, onClick = {}), + swapButton = SwapButton(enabled = true, onClick = {}), onRefresh = {}, onBackClicked = {}, onChangeCardsClicked = {}, From 20bd61d4f4db2b779ced5aee4954fce7ef150c1a Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 25 Dec 2023 11:54:39 +0300 Subject: [PATCH 7/7] Updated on 2026-08-14 --- .../swap/converters/ExchangeStatusConverter.kt | 2 +- .../domain/models/domain/ExchangeStatus.kt | 2 +- .../feature/swap/domain/models/ui/TxState.kt | 3 +-- .../swap/domain/BlockchainInteractor.kt | 2 +- .../swap/domain/DefaultBlockchainInteractor.kt | 4 ++-- .../feature/swap/domain/SwapInteractorImpl.kt | 18 ++++++------------ .../feature/swap/domain/di/SwapDomainModule.kt | 2 -- .../com/tangem/feature/swap/ui/StateBuilder.kt | 3 ++- .../feature/swap/viewmodels/SwapViewModel.kt | 10 +++++++--- ...kenDetailsSwapTransactionsStateConverter.kt | 8 ++++---- 10 files changed, 25 insertions(+), 29 deletions(-) diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ExchangeStatusConverter.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ExchangeStatusConverter.kt index f5901e8c69..30ea8ec4cd 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ExchangeStatusConverter.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/ExchangeStatusConverter.kt @@ -13,7 +13,7 @@ internal class ExchangeStatusConverter : Converter { allowPermissionsHandler.addAddressToInProgress(permissionOptions.forTokenContractAddress) TxState.TxSent( - txAddress = userWalletManager.getLastTransactionHash(networkId, derivationPath).orEmpty(), + txHash = userWalletManager.getLastTransactionHash(networkId, derivationPath).orEmpty(), timestamp = System.currentTimeMillis(), ) } @@ -463,7 +462,7 @@ internal class SwapInteractorImpl @Inject constructor( currencyToGet.symbol, ), toAmountValue = swapData.toTokenAmount.value, - txAddress = userWalletManager.getLastTransactionHash(networkId, derivationPath).orEmpty(), + txHash = userWalletManager.getLastTransactionHash(networkId, derivationPath).orEmpty(), timestamp = System.currentTimeMillis(), ) } @@ -537,10 +536,6 @@ internal class SwapInteractorImpl @Inject constructor( }, ifRight = { val timestamp = System.currentTimeMillis() - val txUrl = blockchainInteractor.getExplorerTransactionLink( - networkId = currencyToSend.currency.network.backendId, - txAddress = exchangeData.transaction.txTo, - ) storeSwapTransaction( currencyToSend = currencyToSend, currencyToGet = currencyToGet, @@ -548,7 +543,7 @@ internal class SwapInteractorImpl @Inject constructor( swapProvider = swapProvider, swapDataModel = exchangeData, timestamp = timestamp, - txUrl = txUrl, + txExternalUrl = externalUrl.orEmpty(), ) storeLastCryptoCurrencyId(currencyToGet.currency) TxState.TxSent( @@ -562,12 +557,11 @@ internal class SwapInteractorImpl @Inject constructor( currencyToGet.currency.symbol, ), toAmountValue = exchangeData.toTokenAmount.value, - txAddress = userWalletManager.getLastTransactionHash( + txHash = userWalletManager.getLastTransactionHash( currencyToSend.currency.network.backendId, derivationPath, ).orEmpty(), txExternalUrl = externalUrl, - txUrl = txUrl, timestamp = timestamp, ) }, @@ -602,7 +596,7 @@ internal class SwapInteractorImpl @Inject constructor( swapProvider: SwapProvider, swapDataModel: SwapDataModel, timestamp: Long, - txUrl: String, + txExternalUrl: String, ) { swapTransactionRepository.storeTransaction( userWalletId = UserWalletId(userWalletManager.getWalletId()), @@ -618,7 +612,7 @@ internal class SwapInteractorImpl @Inject constructor( providerId = swapProvider.providerId, status = ExchangeStatus.New, txId = swapDataModel.transaction.txId, - txUrl = txUrl, + txExternalUrl = txExternalUrl, ), ), ) diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt index 518d7c9fc8..d299f7824e 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt @@ -42,7 +42,6 @@ class SwapDomainModule { walletManagersFacade: WalletManagersFacade, coroutineDispatcherProvider: CoroutineDispatcherProvider, initialToCurrencyResolver: InitialToCurrencyResolver, - blockchainInteractor: BlockchainInteractor, ): SwapInteractor { return SwapInteractorImpl( transactionManager = transactionManager, @@ -57,7 +56,6 @@ class SwapDomainModule { dispatcher = coroutineDispatcherProvider, swapTransactionRepository = swapTransactionRepository, initialToCurrencyResolver = initialToCurrencyResolver, - blockchainInteractor = blockchainInteractor, ) } diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt index fab1b174c2..b7c7418dae 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt @@ -732,6 +732,7 @@ internal class StateBuilder( dataState: SwapProcessDataState, onExploreClick: () -> Unit, onStatusClick: () -> Unit, + txUrl: String, ): SwapStateHolder { val fee = requireNotNull(dataState.selectedFee) val fromCryptoCurrency = requireNotNull(dataState.fromCryptoCurrency) @@ -746,7 +747,7 @@ internal class StateBuilder( return uiState.copy( successState = SwapSuccessStateHolder( timestamp = txState.timestamp, - txUrl = txState.txUrl.orEmpty(), + txUrl = txUrl, providerName = stringReference(providerState.name), providerType = stringReference(providerState.type), showStatusButton = providerState.type == ExchangeProviderType.CEX.name, 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 ee03e66695..955d5e5f74 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 @@ -462,15 +462,19 @@ internal class SwapViewModel @Inject constructor( }.onSuccess { when (it) { is TxState.TxSent -> { + val url = blockchainInteractor.getExplorerTransactionLink( + networkId = fromCurrency.currency.network.backendId, + txHash = it.txHash, + ) updateWalletBalance() uiState = stateBuilder.createSuccessState( uiState = uiState, txState = it, dataState = dataState, + txUrl = url, onExploreClick = { - val txUrl = it.txUrl - if (!txUrl.isNullOrBlank()) { - swapRouter.openUrl(txUrl) + if (it.txHash.isNotEmpty()) { + swapRouter.openUrl(url) } analyticsEventHandler.send( event = SwapEvents.ButtonExplore(initialCryptoCurrency.symbol), diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSwapTransactionsStateConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSwapTransactionsStateConverter.kt index fd13879bc9..514afc7709 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSwapTransactionsStateConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSwapTransactionsStateConverter.kt @@ -66,7 +66,7 @@ internal class TokenDetailsSwapTransactionsStateConverter( SwapTransactionsState( txId = transaction.txId, provider = transaction.provider, - txUrl = transaction.status?.txUrl, + txUrl = transaction.status?.txExternalUrl, timestamp = TextReference.Str("${timestamp.toDateFormat()}, ${timestamp.toTimeFormat()}"), fiatSymbol = appCurrency.symbol, statuses = getStatuses(transaction.status?.status), @@ -74,7 +74,7 @@ internal class TokenDetailsSwapTransactionsStateConverter( activeStatus = transaction.status?.status, notification = getNotification( transaction.status?.status, - transaction.status?.txUrl, + transaction.status?.txExternalUrl, ), toCryptoCurrencyId = toCurrency.currency.id, toCryptoAmount = BigDecimalFormatter.formatCryptoAmount( @@ -112,9 +112,9 @@ internal class TokenDetailsSwapTransactionsStateConverter( return tx.copy( activeStatus = statusModel.status, hasFailed = hasFailed, - notification = getNotification(statusModel.status, statusModel.txUrl), + notification = getNotification(statusModel.status, statusModel.txExternalUrl), statuses = getStatuses(statusModel.status, hasFailed), - txUrl = statusModel.txUrl, + txUrl = statusModel.txExternalUrl, ) }