Updated on 2026-08-14
This commit is contained in:
parent
531fdf166f
commit
3d73befd95
22 changed files with 94 additions and 111 deletions
|
|
@ -12,7 +12,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="@string/send_network_fee_title"
|
||||
android:text="@string/common_network_fee_title"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/flExpandCollapse"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
<string name="send_fee_picker_normal">Normal</string>
|
||||
<string name="send_fee_picker_priority">Priorität</string>
|
||||
<string name="send_max_amount_label">Höchstbetrag</string>
|
||||
<string name="send_network_fee_title">Netzgebühr</string>
|
||||
<string name="common_network_fee_title">Netzgebühr</string>
|
||||
<string name="send_total_label">Gesamt</string>
|
||||
<string name="send_total_subtitle_asset_format">%1$s und %2$s werden gesendet</string>
|
||||
<string name="send_total_subtitle_fiat_format">≈ %1$s (inkl. Gebühr: %2$s)</string>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
<string name="send_fee_picker_normal">Normal</string>
|
||||
<string name="send_fee_picker_priority">Priorité</string>
|
||||
<string name="send_max_amount_label">Somme maximale</string>
|
||||
<string name="send_network_fee_title">Commissions du réseau</string>
|
||||
<string name="common_network_fee_title">Commissions du réseau</string>
|
||||
<string name="send_total_label">Total</string>
|
||||
<string name="send_total_subtitle_asset_format">Sera envoyé %1$s et %2$s</string>
|
||||
<string name="send_total_subtitle_fiat_format">≈ %1$s (incl. les commissions : %2$s)</string>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
<string name="send_fee_picker_normal">Normale</string>
|
||||
<string name="send_fee_picker_priority">Prioritario</string>
|
||||
<string name="send_max_amount_label">Importo totale</string>
|
||||
<string name="send_network_fee_title">Costi della rete</string>
|
||||
<string name="common_network_fee_title">Costi della rete</string>
|
||||
<string name="send_total_label">Totale</string>
|
||||
<string name="send_total_subtitle_asset_format">Sarà inviato %1$s e %2$s</string>
|
||||
<string name="send_total_subtitle_fiat_format">≈ %1$s (inc. commissione: %2$s)</string>
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@
|
|||
<string name="express_provider_not_available">Недоступно для этой пары</string>
|
||||
<string name="express_provider_permission_needed">Требуется разрешение</string>
|
||||
<string name="express_terms_of_use">Условиями использования</string>
|
||||
<string name="express_by_provider">Предоставлено</string>
|
||||
<string name="feedback_data_collection_message">Информация ниже не является обязательной. Вы можете стереть её, если хотите.</string>
|
||||
<string name="feedback_preface_rate_negative">Расскажите, каких функций вам не хватает, и мы постараемся вам помочь.</string>
|
||||
<string name="feedback_preface_scan_failed">Скажите, пожалуйста, какая у вас карта?</string>
|
||||
|
|
@ -469,7 +470,7 @@
|
|||
<string name="send_max_amount_label">Максимальная сумма</string>
|
||||
<string name="send_max_fee">Комиссия не превысит </string>
|
||||
<string name="send_max_fee_footer">Максимальная cумма комиссии</string>
|
||||
<string name="send_network_fee_title">Сетевая комиссия</string>
|
||||
<string name="common_network_fee_title">Сетевая комиссия</string>
|
||||
<string name="send_network_fee_warning_content">Сумма отправки будет уменьшена для покрытия выбранного уровня комиссии</string>
|
||||
<string name="send_network_fee_warning_title">Покрытие сетевой комиссии</string>
|
||||
<string name="send_notification_exceed_balance_text">Недостаточно средств для перевода, так как сумма комиссии и сумма перевода в совокупности больше имеющегося баланса</string>
|
||||
|
|
@ -529,7 +530,6 @@
|
|||
<string name="swapping_from_title">Вы отправляете</string>
|
||||
<string name="swapping_generic_error">Произошла ошибка. Пожалуйста, попробуйте еще раз.</string>
|
||||
<string name="swapping_give_permission">Дать разрешение</string>
|
||||
<string name="swapping_high_price_impact">Сильные колебания цены!</string>
|
||||
<string name="swapping_high_price_impact_description">Обмен этой суммы выбранных токенов может вызвать значительные колебания цены и уменьшить получаемую сумму.</string>
|
||||
<string name="swapping_insufficient_funds">Недостаточно средств</string>
|
||||
<string name="swapping_not_enough_funds_for_fee">Недостаточно средств для оплаты комиссии на вашем %1$s кошельке для создания транзакции. Сначала пополните свой %2$s кошелек.</string>
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@
|
|||
<string name="send_fee_picker_normal">正常</string>
|
||||
<string name="send_fee_picker_priority">優先</string>
|
||||
<string name="send_max_amount_label">最大值</string>
|
||||
<string name="send_network_fee_title">網路費</string>
|
||||
<string name="common_network_fee_title">網路費</string>
|
||||
<string name="send_title_currency_format">發送 %s</string>
|
||||
<string name="send_total_label">總計</string>
|
||||
<string name="send_total_subtitle_asset_format">%1$s 和 %2$s 將被發送</string>
|
||||
|
|
@ -329,7 +329,6 @@
|
|||
<string name="swapping_error_wrapper">錯誤: %s</string>
|
||||
<string name="swapping_generic_error">有錯誤。請再試一遍</string>
|
||||
<string name="swapping_give_permission">賦予權限</string>
|
||||
<string name="swapping_high_price_impact">價格影響高!</string>
|
||||
<string name="swapping_high_price_impact_description">在此代幣交換的數量將對價格產生重大影響,並降低您收到的數量</string>
|
||||
<string name="swapping_insufficient_funds">餘額不足</string>
|
||||
<string name="swapping_not_enough_funds_for_fee">您的 %1$s 錢包中沒有足夠的資金來創建交易。首先為您的 %2$s 錢包充值</string>
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@
|
|||
<string name="express_more_providers_soon">More providers are coming soon.\nStay tuned!</string>
|
||||
<string name="express_estimated_amount">Estimated amount</string>
|
||||
<string name="express_exchange_by">Exchange by %s</string>
|
||||
<string name="express_by_provider">Provided by</string>
|
||||
<string name="express_exchange_notification_failed_text">Visit provider’s website to refund your money</string>
|
||||
<string name="express_exchange_notification_failed_title">Operation failed by provider</string>
|
||||
<string name="express_exchange_notification_verification_text">Visit provider’s website for verification</string>
|
||||
|
|
@ -474,7 +475,7 @@
|
|||
<string name="send_max_fee">Max fee</string>
|
||||
<string name="send_max_fee_footer">Maximum fee amount</string>
|
||||
<string name="send_memo_destination_tag_error">Numbers only for Destination Tag</string>
|
||||
<string name="send_network_fee_title">Network fee</string>
|
||||
<string name="common_network_fee_title">Network fee</string>
|
||||
<string name="send_network_fee_warning_content">Sending amount will be reduced to cover the selected fee level</string>
|
||||
<string name="send_network_fee_warning_title">Network fee coverage</string>
|
||||
<string name="send_notification_exceed_balance_text">Insufficient funds for the transfer, as the total of the fee and transfer amount exceeds the existing balance</string>
|
||||
|
|
@ -546,7 +547,6 @@
|
|||
<string name="swapping_from_title">You swap</string>
|
||||
<string name="swapping_generic_error">There was an error. Please try again.</string>
|
||||
<string name="swapping_give_permission">Give Permission</string>
|
||||
<string name="swapping_high_price_impact">High price impact!</string>
|
||||
<string name="swapping_high_price_impact_description">Swapping this amount of selected tokens will cause a significant price impact and reduce your outcome.</string>
|
||||
<string name="swapping_insufficient_funds">Insufficient funds</string>
|
||||
<string name="swapping_not_enough_funds_for_fee">Insufficient funds in your %1$s wallet to cover fees. Top up your %2$s wallet first.</string>
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ private fun FeeBlock(feeState: SendStates.FeeState, isSuccess: Boolean, onClick:
|
|||
decimals = fee.amount.decimals,
|
||||
)
|
||||
InputRowDefault(
|
||||
title = TextReference.Res(R.string.send_network_fee_title),
|
||||
title = TextReference.Res(R.string.common_network_fee_title),
|
||||
text = TextReference.Str(feeValue),
|
||||
modifier = Modifier
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ sealed class PriceImpact {
|
|||
|
||||
fun getIntPercentValue() = (value * HUNDRED_PERCENTS).toInt()
|
||||
data class Empty(override val value: Float = 0f) : PriceImpact()
|
||||
data class ValueWithNotify(override val value: Float) : PriceImpact()
|
||||
data class Value(override val value: Float) : PriceImpact()
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -834,7 +834,6 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
toTokenAmount = quoteModel.toTokenAmount,
|
||||
swapData = null,
|
||||
txFeeState = txFee,
|
||||
exchangeProviderType = exchangeProviderType,
|
||||
).copy(
|
||||
warnings = manageWarnings(fromToken, amount, txFee),
|
||||
)
|
||||
|
|
@ -997,7 +996,6 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
toTokenAmount = swapData.toTokenAmount,
|
||||
swapData = swapData,
|
||||
txFeeState = txFeeState,
|
||||
exchangeProviderType = ExchangeProviderType.DEX,
|
||||
)
|
||||
swapState.copy(
|
||||
permissionState = PermissionDataState.Empty,
|
||||
|
|
@ -1037,7 +1035,6 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
toTokenAmount: SwapAmount,
|
||||
swapData: SwapDataModel?,
|
||||
txFeeState: TxFeeState,
|
||||
exchangeProviderType: ExchangeProviderType,
|
||||
): SwapState.QuotesLoadedState {
|
||||
val fromToken = fromTokenStatus.currency
|
||||
val toToken = toTokenStatus.currency
|
||||
|
|
@ -1062,7 +1059,6 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
fromRate = rates[fromToken.id]?.fiatRate?.toDouble() ?: 0.0,
|
||||
toTokenAmount = toTokenAmount.value,
|
||||
toRate = rates[toToken.id]?.fiatRate?.toDouble() ?: 0.0,
|
||||
exchangeProviderType = exchangeProviderType,
|
||||
),
|
||||
networkCurrency = userWalletManager.getNetworkCurrency(networkId),
|
||||
swapDataModel = swapData,
|
||||
|
|
@ -1411,15 +1407,11 @@ internal class SwapInteractorImpl @Inject constructor(
|
|||
fromRate: Double,
|
||||
toTokenAmount: BigDecimal,
|
||||
toRate: Double,
|
||||
exchangeProviderType: ExchangeProviderType,
|
||||
): PriceImpact {
|
||||
val fromTokenFiatValue = fromTokenAmount.multiply(fromRate.toBigDecimal())
|
||||
val toTokenFiatValue = toTokenAmount.multiply(toRate.toBigDecimal())
|
||||
val value = (BigDecimal.ONE - toTokenFiatValue.divide(fromTokenFiatValue, 2, RoundingMode.HALF_UP)).toFloat()
|
||||
if (exchangeProviderType == ExchangeProviderType.CEX) {
|
||||
return PriceImpact.Value(value)
|
||||
}
|
||||
return PriceImpact.ValueWithNotify(value)
|
||||
return PriceImpact.Value(value)
|
||||
}
|
||||
|
||||
private suspend fun getApproveData(
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ sealed interface TransactionCardType {
|
|||
) : TransactionCardType
|
||||
|
||||
data class ReadOnly(
|
||||
val highPriceImpact: String? = null,
|
||||
val onWarningClick: (() -> Unit)? = null,
|
||||
@StringRes override val headerResId: Int = R.string.swapping_to_title,
|
||||
) : TransactionCardType
|
||||
}
|
||||
|
|
@ -104,18 +104,12 @@ sealed interface SwapWarning {
|
|||
object InsufficientFunds : SwapWarning
|
||||
data class NoAvailableTokensToSwap(val notificationConfig: NotificationConfig) : SwapWarning
|
||||
data class GenericWarning(
|
||||
val message: String? = null,
|
||||
val message: TextReference? = null,
|
||||
val type: GenericWarningType = GenericWarningType.OTHER,
|
||||
val shouldWrapMessage: Boolean = false,
|
||||
val onClick: () -> Unit,
|
||||
) : SwapWarning
|
||||
// data class RateExpired(val onClick: () -> Unit) : SwapWarning
|
||||
/**
|
||||
* High price impact warning
|
||||
*
|
||||
* @property priceImpact in format = 10 (means 10%)
|
||||
*/
|
||||
data class HighPriceImpact(val priceImpact: Int, val notificationConfig: NotificationConfig) : SwapWarning
|
||||
data class GeneralError(val notificationConfig: NotificationConfig) : SwapWarning
|
||||
data class UnableToCoverFeeWarning(val notificationConfig: NotificationConfig) : SwapWarning
|
||||
data class GeneralWarning(val notificationConfig: NotificationConfig) : SwapWarning
|
||||
|
|
|
|||
|
|
@ -23,4 +23,5 @@ data class UiActions(
|
|||
val onBuyClick: () -> Unit,
|
||||
val onPolicyClick: (String) -> Unit,
|
||||
val onTosClick: (String) -> Unit,
|
||||
val onReceiveCardWarningClick: () -> Unit,
|
||||
)
|
||||
|
|
@ -11,7 +11,6 @@ sealed class FeeItemState {
|
|||
val amountCrypto: String,
|
||||
val symbolCrypto: String,
|
||||
val amountFiatFormatted: String,
|
||||
val explanation: TextReference?,
|
||||
val isClickable: Boolean,
|
||||
val onClick: () -> Unit,
|
||||
) : FeeItemState()
|
||||
|
|
|
|||
|
|
@ -109,7 +109,6 @@ private fun ChooseFeeBottomSheetContent_Preview() {
|
|||
amountCrypto = "1000",
|
||||
symbolCrypto = "MATIC",
|
||||
amountFiatFormatted = "(10$)",
|
||||
explanation = null,
|
||||
isClickable = false,
|
||||
onClick = {},
|
||||
),
|
||||
|
|
@ -119,7 +118,6 @@ private fun ChooseFeeBottomSheetContent_Preview() {
|
|||
amountCrypto = "2000",
|
||||
symbolCrypto = "MATIC",
|
||||
amountFiatFormatted = "(10$)",
|
||||
explanation = null,
|
||||
isClickable = false,
|
||||
onClick = {},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ package com.tangem.feature.swap.ui
|
|||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -26,13 +24,12 @@ fun FeeItemBlock(state: FeeItemState) {
|
|||
|
||||
@Composable
|
||||
fun FeeItem(state: FeeItemState.Content) {
|
||||
Column(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = TangemTheme.colors.background.action,
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
)
|
||||
.padding(start = TangemTheme.dimens.spacing12)
|
||||
.clip(shape = TangemTheme.shapes.roundedCornersXMedium)
|
||||
.clickable(
|
||||
onClick = state.onClick,
|
||||
|
|
@ -43,32 +40,13 @@ fun FeeItem(state: FeeItemState.Content) {
|
|||
val description = "${state.amountCrypto} ${state.symbolCrypto} (${state.amountFiatFormatted})"
|
||||
SimpleActionRow(
|
||||
modifier = Modifier.padding(
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
top = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
title = state.title.resolveReference(),
|
||||
description = description,
|
||||
isClickable = state.isClickable,
|
||||
)
|
||||
state.explanation?.let {
|
||||
Divider(
|
||||
color = TangemTheme.colors.stroke.primary,
|
||||
thickness = TangemTheme.dimens.size0_5,
|
||||
modifier = Modifier.padding(
|
||||
top = TangemTheme.dimens.spacing10,
|
||||
bottom = TangemTheme.dimens.spacing10,
|
||||
end = TangemTheme.dimens.spacing2,
|
||||
),
|
||||
)
|
||||
Text(
|
||||
text = it.resolveReference(),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.padding(
|
||||
bottom = TangemTheme.dimens.spacing10,
|
||||
end = TangemTheme.dimens.spacing16,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,10 +59,6 @@ private fun FeeItemPreview() {
|
|||
amountCrypto = "1000",
|
||||
symbolCrypto = "MATIC",
|
||||
amountFiatFormatted = "(1000$)",
|
||||
explanation = stringReference(
|
||||
"Additionally, the network fee for sending the exchanged funds back to your address is " +
|
||||
"included in the rate",
|
||||
),
|
||||
isClickable = false,
|
||||
onClick = {},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -113,6 +113,12 @@ private fun ProviderContentState(
|
|||
modifier = Modifier.padding(start = TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
Row {
|
||||
Text(
|
||||
text = stringResource(id = R.string.express_by_provider),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.padding(end = TangemTheme.dimens.spacing4),
|
||||
)
|
||||
AnimatedContent(targetState = state.name, label = "") {
|
||||
Text(
|
||||
text = it,
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ internal class StateBuilder(
|
|||
if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
val warnings = getWarningsForSuccessState(quoteModel, fromToken)
|
||||
val feeState = createFeeState(quoteModel.txFee, selectedFeeType, swapProvider)
|
||||
val feeState = createFeeState(quoteModel.txFee, selectedFeeType)
|
||||
val fromCurrencyStatus = quoteModel.fromTokenInfo.cryptoCurrencyStatus
|
||||
val toCurrencyStatus = quoteModel.toTokenInfo.cryptoCurrencyStatus
|
||||
return uiStateHolder.copy(
|
||||
|
|
@ -231,7 +231,7 @@ internal class StateBuilder(
|
|||
isBalanceHidden = isBalanceHiddenProvider(),
|
||||
),
|
||||
receiveCardData = SwapCardState.SwapCardData(
|
||||
type = TransactionCardType.ReadOnly(),
|
||||
type = TransactionCardType.ReadOnly(actions.onReceiveCardWarningClick),
|
||||
amountTextFieldValue = TextFieldValue(quoteModel.toTokenInfo.tokenAmount.formatToUIRepresentation()),
|
||||
amountEquivalent = getFormattedFiatAmount(quoteModel.toTokenInfo.amountFiat),
|
||||
token = toCurrencyStatus,
|
||||
|
|
@ -332,15 +332,6 @@ internal class StateBuilder(
|
|||
warnings.add(SwapWarning.InsufficientFunds)
|
||||
}
|
||||
|
||||
val priceImpact = quoteModel.priceImpact
|
||||
if (priceImpact is PriceImpact.ValueWithNotify && priceImpact.value > PRICE_IMPACT_THRESHOLD) {
|
||||
warnings.add(
|
||||
SwapWarning.HighPriceImpact(
|
||||
priceImpact = priceImpact.getIntPercentValue(),
|
||||
notificationConfig = highPriceImpactNotificationConfig(),
|
||||
),
|
||||
)
|
||||
}
|
||||
if (quoteModel.permissionState is PermissionDataState.PermissionLoading) {
|
||||
warnings.add(
|
||||
SwapWarning.TransactionInProgressWarning(
|
||||
|
|
@ -735,7 +726,7 @@ internal class StateBuilder(
|
|||
)
|
||||
}
|
||||
|
||||
private fun createFeeState(txFeeState: TxFeeState, feeType: FeeType, swapProvider: SwapProvider): FeeItemState {
|
||||
private fun createFeeState(txFeeState: TxFeeState, feeType: FeeType): FeeItemState {
|
||||
val isClickable: Boolean
|
||||
val fee = when (txFeeState) {
|
||||
TxFeeState.Empty -> return FeeItemState.Empty
|
||||
|
|
@ -758,14 +749,9 @@ internal class StateBuilder(
|
|||
|
||||
return FeeItemState.Content(
|
||||
feeType = feeType,
|
||||
title = resourceReference(R.string.common_fee_label),
|
||||
title = resourceReference(R.string.common_network_fee_title),
|
||||
amountCrypto = fee.feeCryptoFormatted,
|
||||
symbolCrypto = fee.cryptoSymbol,
|
||||
explanation = if (swapProvider.type == ExchangeProviderType.CEX) {
|
||||
resourceReference(R.string.express_cex_fee_explanation)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
amountFiatFormatted = fee.feeFiatFormatted,
|
||||
isClickable = isClickable,
|
||||
onClick = actions.onClickFee,
|
||||
|
|
@ -839,6 +825,25 @@ internal class StateBuilder(
|
|||
)
|
||||
}
|
||||
|
||||
fun createImpactAlert(
|
||||
uiState: SwapStateHolder,
|
||||
providerType: ExchangeProviderType,
|
||||
onAlertClick: () -> Unit,
|
||||
): SwapStateHolder {
|
||||
val message = when (providerType) {
|
||||
ExchangeProviderType.CEX -> resourceReference(R.string.express_cex_fee_explanation)
|
||||
ExchangeProviderType.DEX -> resourceReference(R.string.swapping_high_price_impact_description)
|
||||
}
|
||||
return uiState.copy(
|
||||
alert = SwapWarning.GenericWarning(
|
||||
message = message,
|
||||
onClick = onAlertClick,
|
||||
type = GenericWarningType.OTHER,
|
||||
),
|
||||
changeCardsButtonState = ChangeCardsButtonState.ENABLED,
|
||||
)
|
||||
}
|
||||
|
||||
fun addAlert(uiState: SwapStateHolder, onClick: () -> Unit): SwapStateHolder {
|
||||
return uiState.copy(
|
||||
alert = SwapWarning.GenericWarning(
|
||||
|
|
@ -852,7 +857,7 @@ internal class StateBuilder(
|
|||
|
||||
fun addWarning(
|
||||
uiState: SwapStateHolder,
|
||||
message: String?,
|
||||
message: TextReference?,
|
||||
shouldWrapMessage: Boolean = false,
|
||||
onClick: () -> Unit,
|
||||
): SwapStateHolder {
|
||||
|
|
@ -1072,21 +1077,19 @@ internal class StateBuilder(
|
|||
return listOf(
|
||||
FeeItemState.Content(
|
||||
feeType = this.normalFee.feeType,
|
||||
title = resourceReference(R.string.common_fee_label),
|
||||
title = resourceReference(R.string.common_network_fee_title),
|
||||
amountCrypto = this.normalFee.feeCryptoFormatted,
|
||||
symbolCrypto = this.normalFee.cryptoSymbol,
|
||||
amountFiatFormatted = this.normalFee.feeFiatFormatted,
|
||||
explanation = null,
|
||||
isClickable = true,
|
||||
onClick = {},
|
||||
),
|
||||
FeeItemState.Content(
|
||||
feeType = this.priorityFee.feeType,
|
||||
title = resourceReference(R.string.common_fee_label),
|
||||
title = resourceReference(R.string.common_network_fee_title),
|
||||
amountCrypto = this.priorityFee.feeCryptoFormatted,
|
||||
symbolCrypto = this.priorityFee.cryptoSymbol,
|
||||
amountFiatFormatted = this.priorityFee.feeFiatFormatted,
|
||||
explanation = null,
|
||||
isClickable = true,
|
||||
onClick = {},
|
||||
),
|
||||
|
|
@ -1129,14 +1132,6 @@ internal class StateBuilder(
|
|||
)
|
||||
}
|
||||
|
||||
private fun highPriceImpactNotificationConfig(): NotificationConfig {
|
||||
return NotificationConfig(
|
||||
title = resourceReference(R.string.swapping_high_price_impact),
|
||||
subtitle = resourceReference(R.string.swapping_high_price_impact_description),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
)
|
||||
}
|
||||
|
||||
private fun createUnableToCoverFeeNotificationConfig(
|
||||
fromToken: CryptoCurrency,
|
||||
onBuyClick: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ private fun DropdownSelector(
|
|||
@Composable
|
||||
private fun FeeItem(fee: String) {
|
||||
InformationItem(
|
||||
subtitle = stringResource(id = R.string.common_fee_label),
|
||||
subtitle = stringResource(id = R.string.common_network_fee_title),
|
||||
value = fee,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ internal fun SwapScreenContent(state: SwapStateHolder, modifier: Modifier = Modi
|
|||
val message = if (state.alert.type == GenericWarningType.NETWORK) {
|
||||
stringResource(id = R.string.disclaimer_error_loading)
|
||||
} else {
|
||||
state.alert.message ?: stringResource(id = R.string.swapping_generic_error)
|
||||
state.alert.message?.resolveReference() ?: stringResource(id = R.string.swapping_generic_error)
|
||||
}
|
||||
SimpleOkDialog(
|
||||
message = message,
|
||||
|
|
@ -326,12 +326,6 @@ private fun SwapWarnings(warnings: List<SwapWarning>) {
|
|||
) {
|
||||
warnings.forEach { warning ->
|
||||
when (warning) {
|
||||
is SwapWarning.HighPriceImpact -> {
|
||||
Notification(
|
||||
config = warning.notificationConfig,
|
||||
iconTint = TangemTheme.colors.icon.warning,
|
||||
)
|
||||
}
|
||||
is SwapWarning.PermissionNeeded -> {
|
||||
Notification(
|
||||
config = warning.notificationConfig,
|
||||
|
|
@ -340,9 +334,9 @@ private fun SwapWarnings(warnings: List<SwapWarning>) {
|
|||
is SwapWarning.GenericWarning -> {
|
||||
val message = warning.message?.let {
|
||||
if (warning.shouldWrapMessage) {
|
||||
String.format(stringResource(id = R.string.swapping_error_wrapper), it)
|
||||
String.format(stringResource(id = R.string.swapping_error_wrapper), it.resolveReference())
|
||||
} else {
|
||||
it
|
||||
it.resolveReference()
|
||||
}
|
||||
} ?: stringResource(id = R.string.swapping_generic_error)
|
||||
RefreshableWaringCard(
|
||||
|
|
@ -472,7 +466,6 @@ private val state = SwapStateHolder(
|
|||
amountCrypto = "100",
|
||||
symbolCrypto = "1000",
|
||||
amountFiatFormatted = "(100)",
|
||||
explanation = null,
|
||||
isClickable = true,
|
||||
onClick = {},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ private fun SwapSuccessScreenContent(state: SwapSuccessStateHolder, padding: Pad
|
|||
)
|
||||
SpacerH16()
|
||||
InputRowDefault(
|
||||
title = TextReference.Res(R.string.common_fee_label),
|
||||
title = TextReference.Res(R.string.common_network_fee_title),
|
||||
text = state.fee,
|
||||
modifier = Modifier
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
|
|
@ -284,14 +285,19 @@ private fun Content(
|
|||
.align(Alignment.CenterVertically),
|
||||
)
|
||||
SpacerW4()
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_alert_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.attention,
|
||||
modifier = Modifier
|
||||
.size(size = TangemTheme.dimens.size20)
|
||||
.align(Alignment.CenterVertically),
|
||||
)
|
||||
IconButton(
|
||||
onClick = {
|
||||
type.onWarningClick?.invoke()
|
||||
},
|
||||
modifier = Modifier.size(size = TangemTheme.dimens.size20),
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_alert_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.attention,
|
||||
modifier = Modifier.align(Alignment.CenterVertically),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AnimatedContent(targetState = amountEquivalent, label = "") {
|
||||
|
|
@ -468,6 +474,7 @@ private fun makePriceImpactBalanceWarning(value: String, priceImpactPercents: In
|
|||
private fun Preview_SwapMainCard_InLightTheme() {
|
||||
TangemTheme(isDark = false) {
|
||||
TransactionCardPreview()
|
||||
TransactionCardPreviewWithPriceImpact()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -476,6 +483,7 @@ private fun Preview_SwapMainCard_InLightTheme() {
|
|||
private fun Preview_SwapMainCard_InDarkTheme() {
|
||||
TangemTheme(isDark = true) {
|
||||
TransactionCardPreview()
|
||||
TransactionCardPreviewWithPriceImpact()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -494,4 +502,20 @@ private fun TransactionCardPreview() {
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Suppress("MagicNumber")
|
||||
private fun TransactionCardPreviewWithPriceImpact() {
|
||||
TransactionCard(
|
||||
type = TransactionCardType.ReadOnly(),
|
||||
amountEquivalent = "1 000 000",
|
||||
tokenIconUrl = "",
|
||||
tokenCurrency = "DAI",
|
||||
networkIconRes = R.drawable.img_polygon_22,
|
||||
onChangeTokenClick = {},
|
||||
balance = "123",
|
||||
textFieldValue = TextFieldValue(),
|
||||
priceImpact = PriceImpact.Value(0.15F),
|
||||
)
|
||||
}
|
||||
|
||||
// endregion preview
|
||||
|
|
@ -876,6 +876,15 @@ internal class SwapViewModel @Inject constructor(
|
|||
onTosClick = {
|
||||
swapRouter.openUrl(it)
|
||||
},
|
||||
onReceiveCardWarningClick = {
|
||||
val selectedProvider = dataState.selectedProvider ?: return@UiActions
|
||||
uiState = stateBuilder.createImpactAlert(
|
||||
uiState = uiState,
|
||||
providerType = selectedProvider.type,
|
||||
) {
|
||||
uiState = stateBuilder.clearAlert(uiState)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue