From 6d3eb6de79eec302a33b833632c947cf7a1b43ec Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 27 Aug 2024 10:06:13 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/core/ui/res/TangemDimens.kt | 1 + features/markets/impl/build.gradle.kts | 12 +- .../impl/model/MarketsTokenDetailsModel.kt | 12 +- .../impl/DefaultMarketsPortfolioComponent.kt | 10 +- .../impl/model/MarketsPortfolioModel.kt | 70 +++++++++++- .../impl/model/MyPortfolioUMMFactory.kt | 80 ++++++++++++++ .../impl/model/PortfolioTokenUMConverter.kt | 44 ++++++++ .../impl/model/TokensPortfolioUMConverter.kt | 58 ++++++++++ .../markets/portfolio/impl/ui/MyPortfolio.kt | 103 +++++++++--------- libs/crypto/build.gradle.kts | 3 + .../com/tangem/lib/crypto/BlockchainUtils.kt | 6 + 11 files changed, 332 insertions(+), 67 deletions(-) create mode 100644 features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MyPortfolioUMMFactory.kt create mode 100644 features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt create mode 100644 features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokensPortfolioUMConverter.kt diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt index 9b00a821e5..9617ee7825 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt @@ -74,6 +74,7 @@ data class TangemDimens internal constructor( val size56: Dp = 56.dp, val size60: Dp = 60.dp, val size62: Dp = 62.dp, + val size63: Dp = 63.dp, val size64: Dp = 64.dp, val size68: Dp = 68.dp, val size70: Dp = 70.dp, diff --git a/features/markets/impl/build.gradle.kts b/features/markets/impl/build.gradle.kts index 320f41fbc3..410e6dbd11 100644 --- a/features/markets/impl/build.gradle.kts +++ b/features/markets/impl/build.gradle.kts @@ -17,11 +17,16 @@ dependencies { implementation(projects.core.navigation) /* Domain */ - implementation(projects.domain.markets) implementation(projects.domain.appCurrency) implementation(projects.domain.appCurrency.models) - implementation(projects.domain.wallets.models) + implementation(projects.domain.balanceHiding) + implementation(projects.domain.balanceHiding.models) + implementation(projects.domain.markets) + implementation(projects.domain.staking.models) + implementation(projects.domain.tokens) implementation(projects.domain.tokens.models) + implementation(projects.domain.wallets) + implementation(projects.domain.wallets.models) /* Compose */ implementation(deps.compose.coil) @@ -52,4 +57,7 @@ dependencies { implementation(projects.common.ui) implementation(projects.common.uiCharts) implementation(projects.common.routing) + + /* Libs */ + implementation(projects.libs.crypto) } \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/model/MarketsTokenDetailsModel.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/model/MarketsTokenDetailsModel.kt index d2f3aa34f5..41a616a52f 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/model/MarketsTokenDetailsModel.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/model/MarketsTokenDetailsModel.kt @@ -2,7 +2,9 @@ package com.tangem.features.markets.details.impl.model import androidx.compose.runtime.Stable import arrow.core.getOrElse -import com.tangem.common.ui.charts.state.* +import com.tangem.common.ui.charts.state.MarketChartData +import com.tangem.common.ui.charts.state.MarketChartDataProducer +import com.tangem.common.ui.charts.state.MarketChartLook import com.tangem.core.decompose.di.ComponentScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -22,13 +24,11 @@ import com.tangem.features.markets.details.MarketsTokenDetailsComponent import com.tangem.features.markets.details.impl.model.converters.DescriptionConverter import com.tangem.features.markets.details.impl.model.converters.TokenMarketInfoConverter import com.tangem.features.markets.details.impl.model.formatter.* -import com.tangem.features.markets.details.impl.model.formatter.formatAsPrice -import com.tangem.features.markets.details.impl.model.formatter.getChangePercentBetween -import com.tangem.features.markets.details.impl.model.formatter.getPercentByInterval import com.tangem.features.markets.details.impl.model.state.TokenNetworksState import com.tangem.features.markets.details.impl.ui.state.InfoBottomSheetContent import com.tangem.features.markets.details.impl.ui.state.MarketsTokenDetailsUM import com.tangem.features.markets.impl.R +import com.tangem.lib.crypto.BlockchainUtils import com.tangem.utils.Provider import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.JobHolder @@ -296,7 +296,9 @@ internal class MarketsTokenDetailsModel @Inject constructor( ) } - val networks = result.networks + val networks = result.networks?.filter { + BlockchainUtils.isSupportedNetworkId(it.networkId) + } networksState.value = if (networks.isNullOrEmpty()) { TokenNetworksState.NoNetworksAvailable diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/DefaultMarketsPortfolioComponent.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/DefaultMarketsPortfolioComponent.kt index be951a14a5..73841ec05d 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/DefaultMarketsPortfolioComponent.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/DefaultMarketsPortfolioComponent.kt @@ -2,14 +2,15 @@ package com.tangem.features.markets.portfolio.impl import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.domain.markets.TokenMarketInfo import com.tangem.features.markets.portfolio.api.MarketsPortfolioComponent import com.tangem.features.markets.portfolio.impl.model.MarketsPortfolioModel import com.tangem.features.markets.portfolio.impl.ui.MyPortfolio -import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -27,10 +28,9 @@ internal class DefaultMarketsPortfolioComponent @AssistedInject constructor( @Composable override fun Content(modifier: Modifier) { - MyPortfolio( - modifier = modifier, - state = MyPortfolioUM.Loading, - ) + val state by model.state.collectAsStateWithLifecycle() + + MyPortfolio(modifier = modifier, state = state) } @AssistedFactory diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt index ba1f20d5c9..83fd674f85 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MarketsPortfolioModel.kt @@ -1,30 +1,92 @@ package com.tangem.features.markets.portfolio.impl.model import androidx.compose.runtime.Stable +import arrow.core.getOrElse import com.tangem.core.decompose.di.ComponentScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer +import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase +import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.markets.TokenMarketInfo +import com.tangem.domain.tokens.GetAllWalletsCryptoCurrencyStatusesUseCase +import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.features.markets.portfolio.api.MarketsPortfolioComponent +import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.flow.* +import timber.log.Timber import javax.inject.Inject @Stable @ComponentScoped internal class MarketsPortfolioModel @Inject constructor( paramsContainer: ParamsContainer, + getAllWalletsCryptoCurrencyStatusesUseCase: GetAllWalletsCryptoCurrencyStatusesUseCase, + getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, + getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, override val dispatchers: CoroutineDispatcherProvider, ) : Model() { - @Suppress("UnusedPrivateMember") + val state: StateFlow get() = _state + private val _state: MutableStateFlow = MutableStateFlow(value = MyPortfolioUM.Loading) + private val params = paramsContainer.require() - @Suppress("UnusedPrivateMember") + private val availableNetworks = MutableStateFlow?>(value = null) + + private val factory = MyPortfolioUMMFactory(::onAddClick, ::onTokenItemClick) + + init { + combine( + flow = getAllWalletsCryptoCurrencyStatusesUseCase(params.tokenId), + flow2 = availableNetworks, + flow3 = getSelectedAppCurrencyUseCase(), + flow4 = getBalanceHidingSettingsUseCase(), + ) { walletsWithCurrencyStatuses, networks, maybeAppCurrency, isBalanceHidden -> + val appCurrency = maybeAppCurrency.getOrElse { e -> + Timber.e("Failed to load app currency: $e") + AppCurrency.Default + } + + factory.create( + walletsWithCurrencyStatuses = walletsWithCurrencyStatuses, + availableNetworks = networks, + appCurrency = appCurrency, + isBalanceHidden = isBalanceHidden.isBalanceHidden, + ) + } + .onEach { _state.value = it } + .launchIn(modelScope) + } + fun setTokenNetworks(networks: List) { - // TODO [REDACTED_TASK_KEY] + availableNetworks.value = networks } fun setNoNetworksAvailable() { - // TODO [REDACTED_TASK_KEY] + availableNetworks.value = emptyList() + } + + private fun onAddClick() { + // TODO [REDACTED_JIRA] + } + + private fun onTokenItemClick(token: CryptoCurrencyStatus) { + _state.update { + (_state.value as? MyPortfolioUM.Tokens)?.let { state -> + state.copy( + tokens = state.tokens.map { tokenUM -> + if (tokenUM.tokenItemState.id == token.currency.id.value) { + tokenUM.copy(isQuickActionsShown = !tokenUM.isQuickActionsShown) + } else { + tokenUM + } + } + .toImmutableList(), + ) + } ?: it + } } } \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MyPortfolioUMMFactory.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MyPortfolioUMMFactory.kt new file mode 100644 index 0000000000..bd9042cac0 --- /dev/null +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/MyPortfolioUMMFactory.kt @@ -0,0 +1,80 @@ +package com.tangem.features.markets.portfolio.impl.model + +import arrow.core.Either +import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.domain.markets.TokenMarketInfo +import com.tangem.domain.tokens.error.CurrencyStatusError +import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM + +/** + * Factory for creating [MyPortfolioUM] + * + * @property onAddClick callback when user wants to add new token + * @property onTokenItemClick callback when user wants to see actions with token + * +[REDACTED_AUTHOR] + */ +internal class MyPortfolioUMMFactory( + private val onAddClick: () -> Unit, + private val onTokenItemClick: (CryptoCurrencyStatus) -> Unit, +) { + + /** + * Create [MyPortfolioUM] from data set + * + * @param walletsWithCurrencyStatuses wallets with currency statuses + * @param availableNetworks available networks + * @param appCurrency app currency + * @param isBalanceHidden flag that indicates if balance should be hidden + */ + fun create( + walletsWithCurrencyStatuses: Map>>, + availableNetworks: List?, + appCurrency: AppCurrency, + isBalanceHidden: Boolean, + ): MyPortfolioUM { + if (availableNetworks == null) return MyPortfolioUM.Loading + + if (availableNetworks.isEmpty()) return MyPortfolioUM.Unavailable + + val availableWalletsWithStatuses = walletsWithCurrencyStatuses + .filterAvailable(networks = availableNetworks) + .flatMapStatuses() + + if (availableWalletsWithStatuses.isEmpty()) { + return MyPortfolioUM.AddFirstToken(onAddClick = onAddClick) + } + + return TokensPortfolioUMConverter( + appCurrency = appCurrency, + isBalanceHidden = isBalanceHidden, + availableNetworks = availableNetworks, + onAddClick = onAddClick, + onTokenItemClick = onTokenItemClick, + ) + .convert(availableWalletsWithStatuses) + } + + private fun Map>>.filterAvailable( + networks: List, + ): Map> { + val networkIds = networks.map { it.networkId } + + return mapValues { entry -> + entry.value.mapNotNull { maybeStatus -> + maybeStatus.getOrNull() + ?.takeIf { networkIds.contains(it.currency.network.backendId) } + } + } + } + + private fun Map>.flatMapStatuses(): Map { + return this + .flatMap { entry -> + entry.value.map { entry.key to it } + } + .toMap() + } +} \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt new file mode 100644 index 0000000000..d299172177 --- /dev/null +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/PortfolioTokenUMConverter.kt @@ -0,0 +1,44 @@ +package com.tangem.features.markets.portfolio.impl.model + +import com.tangem.common.ui.tokens.TokenItemStateConverter +import com.tangem.core.ui.components.token.state.TokenItemState +import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.features.markets.portfolio.impl.ui.state.PortfolioTokenUM +import com.tangem.utils.converter.Converter + +/** + * Converter from [UserWallet] and [CryptoCurrencyStatus] to [PortfolioTokenUM] + * +[REDACTED_AUTHOR] + */ +internal class PortfolioTokenUMConverter( + private val appCurrency: AppCurrency, + private val isBalanceHidden: Boolean, + private val onTokenItemClick: (CryptoCurrencyStatus) -> Unit, +) : Converter, PortfolioTokenUM> { + + override fun convert(value: Map.Entry): PortfolioTokenUM { + val (userWallet, cryptoCurrencyStatus) = value + + val tokenItemStateConverter = TokenItemStateConverter( + appCurrency = appCurrency, + titleStateProvider = { TokenItemState.TitleState.Content(text = userWallet.name) }, + subtitleStateProvider = { + TokenItemState.SubtitleState.TextContent(value = cryptoCurrencyStatus.currency.name) + }, + onItemClick = onTokenItemClick, + onItemLongClick = null, + ) + + return PortfolioTokenUM( + tokenItemState = tokenItemStateConverter.convert(value = cryptoCurrencyStatus), + isBalanceHidden = isBalanceHidden, + isQuickActionsShown = false, + onQuickActionClick = { + // TODO: [REDACTED_JIRA] + }, + ) + } +} \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokensPortfolioUMConverter.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokensPortfolioUMConverter.kt new file mode 100644 index 0000000000..aa3b90ea8f --- /dev/null +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/TokensPortfolioUMConverter.kt @@ -0,0 +1,58 @@ +package com.tangem.features.markets.portfolio.impl.model + +import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.domain.markets.TokenMarketInfo +import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM +import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM.Tokens.AddButtonState +import com.tangem.utils.converter.Converter +import kotlinx.collections.immutable.toImmutableList + +/** + * Converter from [Map] of [UserWallet] and [CryptoCurrencyStatus] to [MyPortfolioUM.Tokens] + * +[REDACTED_AUTHOR] + */ +internal class TokensPortfolioUMConverter( + private val appCurrency: AppCurrency, + private val isBalanceHidden: Boolean, + private val availableNetworks: List, + private val onAddClick: () -> Unit, + private val onTokenItemClick: (CryptoCurrencyStatus) -> Unit, +) : Converter, MyPortfolioUM.Tokens> { + + override fun convert(value: Map): MyPortfolioUM.Tokens { + return MyPortfolioUM.Tokens( + tokens = PortfolioTokenUMConverter(appCurrency, isBalanceHidden, onTokenItemClick) + .convertList(value.entries) + .toImmutableList(), + buttonState = getAddButtonState( + availableWalletsWithStatuses = value, + availableNetworks = availableNetworks, + ), + onAddClick = onAddClick, + ) + } + + private fun getAddButtonState( + availableWalletsWithStatuses: Map, + availableNetworks: List, + ): AddButtonState { + val networkIds = availableNetworks.map { it.networkId } + + val allNetworksAdded = availableWalletsWithStatuses + // User can add currencies only in multi-currency wallets + .filterKeys(UserWallet::isMultiCurrency) + .entries + .groupBy( + keySelector = { it.key }, + valueTransform = { it.value.currency.network.backendId }, + ) + .mapValues { it.value.toSet() } + // Each wallets contains all available networks? + .all { it.value.containsAll(networkIds) } + + return if (allNetworksAdded) AddButtonState.Unavailable else AddButtonState.Available + } +} \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/MyPortfolio.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/MyPortfolio.kt index 88436fa864..6f5c6f01db 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/MyPortfolio.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/MyPortfolio.kt @@ -11,7 +11,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEachIndexed import com.tangem.core.ui.components.PrimaryButton import com.tangem.core.ui.components.SmallButtonShimmer @@ -26,51 +25,68 @@ import com.tangem.core.ui.res.TangemThemePreview import com.tangem.features.markets.impl.R import com.tangem.features.markets.portfolio.impl.ui.preview.PreviewMyPortfolioUMProvider import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM +import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM.Tokens.AddButtonState @Composable internal fun MyPortfolio(state: MyPortfolioUM, modifier: Modifier = Modifier) { InformationBlock( modifier = modifier, - contentHorizontalPadding = 0.dp, - title = { - Text( - text = stringResource(R.string.markets_common_my_portfolio), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - ) - }, + contentHorizontalPadding = TangemTheme.dimens.spacing0, + title = { Title() }, action = { if (state !is MyPortfolioUM.Tokens) return@InformationBlock - when (state.buttonState) { - MyPortfolioUM.Tokens.AddButtonState.Loading -> { - SmallButtonShimmer( - modifier = Modifier.size(width = 63.dp, height = TangemTheme.dimens.size18), - shape = RoundedCornerShape(TangemTheme.dimens.radius3), - ) - } - else -> { - SecondarySmallButton( - config = SmallButtonConfig( - text = resourceReference(R.string.markets_add_token), - icon = TangemButtonIconPosition.Start(R.drawable.ic_plus_24), - onClick = state.onAddClick, - enabled = state.buttonState == MyPortfolioUM.Tokens.AddButtonState.Available, - ), - ) - } - } + AddButton(state = state.buttonState, onClick = state.onAddClick) }, ) { + val contentModifier = Modifier.padding( + start = TangemTheme.dimens.spacing12, + end = TangemTheme.dimens.spacing12, + bottom = TangemTheme.dimens.spacing12, + ) + when (state) { is MyPortfolioUM.Tokens -> TokenList(state = state) - is MyPortfolioUM.AddFirstToken -> AddFirstTokenContent(state = state) - MyPortfolioUM.Loading -> LoadingPlaceholder() - MyPortfolioUM.Unavailable -> UnavailableContent() + is MyPortfolioUM.AddFirstToken -> AddFirstTokenContent(state = state, modifier = contentModifier) + MyPortfolioUM.Loading -> LoadingPlaceholder(modifier = contentModifier) + MyPortfolioUM.Unavailable -> UnavailableContent(modifier = contentModifier) } } - AddToPortfolioBottomSheet(state.addToPortfolioBS) + AddToPortfolioBottomSheet(config = state.addToPortfolioBS) +} + +@Composable +private fun Title() { + Text( + text = stringResource(R.string.markets_common_my_portfolio), + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + ) +} + +@Composable +private fun AddButton(state: AddButtonState, onClick: () -> Unit) { + when (state) { + AddButtonState.Loading -> { + SmallButtonShimmer( + modifier = Modifier.size(width = TangemTheme.dimens.size63, height = TangemTheme.dimens.size18), + shape = RoundedCornerShape(TangemTheme.dimens.radius3), + ) + } + AddButtonState.Available, + AddButtonState.Unavailable, + -> { + SecondarySmallButton( + config = SmallButtonConfig( + text = resourceReference(R.string.markets_add_token), + icon = TangemButtonIconPosition.Start(R.drawable.ic_plus_24), + onClick = onClick, + enabled = state == AddButtonState.Available, + ), + ) + } + } } @Composable @@ -90,12 +106,7 @@ private fun TokenList(state: MyPortfolioUM.Tokens, modifier: Modifier = Modifier @Composable private fun UnavailableContent(modifier: Modifier = Modifier) { Text( - modifier = modifier - .padding( - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing12, - bottom = TangemTheme.dimens.spacing12, - ), + modifier = modifier, text = stringResource(R.string.markets_add_to_my_portfolio_unavailable_description), style = TangemTheme.typography.body2, color = TangemTheme.colors.text.tertiary, @@ -105,12 +116,7 @@ private fun UnavailableContent(modifier: Modifier = Modifier) { @Composable private fun AddFirstTokenContent(state: MyPortfolioUM.AddFirstToken, modifier: Modifier = Modifier) { Column( - modifier = modifier - .padding( - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing12, - bottom = TangemTheme.dimens.spacing12, - ), + modifier = modifier, verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), ) { Text( @@ -118,6 +124,7 @@ private fun AddFirstTokenContent(state: MyPortfolioUM.AddFirstToken, modifier: M style = TangemTheme.typography.body2, color = TangemTheme.colors.text.tertiary, ) + PrimaryButton( modifier = Modifier.fillMaxWidth(), text = stringResource(R.string.markets_add_to_portfolio_button), @@ -128,19 +135,13 @@ private fun AddFirstTokenContent(state: MyPortfolioUM.AddFirstToken, modifier: M @Composable private fun LoadingPlaceholder(modifier: Modifier = Modifier) { - Column( - modifier = modifier - .padding( - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing12, - bottom = TangemTheme.dimens.spacing12, - ), - ) { + Column(modifier = modifier) { TextShimmer( modifier = Modifier.fillMaxWidth(), style = TangemTheme.typography.body2, textSizeHeight = true, ) + TextShimmer( modifier = Modifier.fillMaxWidth(fraction = 0.7f), style = TangemTheme.typography.body2, diff --git a/libs/crypto/build.gradle.kts b/libs/crypto/build.gradle.kts index 9a8ccaea31..1e443985c3 100644 --- a/libs/crypto/build.gradle.kts +++ b/libs/crypto/build.gradle.kts @@ -20,4 +20,7 @@ dependencies { /** Core */ implementation(projects.core.utils) + + /** Libs */ + implementation(projects.libs.blockchainSdk) } \ No newline at end of file diff --git a/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt b/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt index 35b8386cd9..dd253860fd 100644 --- a/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt +++ b/libs/crypto/src/main/java/com/tangem/lib/crypto/BlockchainUtils.kt @@ -2,6 +2,8 @@ package com.tangem.lib.crypto import com.tangem.blockchain.blockchains.xrp.XrpAddressService import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchainsdk.utils.fromNetworkId +import com.tangem.blockchainsdk.utils.isSupportedInApp import com.tangem.lib.crypto.converter.XrpTaggedAddressConverter import com.tangem.lib.crypto.models.XrpTaggedAddress @@ -55,4 +57,8 @@ object BlockchainUtils { val blockchain = Blockchain.fromId(networkId) return blockchain == Blockchain.Binance || blockchain == Blockchain.BinanceTestnet } + + fun isSupportedNetworkId(networkId: String): Boolean { + return Blockchain.fromNetworkId(networkId)?.isSupportedInApp() ?: false + } } \ No newline at end of file