Updated on 2026-08-14
This commit is contained in:
parent
5d8461a4f2
commit
bc707a571e
15 changed files with 248 additions and 796 deletions
|
|
@ -21,7 +21,7 @@ import java.math.BigDecimal
|
|||
object NotificationsFactory {
|
||||
|
||||
fun MutableList<NotificationUM>.addFeeUnreachableNotification(
|
||||
feeError: GetFeeError,
|
||||
feeError: GetFeeError?,
|
||||
tokenName: String,
|
||||
onReload: () -> Unit,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
package com.tangem.features.send.impl.presentation.errors
|
||||
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
|
||||
|
||||
internal class FeeErrorStateMapper {
|
||||
|
||||
fun getFeeError(loadFeeError: GetFeeError?, tokenName: String): FeeSelectorState.Error {
|
||||
return when (loadFeeError) {
|
||||
GetFeeError.BlockchainErrors.TronActivationError -> FeeSelectorState.Error.TronAccountActivationError(
|
||||
tokenName,
|
||||
)
|
||||
is GetFeeError.DataError,
|
||||
GetFeeError.UnknownError,
|
||||
null,
|
||||
-> FeeSelectorState.Error.NetworkError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,250 +0,0 @@
|
|||
package com.tangem.features.send.impl.presentation.state
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||
import com.tangem.features.send.impl.R
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal sealed class SendNotification(val config: NotificationConfig) {
|
||||
|
||||
sealed class Error(
|
||||
title: TextReference,
|
||||
subtitle: TextReference,
|
||||
iconResId: Int = R.drawable.ic_alert_24,
|
||||
buttonState: NotificationConfig.ButtonsState? = null,
|
||||
onCloseClick: (() -> Unit)? = null,
|
||||
) : SendNotification(
|
||||
config = NotificationConfig(
|
||||
title = title,
|
||||
subtitle = subtitle,
|
||||
iconResId = iconResId,
|
||||
buttonsState = buttonState,
|
||||
onCloseClick = onCloseClick,
|
||||
),
|
||||
) {
|
||||
|
||||
data object TotalExceedsBalance : Error(
|
||||
title = resourceReference(R.string.send_notification_exceed_balance_title),
|
||||
subtitle = resourceReference(R.string.send_notification_exceed_balance_text),
|
||||
)
|
||||
|
||||
data object InvalidAmount : Error(
|
||||
title = resourceReference(R.string.send_notification_invalid_amount_title),
|
||||
subtitle = resourceReference(R.string.send_notification_invalid_amount_text),
|
||||
)
|
||||
|
||||
data class MinimumAmountError(val amount: String) : Error(
|
||||
title = resourceReference(R.string.send_notification_invalid_amount_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.send_notification_invalid_minimum_amount_text,
|
||||
wrappedList(amount, amount),
|
||||
),
|
||||
)
|
||||
|
||||
data class TransactionLimitError(
|
||||
val cryptoCurrency: String,
|
||||
val utxoLimit: String,
|
||||
val amountLimit: String,
|
||||
val onConfirmClick: () -> Unit,
|
||||
) : Error(
|
||||
title = resourceReference(R.string.send_notification_transaction_limit_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.send_notification_transaction_limit_text,
|
||||
wrappedList(cryptoCurrency, utxoLimit, amountLimit),
|
||||
),
|
||||
buttonState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
|
||||
text = resourceReference(R.string.send_notification_leave_button, wrappedList(amountLimit)),
|
||||
onClick = onConfirmClick,
|
||||
),
|
||||
)
|
||||
|
||||
data class ExceedsBalance(
|
||||
val networkIconId: Int,
|
||||
val currencyName: String,
|
||||
val feeName: String,
|
||||
val feeSymbol: String,
|
||||
val networkName: String,
|
||||
val mergeFeeNetworkName: Boolean = false,
|
||||
val onClick: (() -> Unit)? = null,
|
||||
) : Error(
|
||||
title = resourceReference(
|
||||
id = R.string.warning_send_blocked_funds_for_fee_title,
|
||||
wrappedList(feeName),
|
||||
),
|
||||
subtitle = resourceReference(
|
||||
id = R.string.warning_send_blocked_funds_for_fee_message,
|
||||
formatArgs = wrappedList(currencyName, networkName, currencyName, feeName, feeSymbol),
|
||||
),
|
||||
iconResId = networkIconId,
|
||||
buttonState = onClick?.let {
|
||||
NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(
|
||||
R.string.common_buy_currency,
|
||||
wrappedList(
|
||||
if (mergeFeeNetworkName) {
|
||||
"$currencyName ($feeSymbol)"
|
||||
} else {
|
||||
feeName
|
||||
},
|
||||
),
|
||||
),
|
||||
onClick = onClick,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
data class ExistentialDeposit(val deposit: String, val onConfirmClick: () -> Unit) : Error(
|
||||
title = resourceReference(R.string.send_notification_existential_deposit_title),
|
||||
subtitle = resourceReference(R.string.send_notification_existential_deposit_text, wrappedList(deposit)),
|
||||
buttonState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
|
||||
text = resourceReference(R.string.common_ok),
|
||||
onClick = onConfirmClick,
|
||||
),
|
||||
)
|
||||
|
||||
data class ReserveAmount(val amount: String) : Error(
|
||||
title = resourceReference(
|
||||
id = R.string.send_notification_invalid_reserve_amount_title,
|
||||
wrappedList(amount),
|
||||
),
|
||||
subtitle = resourceReference(id = R.string.send_notification_invalid_reserve_amount_text),
|
||||
)
|
||||
}
|
||||
|
||||
sealed class Warning(
|
||||
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 currencyName: String,
|
||||
val amount: String,
|
||||
val onConfirmClick: () -> Unit,
|
||||
val onCloseClick: () -> Unit,
|
||||
) : Warning(
|
||||
title = resourceReference(R.string.send_notification_high_fee_title),
|
||||
subtitle = resourceReference(R.string.send_notification_high_fee_text, wrappedList(currencyName, amount)),
|
||||
buttonsState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
|
||||
text = resourceReference(R.string.send_notification_reduce_by, wrappedList(amount)),
|
||||
onClick = onConfirmClick,
|
||||
),
|
||||
onCloseClick = onCloseClick,
|
||||
)
|
||||
|
||||
data object FeeTooLow : 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(
|
||||
title = resourceReference(id = R.string.send_notification_fee_too_high_title),
|
||||
subtitle = resourceReference(id = R.string.send_notification_fee_too_high_text, wrappedList(value)),
|
||||
)
|
||||
|
||||
data class NetworkFeeUnreachable(val onRefresh: () -> Unit) : Warning(
|
||||
title = resourceReference(R.string.send_fee_unreachable_error_title),
|
||||
subtitle = resourceReference(R.string.send_fee_unreachable_error_text),
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.warning_button_refresh),
|
||||
onClick = onRefresh,
|
||||
),
|
||||
)
|
||||
|
||||
data class TronAccountNotActivated(val tokenName: String) : Warning(
|
||||
title = resourceReference(R.string.send_fee_unreachable_error_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.send_tron_account_activation_error,
|
||||
wrappedList(tokenName),
|
||||
),
|
||||
)
|
||||
|
||||
data class FeeCoverageNotification(val cryptoAmount: String, val fiatAmount: String) : Warning(
|
||||
title = resourceReference(R.string.send_network_fee_warning_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.common_network_fee_warning_content,
|
||||
wrappedList(cryptoAmount, fiatAmount),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
sealed interface Cardano {
|
||||
|
||||
data class MinAdaValueCharged(val tokenName: String, val minAdaValue: String) : Warning(
|
||||
title = resourceReference(id = R.string.cardano_coin_will_be_send_with_token_title),
|
||||
subtitle = resourceReference(
|
||||
id = R.string.cardano_coin_will_be_send_with_token_description,
|
||||
formatArgs = wrappedList(minAdaValue, tokenName),
|
||||
),
|
||||
)
|
||||
|
||||
data object InsufficientBalanceToTransferCoin : Error(
|
||||
title = resourceReference(id = R.string.cardano_max_amount_has_token_title),
|
||||
subtitle = resourceReference(id = R.string.cardano_max_amount_has_token_description),
|
||||
)
|
||||
|
||||
data class InsufficientBalanceToTransferToken(val tokenName: String) : Error(
|
||||
title = resourceReference(id = R.string.cardano_insufficient_balance_to_send_token_title),
|
||||
subtitle = resourceReference(
|
||||
id = R.string.cardano_insufficient_balance_to_send_token_description,
|
||||
formatArgs = wrappedList(tokenName),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
sealed interface Koinos {
|
||||
data class InsufficientRecoverableMana(
|
||||
val mana: BigDecimal,
|
||||
val maxMana: BigDecimal,
|
||||
) : Error(
|
||||
title = resourceReference(R.string.koinos_insufficient_mana_to_send_koin_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.koinos_insufficient_mana_to_send_koin_description,
|
||||
formatArgs = wrappedList(
|
||||
BigDecimalFormatter.formatCryptoAmountShorted(mana, "", Blockchain.Koinos.decimals()),
|
||||
BigDecimalFormatter.formatCryptoAmountShorted(maxMana, "", Blockchain.Koinos.decimals()),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
data object InsufficientBalance : Error(
|
||||
title = resourceReference(R.string.koinos_insufficient_balance_to_send_koin_title),
|
||||
subtitle = resourceReference(R.string.koinos_insufficient_balance_to_send_koin_description),
|
||||
)
|
||||
|
||||
data class ManaExceedsBalance(
|
||||
val availableKoinForTransfer: BigDecimal,
|
||||
val onReduceClick: () -> Unit,
|
||||
) : Error(
|
||||
title = resourceReference(R.string.koinos_mana_exceeds_koin_balance_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.koinos_mana_exceeds_koin_balance_description,
|
||||
formatArgs = wrappedList(
|
||||
BigDecimalFormatter.formatCryptoAmount(
|
||||
availableKoinForTransfer,
|
||||
Blockchain.Koinos.currency,
|
||||
Blockchain.Koinos.decimals(),
|
||||
),
|
||||
),
|
||||
),
|
||||
buttonState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
|
||||
text = resourceReference(R.string.send_notification_reduce_to, wrappedList(availableKoinForTransfer)),
|
||||
onClick = onReduceClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.send.impl.presentation.state
|
|||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountStateConverter
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.event.consumedEvent
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
|
|
@ -164,14 +165,14 @@ internal class SendStateFactory(
|
|||
)
|
||||
}
|
||||
|
||||
fun getSendNotificationState(notifications: ImmutableList<SendNotification>): SendUiState {
|
||||
fun getSendNotificationState(notifications: ImmutableList<NotificationUM>): SendUiState {
|
||||
val state = currentStateProvider()
|
||||
val sendState = state.sendState ?: return state
|
||||
val reducedBy = sendState.reduceAmountBy.takeIf {
|
||||
notifications.none {
|
||||
it is SendNotification.Error.ExistentialDeposit ||
|
||||
it is SendNotification.Error.TransactionLimitError ||
|
||||
it is SendNotification.Warning.HighFeeError
|
||||
it is NotificationUM.Error.ExistentialDeposit ||
|
||||
it is NotificationUM.Error.TransactionLimitError ||
|
||||
it is NotificationUM.Warning.HighFeeError
|
||||
}
|
||||
}
|
||||
return state.copy(
|
||||
|
|
@ -199,10 +200,10 @@ internal class SendStateFactory(
|
|||
private fun isPrimaryButtonEnabled(
|
||||
state: SendUiState,
|
||||
isSending: Boolean,
|
||||
notifications: ImmutableList<SendNotification>,
|
||||
notifications: ImmutableList<NotificationUM>,
|
||||
): Boolean {
|
||||
val feeState = state.getFeeState(stateRouterProvider().isEditState) ?: return false
|
||||
val hasErrorNotifications = notifications.any { it is SendNotification.Error }
|
||||
val hasErrorNotifications = notifications.any { it is NotificationUM.Error }
|
||||
return !hasErrorNotifications && !isSending && feeState.feeSelectorState is FeeSelectorState.Content
|
||||
}
|
||||
//endregion
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import androidx.compose.runtime.Immutable
|
|||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.event.StateEvent
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.features.send.impl.presentation.domain.SendRecipientListContent
|
||||
|
|
@ -112,7 +113,7 @@ internal sealed class SendStates {
|
|||
val appCurrency: AppCurrency,
|
||||
val isFeeApproximate: Boolean,
|
||||
val isCustomSelected: Boolean,
|
||||
val notifications: ImmutableList<SendNotification>,
|
||||
val notifications: ImmutableList<NotificationUM>,
|
||||
val isTronToken: Boolean,
|
||||
) : SendStates()
|
||||
|
||||
|
|
@ -129,7 +130,7 @@ internal sealed class SendStates {
|
|||
val reduceAmountBy: BigDecimal?,
|
||||
val isFromConfirmation: Boolean,
|
||||
val showTapHelp: Boolean,
|
||||
val notifications: ImmutableList<SendNotification>,
|
||||
val notifications: ImmutableList<NotificationUM>,
|
||||
) : SendStates()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,31 +1,35 @@
|
|||
package com.tangem.features.send.impl.presentation.state.confirm
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.blockchainsdk.utils.minimalAmount
|
||||
import com.tangem.common.ui.amountScreen.models.AmountFieldModel
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.amountScreen.utils.getFiatString
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addDustWarningNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addExceedBalanceNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addExceedsBalanceNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addExistentialWarningNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addFeeCoverageNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addFeeUnreachableNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addReserveAmountErrorNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addTransactionLimitErrorNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addValidateTransactionNotifications
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.ui.extensions.networkIconResId
|
||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.core.ui.utils.parseToBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.GetBalanceNotEnoughForFeeWarningUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.GetCurrencyCheckUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.features.send.impl.R
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents
|
||||
import com.tangem.features.send.impl.presentation.state.*
|
||||
import com.tangem.features.send.impl.presentation.state.SendStates
|
||||
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.fee.*
|
||||
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
|
||||
import com.tangem.lib.crypto.BlockchainUtils
|
||||
|
|
@ -41,32 +45,33 @@ import kotlinx.coroutines.flow.map
|
|||
import java.math.BigDecimal
|
||||
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
internal class SendNotificationFactory(
|
||||
internal class SendNotificationFactory constructor(
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val validateTransactionUseCase: ValidateTransactionUseCase,
|
||||
private val getCurrencyCheckUseCase: GetCurrencyCheckUseCase,
|
||||
private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus?>,
|
||||
private val currentStateProvider: Provider<SendUiState>,
|
||||
private val userWalletProvider: Provider<UserWallet>,
|
||||
private val currencyChecksRepository: CurrencyChecksRepository,
|
||||
private val stateRouterProvider: Provider<StateRouter>,
|
||||
private val isSubtractAvailableProvider: Provider<Boolean>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val clickIntents: SendClickIntents,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase,
|
||||
private val validateTransactionUseCase: ValidateTransactionUseCase,
|
||||
private val userWalletId: UserWalletId,
|
||||
) {
|
||||
|
||||
fun create(): Flow<ImmutableList<SendNotification>> = stateRouterProvider().currentState
|
||||
fun create(): Flow<ImmutableList<NotificationUM>> = stateRouterProvider().currentState
|
||||
.filter { it.type == SendUiStateType.Send }
|
||||
.map {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
|
||||
val state = currentStateProvider()
|
||||
val isEditState = stateRouterProvider().isEditState
|
||||
val balance = cryptoCurrencyStatusProvider().value.amount.orZero()
|
||||
val balance = cryptoCurrencyStatus.value.amount.orZero()
|
||||
val sendState = state.sendState ?: return@map persistentListOf()
|
||||
val feeState = state.getFeeState(isEditState) ?: return@map persistentListOf()
|
||||
val amountState = state.getAmountState(isEditState) as? AmountState.Data ?: return@map persistentListOf()
|
||||
|
||||
val recipientAddress = state.recipientState?.addressTextField?.value.orEmpty()
|
||||
val amountValue = amountState.amountTextField.cryptoAmount.value.orZero()
|
||||
val feeValue = feeState.fee?.amount?.value.orZero()
|
||||
val reduceAmountBy = sendState.reduceAmountBy.orZero()
|
||||
|
|
@ -78,42 +83,38 @@ internal class SendNotificationFactory(
|
|||
reduceAmountBy = reduceAmountBy,
|
||||
)
|
||||
val sendingAmount = checkAndCalculateSubtractedAmount(
|
||||
isAmountSubtractAvailable = isFeeCoverage,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatusProvider(),
|
||||
isAmountSubtractAvailable = isSubtractAvailableProvider(),
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
amountValue = amountValue,
|
||||
feeValue = feeValue,
|
||||
reduceAmountBy = reduceAmountBy,
|
||||
)
|
||||
val feeError = (feeState.feeSelectorState as? FeeSelectorState.Error)?.error
|
||||
val currencyCheck = getCurrencyCheckUseCase(
|
||||
userWalletId = userWalletId,
|
||||
currencyStatus = cryptoCurrencyStatus,
|
||||
amount = amountValue,
|
||||
fee = feeValue,
|
||||
)
|
||||
buildList {
|
||||
// errors
|
||||
addFeeUnreachableNotification(feeState.feeSelectorState)
|
||||
addExceedBalanceNotification(feeValue, sendingAmount)
|
||||
addExceedsBalanceNotification(feeState.fee)
|
||||
addDustWarningNotificationForSpecificBlockchains(feeValue, sendingAmount)
|
||||
addTransactionLimitErrorNotification(feeValue, sendingAmount)
|
||||
addReserveAmountErrorNotification(recipientAddress, sendingAmount)
|
||||
|
||||
// warnings
|
||||
addExistentialWarningNotification(feeValue, amountValue)
|
||||
addFeeCoverageNotification(
|
||||
isFeeCoverage = isFeeCoverage,
|
||||
amountField = amountState.amountTextField,
|
||||
sendingValue = sendingAmount,
|
||||
)
|
||||
addHighFeeWarningNotification(amountValue, sendState.ignoreAmountReduce)
|
||||
addTooHighNotification(feeState.feeSelectorState)
|
||||
addTooLowNotification(feeState)
|
||||
|
||||
// blockchain specific
|
||||
addValidateTransactionNotifications(
|
||||
addErrorNotifications(
|
||||
feeError = feeError,
|
||||
sendingAmount = sendingAmount,
|
||||
fee = feeState.fee,
|
||||
state = state,
|
||||
feeValue = feeValue,
|
||||
currencyCheck = currencyCheck,
|
||||
)
|
||||
addWarningNotifications(
|
||||
amountState = amountState,
|
||||
feeState = feeState,
|
||||
sendState = sendState,
|
||||
sendingAmount = sendingAmount,
|
||||
isFeeCoverage = isFeeCoverage,
|
||||
currencyCheck = currencyCheck,
|
||||
)
|
||||
}.toImmutableList()
|
||||
}
|
||||
|
||||
fun dismissNotificationState(clazz: Class<out SendNotification>, isIgnored: Boolean = false): SendUiState {
|
||||
fun dismissNotificationState(clazz: Class<out NotificationUM>, isIgnored: Boolean = false): SendUiState {
|
||||
val state = currentStateProvider()
|
||||
val sendState = state.sendState ?: return state
|
||||
val notificationsToRemove = sendState.notifications.filterIsInstance(clazz)
|
||||
|
|
@ -128,161 +129,120 @@ internal class SendNotificationFactory(
|
|||
)
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addFeeUnreachableNotification(feeSelectorState: FeeSelectorState) {
|
||||
when (feeSelectorState) {
|
||||
is FeeSelectorState.Error.TronAccountActivationError -> add(
|
||||
SendNotification.Warning.TronAccountNotActivated(
|
||||
feeSelectorState.tokenName,
|
||||
),
|
||||
)
|
||||
is FeeSelectorState.Error.NetworkError -> add(
|
||||
SendNotification.Warning.NetworkFeeUnreachable(clickIntents::feeReload),
|
||||
)
|
||||
else -> {
|
||||
/* do nothing */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addExceedBalanceNotification(
|
||||
feeAmount: BigDecimal,
|
||||
receivedAmount: BigDecimal,
|
||||
) {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val balance = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO
|
||||
|
||||
if (!isSubtractAvailableProvider()) return
|
||||
|
||||
val showNotification = receivedAmount + feeAmount > balance
|
||||
if (showNotification) {
|
||||
add(SendNotification.Error.TotalExceedsBalance)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MutableList<SendNotification>.addReserveAmountErrorNotification(
|
||||
recipientAddress: String,
|
||||
private suspend fun MutableList<NotificationUM>.addErrorNotifications(
|
||||
feeError: GetFeeError?,
|
||||
sendingAmount: BigDecimal,
|
||||
feeValue: BigDecimal,
|
||||
currencyCheck: CryptoCurrencyCheck,
|
||||
) {
|
||||
val userWalletId = userWalletProvider().walletId
|
||||
val cryptoCurrency = cryptoCurrencyStatusProvider().currency
|
||||
val isAccountFunded = currencyChecksRepository.checkIfAccountFunded(
|
||||
userWalletId,
|
||||
cryptoCurrency.network,
|
||||
recipientAddress,
|
||||
)
|
||||
val minimumAmount = currencyChecksRepository.getReserveAmount(userWalletId, cryptoCurrency.network)
|
||||
if (!isAccountFunded && minimumAmount != null && minimumAmount > sendingAmount) {
|
||||
add(
|
||||
SendNotification.Error.ReserveAmount(
|
||||
BigDecimalFormatter.formatCryptoAmount(
|
||||
cryptoAmount = minimumAmount,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MutableList<SendNotification>.addTransactionLimitErrorNotification(
|
||||
feeAmount: BigDecimal,
|
||||
receivedAmount: BigDecimal,
|
||||
) {
|
||||
val userWalletId = userWalletProvider().walletId
|
||||
val cryptoCurrency = cryptoCurrencyStatusProvider().currency
|
||||
val utxoLimit = currencyChecksRepository.checkUtxoAmountLimit(
|
||||
userWalletId = userWalletId,
|
||||
network = cryptoCurrency.network,
|
||||
amount = receivedAmount,
|
||||
fee = feeAmount,
|
||||
)
|
||||
|
||||
if (utxoLimit != null) {
|
||||
add(
|
||||
SendNotification.Error.TransactionLimitError(
|
||||
cryptoCurrency = cryptoCurrency.name,
|
||||
utxoLimit = utxoLimit.maxLimit.toPlainString(),
|
||||
amountLimit = BigDecimalFormatter.formatCryptoAmount(
|
||||
cryptoAmount = utxoLimit.maxAmount,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
),
|
||||
onConfirmClick = {
|
||||
clickIntents.onAmountReduceClick(
|
||||
reduceAmountTo = utxoLimit.maxAmount,
|
||||
clazz = SendNotification.Error.TransactionLimitError::class.java,
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MutableList<SendNotification>.addExistentialWarningNotification(
|
||||
feeAmount: BigDecimal,
|
||||
receivedAmount: BigDecimal,
|
||||
) {
|
||||
val userWalletId = userWalletProvider().walletId
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
val balance = cryptoCurrencyStatus.value.amount ?: return
|
||||
val spendingAmount = if (cryptoCurrency is CryptoCurrency.Token) {
|
||||
feeAmount
|
||||
} else {
|
||||
receivedAmount
|
||||
}
|
||||
val currencyDeposit = currencyChecksRepository.getExistentialDeposit(
|
||||
userWalletId,
|
||||
cryptoCurrency.network,
|
||||
val currency = cryptoCurrencyStatusProvider().currency
|
||||
val currencyWarning = getBalanceNotEnoughForFeeWarningUseCase(
|
||||
fee = feeValue,
|
||||
userWalletId = userWalletId,
|
||||
tokenStatus = cryptoCurrencyStatus,
|
||||
coinStatus = feeCryptoCurrencyStatusProvider() ?: cryptoCurrencyStatus,
|
||||
).getOrNull()
|
||||
|
||||
addFeeUnreachableNotification(
|
||||
feeError = feeError,
|
||||
tokenName = currency.name,
|
||||
onReload = clickIntents::feeReload,
|
||||
)
|
||||
val diff = balance.minus(spendingAmount)
|
||||
if (currencyDeposit != null && diff >= BigDecimal.ZERO && currencyDeposit > diff) {
|
||||
add(
|
||||
SendNotification.Error.ExistentialDeposit(
|
||||
deposit = BigDecimalFormatter.formatCryptoAmountUncapped(
|
||||
cryptoAmount = currencyDeposit,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
addExceedBalanceNotification(
|
||||
feeAmount = feeValue,
|
||||
sendingAmount = sendingAmount,
|
||||
isSubtractionAvailable = isSubtractAvailableProvider(),
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
)
|
||||
addExceedsBalanceNotification(
|
||||
cryptoCurrencyWarning = currencyWarning,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
shouldMergeFeeNetworkName = BlockchainUtils.isArbitrum(currency.network.backendId),
|
||||
onClick = clickIntents::onTokenDetailsClick,
|
||||
onAnalyticsEvent = {
|
||||
analyticsEventHandler.send(
|
||||
SendAnalyticEvents.NoticeNotEnoughFee(
|
||||
token = cryptoCurrencyStatus.currency.symbol,
|
||||
blockchain = cryptoCurrencyStatus.currency.network.name,
|
||||
),
|
||||
onConfirmClick = {
|
||||
clickIntents.onAmountReduceClick(
|
||||
reduceAmountByDiff = currencyDeposit.minus(diff),
|
||||
reduceAmountBy = currencyDeposit,
|
||||
clazz = SendNotification.Error.ExistentialDeposit::class.java,
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
if (!BlockchainUtils.isCardano(currency.id.value)) {
|
||||
addDustWarningNotification(
|
||||
dustValue = currencyCheck.dustValue,
|
||||
feeValue = feeValue,
|
||||
sendingAmount = sendingAmount,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
feeCurrencyStatus = feeCryptoCurrencyStatusProvider(),
|
||||
)
|
||||
}
|
||||
addTransactionLimitErrorNotification(
|
||||
utxoLimit = currencyCheck.utxoAmountLimit,
|
||||
cryptoCurrency = currency,
|
||||
onReduceClick = clickIntents::onAmountReduceToClick,
|
||||
)
|
||||
addReserveAmountErrorNotification(
|
||||
reserveAmount = currencyCheck.reserveAmount,
|
||||
sendingAmount = sendingAmount,
|
||||
cryptoCurrency = currency,
|
||||
isAccountFunded = false,
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addFeeCoverageNotification(
|
||||
private suspend fun MutableList<NotificationUM>.addWarningNotifications(
|
||||
amountState: AmountState.Data,
|
||||
feeState: SendStates.FeeState,
|
||||
sendState: SendStates.SendState,
|
||||
sendingAmount: BigDecimal,
|
||||
isFeeCoverage: Boolean,
|
||||
amountField: AmountFieldModel,
|
||||
sendingValue: BigDecimal,
|
||||
currencyCheck: CryptoCurrencyCheck,
|
||||
) {
|
||||
if (isFeeCoverage) {
|
||||
analyticsEventHandler.send(SendAnalyticEvents.NoticeFeeCoverage)
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
val fiatRate = cryptoCurrencyStatus.value.fiatRate
|
||||
val amountValue = amountField.cryptoAmount.value ?: return
|
||||
|
||||
val cryptoDiff = amountValue.minus(sendingValue)
|
||||
add(
|
||||
SendNotification.Warning.FeeCoverageNotification(
|
||||
cryptoAmount = BigDecimalFormatter.formatCryptoAmountUncapped(
|
||||
cryptoAmount = cryptoDiff,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
),
|
||||
fiatAmount = getFiatString(
|
||||
value = cryptoDiff,
|
||||
rate = fiatRate,
|
||||
appCurrency = appCurrencyProvider(),
|
||||
),
|
||||
),
|
||||
)
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val currency = cryptoCurrencyStatus.currency
|
||||
val amountValue = amountState.amountTextField.cryptoAmount.value
|
||||
val validationError = amountValue?.let {
|
||||
validateTransactionUseCase(
|
||||
userWalletId = userWalletId,
|
||||
amount = amountValue.convertToSdkAmount(cryptoCurrencyStatus.currency),
|
||||
fee = feeState.fee,
|
||||
memo = null,
|
||||
destination = "",
|
||||
network = cryptoCurrencyStatus.currency.network,
|
||||
).leftOrNull()
|
||||
}
|
||||
addExistentialWarningNotification(
|
||||
existentialDeposit = currencyCheck.existentialDeposit,
|
||||
feeAmount = feeState.fee?.amount?.value.orZero(),
|
||||
receivedAmount = sendingAmount,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
onReduceClick = clickIntents::onAmountReduceByClick,
|
||||
)
|
||||
addFeeCoverageNotification(
|
||||
isFeeCoverage = isFeeCoverage,
|
||||
amountField = amountState.amountTextField,
|
||||
sendingValue = sendingAmount,
|
||||
appCurrency = appCurrencyProvider(),
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
)
|
||||
addValidateTransactionNotifications(
|
||||
dustValue = currencyCheck.dustValue.orZero(),
|
||||
fee = feeState.fee,
|
||||
validationError = validationError,
|
||||
cryptoCurrency = currency,
|
||||
onReduceClick = clickIntents::onAmountReduceToClick,
|
||||
)
|
||||
|
||||
addHighFeeWarningNotification(
|
||||
amountState.amountTextField.cryptoAmount.value.orZero(),
|
||||
sendState.ignoreAmountReduce,
|
||||
)
|
||||
addTooHighNotification(feeState.feeSelectorState)
|
||||
addTooLowNotification(feeState)
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addHighFeeWarningNotification(
|
||||
private fun MutableList<NotificationUM>.addHighFeeWarningNotification(
|
||||
sendAmount: BigDecimal,
|
||||
ignoreAmountReduce: Boolean,
|
||||
) {
|
||||
|
|
@ -293,61 +253,32 @@ internal class SendNotificationFactory(
|
|||
val isTotalBalance = sendAmount >= balance && balance > threshold
|
||||
if (!ignoreAmountReduce && isTotalBalance && isTezos) {
|
||||
add(
|
||||
SendNotification.Warning.HighFeeError(
|
||||
NotificationUM.Warning.HighFeeError(
|
||||
currencyName = cryptoCurrencyStatus.currency.name,
|
||||
amount = threshold.toPlainString(),
|
||||
onConfirmClick = {
|
||||
clickIntents.onAmountReduceClick(
|
||||
clickIntents.onAmountReduceByClick(
|
||||
reduceAmountBy = threshold,
|
||||
clazz = SendNotification.Warning.HighFeeError::class.java,
|
||||
reduceAmountByDiff = threshold,
|
||||
notification = NotificationUM.Warning.HighFeeError::class.java,
|
||||
)
|
||||
},
|
||||
onCloseClick = {
|
||||
clickIntents.onNotificationCancel(SendNotification.Warning.HighFeeError::class.java)
|
||||
clickIntents.onNotificationCancel(NotificationUM.Warning.HighFeeError::class.java)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MutableList<SendNotification>.addDustWarningNotificationForSpecificBlockchains(
|
||||
feeValue: BigDecimal,
|
||||
sendingAmount: BigDecimal,
|
||||
) {
|
||||
val isCardano = BlockchainUtils.isCardano(cryptoCurrencyStatusProvider().currency.network.id.value)
|
||||
|
||||
if (!isCardano) {
|
||||
addDustWarningNotification(feeValue, sendingAmount)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkDustLimits(feeAmount: BigDecimal, receivedAmount: BigDecimal, dustValue: BigDecimal): Boolean {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val feeCurrencyStatus = feeCryptoCurrencyStatusProvider() ?: return false
|
||||
|
||||
val change = when (cryptoCurrencyStatus.currency) {
|
||||
is CryptoCurrency.Coin -> {
|
||||
val balance = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO
|
||||
balance - (feeAmount + receivedAmount)
|
||||
}
|
||||
is CryptoCurrency.Token -> {
|
||||
val balance = feeCurrencyStatus.value.amount ?: BigDecimal.ZERO
|
||||
balance - feeAmount
|
||||
}
|
||||
}
|
||||
|
||||
val isChangeLowerThanDust = change < dustValue && change > BigDecimal.ZERO
|
||||
return receivedAmount < dustValue || isChangeLowerThanDust
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addTooLowNotification(feeState: SendStates.FeeState) {
|
||||
private fun MutableList<NotificationUM>.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)
|
||||
add(NotificationUM.Warning.FeeTooLow)
|
||||
analyticsEventHandler.send(
|
||||
SendAnalyticEvents.NoticeTransactionDelays(
|
||||
cryptoCurrencyStatusProvider().currency.symbol,
|
||||
|
|
@ -356,206 +287,11 @@ internal class SendNotificationFactory(
|
|||
}
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addTooHighNotification(feeSelectorState: FeeSelectorState) {
|
||||
private fun MutableList<NotificationUM>.addTooHighNotification(feeSelectorState: FeeSelectorState) {
|
||||
if (feeSelectorState !is FeeSelectorState.Content) return
|
||||
|
||||
checkIfFeeTooHigh(feeSelectorState) { diff ->
|
||||
add(SendNotification.Warning.TooHigh(diff))
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MutableList<SendNotification>.addExceedsBalanceNotification(fee: Fee?) {
|
||||
val feeValue = fee?.amount?.value ?: BigDecimal.ZERO
|
||||
val userWalletId = userWalletProvider().walletId
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val feeCurrencyStatus = feeCryptoCurrencyStatusProvider() ?: return
|
||||
|
||||
val warning = getBalanceNotEnoughForFeeWarningUseCase(
|
||||
fee = feeValue,
|
||||
userWalletId = userWalletId,
|
||||
tokenStatus = cryptoCurrencyStatus,
|
||||
coinStatus = feeCurrencyStatus,
|
||||
).getOrNull() ?: return
|
||||
|
||||
val mergeFeeNetworkName = cryptoCurrencyStatus.shouldMergeFeeNetworkName()
|
||||
when (warning) {
|
||||
is CryptoCurrencyWarning.BalanceNotEnoughForFee -> {
|
||||
add(
|
||||
SendNotification.Error.ExceedsBalance(
|
||||
networkIconId = warning.coinCurrency.networkIconResId,
|
||||
networkName = warning.coinCurrency.name,
|
||||
currencyName = cryptoCurrencyStatus.currency.name,
|
||||
feeName = warning.coinCurrency.name,
|
||||
feeSymbol = warning.coinCurrency.symbol,
|
||||
mergeFeeNetworkName = mergeFeeNetworkName,
|
||||
onClick = {
|
||||
clickIntents.onTokenDetailsClick(
|
||||
userWalletId = userWalletId,
|
||||
currency = warning.coinCurrency,
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
analyticsEventHandler.send(
|
||||
SendAnalyticEvents.NoticeNotEnoughFee(
|
||||
token = cryptoCurrencyStatus.currency.symbol,
|
||||
blockchain = cryptoCurrencyStatus.currency.network.name,
|
||||
),
|
||||
)
|
||||
}
|
||||
is CryptoCurrencyWarning.CustomTokenNotEnoughForFee -> {
|
||||
val currency = warning.feeCurrency
|
||||
add(
|
||||
SendNotification.Error.ExceedsBalance(
|
||||
networkIconId = currency?.networkIconResId ?: R.drawable.ic_alert_24,
|
||||
currencyName = warning.currency.name,
|
||||
feeName = warning.feeCurrencyName,
|
||||
feeSymbol = warning.feeCurrencySymbol,
|
||||
networkName = warning.networkName,
|
||||
mergeFeeNetworkName = mergeFeeNetworkName,
|
||||
onClick = currency?.let {
|
||||
{
|
||||
clickIntents.onTokenDetailsClick(
|
||||
userWalletId,
|
||||
currency,
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
analyticsEventHandler.send(
|
||||
SendAnalyticEvents.NoticeNotEnoughFee(
|
||||
token = warning.currency.symbol,
|
||||
blockchain = warning.networkName,
|
||||
),
|
||||
)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
// workaround for networks that users have misunderstanding
|
||||
private fun CryptoCurrencyStatus.shouldMergeFeeNetworkName(): Boolean {
|
||||
return Blockchain.fromNetworkId(this.currency.network.backendId) == Blockchain.Arbitrum
|
||||
}
|
||||
|
||||
private suspend fun MutableList<SendNotification>.addValidateTransactionNotifications(
|
||||
sendingAmount: BigDecimal,
|
||||
fee: Fee?,
|
||||
state: SendUiState,
|
||||
) {
|
||||
val sendingCurrency = cryptoCurrencyStatusProvider().currency
|
||||
|
||||
validateTransactionUseCase(
|
||||
amount = sendingAmount.convertToSdkAmount(sendingCurrency),
|
||||
fee = fee ?: return,
|
||||
memo = state.recipientState?.memoTextField?.value,
|
||||
destination = requireNotNull(state.recipientState?.addressTextField?.value),
|
||||
userWalletId = userWalletProvider().walletId,
|
||||
network = sendingCurrency.network,
|
||||
).fold(
|
||||
ifLeft = {
|
||||
when (it) {
|
||||
is BlockchainSdkError.Cardano -> addCardanoTransactionValidationError(
|
||||
error = it,
|
||||
sendingCurrency = sendingCurrency,
|
||||
)
|
||||
is BlockchainSdkError.Koinos -> addKoinosTransactionValidationError(error = it)
|
||||
else -> return
|
||||
}
|
||||
},
|
||||
ifRight = {
|
||||
(fee as? Fee.CardanoToken)?.let {
|
||||
add(
|
||||
SendNotification.Cardano.MinAdaValueCharged(
|
||||
tokenName = sendingCurrency.name,
|
||||
minAdaValue = it.minAdaValue.parseBigDecimal(sendingCurrency.decimals),
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun MutableList<SendNotification>.addCardanoTransactionValidationError(
|
||||
error: BlockchainSdkError.Cardano,
|
||||
sendingCurrency: CryptoCurrency,
|
||||
) {
|
||||
when (error) {
|
||||
BlockchainSdkError.Cardano.InsufficientMinAdaBalanceToSendToken -> {
|
||||
add(SendNotification.Cardano.InsufficientBalanceToTransferToken(sendingCurrency.name))
|
||||
}
|
||||
BlockchainSdkError.Cardano.InsufficientRemainingBalanceToWithdrawTokens -> {
|
||||
when (sendingCurrency) {
|
||||
is CryptoCurrency.Coin -> SendNotification.Cardano.InsufficientBalanceToTransferCoin
|
||||
is CryptoCurrency.Token -> {
|
||||
SendNotification.Cardano.InsufficientBalanceToTransferToken(sendingCurrency.name)
|
||||
}
|
||||
}.let(::add)
|
||||
}
|
||||
BlockchainSdkError.Cardano.InsufficientRemainingBalance,
|
||||
BlockchainSdkError.Cardano.InsufficientSendingAdaAmount,
|
||||
-> {
|
||||
val dustValue = currencyChecksRepository.getDustValue(
|
||||
userWalletId = userWalletProvider().walletId,
|
||||
network = sendingCurrency.network,
|
||||
) ?: return
|
||||
|
||||
add(
|
||||
SendNotification.Error.MinimumAmountError(
|
||||
amount = dustValue.parseBigDecimal(sendingCurrency.decimals),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addKoinosTransactionValidationError(error: BlockchainSdkError.Koinos) {
|
||||
when (error) {
|
||||
is BlockchainSdkError.Koinos.InsufficientBalance -> {
|
||||
add(SendNotification.Koinos.InsufficientBalance)
|
||||
}
|
||||
is BlockchainSdkError.Koinos.InsufficientMana -> {
|
||||
add(
|
||||
SendNotification.Koinos.InsufficientRecoverableMana(
|
||||
mana = error.manaBalance ?: BigDecimal.ZERO,
|
||||
maxMana = error.maxMana ?: BigDecimal.ZERO,
|
||||
),
|
||||
)
|
||||
}
|
||||
is BlockchainSdkError.Koinos.ManaFeeExceedsBalance -> {
|
||||
add(
|
||||
SendNotification.Koinos.ManaExceedsBalance(
|
||||
availableKoinForTransfer = error.availableKoinForTransfer,
|
||||
onReduceClick = {
|
||||
clickIntents.onAmountReduceClick(
|
||||
reduceAmountTo = error.availableKoinForTransfer,
|
||||
clazz = SendNotification.Koinos.InsufficientRecoverableMana::class.java,
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MutableList<SendNotification>.addDustWarningNotification(
|
||||
feeValue: BigDecimal,
|
||||
sendingAmount: BigDecimal,
|
||||
) {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val dustValue = currencyChecksRepository.getDustValue(
|
||||
userWalletProvider().walletId,
|
||||
cryptoCurrencyStatus.currency.network,
|
||||
) ?: return
|
||||
|
||||
if (checkDustLimits(feeValue, sendingAmount, dustValue)) {
|
||||
add(
|
||||
SendNotification.Error.MinimumAmountError(
|
||||
amount = dustValue.parseBigDecimal(cryptoCurrencyStatus.currency.decimals),
|
||||
),
|
||||
)
|
||||
add(NotificationUM.Warning.TooHigh(diff))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.features.send.impl.presentation.state.fee
|
||||
|
||||
import com.tangem.features.send.impl.presentation.state.SendNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addFeeUnreachableNotification
|
||||
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
|
||||
|
|
@ -25,24 +25,10 @@ internal class FeeNotificationFactory(
|
|||
val feeState = state.getFeeState(stateRouterProvider().isEditState) ?: return@map persistentListOf()
|
||||
buildList {
|
||||
addFeeUnreachableNotification(
|
||||
feeState.feeSelectorState,
|
||||
feeError = (feeState.feeSelectorState as? FeeSelectorState.Error)?.error,
|
||||
tokenName = state.cryptoCurrencyName,
|
||||
onReload = clickIntents::feeReload,
|
||||
)
|
||||
}.toImmutableList()
|
||||
}
|
||||
|
||||
private fun MutableList<SendNotification>.addFeeUnreachableNotification(feeSelectorState: FeeSelectorState) {
|
||||
when (feeSelectorState) {
|
||||
is FeeSelectorState.Error.TronAccountActivationError -> add(
|
||||
SendNotification.Warning.TronAccountNotActivated(
|
||||
feeSelectorState.tokenName,
|
||||
),
|
||||
)
|
||||
is FeeSelectorState.Error.NetworkError -> add(
|
||||
SendNotification.Warning.NetworkFeeUnreachable(clickIntents::feeReload),
|
||||
)
|
||||
else -> {
|
||||
/* do nothing */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.send.impl.presentation.state.fee
|
|||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -17,10 +18,9 @@ internal sealed class FeeSelectorState {
|
|||
|
||||
data object Loading : FeeSelectorState()
|
||||
|
||||
sealed class Error : FeeSelectorState() {
|
||||
data object NetworkError : Error()
|
||||
data class TronAccountActivationError(val tokenName: String) : Error()
|
||||
}
|
||||
data class Error(
|
||||
val error: GetFeeError?,
|
||||
) : FeeSelectorState()
|
||||
}
|
||||
|
||||
enum class FeeType {
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@ import com.tangem.blockchain.common.Token
|
|||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.utils.parseToBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.AmountType
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
|
||||
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.SendUiState
|
||||
import com.tangem.features.send.impl.presentation.state.StateRouter
|
||||
|
|
@ -102,13 +103,13 @@ internal class FeeStateFactory(
|
|||
)
|
||||
}
|
||||
|
||||
fun onFeeOnErrorState(feeError: FeeSelectorState.Error): SendUiState {
|
||||
fun onFeeOnErrorState(feeError: GetFeeError?): SendUiState {
|
||||
val state = currentStateProvider()
|
||||
val isEditState = stateRouterProvider().isEditState
|
||||
return state.copyWrapped(
|
||||
isEditState = isEditState,
|
||||
feeState = state.getFeeState(isEditState)?.copy(
|
||||
feeSelectorState = feeError,
|
||||
feeSelectorState = FeeSelectorState.Error(feeError),
|
||||
),
|
||||
sendState = state.sendState?.copy(
|
||||
isPrimaryButtonEnabled = false,
|
||||
|
|
@ -152,7 +153,7 @@ internal class FeeStateFactory(
|
|||
)
|
||||
}
|
||||
|
||||
fun getFeeNotificationState(notifications: ImmutableList<SendNotification>): SendUiState {
|
||||
fun getFeeNotificationState(notifications: ImmutableList<NotificationUM>): SendUiState {
|
||||
val state = currentStateProvider()
|
||||
val isEditState = stateRouterProvider().isEditState
|
||||
val feeState = state.getFeeState(isEditState) ?: return state
|
||||
|
|
@ -167,7 +168,7 @@ internal class FeeStateFactory(
|
|||
|
||||
private fun isPrimaryButtonEnabled(
|
||||
feeState: SendStates.FeeState,
|
||||
notifications: ImmutableList<SendNotification>,
|
||||
notifications: ImmutableList<NotificationUM>,
|
||||
): Boolean {
|
||||
val feeSelectorState = feeState.feeSelectorState as? FeeSelectorState.Content ?: return false
|
||||
val customValue = feeSelectorState.customValues.firstOrNull()
|
||||
|
|
@ -178,7 +179,7 @@ internal class FeeStateFactory(
|
|||
} else {
|
||||
false
|
||||
}
|
||||
val noErrors = notifications.none { it is SendNotification.Error }
|
||||
val noErrors = notifications.none { it is NotificationUM.Error }
|
||||
|
||||
return noErrors && (isNotEmptyCustom || isNotCustom)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,6 @@ internal object FeeStatePreviewData {
|
|||
)
|
||||
|
||||
val errorFeeState = feeState.copy(
|
||||
feeSelectorState = FeeSelectorState.Error.NetworkError,
|
||||
feeSelectorState = FeeSelectorState.Error(null),
|
||||
)
|
||||
}
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
package com.tangem.features.send.impl.presentation.state.previewdata
|
||||
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
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
|
||||
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -24,11 +23,12 @@ internal object SendClickIntentsStub : SendClickIntents {
|
|||
|
||||
override fun onFailedTxEmailClick(errorMessage: String) {}
|
||||
|
||||
override fun onTokenDetailsClick(userWalletId: UserWalletId, currency: CryptoCurrency) {}
|
||||
override fun onTokenDetailsClick(currency: CryptoCurrency) {}
|
||||
|
||||
override fun onAmountValueChange(value: String) {}
|
||||
|
||||
override fun onCurrencyChangeClick(isFiat: Boolean) {}
|
||||
|
||||
override fun onAmountNext() {}
|
||||
|
||||
override fun onMaxValueClick() {}
|
||||
|
|
@ -61,13 +61,13 @@ internal object SendClickIntentsStub : SendClickIntents {
|
|||
|
||||
override fun onShareClick() {}
|
||||
|
||||
override fun onAmountReduceClick(
|
||||
reduceAmountBy: BigDecimal?,
|
||||
reduceAmountByDiff: BigDecimal?,
|
||||
reduceAmountTo: BigDecimal?,
|
||||
clazz: Class<out SendNotification>,
|
||||
) {
|
||||
}
|
||||
override fun onAmountReduceByClick(
|
||||
reduceAmountBy: BigDecimal,
|
||||
reduceAmountByDiff: BigDecimal,
|
||||
notification: Class<out NotificationUM>,
|
||||
) {}
|
||||
|
||||
override fun onNotificationCancel(clazz: Class<out SendNotification>) {}
|
||||
override fun onAmountReduceToClick(reduceAmountTo: BigDecimal, notification: Class<out NotificationUM>) {}
|
||||
|
||||
override fun onNotificationCancel(clazz: Class<out NotificationUM>) {}
|
||||
}
|
||||
|
|
@ -5,14 +5,14 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.send.impl.presentation.state.SendNotification
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
internal fun LazyListScope.notifications(
|
||||
notifications: ImmutableList<SendNotification>,
|
||||
notifications: ImmutableList<NotificationUM>,
|
||||
modifier: Modifier = Modifier,
|
||||
hasPaddingAbove: Boolean = false,
|
||||
isClickDisabled: Boolean = false,
|
||||
|
|
@ -33,17 +33,18 @@ internal fun LazyListScope.notifications(
|
|||
.padding(top = topPadding)
|
||||
.animateItemPlacement(),
|
||||
containerColor = when (item) {
|
||||
is SendNotification.Error.ExceedsBalance,
|
||||
is SendNotification.Warning.NetworkFeeUnreachable,
|
||||
is SendNotification.Warning.HighFeeError,
|
||||
is NotificationUM.Error.TokenExceedsBalance,
|
||||
is NotificationUM.Warning.NetworkFeeUnreachable,
|
||||
is NotificationUM.Warning.HighFeeError,
|
||||
-> TangemTheme.colors.background.action
|
||||
else -> TangemTheme.colors.button.disabled
|
||||
},
|
||||
iconTint = when (item) {
|
||||
is SendNotification.Error.ExceedsBalance,
|
||||
is SendNotification.Warning,
|
||||
is NotificationUM.Error.TokenExceedsBalance,
|
||||
is NotificationUM.Warning,
|
||||
-> null
|
||||
is SendNotification.Error -> TangemTheme.colors.icon.warning
|
||||
is NotificationUM.Error -> TangemTheme.colors.icon.warning
|
||||
is NotificationUM.Info -> null
|
||||
},
|
||||
isEnabled = !isClickDisabled,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
package com.tangem.features.send.impl.presentation.viewmodel
|
||||
|
||||
import com.tangem.common.ui.amountScreen.AmountScreenClickIntents
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
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
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -25,7 +24,7 @@ internal interface SendClickIntents : AmountScreenClickIntents {
|
|||
|
||||
fun onFailedTxEmailClick(errorMessage: String)
|
||||
|
||||
fun onTokenDetailsClick(userWalletId: UserWalletId, currency: CryptoCurrency)
|
||||
fun onTokenDetailsClick(currency: CryptoCurrency)
|
||||
|
||||
// region Recipient
|
||||
fun onRecipientAddressValueChange(value: String, type: EnterAddressSource? = null)
|
||||
|
|
@ -58,13 +57,14 @@ internal interface SendClickIntents : AmountScreenClickIntents {
|
|||
|
||||
fun onShareClick()
|
||||
|
||||
fun onAmountReduceClick(
|
||||
reduceAmountBy: BigDecimal? = null,
|
||||
reduceAmountByDiff: BigDecimal? = reduceAmountBy,
|
||||
reduceAmountTo: BigDecimal? = null,
|
||||
clazz: Class<out SendNotification>,
|
||||
fun onAmountReduceByClick(
|
||||
reduceAmountBy: BigDecimal,
|
||||
reduceAmountByDiff: BigDecimal,
|
||||
notification: Class<out NotificationUM>,
|
||||
)
|
||||
|
||||
fun onNotificationCancel(clazz: Class<out SendNotification>)
|
||||
fun onAmountReduceToClick(reduceAmountTo: BigDecimal, notification: Class<out NotificationUM>)
|
||||
|
||||
fun onNotificationCancel(clazz: Class<out NotificationUM>)
|
||||
// endregion
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import com.tangem.blockchain.common.transaction.TransactionFee
|
|||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.bundle.unbundle
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
|
|
@ -28,7 +29,6 @@ import com.tangem.domain.tokens.*
|
|||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
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.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.error.ValidateAddressError
|
||||
import com.tangem.domain.transaction.usecase.*
|
||||
|
|
@ -47,7 +47,6 @@ import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents
|
|||
import com.tangem.features.send.impl.presentation.analytics.SendScreenSource
|
||||
import com.tangem.features.send.impl.presentation.analytics.utils.SendScreenAnalyticSender
|
||||
import com.tangem.features.send.impl.presentation.domain.AvailableWallet
|
||||
import com.tangem.features.send.impl.presentation.errors.FeeErrorStateMapper
|
||||
import com.tangem.features.send.impl.presentation.state.*
|
||||
import com.tangem.features.send.impl.presentation.state.amount.AmountStateFactory
|
||||
import com.tangem.features.send.impl.presentation.state.confirm.SendNotificationFactory
|
||||
|
|
@ -99,7 +98,7 @@ internal class SendViewModel @Inject constructor(
|
|||
private val validateWalletMemoUseCase: ValidateWalletMemoUseCase,
|
||||
@DelayedWork private val coroutineScope: CoroutineScope,
|
||||
validateTransactionUseCase: ValidateTransactionUseCase,
|
||||
currencyChecksRepository: CurrencyChecksRepository,
|
||||
getCurrencyCheckUseCase: GetCurrencyCheckUseCase,
|
||||
isFeeApproximateUseCase: IsFeeApproximateUseCase,
|
||||
getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
|
|
@ -124,8 +123,6 @@ internal class SendViewModel @Inject constructor(
|
|||
var stateRouter: StateRouter by Delegates.notNull()
|
||||
private set
|
||||
|
||||
private val feeErrorHandler = FeeErrorStateMapper()
|
||||
|
||||
private val stateFactory = SendStateFactory(
|
||||
clickIntents = this,
|
||||
stateRouterProvider = Provider { stateRouter },
|
||||
|
|
@ -174,18 +171,18 @@ internal class SendViewModel @Inject constructor(
|
|||
)
|
||||
|
||||
private val sendNotificationFactory = SendNotificationFactory(
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
validateTransactionUseCase = validateTransactionUseCase,
|
||||
getCurrencyCheckUseCase = getCurrencyCheckUseCase,
|
||||
getBalanceNotEnoughForFeeWarningUseCase = getBalanceNotEnoughForFeeWarningUseCase,
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
feeCryptoCurrencyStatusProvider = Provider { feeCryptoCurrencyStatus },
|
||||
currentStateProvider = Provider { uiState.value },
|
||||
userWalletProvider = Provider { userWallet },
|
||||
stateRouterProvider = Provider { stateRouter },
|
||||
isSubtractAvailableProvider = Provider { isAmountSubtractAvailable },
|
||||
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
||||
currencyChecksRepository = currencyChecksRepository,
|
||||
clickIntents = this,
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
getBalanceNotEnoughForFeeWarningUseCase = getBalanceNotEnoughForFeeWarningUseCase,
|
||||
validateTransactionUseCase = validateTransactionUseCase,
|
||||
userWalletId = userWalletId,
|
||||
)
|
||||
|
||||
private val sendScreenAnalyticSender by lazy(LazyThreadSafetyMode.NONE) {
|
||||
|
|
@ -537,8 +534,7 @@ internal class SendViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
override fun onTokenDetailsClick(userWalletId: UserWalletId, currency: CryptoCurrency) =
|
||||
innerRouter.openTokenDetails(userWalletId, currency)
|
||||
override fun onTokenDetailsClick(currency: CryptoCurrency) = innerRouter.openTokenDetails(userWalletId, currency)
|
||||
|
||||
private fun onFeeNext(): Boolean {
|
||||
val feeState = uiState.value.getFeeState(stateRouter.isEditState)
|
||||
|
|
@ -730,7 +726,7 @@ internal class SendViewModel @Inject constructor(
|
|||
private fun onFeeLoadFailed(isShowStatus: Boolean, loadFeeError: GetFeeError?) {
|
||||
if (isShowStatus) {
|
||||
uiState.value = feeStateFactory.onFeeOnErrorState(
|
||||
feeErrorHandler.getFeeError(loadFeeError, cryptoCurrency.name),
|
||||
loadFeeError,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -814,26 +810,27 @@ internal class SendViewModel @Inject constructor(
|
|||
analyticsEventHandler.send(SendAnalyticEvents.ShareButtonClicked)
|
||||
}
|
||||
|
||||
override fun onAmountReduceClick(
|
||||
reduceAmountBy: BigDecimal?,
|
||||
reduceAmountByDiff: BigDecimal?,
|
||||
reduceAmountTo: BigDecimal?,
|
||||
clazz: Class<out SendNotification>,
|
||||
) {
|
||||
uiState.value = when {
|
||||
reduceAmountBy != null && reduceAmountByDiff != null -> amountStateFactory.getOnAmountReduceByState(
|
||||
reduceAmountBy = reduceAmountBy,
|
||||
reduceAmountByDiff = reduceAmountByDiff,
|
||||
)
|
||||
reduceAmountTo != null -> amountStateFactory.getOnAmountReduceToState(reduceAmountTo)
|
||||
else -> return
|
||||
}
|
||||
|
||||
uiState.value = sendNotificationFactory.dismissNotificationState(clazz)
|
||||
override fun onAmountReduceToClick(reduceAmountTo: BigDecimal, notification: Class<out NotificationUM>) {
|
||||
uiState.value = amountStateFactory.getOnAmountReduceToState(reduceAmountTo)
|
||||
uiState.value = sendNotificationFactory.dismissNotificationState(notification)
|
||||
updateNotifications()
|
||||
}
|
||||
|
||||
override fun onNotificationCancel(clazz: Class<out SendNotification>) {
|
||||
override fun onAmountReduceByClick(
|
||||
reduceAmountBy: BigDecimal,
|
||||
reduceAmountByDiff: BigDecimal,
|
||||
notification: Class<out NotificationUM>,
|
||||
) {
|
||||
uiState.value = amountStateFactory.getOnAmountReduceByState(
|
||||
reduceAmountBy = reduceAmountBy,
|
||||
reduceAmountByDiff = reduceAmountByDiff,
|
||||
)
|
||||
|
||||
uiState.value = sendNotificationFactory.dismissNotificationState(notification)
|
||||
updateNotifications()
|
||||
}
|
||||
|
||||
override fun onNotificationCancel(clazz: Class<out NotificationUM>) {
|
||||
uiState.value = sendNotificationFactory.dismissNotificationState(clazz = clazz, isIgnored = true)
|
||||
}
|
||||
|
||||
|
|
@ -972,7 +969,7 @@ internal class SendViewModel @Inject constructor(
|
|||
private fun onCheckFeeUpdate() {
|
||||
val sendState = uiState.value.sendState ?: return
|
||||
val isSuccess = sendState.isSuccess
|
||||
val noErrorNotifications = sendState.notifications.none { it is SendNotification.Error }
|
||||
val noErrorNotifications = sendState.notifications.none { it is NotificationUM.Error }
|
||||
|
||||
if (!isSuccess && noErrorNotifications) {
|
||||
viewModelScope.launch {
|
||||
|
|
|
|||
|
|
@ -136,13 +136,11 @@ internal class AddStakingNotificationsTransformer(
|
|||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
val network = cryptoCurrency.network
|
||||
|
||||
if (feeError != null) {
|
||||
addFeeUnreachableNotification(
|
||||
feeError = feeError,
|
||||
tokenName = cryptoCurrencyStatusProvider().currency.name,
|
||||
onReload = onReload,
|
||||
)
|
||||
}
|
||||
addFeeUnreachableNotification(
|
||||
feeError = feeError,
|
||||
tokenName = cryptoCurrencyStatusProvider().currency.name,
|
||||
onReload = onReload,
|
||||
)
|
||||
addStakeExceedBalanceNotification(
|
||||
feeAmount = feeValue,
|
||||
sendingAmount = sendingAmount,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue