diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 3d4d8d7a48..f60477cf1c 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -801,6 +801,10 @@
Holders
The change in the number of token holders within a specific timeframe
Holders
+ D
+ M
+ W
+ Y
Insights
Links
Liquidity
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlockContent.kt b/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlockContent.kt
index a39c6b7783..ea9b54bea5 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlockContent.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlockContent.kt
@@ -40,7 +40,7 @@ inline fun InformationBlockContentScope.ListItems(
}
@Composable
-inline fun InformationBlockContentScope.GridItems(
+inline fun GridItems(
items: ImmutableList,
modifier: Modifier = Modifier,
verticalAlignment: Alignment.Vertical = Alignment.Top,
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/items/DecriptionItem.kt b/core/ui/src/main/java/com/tangem/core/ui/components/items/DecriptionItem.kt
index 25e496e785..2841c1c57e 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/items/DecriptionItem.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/items/DecriptionItem.kt
@@ -1,24 +1,30 @@
package com.tangem.core.ui.components.items
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.TextShimmer
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.utils.PreviewShimmerContainer
import com.tangem.utils.StringsSigns
@@ -29,6 +35,32 @@ fun DescriptionItem(
onReadMoreClick: () -> Unit,
modifier: Modifier = Modifier,
textStyle: TextStyle = TangemTheme.typography.body2,
+) {
+ if (LocalRedesignEnabled.current) {
+ DescriptionItemV2(
+ description = description,
+ hasFullDescription = hasFullDescription,
+ onReadMoreClick = onReadMoreClick,
+ modifier = modifier,
+ )
+ } else {
+ DescriptionItemV1(
+ description = description,
+ hasFullDescription = hasFullDescription,
+ onReadMoreClick = onReadMoreClick,
+ modifier = modifier,
+ textStyle = textStyle,
+ )
+ }
+}
+
+@Composable
+private fun DescriptionItemV1(
+ description: TextReference,
+ hasFullDescription: Boolean,
+ onReadMoreClick: () -> Unit,
+ modifier: Modifier = Modifier,
+ textStyle: TextStyle = TangemTheme.typography.body2,
) {
if (hasFullDescription) {
val text = buildAnnotatedString {
@@ -66,7 +98,58 @@ fun DescriptionItem(
}
@Composable
-public fun DescriptionPlaceholder(modifier: Modifier = Modifier) {
+private fun DescriptionItemV2(
+ description: TextReference,
+ hasFullDescription: Boolean,
+ onReadMoreClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ if (hasFullDescription) {
+ val text = buildAnnotatedString {
+ withStyle(SpanStyle(color = TangemTheme.colors2.text.neutral.tertiary)) {
+ append(description.resolveReference())
+ }
+ withStyle(SpanStyle(color = TangemTheme.colors2.text.neutral.primary)) {
+ append(
+ " " + stringResourceSafe(R.string.common_read_more).replace(
+ ' ',
+ StringsSigns.NON_BREAKING_SPACE,
+ ),
+ )
+ }
+ }
+
+ Text(
+ modifier = modifier
+ .clickable(
+ interactionSource = null,
+ indication = null,
+ onClick = onReadMoreClick,
+ ),
+ text = text,
+ style = TangemTheme.typography2.bodyRegular15,
+ )
+ } else {
+ Text(
+ modifier = modifier,
+ text = description.resolveReference(),
+ style = TangemTheme.typography2.bodyRegular15,
+ color = TangemTheme.colors2.text.neutral.tertiary,
+ )
+ }
+}
+
+@Composable
+fun DescriptionPlaceholder(modifier: Modifier = Modifier) {
+ if (LocalRedesignEnabled.current) {
+ DescriptionPlaceholderV2(modifier)
+ } else {
+ DescriptionPlaceholderV1(modifier)
+ }
+}
+
+@Composable
+private fun DescriptionPlaceholderV1(modifier: Modifier = Modifier) {
Column(
modifier = modifier,
) {
@@ -88,9 +171,33 @@ public fun DescriptionPlaceholder(modifier: Modifier = Modifier) {
}
}
+@Composable
+private fun DescriptionPlaceholderV2(modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier.padding(horizontal = 6.dp),
+ verticalArrangement = Arrangement.spacedBy(6.dp),
+ ) {
+ TextShimmer(
+ modifier = Modifier.fillMaxWidth(),
+ style = TangemTheme.typography2.bodyRegular15,
+ radius = TangemTheme.dimens2.x25,
+ )
+ TextShimmer(
+ modifier = Modifier.fillMaxWidth(),
+ style = TangemTheme.typography2.bodyRegular15,
+ radius = TangemTheme.dimens2.x25,
+ )
+ TextShimmer(
+ modifier = Modifier.fillMaxWidth(fraction = 0.8f),
+ style = TangemTheme.typography2.bodyRegular15,
+ radius = TangemTheme.dimens2.x25,
+ )
+ }
+}
+
@Preview
@Composable
-private fun ContentPreview() {
+private fun ContentPreviewV1() {
TangemThemePreview {
DescriptionItem(
description = stringReference(
@@ -105,15 +212,49 @@ private fun ContentPreview() {
@Preview
@Composable
-private fun PreviewPlaceholder() {
+private fun ContentPreviewV2() {
+ CompositionLocalProvider(LocalRedesignEnabled provides true) {
+ TangemThemePreviewRedesign {
+ DescriptionItem(
+ description = stringReference(
+ "XRP (XRP) is a cryptocurrency launched in January 2009, where the first " +
+ "genesis block was mined on 9th January 2009",
+ ),
+ hasFullDescription = true,
+ onReadMoreClick = {},
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun PreviewPlaceholderV1() {
TangemThemePreview {
PreviewShimmerContainer(
actualContent = {
- ContentPreview()
+ ContentPreviewV1()
},
shimmerContent = {
DescriptionPlaceholder()
},
)
}
+}
+
+@Preview
+@Composable
+private fun PreviewPlaceholderV2() {
+ CompositionLocalProvider(LocalRedesignEnabled provides true) {
+ TangemThemePreviewRedesign {
+ PreviewShimmerContainer(
+ actualContent = {
+ ContentPreviewV2()
+ },
+ shimmerContent = {
+ DescriptionPlaceholder()
+ },
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds/tabs/TangemSegmentedPicker.kt b/core/ui/src/main/java/com/tangem/core/ui/ds/tabs/TangemSegmentedPicker.kt
index fc0a59340b..3f98cea45a 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/ds/tabs/TangemSegmentedPicker.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/ds/tabs/TangemSegmentedPicker.kt
@@ -79,6 +79,7 @@ fun TangemSegmentedPicker(
hasSeparator: Boolean = false,
isFixed: Boolean = false,
isAltSurface: Boolean = false,
+ minSegmentWidth: Dp = Dp.Unspecified,
onClick: (TangemSegmentUM) -> Unit,
) {
if (items.isEmpty() || items.size == 1) return
@@ -123,6 +124,7 @@ fun TangemSegmentedPicker(
item = item,
index = index,
isFixed = isFixed,
+ minSegmentWidth = minSegmentWidth,
selectedIndex = selectedIndex,
onClick = { onClick(item) },
modifier = Modifier
@@ -176,9 +178,11 @@ private fun RowScope.Segment(
selectedIndex: MutableState,
onClick: () -> Unit,
modifier: Modifier = Modifier,
+ minSegmentWidth: Dp = Dp.Unspecified,
) {
Box(
modifier = modifier
+ .defaultMinSize(minWidth = minSegmentWidth)
.conditional(isFixed) {
weight(1f)
}
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoPoint.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoPoint.kt
index a3d85081b4..4baddf7c1a 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoPoint.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoPoint.kt
@@ -2,17 +2,11 @@ package com.tangem.features.feed.ui.market.detailed.components
import android.content.res.Configuration
import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Box
-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.layout.requiredHeight
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.*
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
@@ -21,18 +15,30 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
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.TextShimmer
import com.tangem.core.ui.components.text.TooltipText
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.utils.PreviewShimmerContainer
import com.tangem.features.feed.ui.market.detailed.state.InfoPointUM
@Composable
internal fun InfoPoint(infoPointUM: InfoPointUM, modifier: Modifier = Modifier) {
+ if (LocalRedesignEnabled.current) {
+ InfoPointV2(infoPointUM, modifier)
+ } else {
+ InfoPointV1(infoPointUM, modifier)
+ }
+}
+
+@Composable
+private fun InfoPointV1(infoPointUM: InfoPointUM, modifier: Modifier = Modifier) {
Column(
modifier = modifier.padding(vertical = TangemTheme.dimens.spacing8),
horizontalAlignment = Alignment.Start,
@@ -81,8 +87,68 @@ internal fun InfoPoint(infoPointUM: InfoPointUM, modifier: Modifier = Modifier)
}
}
+@Composable
+private fun InfoPointV2(infoPointUM: InfoPointUM, modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier.padding(vertical = TangemTheme.dimens.spacing8),
+ horizontalAlignment = Alignment.Start,
+ verticalArrangement = Arrangement.spacedBy(4.dp),
+ ) {
+ Row {
+ Text(
+ text = infoPointUM.value,
+ style = TangemTheme.typography2.headingSemibold20,
+ color = TangemTheme.colors2.text.neutral.primary,
+ )
+ if (infoPointUM.change != null) {
+ SpacerW4()
+ Icon(
+ modifier = Modifier
+ .size(TangemTheme.dimens2.x2)
+ .align(Alignment.CenterVertically),
+ imageVector = ImageVector.vectorResource(
+ id = when (infoPointUM.change) {
+ InfoPointUM.ChangeType.UP -> R.drawable.ic_arrow_up_8
+ InfoPointUM.ChangeType.DOWN -> R.drawable.ic_arrow_down_8
+ },
+ ),
+ tint = when (infoPointUM.change) {
+ InfoPointUM.ChangeType.UP -> TangemTheme.colors2.markers.iconGreen
+ InfoPointUM.ChangeType.DOWN -> TangemTheme.colors2.markers.iconRed
+ },
+ contentDescription = null,
+ )
+ }
+ }
+ if (infoPointUM.onInfoClick != null) {
+ InformationTextBlock(
+ text = infoPointUM.title,
+ onInfoClick = infoPointUM.onInfoClick,
+ informationTextBlockIconPosition = InformationTextBlockIconPosition.START,
+ )
+ } else {
+ Text(
+ text = infoPointUM.title.resolveReference(),
+ style = TangemTheme.typography2.captionSemibold12,
+ color = TangemTheme.colors2.text.neutral.tertiary,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ }
+ }
+}
+
@Composable
internal fun InfoPointShimmer(modifier: Modifier = Modifier, withTooltip: Boolean = false) {
+ if (LocalRedesignEnabled.current) {
+ InfoPointShimmerV2(modifier)
+ } else {
+ InfoPointShimmerV1(modifier, withTooltip)
+ }
+}
+
+@Composable
+private fun InfoPointShimmerV1(modifier: Modifier = Modifier, withTooltip: Boolean = false) {
Column(
modifier = modifier.padding(vertical = TangemTheme.dimens.spacing8),
horizontalAlignment = Alignment.Start,
@@ -115,10 +181,34 @@ internal fun InfoPointShimmer(modifier: Modifier = Modifier, withTooltip: Boolea
}
}
+@Composable
+private fun InfoPointShimmerV2(modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier.padding(vertical = TangemTheme.dimens2.x6),
+ horizontalAlignment = Alignment.Start,
+ verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
+ ) {
+ RectangleShimmer(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(24.dp)
+ .padding(end = 10.dp),
+ radius = TangemTheme.dimens2.x25,
+ )
+
+ RectangleShimmer(
+ modifier = Modifier
+ .width(68.dp)
+ .height(16.dp),
+ radius = TangemTheme.dimens2.x25,
+ )
+ }
+}
+
@Preview
@Preview("Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
-private fun ContentPreview() {
+private fun ContentPreviewV1() {
TangemThemePreview {
Column(
modifier = Modifier
@@ -158,6 +248,53 @@ private fun ContentPreview() {
}
}
+@Preview
+@Preview("Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun ContentPreviewV2() {
+ CompositionLocalProvider(
+ LocalRedesignEnabled provides true,
+ ) {
+ TangemThemePreviewRedesign {
+ Column(
+ modifier = Modifier
+ .width(150.dp)
+ .background(TangemTheme.colors.background.tertiary),
+ ) {
+ InfoPoint(
+ infoPointUM = InfoPointUM(
+ title = stringReference("Market Cap"),
+ value = "$1,000,000,000",
+ ),
+ )
+ InfoPoint(
+ infoPointUM = InfoPointUM(
+ title = stringReference("Market Cap"),
+ value = "$1,000,000,000",
+ onInfoClick = { },
+ ),
+ )
+ InfoPoint(
+ infoPointUM = InfoPointUM(
+ title = stringReference("Market Cap"),
+ value = "$1,000,000",
+ change = InfoPointUM.ChangeType.UP,
+ onInfoClick = { },
+ ),
+ )
+ InfoPoint(
+ infoPointUM = InfoPointUM(
+ title = stringReference("Market Cap"),
+ value = "$1,000,000",
+ change = InfoPointUM.ChangeType.DOWN,
+ onInfoClick = { },
+ ),
+ )
+ }
+ }
+ }
+}
+
@Preview
@Preview("Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@@ -186,7 +323,7 @@ private fun PreviewShimmer() {
}
},
actualContent = {
- ContentPreview()
+ ContentPreviewV1()
},
)
}
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InsightsBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InsightsBlock.kt
index 69a803858b..30fd5eda07 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InsightsBlock.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InsightsBlock.kt
@@ -1,37 +1,33 @@
package com.tangem.features.feed.ui.market.detailed.components
import android.content.res.Configuration
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.IntrinsicSize
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
+import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.RectangleShimmer
+import com.tangem.core.ui.components.SpacerW
import com.tangem.core.ui.components.block.information.GridItems
import com.tangem.core.ui.components.block.information.InformationBlock
import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons
import com.tangem.core.ui.components.text.TooltipText
+import com.tangem.core.ui.ds.tabs.TangemSegmentUM
+import com.tangem.core.ui.ds.tabs.TangemSegmentedPicker
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.utils.PreviewShimmerContainer
import com.tangem.domain.markets.PriceChangeInterval
import com.tangem.features.feed.impl.R
+import com.tangem.features.feed.ui.components.TokenMarketInformationBlock
import com.tangem.features.feed.ui.market.detailed.getText
import com.tangem.features.feed.ui.market.detailed.state.InfoPointUM
import com.tangem.features.feed.ui.market.detailed.state.InsightsUM
@@ -40,6 +36,15 @@ import kotlinx.collections.immutable.toImmutableList
@Composable
internal fun InsightsBlock(state: InsightsUM, modifier: Modifier = Modifier) {
+ if (LocalRedesignEnabled.current) {
+ InsightsBlockV2(state, modifier)
+ } else {
+ InsightsBlockV1(state, modifier)
+ }
+}
+
+@Composable
+private fun InsightsBlockV1(state: InsightsUM, modifier: Modifier = Modifier) {
var currentInterval by remember { mutableStateOf(PriceChangeInterval.H24) }
InformationBlock(
@@ -104,8 +109,84 @@ internal fun InsightsBlock(state: InsightsUM, modifier: Modifier = Modifier) {
)
}
+@Composable
+private fun InsightsBlockV2(state: InsightsUM, modifier: Modifier = Modifier) {
+ val segmentItems = persistentListOf(
+ TangemSegmentUM(
+ id = PriceChangeInterval.H24.name,
+ title = resourceReference(R.string.markets_token_details_insight_day_timeline),
+ ),
+ TangemSegmentUM(
+ id = PriceChangeInterval.WEEK.name,
+ title = resourceReference(R.string.markets_token_details_insight_week_timeline),
+ ),
+ TangemSegmentUM(
+ id = PriceChangeInterval.MONTH.name,
+ title = resourceReference(R.string.markets_token_details_insight_month_timeline),
+ ),
+ )
+ var currentInterval by remember { mutableStateOf(segmentItems.first()) }
+
+ TokenMarketInformationBlock(
+ modifier = modifier,
+ title = {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween,
+ ) {
+ Text(
+ text = stringResourceSafe(R.string.markets_token_details_insights),
+ style = TangemTheme.typography2.headingSemibold20,
+ color = TangemTheme.colors2.text.neutral.primary,
+ )
+ TangemSegmentedPicker(
+ items = segmentItems,
+ initialSelectedItem = segmentItems.first(),
+ hasSeparator = true,
+ isFixed = false,
+ isAltSurface = true,
+ minSegmentWidth = 48.dp,
+ onClick = { segment ->
+ currentInterval = segment
+ state.onIntervalChanged(PriceChangeInterval.valueOf(segment.id))
+ },
+ )
+ }
+ },
+ content = {
+ val infoPoints = when (currentInterval.id) {
+ PriceChangeInterval.H24.name -> state.h24Info
+ PriceChangeInterval.WEEK.name -> state.weekInfo
+ PriceChangeInterval.MONTH.name -> state.monthInfo
+ else -> state.h24Info
+ }
+
+ GridItems(
+ modifier = Modifier.padding(top = 24.dp),
+ items = infoPoints,
+ itemContent = { infoPointUM ->
+ InfoPoint(
+ modifier = Modifier.align(Alignment.CenterStart),
+ infoPointUM = infoPointUM,
+ )
+ },
+ )
+ },
+ )
+}
+
@Composable
internal fun InsightsBlockPlaceholder(modifier: Modifier = Modifier) {
+ if (LocalRedesignEnabled.current) {
+ InsightsBlockPlaceholderV2(modifier)
+ } else {
+ InsightsBlockPlaceholderV1(modifier)
+ }
+}
+
+@Composable
+internal fun InsightsBlockPlaceholderV1(modifier: Modifier = Modifier) {
val subtitle2dp = with(LocalDensity.current) { TangemTheme.typography.subtitle2.lineHeight.toDp() }
val caption1dp = with(LocalDensity.current) { TangemTheme.typography.caption1.lineHeight.toDp() }
val headerHeight = maxOf(subtitle2dp, caption1dp) + TangemTheme.dimens.spacing4
@@ -134,10 +215,47 @@ internal fun InsightsBlockPlaceholder(modifier: Modifier = Modifier) {
)
}
+@Composable
+internal fun InsightsBlockPlaceholderV2(modifier: Modifier = Modifier) {
+ TokenMarketInformationBlock(
+ modifier = modifier,
+ title = {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ RectangleShimmer(
+ modifier = Modifier
+ .height(24.dp)
+ .width(120.dp),
+ radius = TangemTheme.dimens2.x25,
+ )
+
+ SpacerW(62.dp)
+
+ RectangleShimmer(
+ modifier = Modifier
+ .height(36.dp)
+ .weight(1f),
+ radius = TangemTheme.dimens2.x25,
+ )
+ }
+ },
+ content = {
+ GridItems(
+ items = List(size = 4) { it }.toImmutableList(),
+ horizontalArragement = Arrangement.spacedBy(10.dp),
+ itemContent = {
+ InfoPointShimmer(modifier = Modifier.fillMaxWidth())
+ },
+ )
+ },
+ )
+}
+
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
-private fun ContentPreview() {
+private fun ContentPreviewV1() {
TangemThemePreview {
InsightsBlock(
state = InsightsUM(
@@ -205,11 +323,95 @@ private fun ContentPreview() {
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
-private fun PreviewPlaceholder() {
+private fun ContentPreviewV2() {
+ CompositionLocalProvider(LocalRedesignEnabled provides true) {
+ TangemThemePreviewRedesign {
+ InsightsBlock(
+ state = InsightsUM(
+ h24Info = persistentListOf(
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_experienced_buyers),
+ value = "1 000 000 000",
+ ),
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_buy_pressure),
+ value = "1 000 000 000",
+ ),
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_holders),
+ value = "1 000 000 000",
+ ),
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_liquidity),
+ value = "1 000 000 000",
+ ),
+ ),
+ weekInfo = persistentListOf(
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_experienced_buyers),
+ value = "1 000 000",
+ ),
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_buy_pressure),
+ value = "1 000 000",
+ ),
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_holders),
+ value = "1 000 000",
+ ),
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_liquidity),
+ value = "1 000 000",
+ ),
+ ),
+ monthInfo = persistentListOf(
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_experienced_buyers),
+ value = "1 000",
+ ),
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_buy_pressure),
+ value = "1 000",
+ ),
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_holders),
+ value = "1 000",
+ ),
+ InfoPointUM(
+ title = resourceReference(R.string.markets_token_details_liquidity),
+ value = "1 000",
+ ),
+ ),
+ onInfoClick = {},
+ onIntervalChanged = {},
+ ),
+ )
+ }
+ }
+}
+
+@Preview
+@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun PreviewPlaceholderV1() {
TangemThemePreview {
PreviewShimmerContainer(
- actualContent = { ContentPreview() },
+ actualContent = { ContentPreviewV1() },
shimmerContent = { InsightsBlockPlaceholder() },
)
}
+}
+
+@Preview
+@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun PreviewPlaceholderV2() {
+ TangemThemePreviewRedesign {
+ CompositionLocalProvider(LocalRedesignEnabled provides true) {
+ PreviewShimmerContainer(
+ actualContent = { ContentPreviewV2() },
+ shimmerContent = { InsightsBlockPlaceholder() },
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ListedOnBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ListedOnBlock.kt
index 3305077d9f..e7e041f634 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ListedOnBlock.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ListedOnBlock.kt
@@ -156,17 +156,17 @@ internal fun ListedOnBlockPlaceholderV1(modifier: Modifier = Modifier) {
@Composable
internal fun ListedOnBlockPlaceholderV2(modifier: Modifier = Modifier) {
TokenMarketInformationBlock(
- modifier = modifier,
+ modifier = modifier.fillMaxWidth(),
title = {
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
TextShimmer(
style = TangemTheme.typography2.headingSemibold20,
- modifier = Modifier.fillMaxWidth(fraction = 0.5f),
+ modifier = Modifier.width(120.dp),
radius = TangemTheme.dimens2.x25,
)
TextShimmer(
style = TangemTheme.typography2.captionSemibold13,
- modifier = Modifier.fillMaxWidth(fraction = 0.5f),
+ modifier = Modifier.width(66.dp),
radius = TangemTheme.dimens2.x25,
)
}
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBlock.kt
index ec4c86a487..70929c2ab5 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBlock.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBlock.kt
@@ -129,7 +129,7 @@ private fun SecurityScoreBlockPlaceholderV2(modifier: Modifier = Modifier) {
TangemRowContainer(modifier = modifier) {
TextShimmer(
modifier = Modifier
- .width(74.dp)
+ .width(114.dp)
.layoutId(layoutId = TangemRowLayoutId.START_TOP),
style = TangemTheme.typography2.headingBold28,
radius = TangemTheme.dimens2.x25,
@@ -137,7 +137,8 @@ private fun SecurityScoreBlockPlaceholderV2(modifier: Modifier = Modifier) {
TextShimmer(
modifier = Modifier
- .width(96.dp)
+ .width(74.dp)
+ .padding(top = 8.dp)
.layoutId(layoutId = TangemRowLayoutId.START_BOTTOM),
style = TangemTheme.typography2.captionSemibold12,
radius = TangemTheme.dimens2.x25,
@@ -145,7 +146,7 @@ private fun SecurityScoreBlockPlaceholderV2(modifier: Modifier = Modifier) {
TextShimmer(
modifier = Modifier
- .width(120.dp)
+ .width(116.dp)
.layoutId(layoutId = TangemRowLayoutId.END_TOP),
style = TangemTheme.typography2.headingBold28,
radius = TangemTheme.dimens2.x25,
@@ -153,7 +154,8 @@ private fun SecurityScoreBlockPlaceholderV2(modifier: Modifier = Modifier) {
TextShimmer(
modifier = Modifier
- .width(72.dp)
+ .width(96.dp)
+ .padding(top = 8.dp)
.layoutId(layoutId = TangemRowLayoutId.END_BOTTOM),
style = TangemTheme.typography2.captionSemibold12,
radius = TangemTheme.dimens2.x25,
diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/TokenMarketDetailsBody.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/TokenMarketDetailsBody.kt
index 4abff26fa9..47d19a1751 100644
--- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/TokenMarketDetailsBody.kt
+++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/TokenMarketDetailsBody.kt
@@ -26,6 +26,26 @@ internal fun LazyListScope.tokenMarketDetailsBody(
state: MarketsTokenDetailsUM.Body,
portfolioBlock: @Composable ((Modifier) -> Unit)?,
relatedNews: RelatedNews,
+) {
+ if (isRedesignEnabled) {
+ tokenMarketDetailsBodyV2(
+ state = state,
+ relatedNews = relatedNews,
+ )
+ } else {
+ tokenMarketDetailsBodyV1(
+ state = state,
+ portfolioBlock = portfolioBlock,
+ relatedNews = relatedNews,
+ )
+ }
+}
+
+@Suppress("CanBeNonNullable")
+private fun LazyListScope.tokenMarketDetailsBodyV1(
+ state: MarketsTokenDetailsUM.Body,
+ portfolioBlock: @Composable ((Modifier) -> Unit)?,
+ relatedNews: RelatedNews,
) {
when (state) {
MarketsTokenDetailsUM.Body.Loading -> {
@@ -41,7 +61,7 @@ internal fun LazyListScope.tokenMarketDetailsBody(
aboutCoinHeader()
- loadingInfoBlocks(isRedesignEnabled)
+ loadingInfoBlocks(false)
}
is MarketsTokenDetailsUM.Body.Content -> {
if (state.description != null) {
@@ -60,9 +80,35 @@ internal fun LazyListScope.tokenMarketDetailsBody(
aboutCoinHeader()
- infoBlocksList(
+ infoBlocksListV1(state = state.infoBlocks)
+ }
+ is MarketsTokenDetailsUM.Body.Error -> {
+ error(state)
+ }
+ MarketsTokenDetailsUM.Body.Nothing -> {
+ // Do nothing
+ }
+ }
+}
+
+@Suppress("CanBeNonNullable")
+private fun LazyListScope.tokenMarketDetailsBodyV2(state: MarketsTokenDetailsUM.Body, relatedNews: RelatedNews) {
+ when (state) {
+ MarketsTokenDetailsUM.Body.Loading -> {
+ item("description-loading") {
+ DescriptionPlaceholder(modifier = Modifier.blockPaddings())
+ }
+
+ loadingInfoBlocks(true)
+ }
+ is MarketsTokenDetailsUM.Body.Content -> {
+ if (state.description != null) {
+ description(state.description)
+ }
+
+ infoBlocksListV2(
state = state.infoBlocks,
- isRedesignEnabled = isRedesignEnabled,
+ relatedNews = relatedNews,
)
}
is MarketsTokenDetailsUM.Body.Error -> {
@@ -116,7 +162,7 @@ private fun LazyListScope.description(description: MarketsTokenDetailsUM.Descrip
}
}
-internal fun LazyListScope.infoBlocksList(state: MarketsTokenDetailsUM.InformationBlocks, isRedesignEnabled: Boolean) {
+internal fun LazyListScope.infoBlocksListV1(state: MarketsTokenDetailsUM.InformationBlocks) {
if (state.insights != null) {
item("insights") {
InsightsBlock(
@@ -126,7 +172,7 @@ internal fun LazyListScope.infoBlocksList(state: MarketsTokenDetailsUM.Informati
}
}
- if (state.securityScore != null && !isRedesignEnabled) {
+ if (state.securityScore != null) {
item("securityScore") {
SecurityScoreBlock(
modifier = Modifier.blockPaddings(),
@@ -160,7 +206,47 @@ internal fun LazyListScope.infoBlocksList(state: MarketsTokenDetailsUM.Informati
)
}
- if (state.securityScore != null && isRedesignEnabled) {
+ if (state.links != null) {
+ item("links") {
+ LinksBlock(
+ modifier = Modifier.blockPaddings(),
+ state = state.links,
+ )
+ }
+ }
+}
+
+internal fun LazyListScope.infoBlocksListV2(state: MarketsTokenDetailsUM.InformationBlocks, relatedNews: RelatedNews) {
+ if (state.metrics != null) {
+ item("metrics") {
+ MetricsBlock(
+ modifier = Modifier.blockPaddings(),
+ state = state.metrics,
+ )
+ }
+ }
+
+ if (state.insights != null) {
+ item("insights") {
+ InsightsBlock(
+ modifier = Modifier.blockPaddings(),
+ state = state.insights,
+ )
+ }
+ }
+
+ item(key = "listedOn") {
+ ListedOnBlock(
+ state = state.listedOn,
+ modifier = Modifier.blockPaddings(),
+ )
+ }
+
+ if (relatedNews.articles.isNotEmpty()) {
+ relatedNews(relatedNews)
+ }
+
+ if (state.securityScore != null) {
item("securityScore") {
SecurityScoreBlock(
modifier = Modifier.blockPaddings(),
@@ -180,16 +266,22 @@ internal fun LazyListScope.infoBlocksList(state: MarketsTokenDetailsUM.Informati
}
private fun LazyListScope.loadingInfoBlocks(isRedesignEnabled: Boolean) {
+ if (isRedesignEnabled) {
+ loadingInfoBlocksV2()
+ } else {
+ loadingInfoBlocksV1()
+ }
+}
+
+private fun LazyListScope.loadingInfoBlocksV1() {
item("insights-loading") {
InsightsBlockPlaceholder(
modifier = Modifier.blockPaddings(),
)
}
- if (!isRedesignEnabled) {
- item("securityScore-loading") {
- SecurityScoreBlockPlaceholder(modifier = Modifier.blockPaddings())
- }
+ item("securityScore-loading") {
+ SecurityScoreBlockPlaceholder(modifier = Modifier.blockPaddings())
}
item("metrics-loading") {
@@ -204,10 +296,28 @@ private fun LazyListScope.loadingInfoBlocks(isRedesignEnabled: Boolean) {
ListedOnBlockPlaceholder(modifier = Modifier.blockPaddings())
}
- if (isRedesignEnabled) {
- item("securityScore-loading") {
- SecurityScoreBlockPlaceholder(modifier = Modifier.blockPaddings())
- }
+ item("links-loading") {
+ LinksBlockPlaceholder(modifier = Modifier.blockPaddings())
+ }
+}
+
+private fun LazyListScope.loadingInfoBlocksV2() {
+ item("metrics-loading") {
+ MetricsBlockPlaceholder(modifier = Modifier.blockPaddings())
+ }
+
+ item("insights-loading") {
+ InsightsBlockPlaceholder(
+ modifier = Modifier.blockPaddings(),
+ )
+ }
+
+ item(key = "listedOn-loading") {
+ ListedOnBlockPlaceholder(modifier = Modifier.blockPaddings())
+ }
+
+ item("securityScore-loading") {
+ SecurityScoreBlockPlaceholder(modifier = Modifier.blockPaddings())
}
item("links-loading") {