Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-08 18:53:25 +03:00
parent 700731a408
commit c500f45307
59 changed files with 1338 additions and 278 deletions

View file

@ -30,6 +30,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
titleAction: TopAppBarButtonUM? = null,
containerColor: Color = TangemTheme.colors.background.primary,
addBottomInsets: Boolean = true,
skipPartiallyExpanded: Boolean = true,
crossinline content: @Composable ColumnScope.(T) -> Unit,
) {
TangemBottomSheet(
@ -37,6 +38,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
containerColor = containerColor,
addBottomInsets = addBottomInsets,
title = { TangemBottomSheetTitle(title = titleText, endButton = titleAction) },
skipPartiallyExpanded = skipPartiallyExpanded,
content = content,
)
}
@ -49,6 +51,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
config: TangemBottomSheetConfig,
containerColor: Color = TangemTheme.colors.background.primary,
addBottomInsets: Boolean = true,
skipPartiallyExpanded: Boolean = true,
crossinline title: @Composable BoxScope.(T) -> Unit = {},
crossinline content: @Composable ColumnScope.(T) -> Unit,
) {
@ -61,6 +64,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
addBottomInsets = addBottomInsets,
title = title,
content = content,
skipPartiallyExpanded = skipPartiallyExpanded,
)
} else {
DefaultBottomSheet<T>(
@ -69,6 +73,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
addBottomInsets = addBottomInsets,
title = title,
content = content,
skipPartiallyExpanded = skipPartiallyExpanded,
)
}
}
@ -79,11 +84,12 @@ inline fun <reified T : TangemBottomSheetConfigContent> DefaultBottomSheet(
config: TangemBottomSheetConfig,
containerColor: Color,
addBottomInsets: Boolean,
skipPartiallyExpanded: Boolean = true,
crossinline title: @Composable (BoxScope.(T) -> Unit),
crossinline content: @Composable (ColumnScope.(T) -> Unit),
) {
var isVisible by remember { mutableStateOf(value = config.isShow) }
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = skipPartiallyExpanded)
if (isVisible && config.content is T) {
BasicBottomSheet<T>(
@ -111,6 +117,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> PreviewBottomSheet(
config: TangemBottomSheetConfig,
containerColor: Color,
addBottomInsets: Boolean,
skipPartiallyExpanded: Boolean = true,
crossinline title: @Composable (BoxScope.(T) -> Unit),
crossinline content: @Composable (ColumnScope.(T) -> Unit),
) {
@ -118,7 +125,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> PreviewBottomSheet(
modifier = Modifier.width(360.dp),
config = config,
sheetState = SheetState(
skipPartiallyExpanded = true,
skipPartiallyExpanded = skipPartiallyExpanded,
initialValue = Expanded,
density = LocalDensity.current,
),

View file

@ -1,10 +1,7 @@
package com.tangem.core.ui.res
import androidx.compose.animation.*
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.*
import androidx.compose.runtime.*
@Immutable
@ -24,10 +21,6 @@ object TangemAnimations {
@Immutable
object TransitionSpecs {
@Stable
val textChange: ContentTransform =
fadeIn(animationSpec = spring(dampingRatio = Spring.DampingRatioNoBouncy)) togetherWith
fadeOut(animationSpec = spring(dampingRatio = Spring.DampingRatioNoBouncy))
// TODO add more transition specs
}
}

View file

@ -117,6 +117,7 @@ object BigDecimalFormatter {
fiatAmount: BigDecimal?,
fiatCurrencyCode: String,
fiatCurrencySymbol: String,
decimals: Int = FIAT_MARKET_DEFAULT_DIGITS,
locale: Locale = Locale.getDefault(),
): String {
if (fiatAmount == null) return EMPTY_BALANCE_SIGN
@ -124,8 +125,8 @@ object BigDecimalFormatter {
val formatterCurrency = getCurrency(fiatCurrencyCode)
val formatter = NumberFormat.getCurrencyInstance(locale).apply {
currency = formatterCurrency
maximumFractionDigits = FIAT_MARKET_DEFAULT_DIGITS
minimumFractionDigits = FIAT_MARKET_DEFAULT_DIGITS
maximumFractionDigits = decimals
minimumFractionDigits = decimals
roundingMode = RoundingMode.HALF_UP
}
@ -250,40 +251,27 @@ object BigDecimalFormatter {
/**
* "123456.6" -> "$123.457K"
* "12345.6" -> "$123.046K"
* Negative amount is not supported
* @param threeDigitsMethod if true, will format the amount always with 3 significant digits
* @param scale the number of digits to the right of the decimal point
*/
@Suppress("MagicNumber")
fun formatCompactAmount(
amount: BigDecimal,
fun formatCompactFiatAmount(
amount: BigDecimal?,
fiatCurrencyCode: String,
fiatCurrencySymbol: String,
threeDigitsMethod: Boolean = false,
scale: Int = 0,
locale: Locale = Locale.getDefault(),
): String {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return BigDecimalFormatterCompat.formatCompactAmountNoLocaleContext(
amount = amount,
fiatCurrencyCode = fiatCurrencyCode,
fiatCurrencySymbol = fiatCurrencySymbol,
locale = locale,
)
}
if (amount == null) return EMPTY_BALANCE_SIGN
val scaledAmount = amount.setScale(0, RoundingMode.HALF_UP)
val digitsCount = scaledAmount.longValueExact().toString().count()
val digitsToFormat = 6 - when (digitsCount % 3) {
0 -> 0
1 -> 2
else -> 1
}
val formatter = CompactDecimalFormat.getInstance(
locale,
CompactDecimalFormat.CompactStyle.SHORT,
).apply {
minimumSignificantDigits = 4
maximumSignificantDigits = digitsToFormat
}
val rawAmount = formatter.format(amount.setScale(0, RoundingMode.HALF_UP))
val rawAmount = formatCompactAmount(
amount = amount,
locale = locale,
threeDigitsMethod = threeDigitsMethod,
scale = scale,
)
return addCurrencySymbolToStringAmount(
amount = rawAmount,
@ -293,5 +281,53 @@ object BigDecimalFormatter {
)
}
/**
* "123456.6" -> "123.457K"
* "12345.6" -> "123.046K"
* Negative amount is not supported
* @param threeDigitsMethod if true, will format the amount always with 3 significant digits
* @param scale the number of digits to the right of the decimal point
*/
@Suppress("MagicNumber")
fun formatCompactAmount(
amount: BigDecimal,
locale: Locale = Locale.getDefault(),
threeDigitsMethod: Boolean = false,
scale: Int = 0,
): String {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return BigDecimalFormatterCompat.formatCompactAmountNoLocaleContext(amount = amount)
}
if (threeDigitsMethod) {
val scaledAmount = amount.setScale(scale, RoundingMode.HALF_UP)
val digitsCount = scaledAmount.longValueExact().toString().count()
val digitsToFormat = 6 - when (digitsCount % 3) {
0 -> 0
1 -> 2
else -> 1
}
val formatter = CompactDecimalFormat.getInstance(
locale,
CompactDecimalFormat.CompactStyle.SHORT,
).apply {
minimumSignificantDigits = 4
maximumSignificantDigits = digitsToFormat
}
return formatter.format(amount.setScale(scale, RoundingMode.HALF_UP))
} else {
val value = amount.setScale(scale, RoundingMode.HALF_UP)
val formatter = CompactDecimalFormat.getInstance(
locale,
CompactDecimalFormat.CompactStyle.SHORT,
)
return formatter.format(value)
}
}
private fun BigDecimal.isLessThanThreshold() = this > BigDecimal.ZERO && this < FIAT_FORMAT_THRESHOLD
}

View file

@ -7,16 +7,32 @@ import java.util.Locale
internal object BigDecimalFormatterCompat {
/**
* Formats value as [BigDecimalFormatter.formatCompactAmount] does using only "T","B","M","K" suffixes
* Formats value as [BigDecimalFormatter.formatCompactFiatAmount] does using only "T","B","M","K" suffixes
* Used for < API24 compatibility
*/
@Suppress("MagicNumber", "UnnecessaryParentheses")
fun formatCompactAmountNoLocaleContext(
fun formatCompactFiatAmountNoLocaleContext(
amount: BigDecimal,
fiatCurrencyCode: String,
fiatCurrencySymbol: String,
locale: Locale = Locale.getDefault(),
): String {
val formatted = formatCompactAmountNoLocaleContext(amount)
return BigDecimalFormatter.addCurrencySymbolToStringAmount(
amount = formatted,
fiatCurrencyCode = fiatCurrencyCode,
fiatCurrencySymbol = fiatCurrencySymbol,
locale = locale,
)
}
/**
* Formats value as [BigDecimalFormatter.formatCompactAmount] does using only "T","B","M","K" suffixes
* Used for < API24 compatibility
*/
@Suppress("MagicNumber", "UnnecessaryParentheses")
fun formatCompactAmountNoLocaleContext(amount: BigDecimal): String {
val value = amount.setScale(0, RoundingMode.HALF_UP).longValueExact()
val formatted = when {
@ -42,11 +58,6 @@ internal object BigDecimalFormatterCompat {
else -> return value.toString()
}
return BigDecimalFormatter.addCurrencySymbolToStringAmount(
amount = formatted,
fiatCurrencyCode = fiatCurrencyCode,
fiatCurrencySymbol = fiatCurrencySymbol,
locale = locale,
)
return formatted
}
}

View file

@ -0,0 +1,15 @@
package com.tangem.core.ui.utils
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
fun Modifier.disableNestedScroll(): Modifier = nestedScroll(DisableParentConnection)
private object DisableParentConnection : NestedScrollConnection {
override fun onPostScroll(consumed: Offset, available: Offset, source: NestedScrollSource): Offset {
return available.copy(x = 0f)
}
}