Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-07 16:39:48 +05:00
parent d369d87c2f
commit 1d47d83d70
12 changed files with 64 additions and 2 deletions

View file

@ -48,6 +48,7 @@ internal sealed class SwapAmountUM {
val swapCurrencies: SwapCurrencies,
val swapQuotes: ImmutableList<SwapQuoteUM>,
val selectedQuote: SwapQuoteUM,
val showFCAWarning: Boolean,
// extra data
val appCurrency: AppCurrency?,

View file

@ -24,6 +24,7 @@ import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
import com.tangem.domain.settings.usercountry.models.UserCountry
import com.tangem.domain.swap.models.SwapCurrencies
import com.tangem.domain.notifications.ShouldShowNotificationUseCase
import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions
import com.tangem.domain.swap.models.SwapDirection
import com.tangem.domain.swap.models.SwapDirection.Companion.withSwapDirection
import com.tangem.domain.swap.models.SwapQuoteModel
@ -150,6 +151,7 @@ internal class SwapAmountModel @Inject constructor(
quoteUM = quoteUM,
secondaryMaximumAmountBoundary = secondaryMaximumAmountBoundary,
secondaryMinimumAmountBoundary = secondaryMinimumAmountBoundary,
needApplyFCARestrictions = userCountry.needApplyFCARestrictions(),
),
)
}
@ -533,6 +535,7 @@ internal class SwapAmountModel @Inject constructor(
secondaryMaximumAmountBoundary = secondaryMaximumAmountBoundary,
secondaryMinimumAmountBoundary = secondaryMinimumAmountBoundary,
isSilentReload = isSilentReload,
needApplyFcaRestrictions = userCountry.needApplyFCARestrictions(),
),
)

View file

@ -54,6 +54,7 @@ internal class SwapAmountPrimaryReadyStateTransformer(
selectedQuote = SwapQuoteUM.Empty,
appCurrency = appCurrency,
showBestRateAnimation = showBestRateAnimation,
showFCAWarning = false,
)
}
}

View file

@ -53,6 +53,7 @@ internal class SwapAmountSecondaryReadyStateTransformer(
selectedQuote = SwapQuoteUM.Empty,
appCurrency = appCurrency,
showBestRateAnimation = showBestRateAnimation,
showFCAWarning = false,
)
}
}

View file

@ -11,6 +11,7 @@ import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountUM
import com.tangem.features.swap.v2.impl.amount.model.SwapAmountQuoteUtils.calculatePriceImpact
import com.tangem.features.swap.v2.impl.amount.model.converter.SwapAmountErrorConverter
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM
import com.tangem.features.swap.v2.impl.common.isRestrictedByFCA
import com.tangem.utils.extensions.orZero
import com.tangem.utils.transformer.Transformer
@ -18,6 +19,7 @@ internal class SwapAmountSelectQuoteTransformer(
private val quoteUM: SwapQuoteUM,
private val secondaryMaximumAmountBoundary: EnterAmountBoundary?,
private val secondaryMinimumAmountBoundary: EnterAmountBoundary?,
private val needApplyFCARestrictions: Boolean,
) : Transformer<SwapAmountUM> {
override fun transform(prevState: SwapAmountUM): SwapAmountUM {
if (prevState !is SwapAmountUM.Content) return prevState
@ -29,6 +31,7 @@ internal class SwapAmountSelectQuoteTransformer(
return prevState.copy(
isPrimaryButtonEnabled = quoteUM is SwapQuoteUM.Content,
selectedQuote = quoteUM,
showFCAWarning = needApplyFCARestrictions && quoteUM.provider?.isRestrictedByFCA() == true,
primaryAmount = if (prevState.selectedAmountType == SwapAmountType.From) {
val swapAmountField = prevState.primaryAmount as? SwapAmountFieldUM.Content
val amountField = swapAmountField?.amountField as? AmountState.Data

View file

@ -8,6 +8,7 @@ import com.tangem.domain.express.models.ExpressError
import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountUM
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM.Content.DifferencePercent
import com.tangem.features.swap.v2.impl.common.isRestrictedByFCA
import com.tangem.utils.StringsSigns
import com.tangem.utils.extensions.isPositive
import com.tangem.utils.transformer.Transformer
@ -20,6 +21,7 @@ internal class SwapAmountSetQuotesTransformer(
private val secondaryMaximumAmountBoundary: EnterAmountBoundary?,
private val secondaryMinimumAmountBoundary: EnterAmountBoundary?,
private val isSilentReload: Boolean,
private val needApplyFcaRestrictions: Boolean,
) : Transformer<SwapAmountUM> {
override fun transform(prevState: SwapAmountUM): SwapAmountUM {
if (prevState !is SwapAmountUM.Content) return prevState
@ -36,6 +38,8 @@ internal class SwapAmountSetQuotesTransformer(
quoteUM = selectedQuote,
secondaryMaximumAmountBoundary = secondaryMaximumAmountBoundary,
secondaryMinimumAmountBoundary = secondaryMinimumAmountBoundary,
needApplyFCARestrictions = needApplyFcaRestrictions &&
selectedQuote.provider?.isRestrictedByFCA() == true,
)
val updatedState = selectQuoteTransformer.transform(prevState = prevState)

View file

@ -114,6 +114,7 @@ internal fun SwapAmountBlockContent(
start.linkTo(parent.start)
end.linkTo(parent.end)
},
showFCAWarning = amountUM.showFCAWarning,
)
}
}

View file

@ -89,6 +89,7 @@ internal data object SwapAmountContentPreview {
swapRateType = ExpressRateType.Float,
appCurrency = AppCurrency.Default,
showBestRateAnimation = false,
showFCAWarning = false,
)
val defaultState = SwapAmountUM.Content(
@ -126,5 +127,6 @@ internal data object SwapAmountContentPreview {
swapRateType = ExpressRateType.Float,
isPrimaryButtonEnabled = true,
showBestRateAnimation = false,
showFCAWarning = true,
)
}

View file

@ -23,6 +23,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -33,6 +34,7 @@ import androidx.constraintlayout.compose.Visibility
import coil.compose.SubcomposeAsyncImage
import coil.request.ImageRequest
import com.tangem.core.ui.components.RectangleShimmer
import com.tangem.core.ui.components.SpacerW8
import com.tangem.core.ui.components.SpacerWMax
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemColorPalette
@ -44,6 +46,7 @@ import com.tangem.domain.express.models.ExpressRateType
import com.tangem.features.swap.v2.impl.R
import kotlinx.coroutines.delay
@Suppress("LongParameterList")
@Composable
fun SwapChooseProviderContent(
expressProvider: ExpressProvider?,
@ -51,6 +54,7 @@ fun SwapChooseProviderContent(
showBestRateAnimation: Boolean,
onClick: () -> Unit,
onFinishAnimation: () -> Unit,
showFCAWarning: Boolean,
modifier: Modifier = Modifier,
) {
Column(
@ -83,6 +87,32 @@ fun SwapChooseProviderContent(
SpacerWMax()
ProviderInfo(expressProvider, isBestRate, showBestRateAnimation, onFinishAnimation)
}
if (showFCAWarning) {
FcaProviderWarning(
modifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 4.dp, bottom = 12.dp),
)
}
}
}
@Composable
private fun FcaProviderWarning(modifier: Modifier = Modifier) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier = Modifier.size(TangemTheme.dimens.size16),
painter = painterResource(id = R.drawable.ic_warning_16),
tint = TangemTheme.colors.icon.informative,
contentDescription = null,
)
SpacerW8()
Text(
text = stringResourceSafe(R.string.express_provider_in_fca_warning_list),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
}
}
@ -281,6 +311,7 @@ private fun SwapChooseProviderContent_Preview() {
slippage = null,
),
onClick = {},
showFCAWarning = true,
onFinishAnimation = {},
)
}