diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index d374882e15..3d4d6f5d2a 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -538,6 +538,13 @@
Token ID
Token Standard
Traits
+
+
+
+
+
+
+
No results. Please try another request.
No collection
Available
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/NFTDetailsComponent.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/NFTDetailsComponent.kt
index 2333a6a0e0..67920ecced 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/NFTDetailsComponent.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/NFTDetailsComponent.kt
@@ -53,6 +53,7 @@ internal class NFTDetailsComponent @AssistedInject constructor(
is NFTDetailsBottomSheetConfig.Info -> nftDetailsInfoComponentFactory.create(
context = childByContext(componentContext),
params = NFTDetailsInfoComponent.Params(
+ title = config.title,
text = config.text,
onDismiss = {
model.bottomSheetNavigation.dismiss()
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/NFTAssetUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/NFTAssetUM.kt
index ded848d638..88808c889c 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/NFTAssetUM.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/NFTAssetUM.kt
@@ -56,6 +56,8 @@ data class NFTAssetUM(
val rank: String,
val label: String,
val showDivider: Boolean,
+ val onRankClick: () -> Unit,
+ val onLabelClick: () -> Unit,
) : Rarity()
}
@@ -64,5 +66,7 @@ data class NFTAssetUM(
val titleTextEllipsis: TextEllipsis = TextEllipsis.End,
val value: String,
val valueTextEllipsis: TextEllipsis = TextEllipsis.End,
+ val showInfoButton: Boolean,
+ val onClick: () -> Unit = { },
)
}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/NFTDetailsBottomSheetConfig.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/NFTDetailsBottomSheetConfig.kt
index e8478f38ac..9c5fc52d41 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/NFTDetailsBottomSheetConfig.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/NFTDetailsBottomSheetConfig.kt
@@ -7,6 +7,7 @@ import kotlinx.serialization.Serializable
internal sealed interface NFTDetailsBottomSheetConfig {
@Serializable
data class Info(
+ val title: TextReference,
val text: TextReference,
) : NFTDetailsBottomSheetConfig
}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/factory/NFTDetailsUMFactory.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/factory/NFTDetailsUMFactory.kt
index 9a8e41a51f..e2e64fdb2b 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/factory/NFTDetailsUMFactory.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/entity/factory/NFTDetailsUMFactory.kt
@@ -1,6 +1,7 @@
package com.tangem.features.nft.details.entity.factory
import com.tangem.core.ui.components.atoms.text.TextEllipsis
+import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.nft.models.NFTAsset
@@ -17,6 +18,7 @@ internal class NFTDetailsUMFactory(
private val onSeeAllTraitsClick: () -> Unit,
private val onExploreClick: () -> Unit,
private val onSendClick: () -> Unit,
+ private val onInfoBlockClick: (title: TextReference, text: TextReference) -> Unit,
) {
fun getInitialState(nftAsset: NFTAsset): NFTDetailsUM = NFTDetailsUM(
@@ -57,6 +59,18 @@ internal class NFTDetailsUMFactory(
rank = rarity.rank,
label = rarity.label,
showDivider = hasSalePrice || hasDescription,
+ onLabelClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_rarity_label),
+ resourceReference(R.string.nft_details_info_rarity_label),
+ )
+ },
+ onRankClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_rarity_rank),
+ resourceReference(R.string.nft_details_info_rarity_rank),
+ )
+ },
)
} else {
NFTAssetUM.Rarity.Empty
@@ -68,6 +82,7 @@ internal class NFTDetailsUMFactory(
NFTAssetUM.BlockItem(
title = stringReference(it.name),
value = it.value,
+ showInfoButton = false,
)
}.toImmutableList(),
showAllTraitsButton = traits.size > MAX_TRAITS_COUNT,
@@ -76,24 +91,53 @@ internal class NFTDetailsUMFactory(
private fun NFTAsset.hasSalePrice() = salePrice !is NFTSalePrice.Empty && salePrice !is NFTSalePrice.Error
+ @Suppress("LongMethod")
private fun NFTAsset.buildBaseInfoItems() = when (val id = id) {
is NFTAsset.Identifier.EVM -> persistentListOf(
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_token_standard),
value = contractType,
+ showInfoButton = true,
+ onClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_token_standard),
+ resourceReference(R.string.nft_details_info_token_standard),
+ )
+ },
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_contract_address),
value = id.tokenAddress,
valueTextEllipsis = TextEllipsis.Middle,
+ showInfoButton = true,
+ onClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_contract_address),
+ resourceReference(R.string.nft_details_info_contract_address),
+ )
+ },
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_token_id),
value = id.tokenId.toString(),
+ showInfoButton = true,
+ onClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_token_id),
+ resourceReference(R.string.nft_details_info_token_id),
+ )
+ },
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_chain),
value = network.name,
+ showInfoButton = true,
+ onClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_chain),
+ resourceReference(R.string.nft_details_info_chain),
+ )
+ },
),
)
is NFTAsset.Identifier.TON -> persistentListOf(
@@ -101,10 +145,24 @@ internal class NFTDetailsUMFactory(
title = resourceReference(R.string.nft_details_token_address),
value = id.tokenAddress,
valueTextEllipsis = TextEllipsis.Middle,
+ showInfoButton = true,
+ onClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_token_address),
+ resourceReference(R.string.nft_details_info_token_address),
+ )
+ },
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_chain),
value = network.name,
+ showInfoButton = true,
+ onClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_chain),
+ resourceReference(R.string.nft_details_info_chain),
+ )
+ },
),
)
is NFTAsset.Identifier.Solana -> persistentListOf(
@@ -112,10 +170,24 @@ internal class NFTDetailsUMFactory(
title = resourceReference(R.string.nft_details_token_address),
value = id.tokenAddress,
valueTextEllipsis = TextEllipsis.Middle,
+ showInfoButton = true,
+ onClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_token_address),
+ resourceReference(R.string.nft_details_info_token_address),
+ )
+ },
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_chain),
value = network.name,
+ showInfoButton = true,
+ onClick = {
+ onInfoBlockClick(
+ resourceReference(R.string.nft_details_chain),
+ resourceReference(R.string.nft_details_info_chain),
+ )
+ },
),
)
is NFTAsset.Identifier.Unknown -> persistentListOf()
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/DefaultNFTDetailsInfoComponent.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/DefaultNFTDetailsInfoComponent.kt
index 26dc1a1dd6..f5311a1f65 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/DefaultNFTDetailsInfoComponent.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/DefaultNFTDetailsInfoComponent.kt
@@ -33,6 +33,7 @@ internal class DefaultNFTDetailsInfoComponent @AssistedInject constructor(
)
}
NFTInfoBottomSheet(
+ title = params.title,
config = bottomSheetConfig,
content = {
NFTInfoBottomSheetContent(
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/NFTDetailsInfoComponent.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/NFTDetailsInfoComponent.kt
index 90650da63b..eb61128969 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/NFTDetailsInfoComponent.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/NFTDetailsInfoComponent.kt
@@ -7,6 +7,7 @@ import com.tangem.core.ui.extensions.TextReference
internal interface NFTDetailsInfoComponent : ComposableBottomSheetComponent {
data class Params(
+ val title: TextReference,
val text: TextReference,
val onDismiss: () -> Unit,
)
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/ui/NFTInfoBottomSheet.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/ui/NFTInfoBottomSheet.kt
index b95179836f..875903640f 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/ui/NFTInfoBottomSheet.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/info/ui/NFTInfoBottomSheet.kt
@@ -14,17 +14,19 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet
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.impl.R
@Composable
-internal fun NFTInfoBottomSheet(config: TangemBottomSheetConfig, content: @Composable () -> Unit) {
+internal fun NFTInfoBottomSheet(
+ title: TextReference,
+ config: TangemBottomSheetConfig,
+ content: @Composable () -> Unit,
+) {
TangemBottomSheet(
config = config,
- titleText = resourceReference(R.string.nft_about_title),
+ titleText = title,
content = { content() },
)
}
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/model/NFTDetailsModel.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/model/NFTDetailsModel.kt
index e81bb43891..dd61ccf4f8 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/model/NFTDetailsModel.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/model/NFTDetailsModel.kt
@@ -8,15 +8,18 @@ import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
-import com.tangem.domain.nft.analytics.NFTAnalyticsEvent
import com.tangem.core.navigation.url.UrlOpener
+import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.nft.GetNFTExploreUrlUseCase
+import com.tangem.domain.nft.analytics.NFTAnalyticsEvent
import com.tangem.features.nft.details.NFTDetailsComponent
import com.tangem.features.nft.details.entity.NFTAssetUM
import com.tangem.features.nft.details.entity.NFTDetailsBottomSheetConfig
import com.tangem.features.nft.details.entity.NFTDetailsUM
import com.tangem.features.nft.details.entity.factory.NFTDetailsUMFactory
+import com.tangem.features.nft.impl.R
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -43,6 +46,7 @@ internal class NFTDetailsModel @Inject constructor(
onSeeAllTraitsClick = { params.onAllTraitsClick() },
onExploreClick = ::onExploreClick,
onSendClick = ::onSendClick,
+ onInfoBlockClick = ::onInfoBlockClick,
)
private val _state = MutableStateFlow(
@@ -50,10 +54,21 @@ internal class NFTDetailsModel @Inject constructor(
)
val bottomSheetNavigation: SlotNavigation = SlotNavigation()
+
init {
analyticsEventHandler.send(NFTAnalyticsEvent.Details.ScreenOpened(params.nftAsset.network.name))
}
+ private fun onInfoBlockClick(title: TextReference, text: TextReference) {
+ analyticsEventHandler.send(NFTAnalyticsEvent.Details.ButtonReadMore)
+ bottomSheetNavigation.activate(
+ NFTDetailsBottomSheetConfig.Info(
+ title = title,
+ text = text,
+ ),
+ )
+ }
+
private fun onReadMoreClick() {
analyticsEventHandler.send(NFTAnalyticsEvent.Details.ButtonReadMore)
when (val topInfo = _state.value.nftAsset.topInfo) {
@@ -61,6 +76,7 @@ internal class NFTDetailsModel @Inject constructor(
is NFTAssetUM.TopInfo.Content -> {
bottomSheetNavigation.activate(
NFTDetailsBottomSheetConfig.Info(
+ title = resourceReference(R.string.nft_about_title),
text = stringReference(topInfo.description.orEmpty()),
),
)
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/ui/NFTDetailsAsset.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/ui/NFTDetailsAsset.kt
index 3edf28fee7..1f955d7860 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/ui/NFTDetailsAsset.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/details/ui/NFTDetailsAsset.kt
@@ -138,32 +138,40 @@ private class NFTAssetProvider : CollectionPreviewParameterProvider(
rank = "Top 1% rarity",
label = "115.28",
showDivider = true,
+ onRankClick = { },
+ onLabelClick = { },
),
),
traits = persistentListOf(
NFTAssetUM.BlockItem(
title = stringReference("Tier"),
value = "Infinite",
+ showInfoButton = false,
),
NFTAssetUM.BlockItem(
title = stringReference("Phygital Toy"),
value = "None",
+ showInfoButton = false,
),
NFTAssetUM.BlockItem(
title = stringReference("Class"),
value = "CYBER",
+ showInfoButton = false,
),
NFTAssetUM.BlockItem(
title = stringReference("Accessory"),
value = "No accessory",
+ showInfoButton = false,
),
NFTAssetUM.BlockItem(
title = stringReference("Sneakers"),
value = "Boots",
+ showInfoButton = false,
),
NFTAssetUM.BlockItem(
title = stringReference("Artist"),
value = "DJ Dragoon",
+ showInfoButton = false,
),
),
showAllTraitsButton = true,
@@ -171,19 +179,23 @@ private class NFTAssetProvider : CollectionPreviewParameterProvider(
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_token_standard),
value = "ERC-721",
+ showInfoButton = true,
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_contract_address),
value = "0x6811f2fgd892ac83f719",
valueTextEllipsis = TextEllipsis.Middle,
+ showInfoButton = true,
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_token_id),
value = "100200273",
+ showInfoButton = true,
),
NFTAssetUM.BlockItem(
title = resourceReference(R.string.nft_details_chain),
value = "Ethereum",
+ showInfoButton = true,
),
),
),
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
index 8df906ff96..cc7726dfd1 100644
--- 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
@@ -30,6 +30,7 @@ import com.tangem.features.nft.impl.R
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
+@Suppress("LongMethod")
@Composable
internal fun NFTDetailsBlocksGroup(
title: TextReference,
@@ -68,11 +69,17 @@ internal fun NFTDetailsBlocksGroup(
NFTDetailsGroupBlock(
modifier = Modifier
.weight(1f)
- .padding(paddingValues),
+ .padding(paddingValues)
+ .clickable(
+ interactionSource = remember { MutableInteractionSource() },
+ indication = null,
+ onClick = item1.onClick,
+ ),
title = item1.title,
value = stringReference(item1.value),
titleEllipsis = item1.titleTextEllipsis,
valueEllipsis = item1.valueTextEllipsis,
+ showInfoButton = item1.showInfoButton,
)
if (item2 == null) {
Box(
@@ -84,11 +91,17 @@ internal fun NFTDetailsBlocksGroup(
NFTDetailsGroupBlock(
modifier = Modifier
.weight(1f)
- .padding(paddingValues),
+ .padding(paddingValues)
+ .clickable(
+ interactionSource = remember { MutableInteractionSource() },
+ indication = null,
+ onClick = item2.onClick,
+ ),
title = item2.title,
value = stringReference(item2.value),
titleEllipsis = item2.titleTextEllipsis,
valueEllipsis = item2.valueTextEllipsis,
+ showInfoButton = item2.showInfoButton,
)
}
}
@@ -113,6 +126,7 @@ internal fun NFTDetailsGroupTitle(text: TextReference, modifier: Modifier = Modi
internal fun NFTDetailsGroupBlock(
title: TextReference,
value: TextReference,
+ showInfoButton: Boolean,
modifier: Modifier = Modifier,
titleEllipsis: TextEllipsis = TextEllipsis.End,
valueEllipsis: TextEllipsis = TextEllipsis.End,
@@ -120,12 +134,29 @@ internal fun NFTDetailsGroupBlock(
Column(
modifier = modifier,
) {
- EllipsisText(
- text = title.resolveReference(),
- style = TangemTheme.typography.caption2,
- color = TangemTheme.colors.text.tertiary,
- ellipsis = titleEllipsis,
- )
+ Row(
+ modifier = Modifier
+ .fillMaxWidth(),
+ ) {
+ EllipsisText(
+ modifier = Modifier
+ .weight(1f, fill = false),
+ text = title.resolveReference(),
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.tertiary,
+ ellipsis = titleEllipsis,
+ )
+ if (showInfoButton) {
+ Icon(
+ modifier = Modifier
+ .padding(start = TangemTheme.dimens.spacing4)
+ .size(TangemTheme.dimens.size16),
+ painter = painterResource(R.drawable.ic_information_24),
+ contentDescription = null,
+ tint = TangemTheme.colors.icon.informative,
+ )
+ }
+ }
EllipsisText(
modifier = Modifier
.padding(top = TangemTheme.dimens.spacing4),
@@ -224,22 +255,27 @@ private class NFTAssetBlocksProvider : CollectionPreviewParameterProvider