Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-02 13:49:33 +03:00
commit aee6f2b131
10 changed files with 62 additions and 53 deletions

View file

@ -1,9 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="romanpotapov">
<words>
<w>blockchain</w>
<w>passcode</w>
<w>tangem</w>
</words>
</dictionary>
</component>

View file

@ -95,7 +95,7 @@ internal class DefaultNFTRepository @Inject constructor(
val salePrice = sdkPrice?.let {
val convertedPrice = salePriceConverter.convert(sdkPrice)
convertedPrice.copy(
value = convertedPrice.value.movePointLeft(nftCurrency.decimals),
value = convertedPrice.value,
decimals = nftCurrency.decimals,
symbol = nftCurrency.symbol,
)
@ -459,7 +459,7 @@ internal class DefaultNFTRepository @Inject constructor(
val nftCurrency = getNFTCurrency(network)
NFTSalePrice.Value(
assetId = assetId,
value = price.value.movePointLeft(nftCurrency.decimals),
value = price.value,
fiatValue = null,
symbol = nftCurrency.symbol,
decimals = nftCurrency.decimals,

View file

@ -518,36 +518,14 @@ internal class DefaultCurrenciesRepository(
currencyRawId: CryptoCurrency.RawID,
): Flow<Map<UserWallet, List<CryptoCurrency>>> {
return userWalletsStore.userWallets.flatMapLatest { userWallets ->
userWallets.filter { it.isMultiCurrency }
.forEach { fetchTokensIfCacheExpired(userWallet = it, refresh = false) }
val userWalletsWithCurrencies = userWallets
.filterNot(UserWallet::isLocked)
.map { userWallet ->
if (userWallet.isMultiCurrency) {
getSavedUserTokensResponse(userWallet.walletId).map { storedTokens ->
val filterResponse = storedTokens.tokens.filter {
getL2CompatibilityTokenComparison(it, currencyRawId.value)
}
responseCryptoCurrenciesFactory.createCurrencies(
response = storedTokens.copy(tokens = filterResponse),
scanResponse = userWallet.requireColdWallet().scanResponse,
)
}
} else {
flow {
val currency = getSingleCurrencyWalletPrimaryCurrency(userWalletId = userWallet.walletId)
val currencies = if (currency.id.rawCurrencyId == currencyRawId) {
listOf(currency)
} else {
emptyList()
}
emit(currencies)
}
}.map { userWallet to it }
getCurrenciesForWallet(userWallet, currencyRawId).map { userWallet to it }
}
combine(userWalletsWithCurrencies) { it.toMap() }
@ -555,6 +533,44 @@ internal class DefaultCurrenciesRepository(
}
}
private suspend fun getCurrenciesForWallet(
userWallet: UserWallet,
currencyRawId: CryptoCurrency.RawID,
): Flow<List<CryptoCurrency>> {
userWallet.requireColdWallet() // TODO [REDACTED_TASK_KEY]
return when {
userWallet.isMultiCurrency -> {
getSavedUserTokensResponse(userWallet.walletId).map { storedTokens ->
val filterResponse = storedTokens.tokens.filter {
getL2CompatibilityTokenComparison(it, currencyRawId.value)
}
responseCryptoCurrenciesFactory.createCurrencies(
response = storedTokens.copy(tokens = filterResponse),
scanResponse = userWallet.requireColdWallet().scanResponse,
)
}
}
else -> {
val currencies = if (userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken()) {
getSingleCurrencyWalletWithCardCurrencies(userWallet.walletId)
} else {
val currency =
getSingleCurrencyWalletPrimaryCurrency(userWalletId = userWallet.walletId)
if (currency.id.rawCurrencyId == currencyRawId) {
listOf(currency)
} else {
emptyList()
}
}
flow {
emit(currencies)
}
}
}
}
override fun isNetworkFeeZero(userWalletId: UserWalletId, network: Network): Boolean {
val blockchain = Blockchain.fromNetworkId(network.backendId)
return blockchain?.isNetworkFeeZero() ?: false

View file

@ -1,12 +1,12 @@
package com.tangem.features.nft.collections.ui
import android.content.res.Configuration
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -76,10 +76,11 @@ private fun Placeholder(modifier: Modifier = Modifier) {
.background(TangemTheme.colors.field.focused),
contentAlignment = Alignment.Center,
) {
Image(
Icon(
modifier = Modifier.size(TangemTheme.dimens.size52),
painter = painterResource(R.drawable.ic_nft_placeholder_120),
contentDescription = null,
tint = TangemTheme.colors.icon.primary1,
)
}
}

View file

@ -1,10 +1,10 @@
package com.tangem.features.nft.collections.ui
import android.content.res.Configuration
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -33,9 +33,10 @@ internal fun NFTCollectionsEmpty(state: NFTCollectionsUM.Empty, modifier: Modifi
.align(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(
Icon(
painter = painterResource(R.drawable.ic_nft_placeholder_add_76),
contentDescription = null,
tint = TangemTheme.colors.icon.inactive,
)
Text(
modifier = Modifier.padding(top = TangemTheme.dimens.spacing24),

View file

@ -9,11 +9,13 @@ 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.core.decompose.ui.UiMessageSender
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
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.nft.FetchNFTCollectionAssetsUseCase
@ -52,6 +54,7 @@ internal class NFTDetailsModel @Inject constructor(
private val fetchNFTCollectionAssetsUseCase: FetchNFTCollectionAssetsUseCase,
private val fetchNFTPriceUseCase: FetchNFTPriceUseCase,
private val clipboardManager: ClipboardManager,
private val uiMessageSender: UiMessageSender,
paramsContainer: ParamsContainer,
) : Model() {
@ -215,5 +218,8 @@ internal class NFTDetailsModel @Inject constructor(
is NFTAsset.Identifier.Unknown -> return
}
clipboardManager.setText(text = addressToCopy, isSensitive = false)
uiMessageSender.send(
message = SnackbarMessage(message = resourceReference(R.string.wallet_notification_address_copied)),
)
}
}

View file

@ -186,30 +186,22 @@ private fun Rarity(state: NFTAssetUM.Rarity, modifier: Modifier = Modifier) {
.weight(1f)
.padding(
horizontal = TangemTheme.dimens.spacing6,
)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onClick = state.onLabelClick,
),
title = resourceReference(R.string.nft_details_rarity_label),
value = stringReference(state.label),
showInfoButton = true,
onBlockClick = state.onLabelClick,
)
NFTDetailsGroupBlock(
modifier = Modifier
.weight(1f)
.padding(
horizontal = TangemTheme.dimens.spacing6,
)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onClick = state.onRankClick,
),
title = resourceReference(R.string.nft_details_rarity_rank),
value = stringReference(state.rank),
showInfoButton = true,
onBlockClick = state.onRankClick,
)
}
}

View file

@ -1,12 +1,12 @@
package com.tangem.features.nft.details.ui
import android.content.res.Configuration
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.material.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -63,10 +63,11 @@ private fun Placeholder(modifier: Modifier = Modifier) {
.background(TangemTheme.colors.field.focused),
contentAlignment = Alignment.Center,
) {
Image(
Icon(
modifier = Modifier.size(TangemTheme.dimens.size120),
painter = painterResource(R.drawable.ic_nft_placeholder_120),
contentDescription = null,
tint = TangemTheme.colors.icon.primary1,
)
}
}

View file

@ -8,6 +8,7 @@ import com.tangem.domain.staking.model.stakekit.action.StakingActionType
import com.tangem.features.staking.impl.presentation.state.BalanceState
import com.tangem.lib.crypto.BlockchainUtils.isBSC
import com.tangem.lib.crypto.BlockchainUtils.isCardano
import com.tangem.lib.crypto.BlockchainUtils.isCosmos
import com.tangem.lib.crypto.BlockchainUtils.isSolana
import com.tangem.lib.crypto.BlockchainUtils.isTron
import kotlinx.collections.immutable.ImmutableList
@ -67,5 +68,5 @@ internal fun isCompositePendingActions(networkId: String, pendingActions: Immuta
}
private fun isStubUnstakeAction(networkId: String): Boolean {
return isBSC(networkId) || isCardano(networkId)
return isBSC(networkId) || isCardano(networkId) || isCosmos(networkId)
}

View file

@ -5,7 +5,7 @@
# https://github.com/tangem/tangem-sdk-android/
# https://github.com/tangem/vico
tangemBlockchainSdk = "develop-1097"
tangemBlockchainSdk = "develop-1102"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-484"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^