Updated on 2026-08-14

This commit is contained in:
Tangem 2024-04-08 11:33:39 +05:00
parent 0b32fcb925
commit 38d95a7a9c
4 changed files with 38 additions and 41 deletions

View file

@ -7,7 +7,6 @@ import androidx.compose.ui.text.input.VisualTransformation
import com.tangem.core.ui.utils.BigDecimalFormatter
import com.tangem.core.ui.utils.defaultFormat
import com.tangem.core.ui.utils.formatWithThousands
import com.tangem.core.ui.utils.parseToBigDecimal
import java.text.DecimalFormat
class AmountVisualTransformation(
@ -23,21 +22,16 @@ class AmountVisualTransformation(
decimals,
)
formattedAmount = formattedAmount.ifEmpty { decimalFormat.defaultFormat() }
val decimalValue = text.text.parseToBigDecimal(decimals)
val formattedText = if (formattedAmount.isNotEmpty() && symbol != null) {
AnnotatedString(
if (currencyCode != null) {
BigDecimalFormatter.formatFiatAmount(
fiatAmount = decimalValue,
BigDecimalFormatter.formatFiatEditableAmount(
fiatAmount = formattedAmount,
fiatCurrencyCode = currencyCode,
fiatCurrencySymbol = symbol,
)
} else {
BigDecimalFormatter.formatCryptoAmountUncapped(
cryptoAmount = decimalValue,
cryptoSymbol = symbol,
decimals = decimals,
)
BigDecimalFormatter.formatWithSymbol(formattedAmount, symbol)
},
)
} else {

View file

@ -1,8 +1,10 @@
package com.tangem.core.ui.utils
import com.tangem.domain.tokens.model.CryptoCurrency
import timber.log.Timber
import java.math.BigDecimal
import java.math.RoundingMode
import java.text.DecimalFormat
import java.text.NumberFormat
import java.util.Currency
import java.util.Locale
@ -38,30 +40,6 @@ object BigDecimalFormatter {
}
}
fun formatCryptoAmountUncapped(
cryptoAmount: BigDecimal?,
cryptoSymbol: String,
decimals: Int,
locale: Locale = Locale.getDefault(),
): String {
if (cryptoAmount == null) return EMPTY_BALANCE_SIGN
val formatter = NumberFormat.getNumberInstance(locale).apply {
maximumFractionDigits = decimals
minimumFractionDigits = minOf(2, decimals)
isGroupingUsed = true
roundingMode = RoundingMode.DOWN
}
return formatter.format(cryptoAmount).let {
if (cryptoSymbol.isEmpty()) {
it
} else {
it + "\u2009$cryptoSymbol"
}
}
}
fun formatCryptoAmount(
cryptoAmount: BigDecimal?,
cryptoCurrency: CryptoCurrency,
@ -90,6 +68,26 @@ object BigDecimalFormatter {
.replace(formatterCurrency.getSymbol(locale), fiatCurrencySymbol)
}
fun formatFiatEditableAmount(
fiatAmount: String?,
fiatCurrencyCode: String,
fiatCurrencySymbol: String,
locale: Locale = Locale.getDefault(),
): String {
if (fiatAmount == null) return EMPTY_BALANCE_SIGN
val formatterCurrency = getCurrency(fiatCurrencyCode)
val numberFormatter = NumberFormat.getCurrencyInstance(locale).apply {
currency = formatterCurrency
}
val formatter = requireNotNull(numberFormatter as? DecimalFormat) {
Timber.e("NumberFormat is null")
return EMPTY_BALANCE_SIGN
}
return "${formatter.positivePrefix}$fiatAmount${formatter.positiveSuffix}"
.replace(formatterCurrency.getSymbol(locale), fiatCurrencySymbol)
}
fun formatPercent(
percent: BigDecimal,
useAbsoluteValue: Boolean,
@ -107,6 +105,8 @@ object BigDecimalFormatter {
return formatter.format(value)
}
fun formatWithSymbol(amount: String, symbol: String) = "$amount\u2009$symbol"
private fun getCurrency(code: String): Currency {
return runCatching { Currency.getInstance(code) }
.getOrElse { e ->

View file

@ -45,7 +45,7 @@ internal class SendAmountFieldChangeConverter(
cryptoAmount = amountTextField.cryptoAmount.copy(value = decimalCryptoValue),
fiatAmount = amountTextField.fiatAmount.copy(value = decimalFiatValue),
keyboardOptions = KeyboardOptions(
imeAction = if (!isExceedBalance) ImeAction.Done else ImeAction.None,
imeAction = getKeyboardAction(isExceedBalance, decimalCryptoValue),
keyboardType = KeyboardType.Number,
),
),
@ -103,4 +103,11 @@ internal class SendAmountFieldChangeConverter(
cryptoDecimal > currencyCryptoAmount
}
}
private fun getKeyboardAction(isExceedBalance: Boolean, decimalCryptoValue: BigDecimal) =
if (!isExceedBalance && !decimalCryptoValue.isZero()) {
ImeAction.Done
} else {
ImeAction.None
}
}

View file

@ -30,13 +30,9 @@ internal fun AmountBlock(
) {
val amount = amountState.amountTextField
val cryptoAmount = BigDecimalFormatter.formatCryptoAmount(
cryptoAmount = amount.cryptoAmount.value,
cryptoCurrency = amount.cryptoAmount.currencySymbol,
decimals = amount.cryptoAmount.decimals,
)
val fiatAmount = BigDecimalFormatter.formatFiatAmount(
fiatAmount = amount.fiatAmount.value,
val cryptoAmount = BigDecimalFormatter.formatWithSymbol(amount.value, amount.cryptoAmount.currencySymbol)
val fiatAmount = BigDecimalFormatter.formatFiatEditableAmount(
fiatAmount = amount.fiatValue,
fiatCurrencySymbol = amount.fiatAmount.currencySymbol,
fiatCurrencyCode = amountState.appCurrencyCode,
)