Updated on 2026-08-14
This commit is contained in:
parent
9cc51216bc
commit
784051ddeb
9 changed files with 78 additions and 73 deletions
|
|
@ -119,7 +119,9 @@ internal class DefaultNFTRepository @Inject constructor(
|
|||
userWalletId: UserWalletId,
|
||||
networks: List<Network>,
|
||||
): Flow<List<NFTCollections>> = combine(
|
||||
networks.map { observeCollectionsInternal(userWalletId, it) },
|
||||
networks
|
||||
.sortedBy { it.name }
|
||||
.map { observeCollectionsInternal(userWalletId, it) },
|
||||
) { it.asList() }
|
||||
|
||||
private suspend fun observeCollectionsInternal(
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.core.decompose.context.AppComponentContext
|
|||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.nft.models.NFTAsset
|
||||
import com.tangem.domain.nft.models.NFTCollection
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.nft.collections.model.NFTCollectionsModel
|
||||
import com.tangem.features.nft.collections.ui.NFTCollections
|
||||
|
|
@ -31,7 +32,7 @@ internal class NFTCollectionsComponent @AssistedInject constructor(
|
|||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val onBackClick: () -> Unit,
|
||||
val onAssetClick: (asset: NFTAsset, collectionName: String) -> Unit,
|
||||
val onAssetClick: (asset: NFTAsset, collection: NFTCollection) -> Unit,
|
||||
val onReceiveClick: () -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ internal class UpdateDataStateTransformer(
|
|||
private val onRetryClick: () -> Unit,
|
||||
private val onExpandCollectionClick: (NFTCollection) -> Unit,
|
||||
private val onRetryAssetsClick: (NFTCollection) -> Unit,
|
||||
private val onAssetClick: (NFTAsset, String) -> Unit,
|
||||
private val onAssetClick: (NFTAsset, NFTCollection) -> Unit,
|
||||
private val initialSearchBarFactory: () -> SearchBarUM,
|
||||
private val collectionIdProvider: NFTCollection.() -> String,
|
||||
) : Transformer<NFTCollectionsStateUM> {
|
||||
|
|
@ -118,12 +118,12 @@ internal class UpdateDataStateTransformer(
|
|||
is NFTCollection.Assets.Value -> NFTCollectionAssetsListUM.Content(
|
||||
items = assets
|
||||
.items
|
||||
.map { it.transform(name.orEmpty()) }
|
||||
.map { it.transform(this) }
|
||||
.toPersistentList(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun NFTAsset.transform(collectionName: String): NFTCollectionAssetUM {
|
||||
private fun NFTAsset.transform(collection: NFTCollection): NFTCollectionAssetUM {
|
||||
return NFTCollectionAssetUM(
|
||||
id = id.toString(),
|
||||
name = name ?: DASH_SIGN,
|
||||
|
|
@ -144,7 +144,7 @@ internal class UpdateDataStateTransformer(
|
|||
)
|
||||
},
|
||||
onItemClick = {
|
||||
onAssetClick(this, collectionName)
|
||||
onAssetClick(this, collection)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ internal class NFTCollectionsModel @Inject constructor(
|
|||
onRetryClick = ::onRefresh,
|
||||
onExpandCollectionClick = ::onExpandCollectionClick,
|
||||
onRetryAssetsClick = ::onRetryAssetsClick,
|
||||
onAssetClick = { asset, collectionName ->
|
||||
params.onAssetClick(asset, collectionName)
|
||||
onAssetClick = { asset, collection ->
|
||||
params.onAssetClick(asset, collection)
|
||||
},
|
||||
initialSearchBarFactory = ::getInitialSearchBar,
|
||||
collectionIdProvider = collectionIdProvider,
|
||||
|
|
|
|||
|
|
@ -112,12 +112,12 @@ internal class DefaultNFTComponent @AssistedInject constructor(
|
|||
),
|
||||
)
|
||||
},
|
||||
onAssetClick = { asset, collectionName ->
|
||||
onAssetClick = { asset, collection ->
|
||||
innerRouter.push(
|
||||
NFTRoute.Details(
|
||||
userWalletId = route.userWalletId,
|
||||
nftAsset = asset,
|
||||
collectionName = collectionName,
|
||||
collection = collection,
|
||||
),
|
||||
)
|
||||
},
|
||||
|
|
@ -144,7 +144,7 @@ internal class DefaultNFTComponent @AssistedInject constructor(
|
|||
params = NFTDetailsComponent.Params(
|
||||
userWalletId = route.userWalletId,
|
||||
nftAsset = route.nftAsset,
|
||||
nftCollectionName = route.collectionName,
|
||||
nftCollection = route.collection,
|
||||
onBackClick = ::onChildBack,
|
||||
onAllTraitsClick = {
|
||||
innerRouter.push(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.nft.common
|
|||
|
||||
import com.tangem.core.decompose.navigation.Route
|
||||
import com.tangem.domain.nft.models.NFTAsset
|
||||
import com.tangem.domain.nft.models.NFTCollection
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ internal sealed class NFTRoute : Route {
|
|||
data class Details(
|
||||
val userWalletId: UserWalletId,
|
||||
val nftAsset: NFTAsset,
|
||||
val collectionName: String,
|
||||
val collection: NFTCollection,
|
||||
) : NFTRoute()
|
||||
|
||||
@Serializable
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
|||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.nft.models.NFTAsset
|
||||
import com.tangem.domain.nft.models.NFTCollection
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.nft.details.entity.NFTDetailsBottomSheetConfig
|
||||
import com.tangem.features.nft.details.info.NFTDetailsInfoComponent
|
||||
|
|
@ -65,7 +66,7 @@ internal class NFTDetailsComponent @AssistedInject constructor(
|
|||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val nftAsset: NFTAsset,
|
||||
val nftCollectionName: String,
|
||||
val nftCollection: NFTCollection,
|
||||
val onBackClick: () -> Unit,
|
||||
val onAllTraitsClick: () -> Unit,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.core.ui.format.bigdecimal.fiat
|
|||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.nft.models.NFTAsset
|
||||
import com.tangem.domain.nft.models.NFTCollection
|
||||
import com.tangem.domain.nft.models.NFTSalePrice
|
||||
import com.tangem.features.nft.details.entity.NFTAssetUM
|
||||
import com.tangem.features.nft.details.entity.NFTDetailsUM
|
||||
|
|
@ -29,8 +30,8 @@ internal class NFTDetailsUMFactory(
|
|||
private val onInfoBlockClick: (title: TextReference, text: TextReference) -> Unit,
|
||||
) {
|
||||
|
||||
fun getInitialState(nftAsset: NFTAsset): NFTDetailsUM = NFTDetailsUM(
|
||||
nftAsset = nftAsset.transform(),
|
||||
fun getInitialState(nftAsset: NFTAsset, nftCollection: NFTCollection): NFTDetailsUM = NFTDetailsUM(
|
||||
nftAsset = nftAsset.transform(nftCollection),
|
||||
pullToRefreshConfig = PullToRefreshConfig(
|
||||
isRefreshing = false,
|
||||
onRefresh = { onRefresh() },
|
||||
|
|
@ -42,63 +43,62 @@ internal class NFTDetailsUMFactory(
|
|||
onSendClick = onSendClick,
|
||||
)
|
||||
|
||||
private fun NFTAsset.transform(): NFTAssetUM = NFTAssetUM(
|
||||
name = name.orEmpty(),
|
||||
media = media?.imageUrl?.let {
|
||||
NFTAssetUM.Media.Content(
|
||||
url = it,
|
||||
)
|
||||
} ?: NFTAssetUM.Media.Empty,
|
||||
topInfo = when {
|
||||
!hasSalePrice() && description.isNullOrEmpty() && rarity == null -> {
|
||||
NFTAssetUM.TopInfo.Empty
|
||||
}
|
||||
else -> {
|
||||
val hasSalePrice = hasSalePrice()
|
||||
val hasDescription = !description.isNullOrEmpty()
|
||||
val rarity = rarity
|
||||
NFTAssetUM.TopInfo.Content(
|
||||
title = if (hasSalePrice) {
|
||||
resourceReference(R.string.nft_details_last_sale_price)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
salePrice = toSalePrice(),
|
||||
description = description,
|
||||
rarity = if (rarity != null) {
|
||||
NFTAssetUM.Rarity.Content(
|
||||
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
|
||||
},
|
||||
private fun NFTAsset.transform(nftCollection: NFTCollection): NFTAssetUM {
|
||||
val description = description?.takeIf { it.isNotEmpty() } ?: nftCollection.description
|
||||
return NFTAssetUM(
|
||||
name = name.orEmpty(),
|
||||
media = media?.imageUrl?.let {
|
||||
NFTAssetUM.Media.Content(
|
||||
url = it,
|
||||
)
|
||||
}
|
||||
},
|
||||
traits = traits.take(MAX_TRAITS_COUNT).map {
|
||||
NFTAssetUM.BlockItem(
|
||||
title = stringReference(it.name),
|
||||
value = it.value,
|
||||
showInfoButton = false,
|
||||
)
|
||||
}.toImmutableList(),
|
||||
showAllTraitsButton = traits.size > MAX_TRAITS_COUNT,
|
||||
baseInfoItems = buildBaseInfoItems(),
|
||||
)
|
||||
} ?: NFTAssetUM.Media.Empty,
|
||||
topInfo = when {
|
||||
!hasSalePrice() && description.isNullOrEmpty() && rarity == null -> {
|
||||
NFTAssetUM.TopInfo.Empty
|
||||
}
|
||||
else -> {
|
||||
val hasSalePrice = hasSalePrice()
|
||||
val hasDescription = !description.isNullOrEmpty()
|
||||
val rarity = rarity
|
||||
NFTAssetUM.TopInfo.Content(
|
||||
title = resourceReference(R.string.nft_details_last_sale_price).takeIf { hasSalePrice },
|
||||
salePrice = toSalePrice(),
|
||||
description = description,
|
||||
rarity = if (rarity != null) {
|
||||
NFTAssetUM.Rarity.Content(
|
||||
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
|
||||
},
|
||||
)
|
||||
}
|
||||
},
|
||||
traits = traits.take(MAX_TRAITS_COUNT).map {
|
||||
NFTAssetUM.BlockItem(
|
||||
title = stringReference(it.name),
|
||||
value = it.value,
|
||||
showInfoButton = false,
|
||||
)
|
||||
}.toImmutableList(),
|
||||
showAllTraitsButton = traits.size > MAX_TRAITS_COUNT,
|
||||
baseInfoItems = buildBaseInfoItems(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun NFTAsset.hasSalePrice() = salePrice !is NFTSalePrice.Empty && salePrice !is NFTSalePrice.Error
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ internal class NFTDetailsModel @Inject constructor(
|
|||
|
||||
private val _state by lazy {
|
||||
MutableStateFlow(
|
||||
value = stateFactory.getInitialState(params.nftAsset),
|
||||
value = stateFactory.getInitialState(params.nftAsset, params.nftCollection),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ internal class NFTDetailsModel @Inject constructor(
|
|||
AppRoute.NFTSend(
|
||||
userWalletId = params.userWalletId,
|
||||
nftAsset = params.nftAsset,
|
||||
nftCollectionName = params.nftCollectionName,
|
||||
nftCollectionName = params.nftCollection.name.orEmpty(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue