diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index 5cd4aa90a1..2629c88c99 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -480,14 +480,12 @@
Комиссия не превысит
Максимальная cумма комиссии
Сетевая комиссия
- Сумма отправки будет уменьшена для покрытия выбранного уровня комиссии
+ Сумма отправки будет уменьшена на %1$s для покрытия выбранного уровня комиссии. Получателю будет отправлено %2$s.
Покрытие сетевой комиссии
Недостаточно средств для перевода, так как сумма комиссии и сумма перевода в совокупности больше имеющегося баланса
Недостаточно средств
Увеличение комиссии
Комиссия при переводе всего баланса выше. Для того, чтобы снизить комиссию Вы можете оставить 0.01.
- Оставить %s XTZ
- Отправить все
Установлена высокая комиссия
Сумма комиссии в %s раз превышает рекомендованную. Убедитесь, что указанная комиссия верна.
Включенная комиссия превышает сумму перевода, что приводит к отрицательному значению
@@ -497,8 +495,10 @@
Сумма отправки не может быть менее %1$s
Обратите внимание, что при определенных параметрах комиссии возможны задержки по вашей транзакции
Возможны задержки по транзакции
- Уменьшить до [%s]
- Уменьшить на [%s]
+ Лимит транзакции
+ Из-за ограничений %1$s в одну транзакцию может поместиться только %2$s UTXO. Это означает, что вы можете отправить только %3$s или меньше. Вам нужно уменьшить сумму.
+ Уменьшить до %s
+ Уменьшить на %s
Необязательное
Последние
Получатель
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index a089602733..a4fd2f577a 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -459,8 +459,9 @@
The recipient will receive %s
The transaction is not completed
Reason: %1$s\nCode: %2$s
- Недостаточно средств для покрытия комиссии сети. Вычесть комиссию из отправляемой сумму?
- Вычесть
+ Not enough funds to cover the network commission. Subtract the commission from the amount sent?
+ Subtract
+ Вы указали комиссию ниже рекомендуемой, это может привести к задержке исполнения вашей транзакции. Продолжить?
Confirm
%1$s at %2$s
Address
@@ -494,8 +495,6 @@
Total exceeds balance
Fee is increased
The fee for transferring the entire balance is higher. To reduce the commission, you can leave 0.01.
- Reduce by %s XTZ
- No, send all
Custom fee is high
The commission amount is %s times the recommended amount. Make sure that the custom settings are correct.
The included commission exceeds the transfer amount, leading to a negative value
@@ -506,11 +505,11 @@
Kindly be aware that your transaction may experience delays under specific fee settings
Transaction delays are possible
Transaction limitation
- Due to %1$s limitations only %2$s UTXOs can fit in a single transaction. This means you can only send %3$s or less. You need to reduce the amount.
+ Due to %1$s limitations only %2$s UTXOs can fit in a single transaction. This means you can only send %3$s or less. You need to reduce the amount.
Existential deposit
The account will be wiped from the blockchain if a balance goes below the existential deposit. Please ensure that the remaining balance after sending will not be less than %s.
- Reduce by [%s]
- Reduce to [%s]
+ Reduce by %s
+ Reduce to %s
Optional
Please align your QR code with the square to scan it. Ensure you scan %s network address.
Recent
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 204b99d3fb..30becd1f7e 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
@@ -50,6 +50,14 @@ internal sealed class SendAlertState {
override val message: TextReference = resourceReference(id = R.string.send_notification_high_fee_title)
}
+ data class FeeTooLow(
+ override val onConfirmClick: () -> Unit,
+ ) : SendAlertState() {
+ override val title: TextReference? = null
+ override val message: TextReference = resourceReference(id = R.string.send_alert_fee_too_low_text)
+ override val confirmButtonText: TextReference = resourceReference(R.string.common_continue)
+ }
+
data class FeeCoverage(
override val onConfirmClick: (() -> Unit),
) : SendAlertState() {
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 1bfe20a62b..fbbc8953ab 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
@@ -3,6 +3,7 @@ package com.tangem.features.send.impl.presentation.state
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.core.ui.event.consumedEvent
import com.tangem.core.ui.event.triggeredEvent
+import com.tangem.core.ui.utils.parseToBigDecimal
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
import com.tangem.features.send.impl.presentation.state.fee.FeeStateFactory
@@ -88,6 +89,29 @@ internal class SendEventStateFactory(
}
}
+ fun getFeeTooLowAlert(onConsume: () -> Unit): SendUiState {
+ val state = currentStateProvider()
+ val feeSelectorState = state.feeState?.feeSelectorState as? FeeSelectorState.Content ?: return state
+ val multipleFees = feeSelectorState.fees as? TransactionFee.Choosable ?: return state
+ val minimumValue = multipleFees.minimum.amount.value ?: return state
+ val customAmount = feeSelectorState.customValues.firstOrNull() ?: return state
+ val customValue = customAmount.value.parseToBigDecimal(customAmount.decimals)
+
+ val isFeeTooLow = feeSelectorState.selectedFee == FeeType.Custom && minimumValue > customValue
+ if (!isFeeTooLow) return state
+
+ return state.copy(
+ event = triggeredEvent(
+ data = SendEvent.ShowAlert(
+ SendAlertState.FeeTooLow(
+ onConfirmClick = clickIntents::showSend,
+ ),
+ ),
+ 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/SendNotification.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt
index 4ab6952836..bf5148d51e 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotification.kt
@@ -12,12 +12,14 @@ internal sealed class SendNotification(val config: NotificationConfig) {
title: TextReference,
subtitle: TextReference,
buttonState: NotificationConfig.ButtonsState? = null,
+ onCloseClick: (() -> Unit)? = null,
) : SendNotification(
config = NotificationConfig(
title = title,
subtitle = subtitle,
iconResId = R.drawable.ic_alert_24,
buttonsState = buttonState,
+ onCloseClick = onCloseClick,
),
) {
@@ -45,12 +47,17 @@ internal sealed class SendNotification(val config: NotificationConfig) {
val cryptoCurrency: String,
val utxoLimit: String,
val amountLimit: String,
+ val onConfirmClick: () -> Unit,
) : Error(
title = resourceReference(R.string.send_notifiaction_transaction_limit_title),
subtitle = resourceReference(
- R.string.send_notifiaction_transaction_limit_text,
+ R.string.send_notification_transaction_limit_text,
wrappedList(cryptoCurrency, utxoLimit, amountLimit),
),
+ buttonState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
+ text = resourceReference(R.string.send_notification_reduce_to, wrappedList(amountLimit)),
+ onClick = onConfirmClick,
+ ),
)
}
@@ -58,27 +65,28 @@ internal sealed class SendNotification(val config: NotificationConfig) {
title: TextReference,
subtitle: TextReference,
buttonsState: NotificationConfig.ButtonsState? = null,
+ onCloseClick: (() -> Unit)? = null,
) : SendNotification(
config = NotificationConfig(
title = title,
subtitle = subtitle,
iconResId = R.drawable.img_attention_20,
buttonsState = buttonsState,
+ onCloseClick = onCloseClick,
),
) {
data class HighFeeError(
val amount: String,
val onConfirmClick: () -> Unit,
- val onDismissClick: () -> Unit,
+ val onCloseClick: () -> Unit,
) : Warning(
title = resourceReference(R.string.send_notification_high_fee_title),
subtitle = resourceReference(R.string.send_notification_high_fee_text, wrappedList(amount)),
- buttonsState = NotificationConfig.ButtonsState.PairButtonsConfig(
- primaryText = resourceReference(R.string.send_notification_fee_too_high_accept, wrappedList(amount)),
- onPrimaryClick = onConfirmClick,
- secondaryText = resourceReference(R.string.send_notification_fee_too_high_ignore),
- onSecondaryClick = onDismissClick,
+ buttonsState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
+ text = resourceReference(R.string.send_notification_reduce_by, wrappedList(amount)),
+ onClick = onConfirmClick,
),
+ onCloseClick = onCloseClick,
)
data class ExistentialDeposit(val deposit: String) : Warning(
@@ -96,5 +104,10 @@ internal sealed class SendNotification(val config: NotificationConfig) {
formatArgs = wrappedList(amountReducedBy, amountReduced),
),
)
+
+ data object FeeTooLow : Warning(
+ title = resourceReference(id = R.string.send_notification_transaction_delay_title),
+ subtitle = resourceReference(id = R.string.send_notification_transaction_delay_text),
+ )
}
}
\ No newline at end of file
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotificationFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotificationFactory.kt
index b253266100..12ea309a87 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotificationFactory.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotificationFactory.kt
@@ -1,11 +1,15 @@
package com.tangem.features.send.impl.presentation.state
import com.tangem.blockchain.common.Blockchain
+import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.core.ui.utils.BigDecimalFormatter
+import com.tangem.core.ui.utils.parseToBigDecimal
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
import com.tangem.domain.wallets.models.UserWallet
+import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
+import com.tangem.features.send.impl.presentation.state.fee.FeeType
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.utils.Provider
import com.tangem.utils.isNullOrZero
@@ -48,13 +52,16 @@ internal class SendNotificationFactory(
addFeeCoverageNotification(sendState.isSubtract, sendAmount)
addExistentialWarningNotification(feeAmount, sendAmount)
addHighFeeWarningNotification(sendAmount, sendState.ignoreAmountReduce)
+ addTooLowNotification(feeState)
}.toImmutableList()
}
- fun dismissHighFeeWarningState(): SendUiState {
+ fun dismissNotificationState(clazz: Class): SendUiState {
val state = currentStateProvider()
val sendState = state.sendState
- val updatedNotifications = sendState.notifications.filterNot { it is SendNotification.Warning.HighFeeError }
+ val notificationsToRemove = sendState.notifications.filterIsInstance(clazz)
+ val updatedNotifications = sendState.notifications.toMutableList()
+ updatedNotifications.removeAll(notificationsToRemove)
return state.copy(
sendState = sendState.copy(
ignoreAmountReduce = true,
@@ -162,6 +169,13 @@ internal class SendNotificationFactory(
cryptoAmount = utxoLimit.maxAmount,
cryptoCurrency = cryptoCurrency,
),
+ onConfirmClick = {
+ val reduceTo = utxoLimit.maxAmount.toPlainString()
+ clickIntents.onAmountReduceClick(
+ reduceTo,
+ SendNotification.Error.TransactionLimitError::class.java,
+ )
+ },
),
)
}
@@ -207,9 +221,11 @@ internal class SendNotificationFactory(
amount = TEZOS_FEE_THRESHOLD.toPlainString(),
onConfirmClick = {
val reduceTo = sendAmount.minus(TEZOS_FEE_THRESHOLD).toPlainString()
- clickIntents.onAmountReduceClick(reduceTo)
+ clickIntents.onAmountReduceClick(reduceTo, SendNotification.Warning.HighFeeError::class.java)
+ },
+ onCloseClick = {
+ clickIntents.onNotificationCancel(SendNotification.Warning.HighFeeError::class.java)
},
- onDismissClick = clickIntents::onAmountReduceIgnoreClick,
),
)
}
@@ -261,6 +277,17 @@ internal class SendNotificationFactory(
}
}
+ private fun MutableList.addTooLowNotification(feeState: SendStates.FeeState) {
+ val feeSelectorState = feeState.feeSelectorState as? FeeSelectorState.Content ?: return
+ val multipleFees = feeSelectorState.fees as? TransactionFee.Choosable ?: return
+ val minimumValue = multipleFees.minimum.amount.value ?: return
+ val customAmount = feeSelectorState.customValues.firstOrNull() ?: return
+ val customValue = customAmount.value.parseToBigDecimal(customAmount.decimals)
+ if (feeSelectorState.selectedFee == FeeType.Custom && minimumValue > customValue) {
+ add(SendNotification.Warning.FeeTooLow)
+ }
+ }
+
companion object {
private const val CARDANO_MINIMUM = "1"
private const val DOGECOIN_MINIMUM = "0.01"
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 f8c304748b..da1277412a 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
@@ -47,7 +47,6 @@ internal class FeeNotificationFactory(
is FeeSelectorState.Content -> {
val customFee = feeSelectorState.customValues
val selectedFee = feeSelectorState.selectedFee
- addTooLowNotification(feeSelectorState.fees, selectedFee, customFee)
addTooHighNotification(feeSelectorState.fees, selectedFee, customFee)
addExceedsBalanceNotification(feeState.fee)
}
@@ -61,20 +60,6 @@ internal class FeeNotificationFactory(
}
}
- private fun MutableList.addTooLowNotification(
- transactionFee: TransactionFee,
- selectedFee: FeeType,
- customFee: List,
- ) {
- val multipleFees = transactionFee as? TransactionFee.Choosable ?: return
- val minimumValue = multipleFees.minimum.amount.value ?: return
- val customAmount = customFee.firstOrNull() ?: return
- val customValue = customAmount.value.parseToBigDecimal(customAmount.decimals)
- if (selectedFee == FeeType.Custom && minimumValue > customValue) {
- add(SendFeeNotification.Warning.TooLow)
- }
- }
-
private fun MutableList.addTooHighNotification(
transactionFee: TransactionFee,
selectedFee: FeeType,
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/SendFeeNotification.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/SendFeeNotification.kt
index 56add5cfe5..c82f072f6a 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/SendFeeNotification.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/SendFeeNotification.kt
@@ -20,11 +20,6 @@ sealed class SendFeeNotification(val config: NotificationConfig) {
buttonsState = buttonsState,
),
) {
- object TooLow : Warning(
- title = resourceReference(id = R.string.send_notification_transaction_delay_title),
- subtitle = resourceReference(id = R.string.send_notification_transaction_delay_text),
- )
-
data class TooHigh(
val value: String,
) : Warning(
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedAndFeeContent.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedAndFeeContent.kt
index 5acd6b57b1..1695763049 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedAndFeeContent.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedAndFeeContent.kt
@@ -74,10 +74,7 @@ private fun LazyListScope.middleNotifications(
modifier: Modifier = Modifier,
) {
notifications(
- configs = configs.filter {
- it is SendFeeNotification.Warning.TooLow ||
- it is SendFeeNotification.Warning.TooHigh
- }.toImmutableList(),
+ configs = configs.filterIsInstance().toImmutableList(),
modifier = modifier,
)
}
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelector.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelector.kt
index 4d13b7d7a5..f5b10f50a8 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelector.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/fee/SendSpeedSelector.kt
@@ -117,10 +117,7 @@ internal fun SendSpeedSelector(
visible = fees.normal is Fee.Ethereum,
label = "Custom fee appearance animation",
) {
- val showWarning = state.notifications.any {
- it is SendFeeNotification.Warning.TooHigh ||
- it is SendFeeNotification.Warning.TooLow
- }
+ val showWarning = state.notifications.any { it is SendFeeNotification.Warning.TooHigh }
SendSpeedSelectorItem(
titleRes = R.string.common_fee_selector_option_custom,
iconRes = R.drawable.ic_edit_24,
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt
index f2eedb220d..9af06fb346 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt
@@ -3,6 +3,7 @@ package com.tangem.features.send.impl.presentation.viewmodel
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.send.impl.presentation.analytics.EnterAddressSource
+import com.tangem.features.send.impl.presentation.state.SendNotification
import com.tangem.features.send.impl.presentation.state.fee.FeeType
@Suppress("TooManyFunctions")
@@ -57,12 +58,14 @@ internal interface SendClickIntents {
fun showFee()
+ fun showSend()
+
fun onExploreClick()
fun onShareClick()
- fun onAmountReduceClick(reducedAmount: String)
+ fun onAmountReduceClick(reducedAmount: String, clazz: Class)
- fun onAmountReduceIgnoreClick()
+ fun onNotificationCancel(clazz: Class)
// endregion
}
\ No newline at end of file
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 7b47227a2e..8267ee3c2a 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
@@ -394,6 +394,9 @@ internal class SendViewModel @Inject constructor(
val currentState = stateRouter.currentState.value
val isCurrentFee = currentState.type == SendUiStateType.Fee
if (isCurrentFee) {
+ uiState = eventStateFactory.getFeeTooLowAlert(
+ onConsume = { uiState = eventStateFactory.onConsumeEventState() },
+ )
val isFeeCoverage = checkFeeCoverage(uiState, cryptoCurrencyStatus)
if (isAmountSubtractAvailable && isFeeCoverage) {
uiState = eventStateFactory.getFeeCoverageAlert(
@@ -606,6 +609,10 @@ internal class SendViewModel @Inject constructor(
analyticsEventHandler.send(SendAnalyticEvents.ScreenReopened(SendScreenSource.Fee))
}
+ override fun showSend() {
+ stateRouter.showSend()
+ }
+
override fun onExploreClick() {
analyticsEventHandler.send(SendAnalyticEvents.ExploreButtonClicked)
innerRouter.openUrl(uiState.sendState.txUrl)
@@ -615,14 +622,14 @@ internal class SendViewModel @Inject constructor(
analyticsEventHandler.send(SendAnalyticEvents.ShareButtonClicked)
}
- override fun onAmountReduceClick(reducedAmount: String) {
+ override fun onAmountReduceClick(reducedAmount: String, clazz: Class) {
uiState = amountStateFactory.getOnAmountValueChange(reducedAmount)
- uiState = sendNotificationFactory.dismissHighFeeWarningState()
+ uiState = sendNotificationFactory.dismissNotificationState(clazz)
loadFee()
}
- override fun onAmountReduceIgnoreClick() {
- uiState = sendNotificationFactory.dismissHighFeeWarningState()
+ override fun onNotificationCancel(clazz: Class) {
+ uiState = sendNotificationFactory.dismissNotificationState(clazz)
}
private fun verifyAndSendTransaction() {