diff --git a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketListItemV2.kt b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketListItemV2.kt
new file mode 100644
index 0000000000..179ed39563
--- /dev/null
+++ b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketListItemV2.kt
@@ -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") }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketsListItem.kt b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketsListItem.kt
new file mode 100644
index 0000000000..037457f908
--- /dev/null
+++ b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketsListItem.kt
@@ -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,
+ )
+ }
+}
\ No newline at end of file
diff --git a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketListItem.kt b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketsListItemV1.kt
similarity index 97%
rename from common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketListItem.kt
rename to common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketsListItemV1.kt
index 3215446426..bfa927d620 100644
--- a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketListItem.kt
+++ b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/MarketsListItemV1.kt
@@ -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,
)
diff --git a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/preview/MarketChartListItemPreviewDataProvider.kt b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/preview/MarketChartListItemPreviewDataProvider.kt
index 7cac4e8314..29cd1685ff 100644
--- a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/preview/MarketChartListItemPreviewDataProvider.kt
+++ b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/preview/MarketChartListItemPreviewDataProvider.kt
@@ -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%",
diff --git a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenPriceText.kt b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenPriceText.kt
index b470546536..df80ddeae9 100644
--- a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenPriceText.kt
+++ b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenPriceText.kt
@@ -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,
+ )
}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds/image/TangemIconUM.kt b/core/ui/src/main/java/com/tangem/core/ui/ds/image/TangemIconUM.kt
index 2c6ecb3b07..a1f0c98b5b 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/ds/image/TangemIconUM.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/ds/image/TangemIconUM.kt
@@ -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,
diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds/opportunities/OpportunitiesBG.kt b/core/ui/src/main/java/com/tangem/core/ui/ds/opportunities/OpportunitiesBG.kt
index 8fd7342071..5a392b66cd 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/ds/opportunities/OpportunitiesBG.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/ds/opportunities/OpportunitiesBG.kt
@@ -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)
+ }
+ }
}
}
diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds/row/TangemRowContainer.kt b/core/ui/src/main/java/com/tangem/core/ui/ds/row/TangemRowContainer.kt
index 026dc41e70..71d79083c4 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/ds/row/TangemRowContainer.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/ds/row/TangemRowContainer.kt
@@ -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),
),
)
diff --git a/core/ui/src/main/res/drawable/ic_laurel_left.xml b/core/ui/src/main/res/drawable/ic_laurel_left.xml
new file mode 100644
index 0000000000..7fb94f1dab
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_laurel_left.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_laurel_right.xml b/core/ui/src/main/res/drawable/ic_laurel_right.xml
new file mode 100644
index 0000000000..99199504e4
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_laurel_right.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleHeader.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleHeader.kt
index fadece2c4e..90e3717cd0 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleHeader.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleHeader.kt
@@ -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,
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/Tags.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/Tags.kt
index f5ec98879e..2554569a61 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/Tags.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/Tags.kt
@@ -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, 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,