Updated on 2026-08-14

This commit is contained in:
Tangem 2025-01-16 18:59:33 +03:00
parent 7fa38a0f26
commit 9cfd045c7b
5 changed files with 38 additions and 23 deletions

View file

@ -82,21 +82,27 @@ data class SwapButton(
sealed interface TransactionCardType {
val header: TextReference
val isError: Boolean
val inputError: InputError
data class Inputtable(
val onAmountChanged: ((String) -> Unit),
val onFocusChanged: ((Boolean) -> Unit),
override val isError: Boolean,
override val inputError: InputError,
override val header: TextReference = TextReference.Res(R.string.swapping_from_title),
) : TransactionCardType
data class ReadOnly(
val showWarning: Boolean = false,
val onWarningClick: (() -> Unit)? = null,
override val isError: Boolean = false,
override val inputError: InputError = InputError.Empty,
override val header: TextReference = TextReference.Res(R.string.swapping_to_title),
) : TransactionCardType
sealed interface InputError {
data object Empty : InputError
data object InsufficientFunds : InputError
data object WrongAmount : InputError
}
}
data class TosState(

View file

@ -80,7 +80,7 @@ internal class StateBuilder(
type = TransactionCardType.Inputtable(
onAmountChanged = actions.onAmountChanged,
onFocusChanged = actions.onAmountSelected,
isError = false,
inputError = TransactionCardType.InputError.Empty,
),
amountEquivalent = null,
amountTextFieldValue = null,
@ -195,11 +195,11 @@ internal class StateBuilder(
if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
val sendInputType = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.Inputtable)
val sendInput = if (sendInputType.isError) {
val sendInput = if (sendInputType.inputError !is TransactionCardType.InputError.Empty) {
sendInputType
} else {
sendInputType.copy(
isError = false,
inputError = TransactionCardType.InputError.Empty,
header = TextReference.Res(R.string.swapping_from_title),
)
}
@ -282,14 +282,22 @@ internal class StateBuilder(
TextReference.Res(R.string.swapping_from_title)
}
val sendCardType = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.Inputtable)
val sendInput = if (sendCardType.isError && !isInsufficientFunds) {
// if any error in inputField and funds enough -> show that error else show fund is not enough error
sendCardType
} else {
sendCardType.copy(
isError = isInsufficientFunds,
header = insufficientFundsHeader,
)
val sendInput = when (sendCardType.inputError) {
is TransactionCardType.InputError.WrongAmount,
-> sendCardType
is TransactionCardType.InputError.Empty,
is TransactionCardType.InputError.InsufficientFunds,
-> {
val error = if (isInsufficientFunds) {
TransactionCardType.InputError.InsufficientFunds
} else {
TransactionCardType.InputError.Empty
}
sendCardType.copy(
inputError = error,
header = insufficientFundsHeader,
)
}
}
return uiStateHolder.copy(
sendCardData = SwapCardState.SwapCardData(
@ -610,12 +618,12 @@ internal class StateBuilder(
crypto(cryptoCurrency = fromToken, ignoreSymbolPosition = true)
}
(uiState.sendCardData.type as? TransactionCardType.Inputtable)?.copy(
isError = true,
inputError = TransactionCardType.InputError.WrongAmount,
header = resourceReference(R.string.transfer_min_amount_error, wrappedList(minAmountFormatted)),
) ?: uiState.sendCardData.type
} else {
(uiState.sendCardData.type as? TransactionCardType.Inputtable)?.copy(
isError = false,
inputError = TransactionCardType.InputError.Empty,
header = TextReference.Res(R.string.swapping_from_title),
) ?: uiState.sendCardData.type
}
@ -1278,6 +1286,7 @@ internal class StateBuilder(
private const val MAX_DECIMALS_TO_SHOW = 8
private const val IF_ZERO_DECIMALS_TO_SHOW = 2
private const val FEE_READ_MORE_URL_FIRST_PART = "https://tangem.com/"
private const val FEE_READ_MORE_URL_SECOND_PART = "/blog/post/what-is-a-transaction-fee-and-why-do-we-need-it/"
private const val FEE_READ_MORE_URL_SECOND_PART =
"/blog/post/what-is-a-transaction-fee-and-why-do-we-need-it/"
}
}

View file

@ -386,7 +386,7 @@ private fun MainButton(state: SwapStateHolder, onPermissionWarningClick: () -> U
// region preview
private val sendCard = SwapCardState.SwapCardData(
type = TransactionCardType.Inputtable({}, {}, false),
type = TransactionCardType.Inputtable({}, {}, TransactionCardType.InputError.Empty),
amountTextFieldValue = TextFieldValue(),
amountEquivalent = "1 000 000",
tokenIconUrl = "",

View file

@ -186,10 +186,10 @@ private fun Header(type: TransactionCardType, balance: String, modifier: Modifie
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
val titleColor = if (type.isError) {
TangemTheme.colors.text.warning
} else {
val titleColor = if (type.inputError is TransactionCardType.InputError.Empty) {
TangemTheme.colors.text.tertiary
} else {
TangemTheme.colors.text.warning
}
Text(
text = type.header.resolveReference(),
@ -551,7 +551,7 @@ private fun Preview_TransactionCardWithoutPriceImpact_InDarkTheme() {
@Composable
private fun TransactionCardPreview() {
TransactionCard(
type = TransactionCardType.Inputtable({}, {}, false),
type = TransactionCardType.Inputtable({}, {}, TransactionCardType.InputError.Empty),
amountEquivalent = "1 000 000",
tokenIconUrl = "",
tokenCurrency = "DAI",

View file

@ -1322,7 +1322,7 @@ internal class SwapViewModel @Inject constructor(
private fun onFailedTxEmailClick(errorMessage: String) {
viewModelScope.launch {
val transaction = dataState.swapDataModel?.transaction
val transaction = dataState.swapDataModel?.transaction
val fromCurrencyStatus = dataState.fromCryptoCurrency ?: initialFromStatus
val network = fromCurrencyStatus.currency.network
val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrElse { error("CardInfo must be not null") }