Updated on 2026-08-14
This commit is contained in:
parent
8a79e65e2e
commit
dbacd5b2a6
12 changed files with 475 additions and 25 deletions
|
|
@ -0,0 +1,323 @@
|
|||
package com.tangem.common.ui.markets
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.layout.layoutId
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.common.ui.charts.MarketChartMini
|
||||
import com.tangem.common.ui.charts.state.MarketChartLook
|
||||
import com.tangem.common.ui.charts.state.MarketChartRawData
|
||||
import com.tangem.common.ui.markets.models.MarketsListItemUM
|
||||
import com.tangem.common.ui.markets.preview.MarketChartListItemPreviewDataProvider
|
||||
import com.tangem.common.ui.tokens.TokenPriceText
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.RectangleShimmer
|
||||
import com.tangem.core.ui.components.SpacerW4
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeInPercent
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.ds.image.TangemIcon
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.ds.row.TangemRowContainer
|
||||
import com.tangem.core.ui.ds.row.TangemRowLayoutId
|
||||
import com.tangem.core.ui.res.LocalIsInDarkTheme
|
||||
import com.tangem.core.ui.res.LocalWindowSize
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.test.MarketsTestTags
|
||||
import com.tangem.core.ui.test.TokenElementsTestTags
|
||||
import com.tangem.core.ui.windowsize.WindowSizeType
|
||||
import com.tangem.utils.StringsSigns.MINUS
|
||||
import kotlin.random.Random
|
||||
|
||||
@Composable
|
||||
fun MarketsListItemV2(model: MarketsListItemUM, modifier: Modifier = Modifier, onClick: () -> Unit = {}) {
|
||||
MarketListItemContentV2(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RectangleShape)
|
||||
.clickable(onClick = onClick)
|
||||
.testTag(MarketsTestTags.TOKENS_LIST_ITEM),
|
||||
model = model,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MarketListItemContentV2(model: MarketsListItemUM, modifier: Modifier = Modifier) {
|
||||
val windowSize = LocalWindowSize.current
|
||||
TangemRowContainer(
|
||||
modifier = modifier,
|
||||
content = {
|
||||
TangemIcon(
|
||||
tangemIconUM = TangemIconUM.Url(model.iconUrl, fallbackRes = R.drawable.ic_custom_token_44),
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.layoutId(layoutId = TangemRowLayoutId.HEAD),
|
||||
)
|
||||
|
||||
TokenTitle(
|
||||
modifier = Modifier
|
||||
.layoutId(layoutId = TangemRowLayoutId.START_TOP)
|
||||
.padding(horizontal = TangemTheme.dimens2.x2),
|
||||
name = model.name,
|
||||
currencySymbol = model.currencySymbol,
|
||||
)
|
||||
|
||||
TokenPriceText(
|
||||
modifier = Modifier
|
||||
.layoutId(layoutId = TangemRowLayoutId.END_TOP)
|
||||
.testTag(tag = TokenElementsTestTags.TOKEN_FIAT_AMOUNT),
|
||||
price = model.price.text,
|
||||
priceChangeType = model.price.changeType,
|
||||
)
|
||||
|
||||
TokenSubtitle(
|
||||
modifier = Modifier
|
||||
.layoutId(layoutId = TangemRowLayoutId.START_BOTTOM)
|
||||
.padding(end = TangemTheme.dimens2.x2, start = TangemTheme.dimens2.x3),
|
||||
ratingPosition = model.ratingPosition,
|
||||
marketCap = model.marketCap,
|
||||
// stakingRate = model.stakingRate, TODO in [REDACTED_TASK_KEY]
|
||||
)
|
||||
|
||||
PriceChangeInPercent(
|
||||
modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.END_BOTTOM),
|
||||
textStyle = TangemTheme.typography2.captionRegular12,
|
||||
type = model.trendType,
|
||||
valueInPercent = model.trendPercentText,
|
||||
)
|
||||
if (windowSize.widthAtLeast(WindowSizeType.Small)) {
|
||||
Chart(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens2.x2)
|
||||
.layoutId(layoutId = TangemRowLayoutId.TAIL),
|
||||
chartType = model.chartType,
|
||||
chartRawData = model.chartData,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TokenTitle(name: String, currencySymbol: String, modifier: Modifier = Modifier) {
|
||||
Row(modifier = modifier) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f, fill = false)
|
||||
.alignByBaseline(),
|
||||
text = name,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
style = TangemTheme.typography2.bodySemibold16,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
SpacerW4()
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
text = currencySymbol,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Visible,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TokenSubtitle(
|
||||
ratingPosition: String?,
|
||||
marketCap: String?,
|
||||
// stakingRate: TextReference?, TODO in [REDACTED_TASK_KEY]
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val ratingColor = mapRatingToColor(ratingPosition)
|
||||
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
|
||||
) {
|
||||
TokenRatingPlace(
|
||||
ratingPosition = ratingPosition,
|
||||
ratingColor = ratingColor,
|
||||
)
|
||||
if (marketCap != null) {
|
||||
TokenMarketCapText(
|
||||
ratingColor = ratingColor,
|
||||
modifier = Modifier.weight(1f, fill = false),
|
||||
text = marketCap,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RowScope.TokenRatingPlace(ratingPosition: String?, ratingColor: Color) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.alignByBaseline()
|
||||
.heightIn(min = TangemTheme.dimens2.x4),
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(height = TangemTheme.dimens2.x4, width = TangemTheme.dimens2.x2),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_laurel_left),
|
||||
tint = ratingColor,
|
||||
contentDescription = null,
|
||||
)
|
||||
|
||||
Text(
|
||||
textAlign = TextAlign.Center,
|
||||
text = ratingPosition ?: MINUS,
|
||||
color = ratingColor,
|
||||
style = TangemTheme.typography2.captionSemibold12.copy(letterSpacing = 0.sp),
|
||||
maxLines = 1,
|
||||
)
|
||||
|
||||
Icon(
|
||||
modifier = Modifier.size(height = TangemTheme.dimens2.x4, width = TangemTheme.dimens2.x2),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_laurel_right),
|
||||
tint = ratingColor,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RowScope.TokenMarketCapText(text: String, ratingColor: Color, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
modifier = modifier.alignByBaseline(),
|
||||
text = text,
|
||||
color = ratingColor,
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Chart(chartType: MarketChartLook.Type, chartRawData: MarketChartRawData?, modifier: Modifier = Modifier) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.padding(vertical = 6.dp)
|
||||
.size(height = TangemTheme.dimens2.x6, width = TangemTheme.dimens2.x12),
|
||||
) {
|
||||
if (chartRawData != null) {
|
||||
MarketChartMini(
|
||||
rawData = chartRawData,
|
||||
type = chartType,
|
||||
)
|
||||
} else {
|
||||
RectangleShimmer(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(TangemTheme.dimens2.x3)
|
||||
.align(Alignment.Center),
|
||||
radius = 3.dp,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun mapRatingToColor(rating: String?): Color {
|
||||
val isDarkTheme = LocalIsInDarkTheme.current
|
||||
|
||||
return when (rating) {
|
||||
"1" -> if (isDarkTheme) Color(GOLD_PLACE_COLOR_NIGHT) else Color(GOLD_PLACE_COLOR_LIGHT)
|
||||
"2" -> if (isDarkTheme) Color(SILVER_PLACE_COLOR_NIGHT) else Color(SILVER_PLACE_COLOR_LIGHT)
|
||||
"3" -> if (isDarkTheme) Color(BRONZE_PLACE_COLOR_NIGHT) else Color(BRONZE_PLACE_COLOR_LIGHT)
|
||||
else -> TangemTheme.colors2.text.neutral.secondary
|
||||
}
|
||||
}
|
||||
|
||||
private const val GOLD_PLACE_COLOR_NIGHT = 0xFFFBEE76
|
||||
private const val GOLD_PLACE_COLOR_LIGHT = 0xFFD9B900
|
||||
private const val SILVER_PLACE_COLOR_NIGHT = 0xFFAABEF7
|
||||
private const val SILVER_PLACE_COLOR_LIGHT = 0xFF6680CC
|
||||
private const val BRONZE_PLACE_COLOR_NIGHT = 0xFFFF9976
|
||||
private const val BRONZE_PLACE_COLOR_LIGHT = 0xFFCC7F66
|
||||
|
||||
// region preview
|
||||
@Preview(showBackground = true, widthDp = 360, name = "normal")
|
||||
@Composable
|
||||
private fun Preview(@PreviewParameter(MarketChartListItemPreviewDataProvider::class) state: MarketsListItemUM) {
|
||||
TangemThemePreviewRedesign {
|
||||
var state1 by remember { mutableStateOf(state) }
|
||||
var state2 by remember { mutableStateOf(state) }
|
||||
var prices by remember {
|
||||
mutableStateOf(
|
||||
listOf(
|
||||
100 to PriceChangeType.NEUTRAL,
|
||||
200 to PriceChangeType.NEUTRAL,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
Column(modifier = Modifier.background(TangemTheme.colors.background.primary)) {
|
||||
MarketsListItemV2(
|
||||
modifier = Modifier,
|
||||
model = state1,
|
||||
)
|
||||
MarketsListItemV2(
|
||||
modifier = Modifier,
|
||||
model = state2,
|
||||
)
|
||||
Row {
|
||||
Button(
|
||||
onClick = {
|
||||
state1 = state1.copy(
|
||||
trendType = PriceChangeType.entries.random(),
|
||||
)
|
||||
state2 = state2.copy(
|
||||
trendType = PriceChangeType.entries.random(),
|
||||
)
|
||||
},
|
||||
) { Text(text = "trend") }
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
prices = prices.map { (price, _) ->
|
||||
if (Random.nextBoolean()) {
|
||||
price.inc() to PriceChangeType.UP
|
||||
} else {
|
||||
price.dec() to PriceChangeType.DOWN
|
||||
}
|
||||
}
|
||||
state1 = state1.copy(
|
||||
price = MarketsListItemUM.Price(
|
||||
text = "0.${prices[0].first}023 $",
|
||||
changeType = prices[0].second,
|
||||
),
|
||||
)
|
||||
state2 = state2.copy(
|
||||
price = MarketsListItemUM.Price(
|
||||
text = "0.${prices[1].first}023 $",
|
||||
changeType = prices[1].second,
|
||||
),
|
||||
)
|
||||
},
|
||||
) { Text(text = "price") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.common.ui.markets
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.common.ui.markets.models.MarketsListItemUM
|
||||
import com.tangem.core.ui.res.LocalRedesignEnabled
|
||||
|
||||
@Composable
|
||||
fun MarketsListItem(model: MarketsListItemUM, modifier: Modifier = Modifier, onClick: () -> Unit = {}) {
|
||||
if (LocalRedesignEnabled.current) {
|
||||
MarketsListItemV2(
|
||||
model = model,
|
||||
modifier = modifier,
|
||||
onClick = onClick,
|
||||
)
|
||||
} else {
|
||||
MarketsListItemV1(
|
||||
model = model,
|
||||
modifier = modifier,
|
||||
onClick = onClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -38,8 +38,8 @@ import com.tangem.utils.StringsSigns.MINUS
|
|||
import kotlin.random.Random
|
||||
|
||||
@Composable
|
||||
fun MarketsListItem(model: MarketsListItemUM, modifier: Modifier = Modifier, onClick: () -> Unit = {}) {
|
||||
MarketsListItemContent(
|
||||
fun MarketsListItemV1(model: MarketsListItemUM, modifier: Modifier = Modifier, onClick: () -> Unit = {}) {
|
||||
MarketsListItemContentV1(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RectangleShape)
|
||||
|
|
@ -50,7 +50,7 @@ fun MarketsListItem(model: MarketsListItemUM, modifier: Modifier = Modifier, onC
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun MarketsListItemContent(model: MarketsListItemUM, modifier: Modifier = Modifier) {
|
||||
private fun MarketsListItemContentV1(model: MarketsListItemUM, modifier: Modifier = Modifier) {
|
||||
val windowSize = LocalWindowSize.current
|
||||
|
||||
Row(
|
||||
|
|
@ -273,11 +273,11 @@ private fun Preview(@PreviewParameter(MarketChartListItemPreviewDataProvider::cl
|
|||
}
|
||||
|
||||
Column(modifier = Modifier.background(TangemTheme.colors.background.primary)) {
|
||||
MarketsListItem(
|
||||
MarketsListItemV1(
|
||||
modifier = Modifier,
|
||||
model = state1,
|
||||
)
|
||||
MarketsListItem(
|
||||
MarketsListItemV1(
|
||||
modifier = Modifier,
|
||||
model = state2,
|
||||
)
|
||||
|
|
@ -16,7 +16,7 @@ class MarketChartListItemPreviewDataProvider : CollectionPreviewParameterProvide
|
|||
name = "Bitcoin",
|
||||
currencySymbol = "BTC",
|
||||
iconUrl = "",
|
||||
ratingPosition = "10",
|
||||
ratingPosition = "1",
|
||||
marketCap = "$6.233 B",
|
||||
price = MarketsListItemUM.Price(text = "31 285.72$"),
|
||||
trendPercentText = "12.43%",
|
||||
|
|
@ -33,7 +33,7 @@ class MarketChartListItemPreviewDataProvider : CollectionPreviewParameterProvide
|
|||
name = "Bitcoin",
|
||||
currencySymbol = "BTC",
|
||||
iconUrl = null,
|
||||
ratingPosition = "10",
|
||||
ratingPosition = "2",
|
||||
marketCap = "$6.233 B",
|
||||
price = MarketsListItemUM.Price(text = "31 285.72$"),
|
||||
trendPercentText = "12.43%",
|
||||
|
|
|
|||
|
|
@ -6,8 +6,12 @@ import androidx.compose.animation.core.tween
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.res.LocalRedesignEnabled
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
/**
|
||||
|
|
@ -18,6 +22,23 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
*/
|
||||
@Composable
|
||||
fun TokenPriceText(price: String, modifier: Modifier = Modifier, priceChangeType: PriceChangeType? = null) {
|
||||
if (LocalRedesignEnabled.current) {
|
||||
TokenPriceTextV2(
|
||||
price = price,
|
||||
modifier = modifier,
|
||||
priceChangeType = priceChangeType,
|
||||
)
|
||||
} else {
|
||||
TokenPriceTextV1(
|
||||
price = price,
|
||||
modifier = modifier,
|
||||
priceChangeType = priceChangeType,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TokenPriceTextV1(price: String, modifier: Modifier = Modifier, priceChangeType: PriceChangeType? = null) {
|
||||
val growColor = TangemTheme.colors.text.accent
|
||||
val fallColor = TangemTheme.colors.text.warning
|
||||
val generalColor = TangemTheme.colors.text.primary1
|
||||
|
|
@ -52,4 +73,60 @@ fun TokenPriceText(price: String, modifier: Modifier = Modifier, priceChangeType
|
|||
style = TangemTheme.typography.body2,
|
||||
overflow = TextOverflow.Visible,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TokenPriceTextV2(price: String, modifier: Modifier = Modifier, priceChangeType: PriceChangeType? = null) {
|
||||
val growColor = TangemTheme.colors2.text.status.accent
|
||||
val fallColor = TangemTheme.colors2.text.status.warning
|
||||
val generalColor = TangemTheme.colors2.text.neutral.primary
|
||||
val decimalColor = TangemTheme.colors2.text.neutral.secondary
|
||||
|
||||
val color = remember(generalColor) { Animatable(generalColor) }
|
||||
var isAnimationSkipped by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(price) {
|
||||
if (!isAnimationSkipped) {
|
||||
isAnimationSkipped = true
|
||||
return@LaunchedEffect
|
||||
}
|
||||
|
||||
if (priceChangeType != null) {
|
||||
val nextColor = when (priceChangeType) {
|
||||
PriceChangeType.UP -> growColor
|
||||
PriceChangeType.DOWN -> fallColor
|
||||
PriceChangeType.NEUTRAL -> return@LaunchedEffect
|
||||
}
|
||||
|
||||
color.animateTo(nextColor, snap())
|
||||
color.animateTo(generalColor, tween(durationMillis = 500))
|
||||
}
|
||||
}
|
||||
|
||||
val annotatedText = remember(price) {
|
||||
buildAnnotatedString {
|
||||
val dotIndex = price.indexOf(".")
|
||||
|
||||
if (dotIndex == -1) {
|
||||
append(price)
|
||||
} else {
|
||||
append(price.take(dotIndex))
|
||||
|
||||
withStyle(
|
||||
style = SpanStyle(color = decimalColor),
|
||||
) {
|
||||
append(price.substring(dotIndex))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = modifier,
|
||||
text = annotatedText,
|
||||
color = color.value,
|
||||
maxLines = 1,
|
||||
style = TangemTheme.typography2.bodySemibold16,
|
||||
overflow = TextOverflow.Visible,
|
||||
)
|
||||
}
|
||||
|
|
@ -2,9 +2,6 @@ package com.tangem.core.ui.ds.image
|
|||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
|
@ -50,7 +47,8 @@ sealed interface TangemIconUM {
|
|||
|
||||
/** Image represented from network by url */
|
||||
data class Url(
|
||||
val url: String,
|
||||
val url: String?,
|
||||
@DrawableRes val fallbackRes: Int,
|
||||
) : TangemIconUM
|
||||
}
|
||||
|
||||
|
|
@ -91,14 +89,12 @@ fun TangemIcon(tangemIconUM: TangemIconUM, modifier: Modifier = Modifier) {
|
|||
.crossfade(enable = true)
|
||||
.allowHardware(enable = false)
|
||||
.build(),
|
||||
loading = { CircleShimmer() },
|
||||
loading = { CircleShimmer(modifier) },
|
||||
error = {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = TangemTheme.colors2.surface.level3,
|
||||
shape = CircleShape,
|
||||
),
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(tangemIconUM.fallbackRes),
|
||||
contentDescription = null,
|
||||
modifier = modifier,
|
||||
)
|
||||
},
|
||||
contentDescription = null,
|
||||
|
|
|
|||
|
|
@ -121,7 +121,13 @@ private fun BoxScope.BackgroundLayer(icon: TangemIconUM, blurRadius: Dp = 26.dp)
|
|||
is TangemIconUM.Icon -> SolidColorBackground(icon.tintReference(), blurRadius)
|
||||
is TangemIconUM.Ident -> Unit
|
||||
is TangemIconUM.Image -> ResBackground(icon.imageRes, blurRadius)
|
||||
is TangemIconUM.Url -> UrlColorBackground(icon.url, blurRadius)
|
||||
is TangemIconUM.Url -> {
|
||||
icon.url?.let { iconUrl ->
|
||||
UrlColorBackground(iconUrl, blurRadius)
|
||||
} ?: run {
|
||||
ResBackground(icon.fallbackRes, blurRadius)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,13 +54,13 @@ fun TangemRowContainer(
|
|||
// Head composable measurement
|
||||
val headPlaceable = measurables.measure(
|
||||
layoutId = TangemRowLayoutId.HEAD,
|
||||
constraints = constraints,
|
||||
constraints = constraints.copy(minWidth = 0),
|
||||
)
|
||||
|
||||
// Tail composable measurement
|
||||
val tailPlaceable = measurables.measure(
|
||||
layoutId = TangemRowLayoutId.TAIL,
|
||||
constraints = constraints,
|
||||
constraints = constraints.copy(minWidth = 0),
|
||||
)
|
||||
|
||||
val availableWidthForBody = layoutWidth - headPlaceable.widthOrZero() - tailPlaceable.widthOrZero()
|
||||
|
|
@ -70,7 +70,7 @@ fun TangemRowContainer(
|
|||
layoutId = TangemRowLayoutId.END_TOP,
|
||||
constraints = constraints.copy(
|
||||
minWidth = 0,
|
||||
maxWidth = availableWidthForBody - startTopMinWidth,
|
||||
maxWidth = max(0, availableWidthForBody - startTopMinWidth),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ fun TangemRowContainer(
|
|||
layoutId = TangemRowLayoutId.END_BOTTOM,
|
||||
constraints = constraints.copy(
|
||||
minWidth = 0,
|
||||
maxWidth = availableWidthForBody - startBottomMinWidth,
|
||||
maxWidth = max(0, availableWidthForBody - startTopMinWidth),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
9
core/ui/src/main/res/drawable/ic_laurel_left.xml
Normal file
9
core/ui/src/main/res/drawable/ic_laurel_left.xml
Normal file
File diff suppressed because one or more lines are too long
9
core/ui/src/main/res/drawable/ic_laurel_right.xml
Normal file
9
core/ui/src/main/res/drawable/ic_laurel_right.xml
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -154,7 +154,10 @@ private fun ArticleHeaderV2(
|
|||
text = tag.text,
|
||||
tangemIconUM = when (val content = tag.leadingContent) {
|
||||
LabelLeadingContentUM.None -> null
|
||||
is LabelLeadingContentUM.Token -> TangemIconUM.Url(content.iconUrl)
|
||||
is LabelLeadingContentUM.Token -> TangemIconUM.Url(
|
||||
url = content.iconUrl,
|
||||
fallbackRes = R.drawable.ic_alert_24,
|
||||
)
|
||||
},
|
||||
shape = TangemBadgeShape.Rounded,
|
||||
size = TangemBadgeSize.X9,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import androidx.compose.ui.layout.SubcomposeLayout
|
|||
import androidx.compose.ui.layout.SubcomposeMeasureScope
|
||||
import androidx.compose.ui.unit.Constraints
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.label.Label
|
||||
import com.tangem.core.ui.components.label.entity.LabelLeadingContentUM
|
||||
import com.tangem.core.ui.components.label.entity.LabelUM
|
||||
|
|
@ -40,7 +41,10 @@ internal fun Tags(tags: ImmutableList<LabelUM>, modifier: Modifier = Modifier) {
|
|||
text = tag.text,
|
||||
tangemIconUM = when (val content = tag.leadingContent) {
|
||||
LabelLeadingContentUM.None -> null
|
||||
is LabelLeadingContentUM.Token -> TangemIconUM.Url(content.iconUrl)
|
||||
is LabelLeadingContentUM.Token -> TangemIconUM.Url(
|
||||
url = content.iconUrl,
|
||||
fallbackRes = R.drawable.ic_alert_24,
|
||||
)
|
||||
},
|
||||
shape = TangemBadgeShape.Rounded,
|
||||
size = TangemBadgeSize.X6,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue