Updated on 2026-08-14

This commit is contained in:
Tangem 2025-04-03 17:20:28 +05:00
parent 38c7183080
commit faf7d0219a
2 changed files with 257 additions and 0 deletions

View file

@ -179,6 +179,7 @@
<string name="common_search">Search</string>
<string name="common_search_tokens">Search tokens</string>
<string name="common_second_no_param">sec</string>
<string name="common_see_all">See all</string>
<string name="common_seed_phrase">Seed phrase</string>
<string name="common_select_action">Select action</string>
<string name="common_sell">Sell</string>
@ -519,6 +520,16 @@
<string name="nft_wallet_title">NFT collections</string>
<string name="nft_wallet_unable_to_load">Unable to load the data</string>
<string name="nft_receive_choose_network">Choose network</string>
<string name="nft_details_last_sale_price">Last sale price</string>
<string name="nft_details_rarity_label">Rarity label</string>
<string name="nft_details_rarity_rank">Rarity rank</string>
<string name="nft_details_traits">Traits</string>
<string name="nft_details_base_information">Base information</string>
<string name="nft_details_token_standard">Token Standard</string>
<string name="nft_details_contract_address">Contract Address</string>
<string name="nft_details_token_id">Token ID</string>
<string name="nft_details_token_address">Token Address</string>
<string name="nft_details_chain">Chain</string>
<string name="onboarding_access_code_feature_1_description">Set up a single access code to protect all your devices.</string>
<string name="onboarding_access_code_feature_1_title">Protect</string>
<string name="onboarding_access_code_feature_2_description">Set an individual access code for each card or ring later.</string>

View file

@ -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<NFTAssetUM.BlockItem>,
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<NFTAssetUM.BlockItem>,
) {
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<ImmutableList<NFTAssetUM.BlockItem>>(
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",
),
),
),
)