Updated on 2026-08-14

This commit is contained in:
Tangem 2025-04-22 17:33:39 +05:00
parent c7151d95a7
commit c227fd1001
18 changed files with 299 additions and 187 deletions

View file

@ -57,7 +57,7 @@ internal object NFTDomainModule {
fun providesGetNFTAvailableNetworksUseCase(
nftRepository: NFTRepository,
currenciesRepository: CurrenciesRepository,
): GetNFTAvailableNetworksUseCase = GetNFTAvailableNetworksUseCase(
): GetNFTNetworksUseCase = GetNFTNetworksUseCase(
currenciesRepository = currenciesRepository,
nftRepository = nftRepository,
)

View file

@ -546,7 +546,6 @@
<string name="nft_receive_unavailable_asset_warning_message">You haven\'t added this network yet. To start receiving NFTs, add it to the main screen!</string>
<string name="nft_receive_unavailable_asset_warning_title">Network not added</string>
<string name="nft_receive_unavailable_section_title">Not Added</string>
<string name="nft_send">Send NFT</string>
<string name="nft_traits_title">Traits</string>
<string name="nft_wallet_count">%1$d NFTs in %2$d collection</string>
<string name="nft_wallet_receive_nft">Tap here to receive first NFT</string>

View file

@ -42,6 +42,7 @@ fun ChainRow(model: ChainRowUM, modifier: Modifier = Modifier, action: @Composab
} else {
null
},
isEnabled = model.enabled,
accentMainText = true,
accentSecondText = false,
)

View file

@ -9,4 +9,5 @@ data class ChainRowUM(
val type: String,
val icon: CurrencyIconState,
val showCustom: Boolean,
val enabled: Boolean = true,
)

View file

@ -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<Network, JobHolder>()
@ -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<Network> {
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,

View file

@ -0,0 +1,8 @@
package com.tangem.domain.nft.models
import com.tangem.domain.tokens.model.Network
data class NFTNetworks(
val availableNetworks: List<Network>,
val notAvailableNetworks: List<Network>,
)

View file

@ -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<Network>, searchQuery: String): List<Network> =
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<Network>.filter(searchQuery: String) = filter {
it.name.contains(searchQuery, ignoreCase = true) ||
it.currencySymbol.contains(searchQuery, ignoreCase = true)
}
}

View file

@ -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<List<Network>> = currenciesRepository
.getWalletCurrenciesUpdates(userWalletId)
.map { cryptoCurrencies ->
cryptoCurrencies
.map { cryptoCurrency -> cryptoCurrency.network }
.distinct()
.filter { nftRepository.isNFTSupported(it) }
}
}

View file

@ -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<NFTNetworks> = 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,
)
}
}

View file

@ -18,5 +18,7 @@ interface NFTRepository {
suspend fun isNFTSupported(network: Network): Boolean
suspend fun getNFTSupportedNetworks(userWalletId: UserWalletId): List<Network>
suspend fun getNFTExploreUrl(network: Network, assetIdentifier: NFTAsset.Identifier): String?
}

View file

@ -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,
)

View file

@ -19,7 +19,8 @@ internal data class NFTReceiveUM(
data object Empty : Networks()
data class Content(
val items: ImmutableList<NFTNetworkUM>,
val availableItems: ImmutableList<NFTNetworkUM>,
val notAvailableItems: ImmutableList<NFTNetworkUM>,
) : Networks()
}
}

View file

@ -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<Network>,
private val onNetworkClick: (Network) -> Unit,
private val networks: NFTNetworks,
private val onNetworkClick: (Network, Boolean) -> Unit,
) : Transformer<NFTReceiveUM> {
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)
},
)
}
}

View file

@ -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
}
}
}

View file

@ -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<NFTNetworkUM>(
collection = listOf(
NFTNetworkUM(
id = "item1",
name = "Nethers #0853",
iconRes = R.drawable.img_eth_22,
onItemClick = { },
),
),
)

View file

@ -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()
}
}
},

View file

@ -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<NFTNetworkUM>) {
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(),
),
)
}

View file

@ -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(