diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index 136cc2857f..256b94877c 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -79,7 +79,7 @@
Посмотреть историю транзакций
Обозреватель
Комиссия
- Сетевые комиссии – это плата пользователя за обработку и подтверждение транзакций. Размер комиссии зависит от нагрузки на сеть, объема транзакции и приоритета исполнения. %s
+ Сетевые комиссии – это плата пользователя за обработку и подтверждение транзакций. Размер комиссии зависит от нагрузки на сеть, объема транзакции и приоритета исполнения. %s
Свое
Быстро
По рынку
@@ -310,7 +310,7 @@
В этом случае вам будет необходимо начать процесс заново.
Вы хотите выйти из процесса активации?
Подготовка
- Другой кошелек уже был создан на карте, которую вы пытаетесь добавить. Хотите сбросить его и использовать карту для бэкапа?
+ Другой кошелек уже был создан на карте, которую вы пытаетесь добавить. Если на нем есть средства, пожалуйста сначала выведите их, а затем сделайте сброс до заводских настроек и используйте как резервную.
Резервная копия
Прочитать о seed-фразе
@@ -426,12 +426,12 @@
Приготовьте свою карту
Уже содержится в введенном адресе
Вычесть
- Недостаточно средств для покрытия комиссии сети. Вычесть комиссию %s из отправляемой сумму?
+ Недостаточно средств для покрытия комиссии сети. Вычесть комиссию %s из отправляемой суммы?
+ Сумма комиссии в %s раз превышает рекомендованную. Убедитесь, что указанная комиссия верна.
Вы указали комиссию ниже рекомендуемой, это может привести к задержке исполнения вашей транзакции. Продолжить?
Причина: %1$s\nКод: %2$s
Транзакция не выполнена
Сумма
- Подтверждение
%1$s, %2$s
Адрес
Код назначения
@@ -536,7 +536,7 @@
Балансы скрыты
Балансы показаны
Отменить
- В данный момент покупка монеты %s недоступна. Но мы работаем над её добавлением.”
+ В данный момент покупка монеты %s недоступна. Но мы работаем над её добавлением.
У вас нет средств для отправки. Пополните счет, чтобы иметь возможность отправить с него средства.
Выбранная операция в данный момент недоступна. Попробуйте позже.
Обмен %s не доступен. Но мы работаем над его добавлением.
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index eacae3a8ac..a68246f965 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -310,7 +310,7 @@
In this case, you will need to start from the beginning.
Do you want to exit the activation process?
Getting started
- Another wallet has already been created on the card you\'re trying to add. Do you want to reset it and use the card for a new wallet?
+ Another wallet has already been created on the card you\'re trying to add. If you have funds in this wallet, please withdraw it and then reset this card and add it as a backup.
Creating a backup
Read more about seed phrase
@@ -422,11 +422,11 @@
Already included in the entered address
Subtract
Not enough funds to cover the network commission. Subtract the commission %s from the amount sent?
+ The commission amount is %s times the recommended amount. Make sure that the custom settings are correct.
You specified a commission below the recommended amount, which could cause a delay in your transaction. Continue?
Reason: %1$s\nCode: %2$s
The transaction is not completed
Amount
- Confirm
%1$s, %2$s
Address
Destination Tag
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendAlertState.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendAlertState.kt
index d3adc2e74c..b8da006bb9 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendAlertState.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendAlertState.kt
@@ -58,6 +58,16 @@ internal sealed class SendAlertState {
override val confirmButtonText: TextReference = resourceReference(R.string.common_continue)
}
+ data class FeeTooHigh(
+ val times: String,
+ override val onConfirmClick: () -> Unit,
+ ) : SendAlertState() {
+ override val title: TextReference? = null
+ override val message: TextReference =
+ resourceReference(id = R.string.send_alert_fee_too_high_text, wrappedList(times))
+ override val confirmButtonText: TextReference = resourceReference(R.string.common_continue)
+ }
+
data class FeeCoverage(
val amount: String,
override val onConfirmClick: (() -> Unit),
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendEventStateFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendEventStateFactory.kt
index 3e615c7835..1798d8fe79 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendEventStateFactory.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendEventStateFactory.kt
@@ -115,6 +115,20 @@ internal class SendEventStateFactory(
)
}
+ fun getFeeTooHighAlert(diff: String, onConsume: () -> Unit): SendUiState {
+ return currentStateProvider().copy(
+ event = triggeredEvent(
+ data = SendEvent.ShowAlert(
+ SendAlertState.FeeTooHigh(
+ onConfirmClick = clickIntents::showSend,
+ times = diff,
+ ),
+ ),
+ onConsume = onConsume,
+ ),
+ )
+ }
+
fun getGenericErrorState(error: Throwable? = null, onConsume: () -> Unit): SendUiState {
val state = currentStateProvider()
return state.copy(
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt
index 709779d1df..6a4e8a383e 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/confirm/SendNotificationFactory.kt
@@ -30,6 +30,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import java.math.BigDecimal
+import java.math.BigInteger
@Suppress("LongParameterList")
internal class SendNotificationFactory(
@@ -64,6 +65,7 @@ internal class SendNotificationFactory(
// warnings
addExistentialWarningNotification(feeAmount, amountValue)
addHighFeeWarningNotification(feeAmount, amountValue, sendState.ignoreAmountReduce)
+ addTooHighNotification(feeState.feeSelectorState)
addTooLowNotification(feeState)
}.toImmutableList()
}
@@ -279,6 +281,18 @@ internal class SendNotificationFactory(
}
}
+ private fun MutableList.addTooHighNotification(feeSelectorState: FeeSelectorState) {
+ if (feeSelectorState !is FeeSelectorState.Content) return
+ val multipleFees = feeSelectorState.fees as? TransactionFee.Choosable ?: return
+ val highValue = multipleFees.priority.amount.value ?: return
+ val customAmount = feeSelectorState.customValues.firstOrNull() ?: return
+ val customValue = customAmount.value.parseToBigDecimal(customAmount.decimals)
+ val diff = (customValue / highValue).toBigInteger()
+ if (feeSelectorState.selectedFee == FeeType.Custom && diff > FEE_MAX_DIFF) {
+ add(SendNotification.Warning.TooHigh(diff.toString()))
+ }
+ }
+
private suspend fun MutableList.addExceedsBalanceNotification(fee: Fee?) {
val feeValue = fee?.amount?.value ?: BigDecimal.ZERO
val userWalletId = userWalletProvider().walletId
@@ -359,5 +373,6 @@ internal class SendNotificationFactory(
companion object {
private const val DOGECOIN_MINIMUM = "0.01"
private val TEZOS_FEE_THRESHOLD = BigDecimal("0.01")
+ internal val FEE_MAX_DIFF = BigInteger("5")
}
}
\ No newline at end of file
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeCalculation.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeCalculation.kt
index 1a57669334..06a47de259 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeCalculation.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeCalculation.kt
@@ -4,6 +4,7 @@ import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.core.ui.utils.parseToBigDecimal
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.presentation.state.SendUiState
+import com.tangem.features.send.impl.presentation.state.confirm.SendNotificationFactory
/**
* Check if sending amount with fee is greater than balance
@@ -26,4 +27,19 @@ internal fun checkIfFeeTooLow(state: SendUiState): Boolean {
val customValue = customAmount.value.parseToBigDecimal(customAmount.decimals)
return feeSelectorState.selectedFee == FeeType.Custom && minimumValue > customValue
+}
+
+/**
+ * Check if custom fee is too high
+ */
+internal fun checkIfFeeTooHigh(state: SendUiState, onShow: (String) -> Unit): Boolean {
+ val feeSelectorState = state.feeState?.feeSelectorState as? FeeSelectorState.Content ?: return false
+ val multipleFees = feeSelectorState.fees as? TransactionFee.Choosable ?: return false
+ val highValue = multipleFees.priority.amount.value ?: return false
+ val customAmount = feeSelectorState.customValues.firstOrNull() ?: return false
+ val customValue = customAmount.value.parseToBigDecimal(customAmount.decimals)
+ val diff = (customValue / highValue).toBigInteger()
+ val isShow = feeSelectorState.selectedFee == FeeType.Custom && diff > SendNotificationFactory.FEE_MAX_DIFF
+ if (isShow) onShow(diff.toString())
+ return isShow
}
\ No newline at end of file
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt
index 217631c38e..92189a24ef 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt
@@ -1,20 +1,15 @@
package com.tangem.features.send.impl.presentation.state.fee
-import com.tangem.blockchain.common.transaction.TransactionFee
-import com.tangem.core.ui.utils.parseToBigDecimal
+import com.tangem.features.send.impl.presentation.state.SendNotification
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.SendUiStateType
import com.tangem.features.send.impl.presentation.state.StateRouter
-import com.tangem.features.send.impl.presentation.state.fields.SendTextField
-import com.tangem.features.send.impl.presentation.state.SendNotification
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.utils.Provider
-import com.tangem.utils.toFormattedString
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
-import java.math.BigDecimal
@Suppress("LongParameterList")
internal class FeeNotificationFactory(
@@ -29,16 +24,7 @@ internal class FeeNotificationFactory(
val state = currentStateProvider()
val feeState = state.feeState ?: return@map persistentListOf()
buildList {
- when (val feeSelectorState = feeState.feeSelectorState) {
- FeeSelectorState.Error -> {
- addFeeUnreachableNotification(feeSelectorState)
- }
- is FeeSelectorState.Content -> {
- val customFee = feeSelectorState.customValues
- val selectedFee = feeSelectorState.selectedFee
- addTooHighNotification(feeSelectorState.fees, selectedFee, customFee)
- }
- }
+ addFeeUnreachableNotification(feeState.feeSelectorState)
}.toImmutableList()
}
@@ -47,24 +33,4 @@ internal class FeeNotificationFactory(
add(SendNotification.Warning.NetworkFeeUnreachable(clickIntents::feeReload))
}
}
-
- private fun MutableList.addTooHighNotification(
- transactionFee: TransactionFee,
- selectedFee: FeeType,
- customFee: List,
- ) {
- val multipleFees = transactionFee as? TransactionFee.Choosable ?: return
- val highValue = multipleFees.priority.amount.value ?: return
- val customAmount = customFee.firstOrNull() ?: return
- val customValue = customAmount.value.parseToBigDecimal(customAmount.decimals)
- val diff = customValue / highValue
- if (selectedFee == FeeType.Custom && diff > FEE_MAX_DIFF) {
- add(SendNotification.Warning.TooHigh(diff.toFormattedString(HIGH_FEE_DIFF_DECIMALS)))
- }
- }
-
- companion object {
- private val FEE_MAX_DIFF = BigDecimal(5)
- private const val HIGH_FEE_DIFF_DECIMALS = 0
- }
}
\ No newline at end of file
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelectorItem.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelectorItem.kt
index bb360d218b..0a2a65c93e 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelectorItem.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelectorItem.kt
@@ -3,7 +3,6 @@ package com.tangem.features.send.impl.presentation.ui.fee
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.animation.*
-import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
@@ -12,15 +11,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.painterResource
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.core.ui.components.SpacerWMax
import com.tangem.core.ui.components.rows.SelectorRowItem
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.BigDecimalFormatter
-import com.tangem.features.send.impl.R
-import com.tangem.features.send.impl.presentation.state.SendNotification
import com.tangem.features.send.impl.presentation.state.SendStates
import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
import com.tangem.features.send.impl.presentation.state.fee.FeeType
@@ -64,11 +60,6 @@ internal fun SendSpeedSelectorItem(
showDivider = showDivider,
)
SendSpeedSelectorItemError(isError = feeSelectorState is FeeSelectorState.Error)
-
- if (feeType == FeeType.Custom) {
- val showWarning = state.notifications.any { it is SendNotification.Warning.TooHigh }
- WarningIcon(showWarning = showWarning)
- }
}
}
}
@@ -97,29 +88,6 @@ private fun SendSpeedSelectorItemError(isError: Boolean) {
}
}
-@Composable
-private fun WarningIcon(showWarning: Boolean = false) {
- Row {
- SpacerWMax()
- AnimatedVisibility(
- visible = showWarning,
- label = "Custom fee warning indicator",
- enter = fadeIn(),
- exit = fadeOut(),
- ) {
- Image(
- painter = painterResource(R.drawable.ic_alert_triangle_20),
- contentDescription = null,
- modifier = Modifier
- .padding(
- vertical = TangemTheme.dimens.spacing12,
- horizontal = TangemTheme.dimens.spacing14,
- ),
- )
- }
- }
-}
-
private fun FeeSelectorState.Content.getAmount(feeType: FeeType): Amount? {
val choosableFees = fees as? TransactionFee.Choosable
return when (feeType) {
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt
index 1533c95e7c..8564920606 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt
@@ -525,7 +525,15 @@ internal class SendViewModel @Inject constructor(
)
return true
}
- return false
+ return checkIfFeeTooHigh(
+ state = uiState,
+ onShow = { diff ->
+ uiState = eventStateFactory.getFeeTooHighAlert(
+ diff = diff,
+ onConsume = { uiState = eventStateFactory.onConsumeEventState() },
+ )
+ },
+ )
}
private fun onFeeCoverageAlert(): Boolean {