diff --git a/core/ui/src/main/java/com/tangem/core/ui/utils/BigDecimalFormatter.kt b/core/ui/src/main/java/com/tangem/core/ui/utils/BigDecimalFormatter.kt index b724559114..f995dee52e 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/utils/BigDecimalFormatter.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/utils/BigDecimalFormatter.kt @@ -16,6 +16,10 @@ object BigDecimalFormatter { private const val TEMP_CURRENCY_CODE = "USD" + private val FIAT_FORMAT_THRESHOLD = BigDecimal("0.01") + private const val FIAT_MARKET_DEFAULT_DIGITS = 2 + private const val FIAT_MARKET_EXTENDED_DIGITS = 6 + fun formatCryptoAmount( cryptoAmount: BigDecimal?, cryptoCurrency: String, @@ -82,8 +86,43 @@ object BigDecimalFormatter { val formatterCurrency = getCurrency(fiatCurrencyCode) val formatter = NumberFormat.getCurrencyInstance(locale).apply { currency = formatterCurrency - maximumFractionDigits = 2 - minimumFractionDigits = 2 + maximumFractionDigits = FIAT_MARKET_DEFAULT_DIGITS + minimumFractionDigits = FIAT_MARKET_DEFAULT_DIGITS + roundingMode = RoundingMode.HALF_UP + } + + return if (fiatAmount.isLessThanThreshold()) { + buildString { + append(CAN_BE_LOWER_SIGN) + append( + formatter.format(FIAT_FORMAT_THRESHOLD) + .replace(formatterCurrency.getSymbol(locale), fiatCurrencySymbol), + ) + } + } else { + formatter.format(fiatAmount) + .replace(formatterCurrency.getSymbol(locale), fiatCurrencySymbol) + } + } + + fun formatFiatAmountUncapped( + fiatAmount: BigDecimal?, + fiatCurrencyCode: String, + fiatCurrencySymbol: String, + locale: Locale = Locale.getDefault(), + ): String { + if (fiatAmount == null) return EMPTY_BALANCE_SIGN + val formatterCurrency = getCurrency(fiatCurrencyCode) + + val digits = if (fiatAmount.isLessThanThreshold()) { + FIAT_MARKET_EXTENDED_DIGITS + } else { + FIAT_MARKET_DEFAULT_DIGITS + } + val formatter = NumberFormat.getCurrencyInstance(locale).apply { + currency = formatterCurrency + maximumFractionDigits = digits + minimumFractionDigits = FIAT_MARKET_DEFAULT_DIGITS roundingMode = RoundingMode.HALF_UP } @@ -141,4 +180,6 @@ object BigDecimalFormatter { } } } + + private fun BigDecimal.isLessThanThreshold() = this > BigDecimal.ZERO && this < FIAT_FORMAT_THRESHOLD } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt index 93cc9067fd..929231d36d 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt @@ -4,7 +4,10 @@ import androidx.compose.animation.* import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon import androidx.compose.material3.Text @@ -31,10 +34,10 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.shareText import com.tangem.core.ui.extensions.wrappedList import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.utils.BigDecimalFormatter import com.tangem.features.send.impl.presentation.state.SendUiCurrentScreen 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.utils.getFiatFormatted @Composable internal fun SendNavigationButtons( @@ -175,15 +178,15 @@ private fun SendingText( } if (feeFiat != null && sendingFiat != null) { - val sendingValue = getFiatFormatted( - value = sendingFiat, - currencySymbol = feeState.appCurrency.symbol, - currencyCode = feeState.appCurrency.code, + val sendingValue = BigDecimalFormatter.formatFiatAmount( + fiatAmount = sendingFiat, + fiatCurrencySymbol = feeState.appCurrency.symbol, + fiatCurrencyCode = feeState.appCurrency.code, ) - val feeValue = getFiatFormatted( - value = feeState.fee?.amount?.value, - currencySymbol = feeState.appCurrency.symbol, - currencyCode = feeState.appCurrency.code, + val feeValue = BigDecimalFormatter.formatFiatAmount( + fiatAmount = feeState.fee?.amount?.value, + fiatCurrencySymbol = feeState.appCurrency.symbol, + fiatCurrencyCode = feeState.appCurrency.code, ) val textResource = remember(sendingValue, feeValue) { resourceReference( diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/utils/FormatterUtils.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/utils/FormatterUtils.kt index f2be7e6ed2..7c8a2becb6 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/utils/FormatterUtils.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/utils/FormatterUtils.kt @@ -8,11 +8,8 @@ import com.tangem.core.ui.utils.BigDecimalFormatter import com.tangem.core.ui.utils.BigDecimalFormatter.EMPTY_BALANCE_SIGN import com.tangem.domain.appcurrency.model.AppCurrency import java.math.BigDecimal -import java.math.RoundingMode -private const val FIAT_DECIMALS = 2 private const val CRYPTO_FEE_DECIMALS = 6 -private const val FEE_MINIMUM_VALUE = 0.01 internal fun getCryptoReference(amount: Amount?, isFeeApproximate: Boolean): TextReference? { if (amount == null) return null @@ -37,27 +34,9 @@ internal fun getFiatReference(value: BigDecimal?, rate: BigDecimal?, appCurrency internal fun getFiatString(value: BigDecimal?, rate: BigDecimal?, appCurrency: AppCurrency): String { if (value == null || rate == null) return EMPTY_BALANCE_SIGN val feeValue = value.multiply(rate) - return getFiatFormatted(feeValue, appCurrency.code, appCurrency.symbol) -} - -internal fun getFiatFormatted(value: BigDecimal?, currencyCode: String, currencySymbol: String): String { - val scaled = value?.setScale(FIAT_DECIMALS, RoundingMode.UP) ?: BigDecimal.ZERO - return if (scaled < BigDecimal(FEE_MINIMUM_VALUE)) { - buildString { - append(BigDecimalFormatter.CAN_BE_LOWER_SIGN) - append( - BigDecimalFormatter.formatFiatAmount( - fiatAmount = BigDecimal(FEE_MINIMUM_VALUE), - fiatCurrencyCode = currencyCode, - fiatCurrencySymbol = currencySymbol, - ), - ) - } - } else { - BigDecimalFormatter.formatFiatAmount( - fiatAmount = value, - fiatCurrencyCode = currencyCode, - fiatCurrencySymbol = currencySymbol, - ) - } + return BigDecimalFormatter.formatFiatAmount( + fiatAmount = feeValue, + fiatCurrencyCode = appCurrency.code, + fiatCurrencySymbol = appCurrency.symbol, + ) } \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt index 05221db9ec..63d735d3ad 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt @@ -133,7 +133,7 @@ internal class TokenDetailsLoadedBalanceConverter( private fun formatPrice(status: CryptoCurrencyStatus.Value, appCurrency: AppCurrency): String { val fiatRate = status.fiatRate ?: return BigDecimalFormatter.EMPTY_BALANCE_SIGN - return BigDecimalFormatter.formatFiatAmount( + return BigDecimalFormatter.formatFiatAmountUncapped( fiatAmount = fiatRate, fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletMarketPriceConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletMarketPriceConverter.kt index 34579188d3..8d710656dc 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletMarketPriceConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletMarketPriceConverter.kt @@ -47,7 +47,7 @@ internal class SingleWalletMarketPriceConverter( private fun formatPrice(status: CryptoCurrencyStatus.Value, appCurrency: AppCurrency): String { val fiatRate = status.fiatRate ?: return BigDecimalFormatter.EMPTY_BALANCE_SIGN - return BigDecimalFormatter.formatFiatAmount( + return BigDecimalFormatter.formatFiatAmountUncapped( fiatAmount = fiatRate, fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenItemStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenItemStateConverter.kt index aa168db655..f41d4d4ee7 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenItemStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenItemStateConverter.kt @@ -108,7 +108,7 @@ internal class TokenItemStateConverter( private fun BigDecimal.getFormattedCryptoPrice(): String { val appCurrency = appCurrencyProvider() - return BigDecimalFormatter.formatFiatAmount( + return BigDecimalFormatter.formatFiatAmountUncapped( fiatAmount = this, fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol,