Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-05 18:33:40 +03:00
parent 1006477fd7
commit 2d753e14af
30 changed files with 189 additions and 55 deletions

View file

@ -7,6 +7,7 @@ import com.tangem.domain.tokens.*
import com.tangem.domain.tokens.repository.*
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.feature.swap.domain.api.SwapRepository
import com.tangem.features.markets.MarketsFeatureToggles
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
@ -230,6 +231,7 @@ internal object TokensDomainModule {
networksRepository: NetworksRepository,
stakingRepository: StakingRepository,
stakingFeatureToggles: StakingFeatureToggles,
marketsFeatureToggles: MarketsFeatureToggles,
dispatchers: CoroutineDispatcherProvider,
): GetCryptoCurrencyActionsUseCase {
return GetCryptoCurrencyActionsUseCase(
@ -241,6 +243,7 @@ internal object TokensDomainModule {
networksRepository = networksRepository,
stakingRepository = stakingRepository,
stakingFeatureToggles = stakingFeatureToggles,
marketsFeatureToggles = marketsFeatureToggles,
dispatchers = dispatchers,
)
}

View file

@ -193,6 +193,7 @@ internal class ChildFactory @Inject constructor(
params = MarketsTokenDetailsComponent.Params(
token = route.token,
appCurrency = route.appCurrency,
showPortfolio = route.showPortfolio,
),
componentFactory = marketsTokenDetailsComponentFactory,
)

View file

@ -271,5 +271,6 @@ sealed class AppRoute(val path: String) : Route {
data class MarketsTokenDetails(
val token: TokenMarketParams,
val appCurrency: AppCurrency,
) : AppRoute(path = "/markets_token_details/${token.id}")
val showPortfolio: Boolean,
) : AppRoute(path = "/markets_token_details/${token.id}/$showPortfolio")
}

View file

@ -125,6 +125,8 @@ fun MarketChart(
// Sometimes the chart is not drawn correctly (ex. in LazyLayout), so we need to force the redraw
.drawBehind {
state.markerFraction
state.chartColor
state.markerHighlightRightSide
},
chart = chart,
modelProducer = state.modelProducer,

View file

@ -22,10 +22,13 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.buttons.PrimarySmallButton
import com.tangem.core.ui.components.buttons.SmallButtonConfig
import com.tangem.core.ui.components.buttons.chip.Chip
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.*
import com.valentinilk.shimmer.*
@ -123,6 +126,22 @@ fun SmallButtonShimmer(
)
}
/**
* Shimmer for Chip
* Height and min width will be set automatically
*/
@Composable
fun ChipShimmer(modifier: Modifier = Modifier) {
Chip(
modifier = modifier
.clip(RoundedCornerShape(size = 100.dp))
.shimmer(LocalTangemShimmer.current),
text = TextReference.EMPTY,
iconResId = R.drawable.ic_plus_24,
onClick = {},
)
}
internal val TangemShimmer: Shimmer
@Composable
get() = rememberShimmer(
@ -195,6 +214,7 @@ private fun ShimmersPreview() {
)
SmallButtonShimmer(withIcon = true)
SmallButtonShimmer(withIcon = false)
ChipShimmer()
}
}
}

View file

@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M3,3V19C3,19.53 3.211,20.039 3.586,20.414C3.961,20.789 4.47,21 5,21H21"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#1E1E1E"/>
<path
android:pathData="M19,9L14,14L10,10L7,13"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#1E1E1E"/>
</vector>

View file

@ -143,7 +143,6 @@ internal class DefaultQuotesRepository(
block = { acc.add(rawCurrencyId) },
)
}
acc
}
}

View file

@ -15,7 +15,7 @@ data class TokenMarketParams(
@Serializable
data class Quotes(
val currentPrice: SerializedBigDecimal,
val h24Percent: SerializedBigDecimal,
val h24Percent: SerializedBigDecimal?,
val weekPercent: SerializedBigDecimal?,
val monthPercent: SerializedBigDecimal?,
)

View file

@ -28,6 +28,7 @@ dependencies {
/** Project - Api */
implementation(projects.features.send.api)
implementation(projects.features.staking.api)
implementation(projects.features.markets.api)
/** Project - Other */
implementation(projects.core.utils)

View file

@ -12,6 +12,7 @@ import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.markets.MarketsFeatureToggles
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.isNullOrZero
@ -33,6 +34,7 @@ class GetCryptoCurrencyActionsUseCase(
private val networksRepository: NetworksRepository,
private val stakingRepository: StakingRepository,
private val stakingFeatureToggles: StakingFeatureToggles,
private val marketsFeatureToggles: MarketsFeatureToggles,
private val dispatchers: CoroutineDispatcherProvider,
) {
@ -112,6 +114,12 @@ class GetCryptoCurrencyActionsUseCase(
val activeList = mutableListOf<TokenActionsState.ActionState>()
val disabledList = mutableListOf<TokenActionsState.ActionState>()
// markets
// not a custom token
if (marketsFeatureToggles.isFeatureEnabled && cryptoCurrencyStatus.currency.id.rawCurrencyId != null) {
activeList.add(TokenActionsState.ActionState.Analytics(ScenarioUnavailabilityReason.None))
}
// copy address
if (isAddressAvailable(cryptoCurrencyStatus.value.networkAddress)) {
activeList.add(TokenActionsState.ActionState.CopyAddress(ScenarioUnavailabilityReason.None))

View file

@ -30,6 +30,8 @@ data class TokenActionsState(
data class Send(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState()
data class Analytics(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState()
data class HideToken(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState()
}
}

View file

@ -53,6 +53,8 @@ import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
import com.tangem.core.ui.event.EventEffect
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.haptic.TangemHapticEffect
import com.tangem.core.ui.res.LocalHapticManager
import com.tangem.core.ui.res.LocalSnackbarHostState
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -369,6 +371,8 @@ private fun NetworksList(
isEditable: Boolean,
modifier: Modifier = Modifier,
) {
val hapticManager = LocalHapticManager.current
AnimatedVisibility(
modifier = modifier,
visible = networks is NetworksUM.Expanded,
@ -403,7 +407,14 @@ private fun NetworksList(
if (isEditable) {
TangemSwitch(
checked = network.isSelected,
onCheckedChange = network.onSelectedStateChange,
onCheckedChange = { checked ->
if (checked) {
hapticManager.perform(TangemHapticEffect.View.ToggleOn)
} else {
hapticManager.perform(TangemHapticEffect.View.ToggleOff)
}
network.onSelectedStateChange(checked)
},
)
}
},

View file

@ -19,6 +19,7 @@ interface MarketsTokenDetailsComponent : ComposableContentComponent {
data class Params(
val token: TokenMarketParams,
val appCurrency: AppCurrency,
val showPortfolio: Boolean,
)
@Composable

View file

@ -46,6 +46,7 @@ dependencies {
implementation(deps.compose.ui.utils)
implementation(deps.lifecycle.compose)
implementation(deps.androidx.activity.compose)
implementation(deps.markdown.composeview)
/* DI */
implementation(deps.hilt.android)

View file

@ -33,17 +33,21 @@ internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor(
private val model: MarketsTokenDetailsModel = getOrCreateModel(params)
private val portfolioComponent = portfolioComponentFactory.create(
context = child("my_portfolio"),
params = MarketsPortfolioComponent.Params(params.token),
)
private val portfolioComponent: MarketsPortfolioComponent? = if (params.showPortfolio) {
portfolioComponentFactory.create(
context = child("my_portfolio"),
params = MarketsPortfolioComponent.Params(params.token),
)
} else {
null
}
init {
componentScope.launch {
model.networksState.collectLatest {
when (it) {
is TokenNetworksState.NetworksAvailable -> portfolioComponent.setTokenNetworks(it.networks)
TokenNetworksState.NoNetworksAvailable -> portfolioComponent.setNoNetworksAvailable()
is TokenNetworksState.NetworksAvailable -> portfolioComponent?.setTokenNetworks(it.networks)
TokenNetworksState.NoNetworksAvailable -> portfolioComponent?.setNoNetworksAvailable()
else -> {}
}
}
@ -79,10 +83,16 @@ internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor(
backgroundColor = LocalMainBottomSheetColor.current.value,
addTopBarStatusBarPadding = false,
state = state,
onBackClick = ::navigateBack,
onBackClick = {
if (bsState == BottomSheetState.EXPANDED) {
navigateBack()
}
},
onHeaderSizeChange = onHeaderSizeChange,
portfolioBlock = { blockModifier ->
portfolioComponent.Content(blockModifier)
portfolioBlock = portfolioComponent?.let { component ->
{ blockModifier ->
component.Content(blockModifier)
}
},
)
}
@ -109,8 +119,10 @@ internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor(
state = state,
onBackClick = ::navigateBack,
onHeaderSizeChange = {},
portfolioBlock = { blockModifier ->
portfolioComponent.Content(blockModifier)
portfolioBlock = portfolioComponent?.let { component ->
{ blockModifier ->
component.Content(blockModifier)
}
},
)
}

View file

@ -4,7 +4,6 @@ import androidx.compose.runtime.Stable
import arrow.core.getOrElse
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.common.ui.charts.state.sorted
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
@ -135,15 +134,16 @@ internal class MarketsTokenDetailsModel @Inject constructor(
fiatCurrencySymbol = currentAppCurrency.value.symbol,
),
dateTimeText = resourceReference(R.string.common_today),
priceChangePercentText = BigDecimalFormatter.formatPercent(
percent = params.token.tokenQuotes.h24Percent,
useAbsoluteValue = true,
),
priceChangePercentText = params.token.tokenQuotes.h24Percent?.let {
BigDecimalFormatter.formatPercent(
percent = it,
useAbsoluteValue = true,
)
},
priceChangeType = params.token.tokenQuotes.h24Percent.percentChangeType(),
iconUrl = params.token.imageUrl,
chartState = MarketsTokenDetailsUM.ChartState(
dataProducer = chartDataProducer,
chartLook = MarketChartLook(),
onLoadRetryClick = ::onLoadRetryClicked,
status = MarketsTokenDetailsUM.ChartState.Status.LOADING,
onMarkerPointSelected = ::onMarkerPointSelected,
@ -320,6 +320,7 @@ internal class MarketsTokenDetailsModel @Inject constructor(
currentQuotes.value = newInfo.quotes
val percent = newInfo.quotes.getPercentByInterval(interval = state.value.selectedInterval)
state.update {
it.copy(
priceText = newInfo.quotes.currentPrice.formatAsPrice(currentAppCurrency.value),

View file

@ -18,7 +18,6 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import com.tangem.common.ui.charts.state.MarketChartDataProducer
import com.tangem.common.ui.charts.state.MarketChartLook
import com.tangem.core.ui.components.*
import com.tangem.core.ui.components.appbar.TangemTopAppBar
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
@ -54,7 +53,7 @@ internal fun MarketsTokenDetailsContent(
addTopBarStatusBarPadding: Boolean,
onBackClick: () -> Unit,
onHeaderSizeChange: (Dp) -> Unit,
portfolioBlock: @Composable (Modifier) -> Unit,
portfolioBlock: @Composable ((Modifier) -> Unit)?,
modifier: Modifier = Modifier,
) {
Content(
@ -78,7 +77,7 @@ private fun Content(
addTopBarStatusBarInsets: Boolean,
onBackClick: () -> Unit,
onHeaderSizeChange: (Dp) -> Unit,
portfolioBlock: @Composable (Modifier) -> Unit,
portfolioBlock: @Composable ((Modifier) -> Unit)?,
modifier: Modifier = Modifier,
) {
val density = LocalDensity.current
@ -129,9 +128,7 @@ private fun Content(
)
}
item { SpacerH32() }
item(
contentType = "chart",
) {
item("chart") {
MarketTokenDetailsChart(
modifier = Modifier.fillMaxWidth(),
backgroundColor = backgroundColor,
@ -167,11 +164,13 @@ private fun Header(state: MarketsTokenDetailsUM, modifier: Modifier = Modifier)
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
PriceChangeInPercent(
valueInPercent = state.priceChangePercentText,
type = state.priceChangeType,
textStyle = TangemTheme.typography.caption2,
)
if (state.priceChangePercentText != null) {
PriceChangeInPercent(
valueInPercent = state.priceChangePercentText,
type = state.priceChangeType,
textStyle = TangemTheme.typography.caption2,
)
}
}
}
SpacerW4()
@ -290,7 +289,6 @@ private fun Preview() {
priceChangeType = PriceChangeType.UP,
chartState = MarketsTokenDetailsUM.ChartState(
dataProducer = MarketChartDataProducer.build { },
chartLook = MarketChartLook(),
onLoadRetryClick = {},
status = MarketsTokenDetailsUM.ChartState.Status.LOADING,
onMarkerPointSelected = { _, _ -> },

View file

@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
@ -17,6 +16,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetTitle
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.markets.details.impl.ui.state.InfoBottomSheetContent
import dev.jeziellago.compose.markdowntext.MarkdownText
@Composable
internal fun InfoBottomSheet(config: TangemBottomSheetConfig) {
@ -35,10 +35,14 @@ internal fun InfoBottomSheet(config: TangemBottomSheetConfig) {
.verticalScroll(rememberScrollState())
.padding(horizontal = TangemTheme.dimens.spacing28),
) {
Text(
text = it.body.resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.secondary,
MarkdownText(
markdown = it.body.resolveReference(),
disableLinkMovementMethod = true,
linkifyMask = 0,
syntaxHighlightColor = TangemTheme.colors.text.secondary,
style = TangemTheme.typography.body2.copy(
color = TangemTheme.colors.text.secondary,
),
)
SpacerH(bottomBarHeight)
}

View file

@ -10,7 +10,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach
import com.tangem.core.ui.components.SmallButtonShimmer
import com.tangem.core.ui.components.ChipShimmer
import com.tangem.core.ui.components.TextShimmer
import com.tangem.core.ui.components.block.information.InformationBlock
import com.tangem.core.ui.components.buttons.chip.Chip
@ -145,9 +145,8 @@ private fun SubBlockPlaceholder(modifier: Modifier = Modifier, lastBlock: Boolea
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
repeat(times = 3) {
SmallButtonShimmer(
ChipShimmer(
modifier = Modifier.weight(1f),
withIcon = true,
)
}
}

View file

@ -161,7 +161,7 @@ internal fun PricePerformanceBlockPlaceholder(modifier: Modifier = Modifier) {
},
content = {
Column(
modifier = modifier.padding(vertical = TangemTheme.dimens.spacing8),
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing8),
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
Row(

View file

@ -13,7 +13,7 @@ import com.tangem.features.markets.tokenlist.impl.ui.components.UnableToLoadData
internal fun LazyListScope.tokenMarketDetailsBody(
state: MarketsTokenDetailsUM.Body,
portfolioBlock: @Composable (Modifier) -> Unit,
portfolioBlock: @Composable ((Modifier) -> Unit)?,
) {
when (state) {
MarketsTokenDetailsUM.Body.Loading -> {
@ -21,8 +21,10 @@ internal fun LazyListScope.tokenMarketDetailsBody(
DescriptionPlaceholder(modifier = Modifier.blockPaddings())
}
item(key = "portfolio") {
portfolioBlock(Modifier.blockPaddings())
if (portfolioBlock != null) {
item(key = "portfolio") {
portfolioBlock(Modifier.blockPaddings())
}
}
loadingInfoBlocks()
@ -32,8 +34,10 @@ internal fun LazyListScope.tokenMarketDetailsBody(
description(state.description)
}
item(key = "portfolio") {
portfolioBlock(Modifier.blockPaddings())
if (portfolioBlock != null) {
item(key = "portfolio") {
portfolioBlock(Modifier.blockPaddings())
}
}
infoBlocksList(state.infoBlocks)

View file

@ -2,7 +2,6 @@ package com.tangem.features.markets.details.impl.ui.state
import androidx.compose.runtime.Immutable
import com.tangem.common.ui.charts.state.MarketChartDataProducer
import com.tangem.common.ui.charts.state.MarketChartLook
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.marketprice.PriceChangeType
import com.tangem.core.ui.event.StateEvent
@ -15,7 +14,7 @@ internal data class MarketsTokenDetailsUM(
val priceText: String,
val iconUrl: String?,
val dateTimeText: TextReference,
val priceChangePercentText: String,
val priceChangePercentText: String?,
val priceChangeType: PriceChangeType,
val selectedInterval: PriceChangeInterval,
val markerSet: Boolean,
@ -29,7 +28,6 @@ internal data class MarketsTokenDetailsUM(
data class ChartState(
val status: Status,
val dataProducer: MarketChartDataProducer,
val chartLook: MarketChartLook,
val onLoadRetryClick: () -> Unit,
val onMarkerPointSelected: (time: BigDecimal?, price: BigDecimal?) -> Unit,
) {

View file

@ -70,6 +70,7 @@ internal class DefaultMarketsEntryComponent @AssistedInject constructor(
params = MarketsTokenDetailsComponent.Params(
token = token.toSerializableParam(),
appCurrency = appCurrency,
showPortfolio = true,
),
),
)

View file

@ -182,13 +182,12 @@ internal class TokenActionsHandler @AssistedInject constructor(
is TokenActionsState.ActionState.HideToken -> null
is TokenActionsState.ActionState.Receive -> TokenActionsBSContentUM.Action.Receive
is TokenActionsState.ActionState.Sell -> TokenActionsBSContentUM.Action.Sell
is TokenActionsState.ActionState.Send -> {
TokenActionsBSContentUM.Action.Send.takeIf {
cryptoCurrencyData.status.value.amount.isNullOrZero().not()
}
is TokenActionsState.ActionState.Send -> TokenActionsBSContentUM.Action.Send.takeIf {
cryptoCurrencyData.status.value.amount.isNullOrZero().not()
}
is TokenActionsState.ActionState.Stake -> TokenActionsBSContentUM.Action.Stake
is TokenActionsState.ActionState.Swap -> TokenActionsBSContentUM.Action.Exchange
is TokenActionsState.ActionState.Analytics -> null
}
.takeIf { this.unavailabilityReason == ScenarioUnavailabilityReason.None }

View file

@ -36,6 +36,8 @@ import com.tangem.core.ui.components.currency.icon.CoinIcon
import com.tangem.core.ui.components.rows.ArrowRow
import com.tangem.core.ui.components.rows.BlockchainRow
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.haptic.TangemHapticEffect
import com.tangem.core.ui.res.LocalHapticManager
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.markets.impl.R
@ -168,6 +170,8 @@ private fun ContinueButton(
@Suppress("LongMethod")
@Composable
private fun NetworkSelection(state: SelectNetworkUM, modifier: Modifier = Modifier) {
val hapticManager = LocalHapticManager.current
InformationBlock(
modifier = modifier,
title = {
@ -229,7 +233,15 @@ private fun NetworkSelection(state: SelectNetworkUM, modifier: Modifier = Modifi
} else {
TangemTheme.colors.icon.inactive
},
onCheckedChange = { state.onNetworkSwitchClick(network, it) },
onCheckedChange = { checked ->
if (checked) {
hapticManager.perform(TangemHapticEffect.View.ToggleOn)
} else {
hapticManager.perform(TangemHapticEffect.View.ToggleOff)
}
state.onNetworkSwitchClick(network, checked)
},
enabled = network.isEnabled,
)
},

View file

@ -143,6 +143,7 @@ internal class TokenMarketBlockModel @Inject constructor(
AppRoute.MarketsTokenDetails(
token = tokenParam,
appCurrency = currentAppCurrency.value,
showPortfolio = false,
),
)
}

View file

@ -79,6 +79,7 @@ dependencies {
implementation(projects.domain.analytics)
implementation(projects.domain.visa)
implementation(projects.domain.staking.models)
implementation(projects.domain.markets.models)
//TODO: Create api/impl modules for onboarding [REDACTED_JIRA]
implementation(projects.features.onboarding)

View file

@ -95,6 +95,11 @@ internal class MultiWalletCurrencyActionsConverter(
icon = R.drawable.ic_hide_24
action = { clickIntents.onHideTokensClick(cryptoCurrencyStatus) }
}
is TokenActionsState.ActionState.Analytics -> {
title = resourceReference(R.string.common_analytics)
icon = R.drawable.ic_analytics_24
action = { clickIntents.onAnalyticsClick(cryptoCurrencyStatus) }
}
}
return TokenActionButtonConfig(

View file

@ -20,6 +20,7 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.extenstions.unwrap
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.markets.TokenMarketParams
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.staking.model.stakekit.Yield
import com.tangem.domain.tokens.*
@ -48,6 +49,7 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.launch
import java.math.BigDecimal
import javax.inject.Inject
interface WalletCurrencyActionsClickIntents {
@ -77,6 +79,8 @@ interface WalletCurrencyActionsClickIntents {
fun onPerformHideToken(cryptoCurrencyStatus: CryptoCurrencyStatus)
fun onExploreClick()
fun onAnalyticsClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
}
@Suppress("LongParameterList", "LargeClass")
@ -378,6 +382,31 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
showErrorIfDemoModeOrElse(action = ::openExplorer)
}
override fun onAnalyticsClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
viewModelScope.launch {
val rawId = cryptoCurrencyStatus.currency.id.rawCurrencyId ?: return@launch
appRouter.push(
AppRoute.MarketsTokenDetails(
TokenMarketParams(
id = rawId,
name = cryptoCurrencyStatus.currency.name,
symbol = cryptoCurrencyStatus.currency.symbol,
tokenQuotes = TokenMarketParams.Quotes(
currentPrice = cryptoCurrencyStatus.value.fiatRate ?: BigDecimal.ZERO,
h24Percent = cryptoCurrencyStatus.value.priceChange,
weekPercent = null,
monthPercent = null,
),
imageUrl = cryptoCurrencyStatus.currency.iconUrl,
),
appCurrency = getSelectedAppCurrencyUseCase.unwrap(),
showPortfolio = true,
),
)
}
}
override fun onStakeClick(cryptoCurrencyStatus: CryptoCurrencyStatus, yield: Yield?) {
val userWallet = getSelectedWalletSyncUseCase.unwrap() ?: return
stateHolder.update(CloseBottomSheetTransformer(userWalletId = userWallet.walletId))

View file

@ -85,6 +85,7 @@ leakcanary = "2.13"
decompose = "2.2.2"
room = "2.6.1"
markdown = "0.7.2"
markdownComposeView = "0.5.4"
# endregion Other libraries
# region Tangem
@ -270,4 +271,5 @@ room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
markdown = { module = "org.jetbrains:markdown", version.ref = "markdown" }
markdown-composeview = { module = "com.github.jeziellago:compose-markdown", version.ref = "markdownComposeView" }
# endregion Other