Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-11 15:04:32 +01:00
parent 5f4dfefc2e
commit 519e59d96b
4 changed files with 257 additions and 28 deletions

View file

@ -87,8 +87,8 @@ fun TangemBadge(
.heightIn(min = size.toHeightDp())
.clip(shape.toShape(size))
.getBackgroundColor(type = type, color = color, shape = shape.toShape(size))
.padding(size.toPaddingDp(position = iconPosition))
.clickableSingle(enabled = onClick != null, onClick = { onClick?.invoke() }),
.clickableSingle(enabled = onClick != null, onClick = { onClick?.invoke() })
.padding(size.toPaddingDp(position = iconPosition)),
) {
StartIcon(
tangemIconUM = tangemIconUM,

View file

@ -0,0 +1,32 @@
package com.tangem.features.feed.ui.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.res.TangemTheme
@Composable
internal fun ContainerWithDivider(
modifier: Modifier = Modifier,
showDivider: Boolean = false,
paddingValues: PaddingValues = PaddingValues(start = TangemTheme.dimens2.x3),
content: @Composable () -> Unit,
) {
Box(modifier = modifier) {
content()
if (showDivider) {
HorizontalDivider(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(paddingValues),
color = TangemTheme.colors2.graphic.neutral.quaternary,
thickness = 1.dp,
)
}
}
}

View file

@ -234,7 +234,7 @@ private fun TrendingArticleBackground(
Color(0xFF7C16F1).copy(alpha = .8f),
Color.Transparent,
),
center = Offset(w / 2f, 2.4f * h),
center = Offset(w / 2f, 2.6f * h),
radius = radiusScale * 1.57f,
),
)

View file

@ -1,14 +1,7 @@
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.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
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.ui.Modifier
@ -21,18 +14,35 @@ import com.tangem.core.ui.components.TextShimmer
import com.tangem.core.ui.components.block.information.InformationBlock
import com.tangem.core.ui.components.buttons.chip.Chip
import com.tangem.core.ui.components.inputrow.inner.DividerContainer
import com.tangem.core.ui.ds.badge.TangemBadge
import com.tangem.core.ui.ds.badge.TangemBadgeIconPosition
import com.tangem.core.ui.ds.badge.TangemBadgeShape
import com.tangem.core.ui.ds.badge.TangemBadgeSize
import com.tangem.core.ui.ds.image.TangemIconUM
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.features.feed.impl.R
import com.tangem.features.feed.ui.components.ContainerWithDivider
import com.tangem.features.feed.ui.market.detailed.state.LinksUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@Composable
internal fun LinksBlock(state: LinksUM, modifier: Modifier = Modifier) {
if (LocalRedesignEnabled.current) {
LinksBlockV2(state, modifier)
} else {
LinksBlockV1(state, modifier)
}
}
@Composable
private fun LinksBlockV1(state: LinksUM, modifier: Modifier = Modifier) {
InformationBlock(
modifier = modifier,
contentHorizontalPadding = 0.dp,
@ -47,22 +57,22 @@ internal fun LinksBlock(state: LinksUM, modifier: Modifier = Modifier) {
},
content = {
Column {
SubBlock(
SubBlockV1(
title = stringResourceSafe(id = R.string.markets_token_details_official_links),
links = state.officialLinks,
onLinkClick = state.onLinkClick,
)
SubBlock(
SubBlockV1(
title = stringResourceSafe(id = R.string.markets_token_details_social),
links = state.social,
onLinkClick = state.onLinkClick,
)
SubBlock(
SubBlockV1(
title = stringResourceSafe(id = R.string.markets_token_details_repository),
links = state.repository,
onLinkClick = state.onLinkClick,
)
SubBlock(
SubBlockV1(
title = stringResourceSafe(id = R.string.markets_token_details_blockchain_site),
links = state.blockchainSite,
onLinkClick = state.onLinkClick,
@ -73,9 +83,36 @@ internal fun LinksBlock(state: LinksUM, modifier: Modifier = Modifier) {
)
}
@Composable
private fun LinksBlockV2(state: LinksUM, modifier: Modifier = Modifier) {
Column(modifier = modifier) {
SubBlockV2(
title = stringResourceSafe(id = R.string.markets_token_details_official_links),
links = state.officialLinks,
onLinkClick = state.onLinkClick,
)
SubBlockV2(
title = stringResourceSafe(id = R.string.markets_token_details_social),
links = state.social,
onLinkClick = state.onLinkClick,
)
SubBlockV2(
title = stringResourceSafe(id = R.string.markets_token_details_repository),
links = state.repository,
onLinkClick = state.onLinkClick,
)
SubBlockV2(
title = stringResourceSafe(id = R.string.markets_token_details_blockchain_site),
links = state.blockchainSite,
onLinkClick = state.onLinkClick,
lastBlock = true,
)
}
}
@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun SubBlock(
private fun SubBlockV1(
links: ImmutableList<LinksUM.Link>,
onLinkClick: (LinksUM.Link) -> Unit,
modifier: Modifier = Modifier,
@ -115,8 +152,67 @@ private fun SubBlock(
}
}
@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun SubBlockV2(
title: String,
links: ImmutableList<LinksUM.Link>,
onLinkClick: (LinksUM.Link) -> Unit,
modifier: Modifier = Modifier,
lastBlock: Boolean = false,
) {
if (links.isEmpty()) return
ContainerWithDivider(
modifier = modifier,
showDivider = !lastBlock,
) {
Column(
modifier = Modifier.padding(vertical = TangemTheme.dimens2.x2),
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
) {
Text(
modifier = Modifier.padding(start = 10.dp, top = TangemTheme.dimens2.x4),
text = title,
style = TangemTheme.typography2.bodySemibold16,
color = TangemTheme.colors2.text.neutral.primary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
FlowRow(
modifier = Modifier.padding(vertical = TangemTheme.dimens2.x2, horizontal = 3.dp),
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
) {
links.fastForEach { link ->
TangemBadge(
text = stringReference(link.title),
onClick = { onLinkClick(link) },
iconPosition = TangemBadgeIconPosition.Start,
tangemIconUM = TangemIconUM.Icon(
iconRes = link.iconRes,
tintReference = { TangemTheme.colors2.markers.iconGray },
),
size = TangemBadgeSize.X9,
shape = TangemBadgeShape.Rounded,
)
}
}
}
}
}
@Composable
fun LinksBlockPlaceholder(modifier: Modifier = Modifier) {
if (LocalRedesignEnabled.current) {
LinksBlockPlaceholderV2(modifier)
} else {
LinksBlockPlaceholderV1(modifier)
}
}
@Composable
private fun LinksBlockPlaceholderV1(modifier: Modifier = Modifier) {
InformationBlock(
modifier = modifier,
contentHorizontalPadding = 0.dp,
@ -128,22 +224,31 @@ fun LinksBlockPlaceholder(modifier: Modifier = Modifier) {
},
content = {
Column {
SubBlockPlaceholder()
SubBlockPlaceholder()
SubBlockPlaceholder(lastBlock = true)
SubBlockPlaceholderV1()
SubBlockPlaceholderV1()
SubBlockPlaceholderV1(lastBlock = true)
}
},
)
}
@Composable
private fun SubBlockPlaceholder(modifier: Modifier = Modifier, lastBlock: Boolean = false) {
private fun LinksBlockPlaceholderV2(modifier: Modifier = Modifier) {
Column(modifier = modifier) {
SubBlockPlaceholderV2()
SubBlockPlaceholderV2()
SubBlockPlaceholderV2(lastBlock = true)
}
}
@Composable
private fun SubBlockPlaceholderV1(modifier: Modifier = Modifier, lastBlock: Boolean = false) {
DividerContainer(
modifier = modifier,
showDivider = !lastBlock,
) {
Column(
modifier = Modifier.padding(TangemTheme.dimens.spacing12),
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing12),
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
TextShimmer(
@ -163,12 +268,42 @@ private fun SubBlockPlaceholder(modifier: Modifier = Modifier, lastBlock: Boolea
}
}
@Composable
private fun SubBlockPlaceholderV2(modifier: Modifier = Modifier, lastBlock: Boolean = false) {
ContainerWithDivider(
modifier = modifier,
showDivider = !lastBlock,
) {
Column(
modifier = Modifier.padding(TangemTheme.dimens2.x2),
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
) {
TextShimmer(
modifier = Modifier.width(56.dp),
style = TangemTheme.typography2.bodySemibold16,
radius = TangemTheme.dimens2.x25,
)
Row(
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
) {
repeat(times = 3) {
ChipShimmer(
modifier = Modifier
.height(36.dp)
.weight(1f),
)
}
}
}
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun ContentPreview() {
private fun ContentPreviewV1() {
TangemThemePreview {
LinksBlock(
LinksBlockV1(
state = LinksUM(
officialLinks = persistentListOf(
LinksUM.Link(
@ -216,11 +351,73 @@ private fun ContentPreview() {
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PlaceholderPreview() {
TangemThemePreview {
PreviewShimmerContainer(
shimmerContent = { LinksBlockPlaceholder() },
actualContent = { ContentPreview() },
private fun ContentPreviewV2() {
TangemThemePreviewRedesign {
LinksBlockV2(
state = LinksUM(
officialLinks = persistentListOf(
LinksUM.Link(
title = "Website",
iconRes = R.drawable.ic_plus_24,
url = "https://tangem.com",
),
LinksUM.Link(
title = "Website",
iconRes = R.drawable.ic_plus_24,
url = "https://tangem.com",
),
LinksUM.Link(
title = "Website",
iconRes = R.drawable.ic_plus_24,
url = "https://tangem.com",
),
),
social = persistentListOf(
LinksUM.Link(
title = "Twitter",
iconRes = R.drawable.ic_plus_24,
url = "https://tangem.com",
),
LinksUM.Link(
title = "Facebook",
iconRes = R.drawable.ic_plus_24,
url = "https://tangem.com",
),
),
repository = persistentListOf(
LinksUM.Link(
title = "Github",
iconRes = R.drawable.ic_plus_24,
url = "https://tangem.com",
),
),
blockchainSite = persistentListOf(),
onLinkClick = {},
),
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PlaceholderPreviewV1() {
TangemThemePreview {
PreviewShimmerContainer(
shimmerContent = { LinksBlockPlaceholderV1() },
actualContent = { ContentPreviewV1() },
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PlaceholderPreviewV2() {
TangemThemePreviewRedesign {
Column {
LinksBlockPlaceholderV2()
ContentPreviewV2()
}
}
}