From faf7d0219ae0f9c9607c5cf652ec58e4fae225e2 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 3 Apr 2025 17:20:28 +0500 Subject: [PATCH] Updated on 2026-08-14 --- core/res/src/main/res/values/strings.xml | 11 + .../nft/details/ui/NFTDetailsBlocksGroup.kt | 246 ++++++++++++++++++ 2 files changed, 257 insertions(+) create mode 100644 features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/ui/NFTDetailsBlocksGroup.kt diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 0eba9dda01..a23e1b705f 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -179,6 +179,7 @@ Search Search tokens sec + See all Seed phrase Select action Sell @@ -519,6 +520,16 @@ NFT collections Unable to load the data Choose network + Last sale price + Rarity label + Rarity rank + Traits + Base information + Token Standard + Contract Address + Token ID + Token Address + Chain Set up a single access code to protect all your devices. Protect Set an individual access code for each card or ring later. diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/ui/NFTDetailsBlocksGroup.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/ui/NFTDetailsBlocksGroup.kt new file mode 100644 index 0000000000..8df906ff96 --- /dev/null +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/ui/NFTDetailsBlocksGroup.kt @@ -0,0 +1,246 @@ +package com.tangem.features.nft.details.ui + +import android.content.res.Configuration +import androidx.annotation.DrawableRes +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.key +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.components.atoms.text.EllipsisText +import com.tangem.core.ui.components.atoms.text.TextEllipsis +import com.tangem.core.ui.components.block.information.InformationBlock +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview +import com.tangem.features.nft.details.entity.NFTAssetUM +import com.tangem.features.nft.impl.R +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf + +@Composable +internal fun NFTDetailsBlocksGroup( + title: TextReference, + action: (@Composable BoxScope.() -> Unit)?, + items: ImmutableList, + modifier: Modifier = Modifier, +) { + val itemsCount = items.size + if (items.size > 0) { + val rowCount = (itemsCount + 1) / 2 + val paddingValues = PaddingValues( + horizontal = TangemTheme.dimens.spacing6, + vertical = TangemTheme.dimens.spacing8, + ) + InformationBlock( + modifier = modifier, + title = { + NFTDetailsGroupTitle( + text = title, + ) + }, + action = action, + contentHorizontalPadding = TangemTheme.dimens.spacing6, + ) { + Column( + modifier = Modifier + .padding(bottom = TangemTheme.dimens.spacing12), + ) { + repeat(rowCount) { rowIndex -> + val item1 = items[rowIndex * 2] + val item2 = items.getOrNull(rowIndex * 2 + 1) + key(rowIndex) { + Row( + modifier = Modifier.fillMaxWidth(), + ) { + NFTDetailsGroupBlock( + modifier = Modifier + .weight(1f) + .padding(paddingValues), + title = item1.title, + value = stringReference(item1.value), + titleEllipsis = item1.titleTextEllipsis, + valueEllipsis = item1.valueTextEllipsis, + ) + if (item2 == null) { + Box( + modifier = Modifier + .weight(1f) + .padding(paddingValues), + ) + } else { + NFTDetailsGroupBlock( + modifier = Modifier + .weight(1f) + .padding(paddingValues), + title = item2.title, + value = stringReference(item2.value), + titleEllipsis = item2.titleTextEllipsis, + valueEllipsis = item2.valueTextEllipsis, + ) + } + } + } + } + } + } + } +} + +@Composable +internal fun NFTDetailsGroupTitle(text: TextReference, modifier: Modifier = Modifier) { + Text( + modifier = modifier, + text = text.resolveReference(), + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + ) +} + +@Composable +internal fun NFTDetailsGroupBlock( + title: TextReference, + value: TextReference, + modifier: Modifier = Modifier, + titleEllipsis: TextEllipsis = TextEllipsis.End, + valueEllipsis: TextEllipsis = TextEllipsis.End, +) { + Column( + modifier = modifier, + ) { + EllipsisText( + text = title.resolveReference(), + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.tertiary, + ellipsis = titleEllipsis, + ) + EllipsisText( + modifier = Modifier + .padding(top = TangemTheme.dimens.spacing4), + text = value.resolveReference(), + style = TangemTheme.typography.body1, + color = TangemTheme.colors.text.primary1, + ellipsis = valueEllipsis, + ) + } +} + +@Composable +internal fun NFTBlocksGroupAction( + text: TextReference, + startIcon: @Composable RowScope.() -> Unit, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + val interactionSource = remember { MutableInteractionSource() } + + Row( + modifier = modifier + .clickable( + interactionSource = interactionSource, + indication = null, + onClick = onClick, + ), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing2), + ) { + startIcon() + Text( + text = text.resolveReference(), + color = TangemTheme.colors.text.accent, + style = TangemTheme.typography.subtitle2, + ) + } +} + +@Composable +internal fun NFTBlocksGroupActionIcon(@DrawableRes iconRes: Int, modifier: Modifier = Modifier) { + Icon( + modifier = modifier.size(size = TangemTheme.dimens.size16), + painter = painterResource(id = iconRes), + tint = TangemTheme.colors.icon.accent, + contentDescription = null, + ) +} + +@Preview(widthDp = 360) +@Preview(widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun Preview_NFTDetailsInfoBlock( + @PreviewParameter(NFTAssetBlocksProvider::class) state: ImmutableList, +) { + TangemThemePreview { + Column { + NFTDetailsBlocksGroup( + title = stringReference("Title"), + action = null, + items = state, + ) + NFTDetailsBlocksGroup( + modifier = Modifier.padding(top = TangemTheme.dimens.spacing12), + title = stringReference("Title"), + action = { + NFTBlocksGroupAction( + text = resourceReference(R.string.common_see_all), + startIcon = { }, + onClick = { }, + ) + }, + items = state, + ) + NFTDetailsBlocksGroup( + modifier = Modifier.padding(top = TangemTheme.dimens.spacing12), + title = stringReference("Title"), + action = { + NFTBlocksGroupAction( + text = resourceReference(R.string.common_explore), + startIcon = { + NFTBlocksGroupActionIcon(iconRes = R.drawable.ic_compass_24) + }, + onClick = { }, + ) + }, + items = state, + ) + } + } +} + +private class NFTAssetBlocksProvider : CollectionPreviewParameterProvider>( + collection = listOf( + persistentListOf( + NFTAssetUM.BlockItem( + title = stringReference("Tier"), + value = "Infinite", + ), + NFTAssetUM.BlockItem( + title = stringReference("Phygital Toy"), + value = "None", + ), + NFTAssetUM.BlockItem( + title = stringReference("Class"), + value = "CYBER", + ), + NFTAssetUM.BlockItem( + title = stringReference("Accessory"), + value = "No accessory", + ), + NFTAssetUM.BlockItem( + title = stringReference("Sneakers"), + value = "Boots", + ), + ), + ), +) \ No newline at end of file