diff --git a/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt
index 697065bb97..0578e95316 100644
--- a/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt
+++ b/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt
@@ -57,7 +57,7 @@ internal object NFTDomainModule {
fun providesGetNFTAvailableNetworksUseCase(
nftRepository: NFTRepository,
currenciesRepository: CurrenciesRepository,
- ): GetNFTAvailableNetworksUseCase = GetNFTAvailableNetworksUseCase(
+ ): GetNFTNetworksUseCase = GetNFTNetworksUseCase(
currenciesRepository = currenciesRepository,
nftRepository = nftRepository,
)
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index bda274d668..94ac2266d6 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -546,7 +546,6 @@
You haven\'t added this network yet. To start receiving NFTs, add it to the main screen!
Network not added
Not Added
- Send NFT
Traits
%1$d NFTs in %2$d collection
Tap here to receive first NFT
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/rows/ChainRow.kt b/core/ui/src/main/java/com/tangem/core/ui/components/rows/ChainRow.kt
index 7b8f2c9fff..a9020f35ae 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/rows/ChainRow.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/rows/ChainRow.kt
@@ -42,6 +42,7 @@ fun ChainRow(model: ChainRowUM, modifier: Modifier = Modifier, action: @Composab
} else {
null
},
+ isEnabled = model.enabled,
accentMainText = true,
accentSecondText = false,
)
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/ChainRowUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/ChainRowUM.kt
index c0c3764c5e..5b5f0ebd21 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/ChainRowUM.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/ChainRowUM.kt
@@ -9,4 +9,5 @@ data class ChainRowUM(
val type: String,
val icon: CurrencyIconState,
val showCustom: Boolean,
+ val enabled: Boolean = true,
)
\ No newline at end of file
diff --git a/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt b/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt
index 7fe4317d15..b19fef322d 100644
--- a/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt
+++ b/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt
@@ -2,7 +2,9 @@ package com.tangem.data.nft
import arrow.core.Either
import com.tangem.blockchain.common.Blockchain
+import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.blockchainsdk.utils.fromNetworkId
+import com.tangem.data.common.currency.getNetwork
import com.tangem.datasource.local.nft.NFTPersistenceStore
import com.tangem.datasource.local.nft.NFTPersistenceStoreFactory
import com.tangem.datasource.local.nft.NFTRuntimeStore
@@ -10,6 +12,7 @@ import com.tangem.datasource.local.nft.NFTRuntimeStoreFactory
import com.tangem.datasource.local.nft.converter.NFTSdkAssetIdentifierConverter
import com.tangem.datasource.local.nft.converter.NFTSdkCollectionConverter
import com.tangem.datasource.local.nft.converter.NFTSdkCollectionIdentifierConverter
+import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.models.StatusSource
import com.tangem.domain.nft.models.NFTAsset
import com.tangem.domain.nft.models.NFTCollection
@@ -37,6 +40,8 @@ internal class DefaultNFTRepository @Inject constructor(
private val nftRuntimeStoreFactory: NFTRuntimeStoreFactory,
private val walletManagersFacade: WalletManagersFacade,
private val dispatchers: CoroutineDispatcherProvider,
+ private val excludedBlockchains: ExcludedBlockchains,
+ private val userWalletsStore: UserWalletsStore,
) : NFTRepository {
private val networkJobs = ConcurrentHashMap()
@@ -129,6 +134,24 @@ internal class DefaultNFTRepository @Inject constructor(
override suspend fun isNFTSupported(network: Network): Boolean = network.canHandleNFTs()
+ override suspend fun getNFTSupportedNetworks(userWalletId: UserWalletId): List {
+ val userWallet = requireNotNull(userWalletsStore.getSyncOrNull(userWalletId)) {
+ "User wallet [$userWalletId] not found"
+ }
+ return Blockchain
+ .entries
+ .filter { it.canHandleNFTs() }
+ .filter { !it.isTestnet() }
+ .mapNotNull {
+ getNetwork(
+ blockchain = it,
+ extraDerivationPath = null,
+ scanResponse = userWallet.scanResponse,
+ excludedBlockchains = excludedBlockchains,
+ )
+ }
+ }
+
override suspend fun getNFTExploreUrl(network: Network, assetIdentifier: NFTAsset.Identifier): String? =
walletManagersFacade.getNFTExploreUrl(
network = network,
diff --git a/domain/nft/models/src/main/kotlin/com/tangem/domain/nft/models/NFTNetworks.kt b/domain/nft/models/src/main/kotlin/com/tangem/domain/nft/models/NFTNetworks.kt
new file mode 100644
index 0000000000..14cb57f3e7
--- /dev/null
+++ b/domain/nft/models/src/main/kotlin/com/tangem/domain/nft/models/NFTNetworks.kt
@@ -0,0 +1,8 @@
+package com.tangem.domain.nft.models
+
+import com.tangem.domain.tokens.model.Network
+
+data class NFTNetworks(
+ val availableNetworks: List,
+ val notAvailableNetworks: List,
+)
\ No newline at end of file
diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/FilterNFTAvailableNetworksUseCase.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/FilterNFTAvailableNetworksUseCase.kt
index 3308232789..ca8aff4b42 100644
--- a/domain/nft/src/main/kotlin/com/tangem/domain/nft/FilterNFTAvailableNetworksUseCase.kt
+++ b/domain/nft/src/main/kotlin/com/tangem/domain/nft/FilterNFTAvailableNetworksUseCase.kt
@@ -1,5 +1,6 @@
package com.tangem.domain.nft
+import com.tangem.domain.nft.models.NFTNetworks
import com.tangem.domain.tokens.model.Network
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.withContext
@@ -7,11 +8,16 @@ import kotlinx.coroutines.withContext
class FilterNFTAvailableNetworksUseCase(
private val dispatchers: CoroutineDispatcherProvider,
) {
- suspend operator fun invoke(networks: List, searchQuery: String): List =
+ suspend operator fun invoke(networks: NFTNetworks, searchQuery: String): NFTNetworks =
withContext(dispatchers.default) {
- networks.filter {
- it.name.contains(searchQuery, ignoreCase = true) ||
- it.currencySymbol.contains(searchQuery, ignoreCase = true)
- }
+ NFTNetworks(
+ availableNetworks = networks.availableNetworks.filter(searchQuery),
+ notAvailableNetworks = networks.notAvailableNetworks.filter(searchQuery),
+ )
}
+
+ private fun List.filter(searchQuery: String) = filter {
+ it.name.contains(searchQuery, ignoreCase = true) ||
+ it.currencySymbol.contains(searchQuery, ignoreCase = true)
+ }
}
\ No newline at end of file
diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/GetNFTAvailableNetworksUseCase.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/GetNFTAvailableNetworksUseCase.kt
deleted file mode 100644
index 203f12e012..0000000000
--- a/domain/nft/src/main/kotlin/com/tangem/domain/nft/GetNFTAvailableNetworksUseCase.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.tangem.domain.nft
-
-import com.tangem.domain.nft.repository.NFTRepository
-import com.tangem.domain.tokens.model.Network
-import com.tangem.domain.tokens.repository.CurrenciesRepository
-import com.tangem.domain.wallets.models.UserWalletId
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
-
-class GetNFTAvailableNetworksUseCase(
- private val currenciesRepository: CurrenciesRepository,
- private val nftRepository: NFTRepository,
-) {
- operator fun invoke(userWalletId: UserWalletId): Flow> = currenciesRepository
- .getWalletCurrenciesUpdates(userWalletId)
- .map { cryptoCurrencies ->
- cryptoCurrencies
- .map { cryptoCurrency -> cryptoCurrency.network }
- .distinct()
- .filter { nftRepository.isNFTSupported(it) }
- }
-}
\ No newline at end of file
diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/GetNFTNetworksUseCase.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/GetNFTNetworksUseCase.kt
new file mode 100644
index 0000000000..ca8a8c22bd
--- /dev/null
+++ b/domain/nft/src/main/kotlin/com/tangem/domain/nft/GetNFTNetworksUseCase.kt
@@ -0,0 +1,32 @@
+package com.tangem.domain.nft
+
+import com.tangem.domain.nft.models.NFTNetworks
+import com.tangem.domain.nft.repository.NFTRepository
+import com.tangem.domain.tokens.repository.CurrenciesRepository
+import com.tangem.domain.wallets.models.UserWalletId
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+
+class GetNFTNetworksUseCase(
+ private val currenciesRepository: CurrenciesRepository,
+ private val nftRepository: NFTRepository,
+) {
+ operator fun invoke(userWalletId: UserWalletId): Flow = currenciesRepository
+ .getWalletCurrenciesUpdates(userWalletId)
+ .map { cryptoCurrencies ->
+ val availableNetworks = cryptoCurrencies
+ .map { cryptoCurrency -> cryptoCurrency.network }
+ .filter { nftRepository.isNFTSupported(it) }
+ .sortedBy { it.name }
+
+ val notAvailableNetworks = nftRepository
+ .getNFTSupportedNetworks(userWalletId)
+ .filter { supportedNetwork -> availableNetworks.none { it.id == supportedNetwork.id } }
+ .sortedBy { it.name }
+
+ NFTNetworks(
+ availableNetworks = availableNetworks,
+ notAvailableNetworks = notAvailableNetworks,
+ )
+ }
+}
\ No newline at end of file
diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/repository/NFTRepository.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/repository/NFTRepository.kt
index ea99cbca2a..1484b241a3 100644
--- a/domain/nft/src/main/kotlin/com/tangem/domain/nft/repository/NFTRepository.kt
+++ b/domain/nft/src/main/kotlin/com/tangem/domain/nft/repository/NFTRepository.kt
@@ -18,5 +18,7 @@ interface NFTRepository {
suspend fun isNFTSupported(network: Network): Boolean
+ suspend fun getNFTSupportedNetworks(userWalletId: UserWalletId): List
+
suspend fun getNFTExploreUrl(network: Network, assetIdentifier: NFTAsset.Identifier): String?
}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/NFTNetworkUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/NFTNetworkUM.kt
index 0ef73aa689..dc3c6ae968 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/NFTNetworkUM.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/NFTNetworkUM.kt
@@ -1,10 +1,9 @@
package com.tangem.features.nft.receive.entity
-import androidx.annotation.DrawableRes
+import com.tangem.core.ui.components.rows.model.ChainRowUM
internal data class NFTNetworkUM(
val id: String,
- @DrawableRes val iconRes: Int,
- val name: String,
+ val chainRowUM: ChainRowUM,
val onItemClick: () -> Unit,
)
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/NFTReceiveUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/NFTReceiveUM.kt
index e31c80c425..eea9a23b79 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/NFTReceiveUM.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/NFTReceiveUM.kt
@@ -19,7 +19,8 @@ internal data class NFTReceiveUM(
data object Empty : Networks()
data class Content(
- val items: ImmutableList,
+ val availableItems: ImmutableList,
+ val notAvailableItems: ImmutableList,
) : Networks()
}
}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/transformer/UpdateDataStateTransformer.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/transformer/UpdateDataStateTransformer.kt
index 560bf018f7..c113d54905 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/transformer/UpdateDataStateTransformer.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/entity/transformer/UpdateDataStateTransformer.kt
@@ -1,6 +1,9 @@
package com.tangem.features.nft.receive.entity.transformer
+import com.tangem.core.ui.components.currency.icon.CurrencyIconState
+import com.tangem.core.ui.components.rows.model.ChainRowUM
import com.tangem.core.ui.extensions.getActiveIconRes
+import com.tangem.domain.nft.models.NFTNetworks
import com.tangem.domain.tokens.model.Network
import com.tangem.features.nft.receive.entity.NFTNetworkUM
import com.tangem.features.nft.receive.entity.NFTReceiveUM
@@ -8,27 +11,44 @@ import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.toPersistentList
internal class UpdateDataStateTransformer(
- private val networks: List,
- private val onNetworkClick: (Network) -> Unit,
+ private val networks: NFTNetworks,
+ private val onNetworkClick: (Network, Boolean) -> Unit,
) : Transformer {
override fun transform(prevState: NFTReceiveUM): NFTReceiveUM = prevState.copy(
networks = when {
- networks.isEmpty() -> NFTReceiveUM.Networks.Empty
+ networks.availableNetworks.isEmpty() && networks.notAvailableNetworks.isEmpty()
+ -> NFTReceiveUM.Networks.Empty
else -> NFTReceiveUM.Networks.Content(
- items = networks
- .map { it.transform() }
+ availableItems = networks.availableNetworks
+ .map { it.transform(true) }
+ .toPersistentList(),
+ notAvailableItems = networks.notAvailableNetworks
+ .map { it.transform(false) }
.toPersistentList(),
)
},
)
- private fun Network.transform(): NFTNetworkUM = NFTNetworkUM(
- id = id.value,
- iconRes = getActiveIconRes(id.value),
- name = name,
- onItemClick = {
- onNetworkClick(this)
- },
- )
+ private fun Network.transform(enabled: Boolean): NFTNetworkUM {
+ val custom = derivationPath is Network.DerivationPath.Custom
+ return NFTNetworkUM(
+ id = id.value + derivationPath.value,
+ chainRowUM = ChainRowUM(
+ name = name,
+ type = "",
+ icon = CurrencyIconState.CoinIcon(
+ url = null,
+ fallbackResId = getActiveIconRes(id.value),
+ isGrayscale = !enabled,
+ showCustomBadge = custom,
+ ),
+ showCustom = custom,
+ enabled = enabled,
+ ),
+ onItemClick = {
+ onNetworkClick(this, enabled)
+ },
+ )
+ }
}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/model/NFTReceiveModel.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/model/NFTReceiveModel.kt
index 88a9b57851..090d51ff5c 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/model/NFTReceiveModel.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/model/NFTReceiveModel.kt
@@ -4,14 +4,16 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
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.ui.UiMessageSender
import com.tangem.core.navigation.share.ShareManager
import com.tangem.core.ui.clipboard.ClipboardManager
import com.tangem.core.ui.components.fields.InputManager
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
+import com.tangem.core.ui.message.DialogMessage
import com.tangem.domain.nft.FilterNFTAvailableNetworksUseCase
-import com.tangem.domain.nft.GetNFTAvailableNetworksUseCase
+import com.tangem.domain.nft.GetNFTNetworksUseCase
import com.tangem.domain.nft.GetNFTNetworkStatusUseCase
import com.tangem.domain.nft.analytics.NFTAnalyticsEvent
import com.tangem.domain.tokens.model.Network
@@ -34,12 +36,13 @@ import javax.inject.Inject
internal class NFTReceiveModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val searchManager: InputManager,
- private val getNFTAvailableNetworksUseCase: GetNFTAvailableNetworksUseCase,
+ private val getNFTNetworksUseCase: GetNFTNetworksUseCase,
private val filterNFTAvailableNetworksUseCase: FilterNFTAvailableNetworksUseCase,
private val getNFTNetworkStatusUseCase: GetNFTNetworkStatusUseCase,
private val clipboardManager: ClipboardManager,
private val shareManager: ShareManager,
private val analyticsEventHandler: AnalyticsEventHandler,
+ private val messageSender: UiMessageSender,
paramsContainer: ParamsContainer,
) : Model() {
@@ -53,7 +56,10 @@ internal class NFTReceiveModel @Inject constructor(
formatArgs = wrappedList(params.walletName),
),
search = getInitialSearchBar(),
- networks = NFTReceiveUM.Networks.Content(persistentListOf()),
+ networks = NFTReceiveUM.Networks.Content(
+ availableItems = persistentListOf(),
+ notAvailableItems = persistentListOf(),
+ ),
bottomSheetConfig = null,
),
)
@@ -67,7 +73,7 @@ internal class NFTReceiveModel @Inject constructor(
private fun subscribeToNFTAvailableNetworks() {
combine(
- flow = getNFTAvailableNetworksUseCase(params.userWalletId),
+ flow = getNFTNetworksUseCase(params.userWalletId),
flow2 = searchManager.query.distinctUntilChanged(),
) { networks, query ->
filterNFTAvailableNetworksUseCase(networks, query)
@@ -113,31 +119,40 @@ internal class NFTReceiveModel @Inject constructor(
}
}
- private fun onNetworkClick(network: Network) {
- modelScope.launch {
- analyticsEventHandler.send(NFTAnalyticsEvent.Receive.BlockchainChosen(network.name))
+ private fun onNetworkClick(network: Network, enabled: Boolean) {
+ if (!enabled) {
+ val message = DialogMessage(
+ title = resourceReference(R.string.nft_receive_unavailable_asset_warning_title),
+ message = resourceReference(R.string.nft_receive_unavailable_asset_warning_message),
+ )
- val networkStatus = getNFTNetworkStatusUseCase.invoke(
- userWalletId = params.userWalletId,
- network = network,
- ) ?: return@launch
+ messageSender.send(message)
+ } else {
+ modelScope.launch {
+ analyticsEventHandler.send(NFTAnalyticsEvent.Receive.BlockchainChosen(network.name))
- when (val value = networkStatus.value) {
- is NetworkStatus.Verified -> {
- _state.update {
- ShowReceiveBottomSheetTransformer(
- network = network,
- networkAddress = value.address,
- onDismissBottomSheet = ::onReceiveBottomSheetDismiss,
- onCopyClick = { text -> onCopyClick(text, network) },
- onShareClick = { text -> onShareClick(text, network) },
- ).transform(it)
+ val networkStatus = getNFTNetworkStatusUseCase.invoke(
+ userWalletId = params.userWalletId,
+ network = network,
+ ) ?: return@launch
+
+ when (val value = networkStatus.value) {
+ is NetworkStatus.Verified -> {
+ _state.update {
+ ShowReceiveBottomSheetTransformer(
+ network = network,
+ networkAddress = value.address,
+ onDismissBottomSheet = ::onReceiveBottomSheetDismiss,
+ onCopyClick = { text -> onCopyClick(text, network) },
+ onShareClick = { text -> onShareClick(text, network) },
+ ).transform(it)
+ }
}
+ is NetworkStatus.MissedDerivation,
+ is NetworkStatus.NoAccount,
+ is NetworkStatus.Unreachable,
+ -> Unit
}
- is NetworkStatus.MissedDerivation,
- is NetworkStatus.NoAccount,
- is NetworkStatus.Unreachable,
- -> Unit
}
}
}
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTNetwork.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTNetwork.kt
deleted file mode 100644
index 9b60320b49..0000000000
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTNetwork.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.tangem.features.nft.receive.ui
-
-import android.content.res.Configuration
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.style.TextOverflow
-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.res.TangemTheme
-import com.tangem.core.ui.res.TangemThemePreview
-import com.tangem.features.nft.impl.R
-import com.tangem.features.nft.receive.entity.NFTNetworkUM
-
-@Composable
-internal fun NFTNetwork(state: NFTNetworkUM, modifier: Modifier = Modifier) {
- Row(
- modifier = modifier
- .fillMaxWidth()
- .clickable { state.onItemClick() }
- .padding(TangemTheme.dimens.spacing12),
- verticalAlignment = Alignment.CenterVertically,
- ) {
- Image(
- modifier = Modifier
- .size(TangemTheme.dimens.size24)
- .clip(CircleShape),
- painter = painterResource(state.iconRes),
- contentDescription = null,
- )
- Text(
- modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing12),
- text = state.name,
- style = TangemTheme.typography.subtitle2,
- color = TangemTheme.colors.text.primary1,
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
- )
- }
-}
-
-@Preview(widthDp = 360, showBackground = true)
-@Preview(widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
-@Composable
-private fun Preview_NFTNetwork(@PreviewParameter(NFTNetworkProvider::class) state: NFTNetworkUM) {
- TangemThemePreview {
- NFTNetwork(
- state = state,
- )
- }
-}
-
-private class NFTNetworkProvider : CollectionPreviewParameterProvider(
- collection = listOf(
- NFTNetworkUM(
- id = "item1",
- name = "Nethers #0853",
- iconRes = R.drawable.img_eth_22,
- onItemClick = { },
- ),
- ),
-)
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceive.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceive.kt
index 47a338514f..4dac3a8d5c 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceive.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceive.kt
@@ -1,7 +1,6 @@
package com.tangem.features.nft.receive.ui
import androidx.activity.compose.BackHandler
-import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
@@ -51,18 +50,9 @@ internal fun NFTReceive(state: NFTReceiveUM, modifier: Modifier = Modifier) {
colors = TangemSearchBarDefaults.secondaryTextFieldColors,
)
- val contentModifier = Modifier
- .padding(TangemTheme.dimens.spacing16)
-
- AnimatedContent(
- targetState = state.networks,
- contentKey = { it::class },
- label = "NFT Receive",
- ) {
- when (val networks = it) {
- is NFTReceiveUM.Networks.Content -> NFTReceiveNetworksContent(networks, contentModifier)
- is NFTReceiveUM.Networks.Empty -> NFTReceiveNetworksEmpty(contentModifier)
- }
+ when (val networks = state.networks) {
+ is NFTReceiveUM.Networks.Content -> NFTReceiveNetworksContent(networks)
+ is NFTReceiveUM.Networks.Empty -> NFTReceiveNetworksEmpty()
}
}
},
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceiveNetworksContent.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceiveNetworksContent.kt
index 23fab1ef15..8b01fd73b0 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceiveNetworksContent.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceiveNetworksContent.kt
@@ -1,19 +1,29 @@
package com.tangem.features.nft.receive.ui
import android.content.res.Configuration
-import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.lazy.LazyListScope
+import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.composed
import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Preview
-import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.components.currency.icon.CurrencyIconState
+import com.tangem.core.ui.components.rows.ChainRow
+import com.tangem.core.ui.components.rows.model.ChainRowUM
+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.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.nft.impl.R
@@ -27,40 +37,86 @@ internal fun NFTReceiveNetworksContent(state: NFTReceiveUM.Networks.Content, mod
LazyColumn(
modifier = modifier
- .fillMaxWidth()
- .clip(TangemTheme.shapes.roundedCornersXMedium)
- .background(TangemTheme.colors.background.primary)
- .animateContentSize(),
+ .fillMaxSize()
+ .padding(
+ vertical = TangemTheme.dimens.spacing8,
+ ),
state = listState,
+ contentPadding = PaddingValues(
+ horizontal = TangemTheme.dimens.spacing16,
+ ),
) {
- item(
- key = "title",
- ) {
- Title()
+ if (state.availableItems.isNotEmpty()) {
+ item(
+ key = "available_title",
+ ) {
+ Title(resourceReference(R.string.nft_receive_available_section_title))
+ }
+ networks(state.availableItems)
}
- items(
- items = state.items,
- key = NFTNetworkUM::id,
- ) { network ->
- NFTNetwork(
- state = network,
- modifier = Modifier.animateItem(),
- )
+ if (state.notAvailableItems.isNotEmpty()) {
+ item(
+ key = "not_available_title",
+ ) {
+ Title(resourceReference(R.string.nft_receive_unavailable_section_title))
+ }
+ networks(state.notAvailableItems)
}
}
}
+private fun LazyListScope.networks(items: List) {
+ itemsIndexed(
+ items = items,
+ key = { _, item -> item.id },
+ ) { index, network ->
+ val isLastItem = index == items.size - 1
+ ChainRow(
+ modifier = Modifier
+ .composed {
+ if (isLastItem) {
+ padding(
+ bottom = TangemTheme.dimens.spacing8,
+ )
+ .clip(
+ RoundedCornerShape(
+ bottomStart = TangemTheme.dimens.radius16,
+ bottomEnd = TangemTheme.dimens.radius16,
+ ),
+ )
+ } else {
+ this
+ }
+ }
+ .background(TangemTheme.colors.background.primary)
+ .clickable { network.onItemClick() },
+ model = network.chainRowUM,
+ )
+ }
+}
+
@Composable
-private fun Title(modifier: Modifier = Modifier) {
+private fun Title(text: TextReference, modifier: Modifier = Modifier) {
Text(
modifier = modifier
+ .fillMaxWidth()
+ .padding(
+ top = TangemTheme.dimens.spacing8,
+ )
+ .background(
+ color = TangemTheme.colors.background.primary,
+ shape = RoundedCornerShape(
+ topStart = TangemTheme.dimens.radius16,
+ topEnd = TangemTheme.dimens.radius16,
+ ),
+ )
.padding(
start = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing4,
),
- text = stringResourceSafe(R.string.nft_receive_choose_network),
+ text = text.resolveReference(),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
@@ -74,32 +130,84 @@ private fun Preview_NFTReceiveNetworksUM() {
TangemThemePreview {
NFTReceiveNetworksContent(
state = NFTReceiveUM.Networks.Content(
- items = persistentListOf(
+ availableItems = persistentListOf(
NFTNetworkUM(
id = "item1",
- name = "Ethereum",
- iconRes = R.drawable.img_eth_22,
+ chainRowUM = ChainRowUM(
+ name = "Ethereum",
+ type = "",
+ icon = CurrencyIconState.CoinIcon(
+ url = null,
+ fallbackResId = R.drawable.img_eth_22,
+ isGrayscale = false,
+ showCustomBadge = false,
+ ),
+ showCustom = false,
+ ),
onItemClick = { },
),
NFTNetworkUM(
id = "item2",
- name = "Polygon",
- iconRes = R.drawable.img_polygon_22,
+ chainRowUM = ChainRowUM(
+ name = "Polygon",
+ type = "",
+ icon = CurrencyIconState.CoinIcon(
+ url = null,
+ fallbackResId = R.drawable.img_polygon_22,
+ isGrayscale = false,
+ showCustomBadge = false,
+ ),
+ showCustom = false,
+ ),
onItemClick = { },
),
NFTNetworkUM(
id = "item3",
- name = "BSC",
- iconRes = R.drawable.img_bsc_22,
+ chainRowUM = ChainRowUM(
+ name = "BSC",
+ type = "",
+ icon = CurrencyIconState.CoinIcon(
+ url = null,
+ fallbackResId = R.drawable.img_bsc_22,
+ isGrayscale = false,
+ showCustomBadge = false,
+ ),
+ showCustom = false,
+ ),
onItemClick = { },
),
NFTNetworkUM(
id = "item4",
- name = "Avalanche",
- iconRes = R.drawable.img_avalanche_22,
+ chainRowUM = ChainRowUM(
+ name = "Avalanche",
+ type = "",
+ icon = CurrencyIconState.CoinIcon(
+ url = null,
+ fallbackResId = R.drawable.img_avalanche_22,
+ isGrayscale = false,
+ showCustomBadge = false,
+ ),
+ showCustom = false,
+ ),
+ onItemClick = { },
+ ),
+ NFTNetworkUM(
+ id = "item5",
+ chainRowUM = ChainRowUM(
+ name = "Avalanche",
+ type = "",
+ icon = CurrencyIconState.CoinIcon(
+ url = null,
+ fallbackResId = R.drawable.img_avalanche_22,
+ isGrayscale = false,
+ showCustomBadge = true,
+ ),
+ showCustom = true,
+ ),
onItemClick = { },
),
),
+ notAvailableItems = persistentListOf(),
),
)
}
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceiveNetworksEmpty.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceiveNetworksEmpty.kt
index 931138a97d..368e7fd8fc 100644
--- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceiveNetworksEmpty.kt
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/receive/ui/NFTReceiveNetworksEmpty.kt
@@ -3,6 +3,7 @@ package com.tangem.features.nft.receive.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@@ -16,6 +17,7 @@ internal fun NFTReceiveNetworksEmpty(modifier: Modifier = Modifier) {
Box(
modifier = modifier
.fillMaxSize()
+ .padding(TangemTheme.dimens.spacing16)
.background(TangemTheme.colors.background.secondary),
) {
Text(