Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-29 21:24:01 +03:00
parent 8a74fcc5fb
commit c483364df1
7 changed files with 115 additions and 24 deletions

View file

@ -28,6 +28,7 @@ import com.tangem.domain.models.wallet.isMultiCurrency
import com.tangem.domain.tokens.GetMinimumTransactionAmountSyncUseCase
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.features.send.v2.api.SendFeatureToggles
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.api.subcomponents.amount.analytics.CommonSendAmountAnalyticEvents
@ -66,6 +67,7 @@ internal class SendAmountModel @Inject constructor(
private val getUserWalletUseCase: GetUserWalletUseCase,
private val rampStateManager: RampStateManager,
private val sendAmountAlertFactory: SendAmountAlertFactory,
private val getWalletsUseCase: GetWalletsUseCase,
) : Model(), SendAmountClickIntents {
private val params: SendAmountComponentParams = paramsContainer.require()
@ -176,6 +178,7 @@ internal class SendAmountModel @Inject constructor(
private fun initialState() {
if (uiState.value is AmountState.Empty && userWallet != null) {
val isSingleWallet = getWalletsUseCase.invokeSync().size == 1
_uiState.update {
AmountStateConverterV2(
clickIntents = this,
@ -187,10 +190,14 @@ internal class SendAmountModel @Inject constructor(
isBalanceHidden = params.isBalanceHidingFlow.value,
).convert(
AmountParameters(
title = resourceReference(
R.string.send_from_wallet_name,
WrappedList(listOf(userWallet?.name.orEmpty())), // TODO [REDACTED_TASK_KEY]
),
title = if (isSingleWallet) {
resourceReference(R.string.send_from_title)
} else {
resourceReference(
R.string.send_from_wallet_name,
WrappedList(listOf(userWallet?.name.orEmpty())), // TODO [REDACTED_TASK_KEY]
)
},
value = "",
),
)

View file

@ -35,6 +35,7 @@ import com.tangem.domain.swap.usecase.GetSwapQuoteUseCase
import com.tangem.domain.swap.usecase.SelectInitialPairUseCase
import com.tangem.domain.tokens.GetMinimumTransactionAmountSyncUseCase
import com.tangem.domain.transaction.usecase.GetAllowanceUseCase
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.features.send.v2.api.subcomponents.amount.analytics.CommonSendAmountAnalyticEvents
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
import com.tangem.features.swap.v2.api.choosetoken.SwapChooseTokenNetworkListener
@ -91,6 +92,7 @@ internal class SwapAmountModel @Inject constructor(
private val feeSelectorReloadTrigger: FeeSelectorReloadTrigger,
private val shouldShowNotificationUseCase: ShouldShowNotificationUseCase,
private val analyticsEventHandler: AnalyticsEventHandler,
private val getWalletsUseCase: GetWalletsUseCase,
) : Model(), SwapAmountClickIntents, SwapChooseProviderComponent.ModelCallback {
private val params: SwapAmountComponentParams = paramsContainer.require()
@ -328,21 +330,18 @@ internal class SwapAmountModel @Inject constructor(
}
private fun subscribeOnBalanceHiddenUpdates() {
params.isBalanceHidingFlow.onEach {
val primaryCryptoCurrencyStatus = (uiState.value as? SwapAmountUM.Content)?.primaryCryptoCurrencyStatus
if (primaryCryptoCurrencyStatus != null) {
uiState.transformerUpdate(
SwapAmountPrimaryReadyStateTransformer(
userWallet = userWallet,
primaryCryptoCurrencyStatus = primaryCryptoCurrencyStatus,
appCurrency = appCurrency,
swapDirection = swapDirection,
clickIntents = this,
isBalanceHidden = params.isBalanceHidingFlow.value,
showBestRateAnimation = showBestRateAnimation,
),
)
}
params.isBalanceHidingFlow.onEach { isHidden ->
val isSingleWallet = getWalletsUseCase.invokeSync().size == 1
uiState.transformerUpdate(
SwapAmountBalanceHiddenTransformer(
isBalanceHidden = isHidden,
isSingleWallet = isSingleWallet,
userWallet = userWallet,
appCurrency = appCurrency,
swapDirection = swapDirection,
clickIntents = this,
),
)
}.launchIn(modelScope)
}
@ -352,6 +351,7 @@ internal class SwapAmountModel @Inject constructor(
val primaryCryptoCurrencyStatus = (uiState.value as? SwapAmountUM.Content)?.primaryCryptoCurrencyStatus
if (primaryCryptoCurrencyStatus != null) {
val isSingleWallet = getWalletsUseCase.invokeSync().size == 1
uiState.transformerUpdate(
SwapAmountPrimaryReadyStateTransformer(
userWallet = userWallet,
@ -361,6 +361,7 @@ internal class SwapAmountModel @Inject constructor(
clickIntents = this,
isBalanceHidden = params.isBalanceHidingFlow.value,
showBestRateAnimation = showBestRateAnimation,
isSingleWallet = isSingleWallet,
),
)
}
@ -386,6 +387,7 @@ internal class SwapAmountModel @Inject constructor(
),
)
} else {
val isSingleWallet = getWalletsUseCase.invokeSync().size == 1
uiState.transformerUpdate(
SwapAmountPrimaryReadyStateTransformer(
userWallet = userWallet,
@ -395,6 +397,7 @@ internal class SwapAmountModel @Inject constructor(
clickIntents = this,
isBalanceHidden = params.isBalanceHidingFlow.value,
showBestRateAnimation = showBestRateAnimation,
isSingleWallet = isSingleWallet,
),
)
}
@ -492,6 +495,7 @@ internal class SwapAmountModel @Inject constructor(
val primaryStatus = (uiState.value as? SwapAmountUM.Content)?.primaryCryptoCurrencyStatus
if (secondaryStatus != null && primaryStatus != null) {
initCurrencies(primaryStatus, secondaryStatus)
val isSingleWallet = getWalletsUseCase.invokeSync().size == 1
uiState.transformerUpdate(
SwapAmountSecondaryReadyStateTransformer(
userWallet = userWallet,
@ -503,6 +507,7 @@ internal class SwapAmountModel @Inject constructor(
clickIntents = this@SwapAmountModel,
isBalanceHidden = params.isBalanceHidingFlow.value,
showBestRateAnimation = showBestRateAnimation,
isSingleWallet = isSingleWallet,
),
)
startLoadingQuotesTask(isSilentReload = false)

View file

@ -25,6 +25,7 @@ internal class SwapAmountFieldConverter(
private val userWallet: UserWallet,
private val appCurrency: AppCurrency,
private val clickIntents: AmountScreenClickIntents,
private val isSingleWallet: Boolean,
) {
private val iconStateConverter = CryptoCurrencyToIconStateConverter()
@ -51,11 +52,15 @@ internal class SwapAmountFieldConverter(
isBalanceHidden = isBalanceHidden,
).convert(
AmountParameters(
title = combinedReference(
resourceReference(R.string.send_from_wallet_android),
stringReference(" "),
stringReference(userWallet.name),
),
title = if (isSingleWallet) {
resourceReference(R.string.send_from_title)
} else {
combinedReference(
resourceReference(R.string.send_from_wallet_android),
stringReference(" "),
stringReference(userWallet.name),
)
},
value = "",
),
),

View file

@ -0,0 +1,66 @@
package com.tangem.features.swap.v2.impl.amount.model.transformers
import com.tangem.common.ui.amountScreen.AmountScreenClickIntents
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.swap.models.SwapDirection
import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountFieldUM
import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountType
import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountUM
import com.tangem.features.swap.v2.impl.amount.model.converter.SwapAmountFieldConverter
import com.tangem.utils.transformer.Transformer
internal class SwapAmountBalanceHiddenTransformer(
private val isBalanceHidden: Boolean,
private val isSingleWallet: Boolean,
private val userWallet: UserWallet,
private val appCurrency: AppCurrency,
private val swapDirection: SwapDirection,
private val clickIntents: AmountScreenClickIntents,
) : Transformer<SwapAmountUM> {
override fun transform(prevState: SwapAmountUM): SwapAmountUM {
val content = prevState as? SwapAmountUM.Content ?: return prevState
val amountFieldConverter = SwapAmountFieldConverter(
swapDirection = swapDirection,
isBalanceHidden = isBalanceHidden,
userWallet = userWallet,
appCurrency = appCurrency,
clickIntents = clickIntents,
isSingleWallet = isSingleWallet,
)
val recalculatedPrimary = amountFieldConverter.convert(
selectedType = SwapAmountType.From,
cryptoCurrencyStatus = content.primaryCryptoCurrencyStatus,
) as SwapAmountFieldUM.Content
val oldPrimary = content.primaryAmount as? SwapAmountFieldUM.Content
val mergedAmountField = if (
oldPrimary?.amountField is AmountState.Data && recalculatedPrimary.amountField is AmountState.Data
) {
val oldData = oldPrimary.amountField
val newData = recalculatedPrimary.amountField
newData.copy(
amountTextField = oldData.amountTextField,
selectedButton = oldData.selectedButton,
isPrimaryButtonEnabled = oldData.isPrimaryButtonEnabled,
isSegmentedButtonsEnabled = oldData.isSegmentedButtonsEnabled,
isEditingDisabled = oldData.isEditingDisabled,
reduceAmountBy = oldData.reduceAmountBy,
isIgnoreReduce = oldData.isIgnoreReduce,
)
} else {
recalculatedPrimary.amountField
}
val updatedPrimaryAmount = recalculatedPrimary.copy(
amountField = mergedAmountField,
)
return content.copy(primaryAmount = updatedPrimaryAmount)
}
}

View file

@ -24,6 +24,7 @@ internal class SwapAmountPrimaryReadyStateTransformer(
private val swapDirection: SwapDirection,
private val isBalanceHidden: Boolean,
private val showBestRateAnimation: Boolean,
private val isSingleWallet: Boolean,
) : Transformer<SwapAmountUM> {
private val amountFieldConverter = SwapAmountFieldConverter(
@ -32,6 +33,7 @@ internal class SwapAmountPrimaryReadyStateTransformer(
userWallet = userWallet,
appCurrency = appCurrency,
clickIntents = clickIntents,
isSingleWallet = isSingleWallet,
)
override fun transform(prevState: SwapAmountUM): SwapAmountUM {

View file

@ -25,6 +25,7 @@ internal class SwapAmountSecondaryReadyStateTransformer(
private val swapDirection: SwapDirection,
private val isBalanceHidden: Boolean,
private val showBestRateAnimation: Boolean,
private val isSingleWallet: Boolean,
) : Transformer<SwapAmountUM> {
private val amountFieldConverter = SwapAmountFieldConverter(
@ -33,6 +34,7 @@ internal class SwapAmountSecondaryReadyStateTransformer(
userWallet = userWallet,
appCurrency = appCurrency,
clickIntents = clickIntents,
isSingleWallet = isSingleWallet,
)
override fun transform(prevState: SwapAmountUM): SwapAmountUM {