Updated on 2026-08-14

This commit is contained in:
Tangem 2025-06-27 14:21:36 +05:00
parent 51efb0e781
commit b51b57cf89
4 changed files with 80 additions and 39 deletions

View file

@ -62,6 +62,7 @@ data class NFTAssetUM(
val value: String,
val valueTextEllipsis: TextEllipsis = TextEllipsis.End,
val showInfoButton: Boolean,
val onClick: () -> Unit = { },
val onBlockClick: (() -> Unit)? = null,
val onValueClick: (() -> Unit)? = null,
)
}

View file

@ -27,7 +27,8 @@ internal class NFTDetailsUMFactory(
private val onExploreClick: () -> Unit,
private val onSendClick: () -> Unit,
private val onRefresh: () -> Unit,
private val onInfoBlockClick: (title: TextReference, text: TextReference) -> Unit,
private val onRegularInfoBlockClick: (title: TextReference, text: TextReference) -> Unit,
private val onTokenAddressBlockClick: () -> Unit,
) {
fun getInitialState(nftAsset: NFTAsset, nftCollection: NFTCollection): NFTDetailsUM = NFTDetailsUM(
@ -70,13 +71,13 @@ internal class NFTDetailsUMFactory(
label = rarity.label,
showDivider = hasSalePrice || hasDescription,
onLabelClick = {
onInfoBlockClick(
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_rarity_label),
resourceReference(R.string.nft_details_info_rarity_label),
)
},
onRankClick = {
onInfoBlockClick(
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_rarity_rank),
resourceReference(R.string.nft_details_info_rarity_rank),
)
@ -135,8 +136,8 @@ internal class NFTDetailsUMFactory(
title = resourceReference(R.string.nft_details_token_standard),
value = contractType,
showInfoButton = true,
onClick = {
onInfoBlockClick(
onBlockClick = {
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_token_standard),
resourceReference(R.string.nft_details_info_token_standard),
)
@ -147,20 +148,23 @@ internal class NFTDetailsUMFactory(
value = id.tokenAddress,
valueTextEllipsis = TextEllipsis.Middle,
showInfoButton = true,
onClick = {
onInfoBlockClick(
onBlockClick = {
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_contract_address),
resourceReference(R.string.nft_details_info_contract_address),
)
},
onValueClick = {
onTokenAddressBlockClick()
},
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_token_id),
value = id.tokenId.toString(),
valueTextEllipsis = TextEllipsis.Middle,
showInfoButton = true,
onClick = {
onInfoBlockClick(
onBlockClick = {
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_token_id),
resourceReference(R.string.nft_details_info_token_id),
)
@ -170,8 +174,8 @@ internal class NFTDetailsUMFactory(
title = resourceReference(R.string.nft_details_chain),
value = network.name,
showInfoButton = true,
onClick = {
onInfoBlockClick(
onBlockClick = {
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_chain),
resourceReference(R.string.nft_details_info_chain),
)
@ -184,19 +188,22 @@ internal class NFTDetailsUMFactory(
value = id.tokenAddress,
valueTextEllipsis = TextEllipsis.Middle,
showInfoButton = true,
onClick = {
onInfoBlockClick(
onBlockClick = {
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_token_address),
resourceReference(R.string.nft_details_info_token_address),
)
},
onValueClick = {
onTokenAddressBlockClick()
},
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_chain),
value = network.name,
showInfoButton = true,
onClick = {
onInfoBlockClick(
onBlockClick = {
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_chain),
resourceReference(R.string.nft_details_info_chain),
)
@ -209,19 +216,22 @@ internal class NFTDetailsUMFactory(
value = id.tokenAddress,
valueTextEllipsis = TextEllipsis.Middle,
showInfoButton = true,
onClick = {
onInfoBlockClick(
onBlockClick = {
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_token_address),
resourceReference(R.string.nft_details_info_token_address),
)
},
onValueClick = {
onTokenAddressBlockClick()
},
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_chain),
value = network.name,
showInfoButton = true,
onClick = {
onInfoBlockClick(
onBlockClick = {
onRegularInfoBlockClick(
resourceReference(R.string.nft_details_chain),
resourceReference(R.string.nft_details_info_chain),
)

View file

@ -10,6 +10,7 @@ import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.clipboard.ClipboardManager
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
@ -20,6 +21,7 @@ import com.tangem.domain.nft.FetchNFTPriceUseCase
import com.tangem.domain.nft.GetNFTExploreUrlUseCase
import com.tangem.domain.nft.GetNFTPriceUseCase
import com.tangem.domain.nft.analytics.NFTAnalyticsEvent
import com.tangem.domain.nft.models.NFTAsset
import com.tangem.features.nft.details.NFTDetailsComponent
import com.tangem.features.nft.details.entity.NFTAssetUM
import com.tangem.features.nft.details.entity.NFTDetailsBottomSheetConfig
@ -49,6 +51,7 @@ internal class NFTDetailsModel @Inject constructor(
private val getNFTPriceUseCase: GetNFTPriceUseCase,
private val fetchNFTCollectionAssetsUseCase: FetchNFTCollectionAssetsUseCase,
private val fetchNFTPriceUseCase: FetchNFTPriceUseCase,
private val clipboardManager: ClipboardManager,
paramsContainer: ParamsContainer,
) : Model() {
@ -68,8 +71,9 @@ internal class NFTDetailsModel @Inject constructor(
},
onExploreClick = ::onExploreClick,
onSendClick = ::onSendClick,
onInfoBlockClick = ::onInfoBlockClick,
onRegularInfoBlockClick = ::onInfoBlockClick,
onRefresh = ::onRefresh,
onTokenAddressBlockClick = ::onTokenAddressBlockClick,
)
private val _state by lazy {
@ -191,4 +195,15 @@ internal class NFTDetailsModel @Inject constructor(
),
)
}
private fun onTokenAddressBlockClick() {
val asset = params.nftAsset
val addressToCopy = when (val id = asset.id) {
is NFTAsset.Identifier.EVM -> id.tokenAddress
is NFTAsset.Identifier.Solana -> id.tokenAddress
is NFTAsset.Identifier.TON -> id.tokenAddress
is NFTAsset.Identifier.Unknown -> return
}
clipboardManager.setText(text = addressToCopy, isSensitive = false)
}
}

View file

@ -69,17 +69,14 @@ internal fun NFTDetailsBlocksGroup(
NFTDetailsGroupBlock(
modifier = Modifier
.weight(1f)
.padding(paddingValues)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onClick = item1.onClick,
),
.padding(paddingValues),
title = item1.title,
value = stringReference(item1.value),
titleEllipsis = item1.titleTextEllipsis,
valueEllipsis = item1.valueTextEllipsis,
showInfoButton = item1.showInfoButton,
onBlockClick = item1.onBlockClick,
onValueClick = item1.onValueClick,
)
if (item2 == null) {
Box(
@ -91,17 +88,14 @@ internal fun NFTDetailsBlocksGroup(
NFTDetailsGroupBlock(
modifier = Modifier
.weight(1f)
.padding(paddingValues)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onClick = item2.onClick,
),
.padding(paddingValues),
title = item2.title,
value = stringReference(item2.value),
titleEllipsis = item2.titleTextEllipsis,
valueEllipsis = item2.valueTextEllipsis,
showInfoButton = item2.showInfoButton,
onBlockClick = item2.onBlockClick,
onValueClick = item2.onValueClick,
)
}
}
@ -128,6 +122,8 @@ internal fun NFTDetailsGroupBlock(
value: TextReference,
showInfoButton: Boolean,
modifier: Modifier = Modifier,
onBlockClick: (() -> Unit)? = null,
onValueClick: (() -> Unit)? = null,
titleEllipsis: TextEllipsis = TextEllipsis.End,
valueEllipsis: TextEllipsis = TextEllipsis.End,
) {
@ -136,7 +132,14 @@ internal fun NFTDetailsGroupBlock(
) {
Row(
modifier = Modifier
.fillMaxWidth(),
.fillMaxWidth()
.clickable(
enabled = onBlockClick != null,
interactionSource = remember { MutableInteractionSource() },
indication = null,
) {
onBlockClick?.invoke()
},
) {
EllipsisText(
modifier = Modifier
@ -159,6 +162,18 @@ internal fun NFTDetailsGroupBlock(
}
EllipsisText(
modifier = Modifier
.fillMaxWidth()
.clickable(
enabled = onValueClick != null || onBlockClick != null,
interactionSource = remember { MutableInteractionSource() },
indication = null,
) {
if (onValueClick != null) {
onValueClick.invoke()
} else {
onBlockClick?.invoke()
}
}
.padding(top = TangemTheme.dimens.spacing4),
text = value.resolveReference(),
style = TangemTheme.typography.body1,
@ -255,27 +270,27 @@ private class NFTAssetBlocksProvider : CollectionPreviewParameterProvider<Immuta
NFTAssetUM.BlockItem(
title = stringReference("Tier"),
value = "Infinite",
showInfoButton = false,
showInfoButton = true,
),
NFTAssetUM.BlockItem(
title = stringReference("Phygital Toy"),
value = "None",
showInfoButton = false,
showInfoButton = true,
),
NFTAssetUM.BlockItem(
title = stringReference("Class"),
value = "CYBER",
showInfoButton = false,
showInfoButton = true,
),
NFTAssetUM.BlockItem(
title = stringReference("Accessory"),
value = "No accessory",
showInfoButton = false,
showInfoButton = true,
),
NFTAssetUM.BlockItem(
title = stringReference("Sneakers"),
value = "Boots",
showInfoButton = false,
showInfoButton = true,
),
),
),