Updated on 2026-08-14
This commit is contained in:
parent
ff2559df3e
commit
0bbc78f821
15 changed files with 368 additions and 17 deletions
|
|
@ -28,4 +28,8 @@ internal class DefaultSwapFeatureToggles @Inject constructor(
|
|||
override val isSwapRateExperienceEnabled: Boolean = featureTogglesManager.isFeatureEnabled(
|
||||
toggle = FeatureToggles.AND_15103_SWAP_RATE_EXPERIENCE_ENABLED,
|
||||
)
|
||||
|
||||
override val isSwapPredefinedButtonsEnabled: Boolean = featureTogglesManager.isFeatureEnabled(
|
||||
toggle = FeatureToggles.AND_15122_SWAP_PREDEFINED_BUTTONS_ENABLED,
|
||||
)
|
||||
}
|
||||
|
|
@ -62,7 +62,9 @@ import com.tangem.domain.settings.usercountry.models.UserCountry
|
|||
import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions
|
||||
import com.tangem.domain.stories.ShouldShowStoriesUseCase
|
||||
import com.tangem.domain.stories.models.StoryContentIds
|
||||
import com.tangem.domain.swap.models.PredefinedPercentAmount
|
||||
import com.tangem.domain.swap.models.SwapCurrencyStatus
|
||||
import com.tangem.domain.swap.usecase.CalculateAmountUseCase
|
||||
import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayWithdrawUseCase
|
||||
import com.tangem.domain.tokens.GetMinimumTransactionAmountSyncUseCase
|
||||
|
|
@ -162,6 +164,7 @@ internal class SwapModel @Inject constructor(
|
|||
swapFeatureToggles: SwapFeatureToggles,
|
||||
private val getSwapUiModeUseCase: GetSwapUiModeUseCase,
|
||||
private val setSwapUiModeUseCase: SetSwapUiModeUseCase,
|
||||
private val calculateAmountUseCase: CalculateAmountUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<SwapComponent.Params>()
|
||||
|
|
@ -1514,6 +1517,25 @@ internal class SwapModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun onPredefinedPercentSelected(percent: PredefinedPercentAmount) {
|
||||
if (percent == PredefinedPercentAmount.MAX) {
|
||||
onMaxAmountClicked()
|
||||
return
|
||||
}
|
||||
val fromCurrency = dataState.fromSwapCurrencyStatus ?: return
|
||||
val newValue = calculateAmountUseCase(
|
||||
balance = fromCurrency.status.value.amount ?: BigDecimal.ZERO,
|
||||
decimals = fromCurrency.status.currency.decimals,
|
||||
percent = percent,
|
||||
)
|
||||
onAmountChanged(
|
||||
SwapAmount(
|
||||
value = newValue,
|
||||
decimals = fromCurrency.status.currency.decimals,
|
||||
).formatToUIRepresentation(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onReduceAmountClicked(newAmount: SwapAmount, reduceBalanceBy: BigDecimal = BigDecimal.ZERO) {
|
||||
onAmountChanged(
|
||||
value = newAmount.formatToUIRepresentation(),
|
||||
|
|
@ -1658,6 +1680,7 @@ internal class SwapModel @Inject constructor(
|
|||
}
|
||||
},
|
||||
onMaxAmountSelected = ::onMaxAmountClicked,
|
||||
onPredefinedPercentSelected = ::onPredefinedPercentSelected,
|
||||
onReduceToAmount = ::onReduceAmountClicked,
|
||||
onReduceByAmount = ::onReduceAmountClicked,
|
||||
openPermissionBottomSheet = {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.common.ui.notifications.NotificationUM
|
|||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.swap.models.PredefinedPercentAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.feature.swap.domain.models.ui.PriceImpact
|
||||
import com.tangem.feature.swap.models.states.ProviderState
|
||||
|
|
@ -32,6 +33,7 @@ internal data class SwapStateHolder(
|
|||
val tosState: TosState? = null,
|
||||
val swapUIMode: SwapUIMode = SwapUIMode.Detailed,
|
||||
val shouldShowAbMenu: Boolean = false,
|
||||
val isPredefinedButtonsEnabled: Boolean = false,
|
||||
|
||||
val transferFooter: TextReference? = null,
|
||||
|
||||
|
|
@ -41,6 +43,7 @@ internal data class SwapStateHolder(
|
|||
val onSelectTokenClick: ((TokenSelectionDirection) -> Unit),
|
||||
val onSuccess: (() -> Unit),
|
||||
val onMaxAmountSelected: (() -> Unit)? = null,
|
||||
val onPredefinedPercentSelected: ((PredefinedPercentAmount) -> Unit)? = null,
|
||||
val onShowPermissionBottomSheet: () -> Unit = {},
|
||||
val onSwapUIModeChange: (SwapUIMode) -> Unit = {},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.swap.models
|
|||
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.express.models.ProviderFilterType
|
||||
import com.tangem.domain.swap.models.PredefinedPercentAmount
|
||||
import com.tangem.feature.swap.domain.models.SwapAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -14,6 +15,7 @@ internal data class UiActions(
|
|||
val onChangeCardsClicked: () -> Unit,
|
||||
val onBackClicked: () -> Unit,
|
||||
val onMaxAmountSelected: () -> Unit,
|
||||
val onPredefinedPercentSelected: (PredefinedPercentAmount) -> Unit,
|
||||
val onReduceToAmount: (SwapAmount) -> Unit,
|
||||
val onReduceByAmount: (SwapAmount, reduceBy: BigDecimal) -> Unit,
|
||||
val openPermissionBottomSheet: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ internal class StateBuilder(
|
|||
onBackClicked = actions.onBackClicked,
|
||||
onChangeCardsClicked = actions.onChangeCardsClicked,
|
||||
onMaxAmountSelected = actions.onMaxAmountSelected,
|
||||
onPredefinedPercentSelected = actions.onPredefinedPercentSelected,
|
||||
changeCardsButtonState = ChangeCardsButtonState.DISABLED,
|
||||
onShowPermissionBottomSheet = actions.openPermissionBottomSheet,
|
||||
onSelectTokenClick = actions.onSelectTokenClick,
|
||||
|
|
@ -108,6 +109,7 @@ internal class StateBuilder(
|
|||
swapUIMode = swapUIMode,
|
||||
onSwapUIModeChange = actions.onSwapUIModeChange,
|
||||
shouldShowAbMenu = swapFeatureToggles.isSwapAbEnabled,
|
||||
isPredefinedButtonsEnabled = swapFeatureToggles.isSwapPredefinedButtonsEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,13 +33,17 @@ import androidx.constraintlayout.compose.ConstraintLayout
|
|||
import com.tangem.common.ui.footers.SendingText
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.components.buttons.predefined.PredefinedPercentButtonUM
|
||||
import com.tangem.core.ui.components.buttons.predefined.PredefinedPercentButtonsRow
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.SwapTokenScreenTestTags
|
||||
import com.tangem.domain.swap.models.PredefinedPercentAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.feature.swap.domain.models.ui.PriceImpact
|
||||
import com.tangem.feature.swap.models.*
|
||||
|
|
@ -49,6 +53,7 @@ import com.tangem.feature.swap.presentation.R
|
|||
import com.tangem.feature.swap.ui.preview.SwapTransactionCardPreview.receiveCard
|
||||
import com.tangem.feature.swap.ui.preview.SwapTransactionCardPreview.sendCard
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
|
|
@ -111,26 +116,49 @@ internal fun SwapScreenContent(
|
|||
}
|
||||
|
||||
if (state.shouldShowMaxAmount && keyboard is Keyboard.Opened) {
|
||||
Text(
|
||||
text = stringResourceSafe(id = R.string.send_max_amount_label),
|
||||
style = TangemTheme.typography.button,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.imePadding()
|
||||
.fillMaxWidth()
|
||||
.background(TangemTheme.colors.button.secondary)
|
||||
.clickable { state.onMaxAmountSelected?.invoke() }
|
||||
.padding(
|
||||
horizontal = TangemTheme.dimens.spacing14,
|
||||
vertical = TangemTheme.dimens.spacing16,
|
||||
),
|
||||
textAlign = TextAlign.Start,
|
||||
)
|
||||
val onPercentClick = state.onPredefinedPercentSelected
|
||||
if (state.isPredefinedButtonsEnabled && onPercentClick != null) {
|
||||
PredefinedPercentButtonsRow(
|
||||
items = PredefinedPercentAmount.entries.map { percent ->
|
||||
PredefinedPercentButtonUM(
|
||||
id = percent.name,
|
||||
label = percent.toLabel(),
|
||||
onClick = { onPercentClick(percent) },
|
||||
)
|
||||
}.toImmutableList(),
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.imePadding(),
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = stringResourceSafe(id = R.string.send_max_amount_label),
|
||||
style = TangemTheme.typography.button,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.imePadding()
|
||||
.fillMaxWidth()
|
||||
.background(TangemTheme.colors.button.secondary)
|
||||
.clickable { state.onMaxAmountSelected?.invoke() }
|
||||
.padding(
|
||||
horizontal = TangemTheme.dimens.spacing14,
|
||||
vertical = TangemTheme.dimens.spacing16,
|
||||
),
|
||||
textAlign = TextAlign.Start,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun PredefinedPercentAmount.toLabel() = when (this) {
|
||||
PredefinedPercentAmount.PERCENT_25 -> stringReference("25%")
|
||||
PredefinedPercentAmount.PERCENT_50 -> stringReference("50%")
|
||||
PredefinedPercentAmount.PERCENT_75 -> stringReference("75%")
|
||||
PredefinedPercentAmount.MAX -> resourceReference(R.string.send_max_amount)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainInfo(state: SwapStateHolder) {
|
||||
ConstraintLayout(
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ internal class StateBuilderInitialStateTest {
|
|||
isAccountsModeProvider = isAccountsModeProvider,
|
||||
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
|
||||
swapFeatureToggles = swapFeatureToggles,
|
||||
appRouter = appRouter
|
||||
appRouter = appRouter,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue