Updated on 2026-08-14
This commit is contained in:
parent
1006477fd7
commit
2d753e14af
30 changed files with 189 additions and 55 deletions
|
|
@ -7,6 +7,7 @@ import com.tangem.domain.tokens.*
|
||||||
import com.tangem.domain.tokens.repository.*
|
import com.tangem.domain.tokens.repository.*
|
||||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
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.features.staking.api.featuretoggles.StakingFeatureToggles
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
|
@ -230,6 +231,7 @@ internal object TokensDomainModule {
|
||||||
networksRepository: NetworksRepository,
|
networksRepository: NetworksRepository,
|
||||||
stakingRepository: StakingRepository,
|
stakingRepository: StakingRepository,
|
||||||
stakingFeatureToggles: StakingFeatureToggles,
|
stakingFeatureToggles: StakingFeatureToggles,
|
||||||
|
marketsFeatureToggles: MarketsFeatureToggles,
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
): GetCryptoCurrencyActionsUseCase {
|
): GetCryptoCurrencyActionsUseCase {
|
||||||
return GetCryptoCurrencyActionsUseCase(
|
return GetCryptoCurrencyActionsUseCase(
|
||||||
|
|
@ -241,6 +243,7 @@ internal object TokensDomainModule {
|
||||||
networksRepository = networksRepository,
|
networksRepository = networksRepository,
|
||||||
stakingRepository = stakingRepository,
|
stakingRepository = stakingRepository,
|
||||||
stakingFeatureToggles = stakingFeatureToggles,
|
stakingFeatureToggles = stakingFeatureToggles,
|
||||||
|
marketsFeatureToggles = marketsFeatureToggles,
|
||||||
dispatchers = dispatchers,
|
dispatchers = dispatchers,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,7 @@ internal class ChildFactory @Inject constructor(
|
||||||
params = MarketsTokenDetailsComponent.Params(
|
params = MarketsTokenDetailsComponent.Params(
|
||||||
token = route.token,
|
token = route.token,
|
||||||
appCurrency = route.appCurrency,
|
appCurrency = route.appCurrency,
|
||||||
|
showPortfolio = route.showPortfolio,
|
||||||
),
|
),
|
||||||
componentFactory = marketsTokenDetailsComponentFactory,
|
componentFactory = marketsTokenDetailsComponentFactory,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -271,5 +271,6 @@ sealed class AppRoute(val path: String) : Route {
|
||||||
data class MarketsTokenDetails(
|
data class MarketsTokenDetails(
|
||||||
val token: TokenMarketParams,
|
val token: TokenMarketParams,
|
||||||
val appCurrency: AppCurrency,
|
val appCurrency: AppCurrency,
|
||||||
) : AppRoute(path = "/markets_token_details/${token.id}")
|
val showPortfolio: Boolean,
|
||||||
|
) : AppRoute(path = "/markets_token_details/${token.id}/$showPortfolio")
|
||||||
}
|
}
|
||||||
|
|
@ -125,6 +125,8 @@ fun MarketChart(
|
||||||
// Sometimes the chart is not drawn correctly (ex. in LazyLayout), so we need to force the redraw
|
// Sometimes the chart is not drawn correctly (ex. in LazyLayout), so we need to force the redraw
|
||||||
.drawBehind {
|
.drawBehind {
|
||||||
state.markerFraction
|
state.markerFraction
|
||||||
|
state.chartColor
|
||||||
|
state.markerHighlightRightSide
|
||||||
},
|
},
|
||||||
chart = chart,
|
chart = chart,
|
||||||
modelProducer = state.modelProducer,
|
modelProducer = state.modelProducer,
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,13 @@ import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import com.tangem.core.ui.R
|
import com.tangem.core.ui.R
|
||||||
import com.tangem.core.ui.components.buttons.PrimarySmallButton
|
import com.tangem.core.ui.components.buttons.PrimarySmallButton
|
||||||
import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
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.components.buttons.common.TangemButtonIconPosition
|
||||||
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
import com.tangem.core.ui.res.*
|
import com.tangem.core.ui.res.*
|
||||||
import com.valentinilk.shimmer.*
|
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
|
internal val TangemShimmer: Shimmer
|
||||||
@Composable
|
@Composable
|
||||||
get() = rememberShimmer(
|
get() = rememberShimmer(
|
||||||
|
|
@ -195,6 +214,7 @@ private fun ShimmersPreview() {
|
||||||
)
|
)
|
||||||
SmallButtonShimmer(withIcon = true)
|
SmallButtonShimmer(withIcon = true)
|
||||||
SmallButtonShimmer(withIcon = false)
|
SmallButtonShimmer(withIcon = false)
|
||||||
|
ChipShimmer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
core/ui/src/main/res/drawable/ic_analytics_24.xml
Normal file
18
core/ui/src/main/res/drawable/ic_analytics_24.xml
Normal 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>
|
||||||
|
|
@ -143,7 +143,6 @@ internal class DefaultQuotesRepository(
|
||||||
block = { acc.add(rawCurrencyId) },
|
block = { acc.add(rawCurrencyId) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ data class TokenMarketParams(
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Quotes(
|
data class Quotes(
|
||||||
val currentPrice: SerializedBigDecimal,
|
val currentPrice: SerializedBigDecimal,
|
||||||
val h24Percent: SerializedBigDecimal,
|
val h24Percent: SerializedBigDecimal?,
|
||||||
val weekPercent: SerializedBigDecimal?,
|
val weekPercent: SerializedBigDecimal?,
|
||||||
val monthPercent: SerializedBigDecimal?,
|
val monthPercent: SerializedBigDecimal?,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ dependencies {
|
||||||
/** Project - Api */
|
/** Project - Api */
|
||||||
implementation(projects.features.send.api)
|
implementation(projects.features.send.api)
|
||||||
implementation(projects.features.staking.api)
|
implementation(projects.features.staking.api)
|
||||||
|
implementation(projects.features.markets.api)
|
||||||
|
|
||||||
/** Project - Other */
|
/** Project - Other */
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import com.tangem.domain.tokens.repository.NetworksRepository
|
||||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
|
import com.tangem.features.markets.MarketsFeatureToggles
|
||||||
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
|
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.utils.isNullOrZero
|
import com.tangem.utils.isNullOrZero
|
||||||
|
|
@ -33,6 +34,7 @@ class GetCryptoCurrencyActionsUseCase(
|
||||||
private val networksRepository: NetworksRepository,
|
private val networksRepository: NetworksRepository,
|
||||||
private val stakingRepository: StakingRepository,
|
private val stakingRepository: StakingRepository,
|
||||||
private val stakingFeatureToggles: StakingFeatureToggles,
|
private val stakingFeatureToggles: StakingFeatureToggles,
|
||||||
|
private val marketsFeatureToggles: MarketsFeatureToggles,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
@ -112,6 +114,12 @@ class GetCryptoCurrencyActionsUseCase(
|
||||||
val activeList = mutableListOf<TokenActionsState.ActionState>()
|
val activeList = mutableListOf<TokenActionsState.ActionState>()
|
||||||
val disabledList = 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
|
// copy address
|
||||||
if (isAddressAvailable(cryptoCurrencyStatus.value.networkAddress)) {
|
if (isAddressAvailable(cryptoCurrencyStatus.value.networkAddress)) {
|
||||||
activeList.add(TokenActionsState.ActionState.CopyAddress(ScenarioUnavailabilityReason.None))
|
activeList.add(TokenActionsState.ActionState.CopyAddress(ScenarioUnavailabilityReason.None))
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ data class TokenActionsState(
|
||||||
|
|
||||||
data class Send(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState()
|
data class Send(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState()
|
||||||
|
|
||||||
|
data class Analytics(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState()
|
||||||
|
|
||||||
data class HideToken(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState()
|
data class HideToken(override val unavailabilityReason: ScenarioUnavailabilityReason) : ActionState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -53,6 +53,8 @@ import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
|
||||||
import com.tangem.core.ui.event.EventEffect
|
import com.tangem.core.ui.event.EventEffect
|
||||||
import com.tangem.core.ui.extensions.resolveReference
|
import com.tangem.core.ui.extensions.resolveReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
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.LocalSnackbarHostState
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
|
|
@ -369,6 +371,8 @@ private fun NetworksList(
|
||||||
isEditable: Boolean,
|
isEditable: Boolean,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
val hapticManager = LocalHapticManager.current
|
||||||
|
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
visible = networks is NetworksUM.Expanded,
|
visible = networks is NetworksUM.Expanded,
|
||||||
|
|
@ -403,7 +407,14 @@ private fun NetworksList(
|
||||||
if (isEditable) {
|
if (isEditable) {
|
||||||
TangemSwitch(
|
TangemSwitch(
|
||||||
checked = network.isSelected,
|
checked = network.isSelected,
|
||||||
onCheckedChange = network.onSelectedStateChange,
|
onCheckedChange = { checked ->
|
||||||
|
if (checked) {
|
||||||
|
hapticManager.perform(TangemHapticEffect.View.ToggleOn)
|
||||||
|
} else {
|
||||||
|
hapticManager.perform(TangemHapticEffect.View.ToggleOff)
|
||||||
|
}
|
||||||
|
network.onSelectedStateChange(checked)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ interface MarketsTokenDetailsComponent : ComposableContentComponent {
|
||||||
data class Params(
|
data class Params(
|
||||||
val token: TokenMarketParams,
|
val token: TokenMarketParams,
|
||||||
val appCurrency: AppCurrency,
|
val appCurrency: AppCurrency,
|
||||||
|
val showPortfolio: Boolean,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ dependencies {
|
||||||
implementation(deps.compose.ui.utils)
|
implementation(deps.compose.ui.utils)
|
||||||
implementation(deps.lifecycle.compose)
|
implementation(deps.lifecycle.compose)
|
||||||
implementation(deps.androidx.activity.compose)
|
implementation(deps.androidx.activity.compose)
|
||||||
|
implementation(deps.markdown.composeview)
|
||||||
|
|
||||||
/* DI */
|
/* DI */
|
||||||
implementation(deps.hilt.android)
|
implementation(deps.hilt.android)
|
||||||
|
|
|
||||||
|
|
@ -33,17 +33,21 @@ internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor(
|
||||||
|
|
||||||
private val model: MarketsTokenDetailsModel = getOrCreateModel(params)
|
private val model: MarketsTokenDetailsModel = getOrCreateModel(params)
|
||||||
|
|
||||||
private val portfolioComponent = portfolioComponentFactory.create(
|
private val portfolioComponent: MarketsPortfolioComponent? = if (params.showPortfolio) {
|
||||||
context = child("my_portfolio"),
|
portfolioComponentFactory.create(
|
||||||
params = MarketsPortfolioComponent.Params(params.token),
|
context = child("my_portfolio"),
|
||||||
)
|
params = MarketsPortfolioComponent.Params(params.token),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
componentScope.launch {
|
componentScope.launch {
|
||||||
model.networksState.collectLatest {
|
model.networksState.collectLatest {
|
||||||
when (it) {
|
when (it) {
|
||||||
is TokenNetworksState.NetworksAvailable -> portfolioComponent.setTokenNetworks(it.networks)
|
is TokenNetworksState.NetworksAvailable -> portfolioComponent?.setTokenNetworks(it.networks)
|
||||||
TokenNetworksState.NoNetworksAvailable -> portfolioComponent.setNoNetworksAvailable()
|
TokenNetworksState.NoNetworksAvailable -> portfolioComponent?.setNoNetworksAvailable()
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -79,10 +83,16 @@ internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor(
|
||||||
backgroundColor = LocalMainBottomSheetColor.current.value,
|
backgroundColor = LocalMainBottomSheetColor.current.value,
|
||||||
addTopBarStatusBarPadding = false,
|
addTopBarStatusBarPadding = false,
|
||||||
state = state,
|
state = state,
|
||||||
onBackClick = ::navigateBack,
|
onBackClick = {
|
||||||
|
if (bsState == BottomSheetState.EXPANDED) {
|
||||||
|
navigateBack()
|
||||||
|
}
|
||||||
|
},
|
||||||
onHeaderSizeChange = onHeaderSizeChange,
|
onHeaderSizeChange = onHeaderSizeChange,
|
||||||
portfolioBlock = { blockModifier ->
|
portfolioBlock = portfolioComponent?.let { component ->
|
||||||
portfolioComponent.Content(blockModifier)
|
{ blockModifier ->
|
||||||
|
component.Content(blockModifier)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -109,8 +119,10 @@ internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor(
|
||||||
state = state,
|
state = state,
|
||||||
onBackClick = ::navigateBack,
|
onBackClick = ::navigateBack,
|
||||||
onHeaderSizeChange = {},
|
onHeaderSizeChange = {},
|
||||||
portfolioBlock = { blockModifier ->
|
portfolioBlock = portfolioComponent?.let { component ->
|
||||||
portfolioComponent.Content(blockModifier)
|
{ blockModifier ->
|
||||||
|
component.Content(blockModifier)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import androidx.compose.runtime.Stable
|
||||||
import arrow.core.getOrElse
|
import arrow.core.getOrElse
|
||||||
import com.tangem.common.ui.charts.state.MarketChartData
|
import com.tangem.common.ui.charts.state.MarketChartData
|
||||||
import com.tangem.common.ui.charts.state.MarketChartDataProducer
|
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.common.ui.charts.state.sorted
|
||||||
import com.tangem.core.decompose.di.ComponentScoped
|
import com.tangem.core.decompose.di.ComponentScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
|
|
@ -135,15 +134,16 @@ internal class MarketsTokenDetailsModel @Inject constructor(
|
||||||
fiatCurrencySymbol = currentAppCurrency.value.symbol,
|
fiatCurrencySymbol = currentAppCurrency.value.symbol,
|
||||||
),
|
),
|
||||||
dateTimeText = resourceReference(R.string.common_today),
|
dateTimeText = resourceReference(R.string.common_today),
|
||||||
priceChangePercentText = BigDecimalFormatter.formatPercent(
|
priceChangePercentText = params.token.tokenQuotes.h24Percent?.let {
|
||||||
percent = params.token.tokenQuotes.h24Percent,
|
BigDecimalFormatter.formatPercent(
|
||||||
useAbsoluteValue = true,
|
percent = it,
|
||||||
),
|
useAbsoluteValue = true,
|
||||||
|
)
|
||||||
|
},
|
||||||
priceChangeType = params.token.tokenQuotes.h24Percent.percentChangeType(),
|
priceChangeType = params.token.tokenQuotes.h24Percent.percentChangeType(),
|
||||||
iconUrl = params.token.imageUrl,
|
iconUrl = params.token.imageUrl,
|
||||||
chartState = MarketsTokenDetailsUM.ChartState(
|
chartState = MarketsTokenDetailsUM.ChartState(
|
||||||
dataProducer = chartDataProducer,
|
dataProducer = chartDataProducer,
|
||||||
chartLook = MarketChartLook(),
|
|
||||||
onLoadRetryClick = ::onLoadRetryClicked,
|
onLoadRetryClick = ::onLoadRetryClicked,
|
||||||
status = MarketsTokenDetailsUM.ChartState.Status.LOADING,
|
status = MarketsTokenDetailsUM.ChartState.Status.LOADING,
|
||||||
onMarkerPointSelected = ::onMarkerPointSelected,
|
onMarkerPointSelected = ::onMarkerPointSelected,
|
||||||
|
|
@ -320,6 +320,7 @@ internal class MarketsTokenDetailsModel @Inject constructor(
|
||||||
currentQuotes.value = newInfo.quotes
|
currentQuotes.value = newInfo.quotes
|
||||||
|
|
||||||
val percent = newInfo.quotes.getPercentByInterval(interval = state.value.selectedInterval)
|
val percent = newInfo.quotes.getPercentByInterval(interval = state.value.selectedInterval)
|
||||||
|
|
||||||
state.update {
|
state.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
priceText = newInfo.quotes.currentPrice.formatAsPrice(currentAppCurrency.value),
|
priceText = newInfo.quotes.currentPrice.formatAsPrice(currentAppCurrency.value),
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import com.tangem.common.ui.charts.state.MarketChartDataProducer
|
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.*
|
||||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
||||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||||
|
|
@ -54,7 +53,7 @@ internal fun MarketsTokenDetailsContent(
|
||||||
addTopBarStatusBarPadding: Boolean,
|
addTopBarStatusBarPadding: Boolean,
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
onHeaderSizeChange: (Dp) -> Unit,
|
onHeaderSizeChange: (Dp) -> Unit,
|
||||||
portfolioBlock: @Composable (Modifier) -> Unit,
|
portfolioBlock: @Composable ((Modifier) -> Unit)?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
Content(
|
Content(
|
||||||
|
|
@ -78,7 +77,7 @@ private fun Content(
|
||||||
addTopBarStatusBarInsets: Boolean,
|
addTopBarStatusBarInsets: Boolean,
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
onHeaderSizeChange: (Dp) -> Unit,
|
onHeaderSizeChange: (Dp) -> Unit,
|
||||||
portfolioBlock: @Composable (Modifier) -> Unit,
|
portfolioBlock: @Composable ((Modifier) -> Unit)?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
|
|
@ -129,9 +128,7 @@ private fun Content(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
item { SpacerH32() }
|
item { SpacerH32() }
|
||||||
item(
|
item("chart") {
|
||||||
contentType = "chart",
|
|
||||||
) {
|
|
||||||
MarketTokenDetailsChart(
|
MarketTokenDetailsChart(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
|
|
@ -167,11 +164,13 @@ private fun Header(state: MarketsTokenDetailsUM, modifier: Modifier = Modifier)
|
||||||
style = TangemTheme.typography.caption2,
|
style = TangemTheme.typography.caption2,
|
||||||
color = TangemTheme.colors.text.tertiary,
|
color = TangemTheme.colors.text.tertiary,
|
||||||
)
|
)
|
||||||
PriceChangeInPercent(
|
if (state.priceChangePercentText != null) {
|
||||||
valueInPercent = state.priceChangePercentText,
|
PriceChangeInPercent(
|
||||||
type = state.priceChangeType,
|
valueInPercent = state.priceChangePercentText,
|
||||||
textStyle = TangemTheme.typography.caption2,
|
type = state.priceChangeType,
|
||||||
)
|
textStyle = TangemTheme.typography.caption2,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SpacerW4()
|
SpacerW4()
|
||||||
|
|
@ -290,7 +289,6 @@ private fun Preview() {
|
||||||
priceChangeType = PriceChangeType.UP,
|
priceChangeType = PriceChangeType.UP,
|
||||||
chartState = MarketsTokenDetailsUM.ChartState(
|
chartState = MarketsTokenDetailsUM.ChartState(
|
||||||
dataProducer = MarketChartDataProducer.build { },
|
dataProducer = MarketChartDataProducer.build { },
|
||||||
chartLook = MarketChartLook(),
|
|
||||||
onLoadRetryClick = {},
|
onLoadRetryClick = {},
|
||||||
status = MarketsTokenDetailsUM.ChartState.Status.LOADING,
|
status = MarketsTokenDetailsUM.ChartState.Status.LOADING,
|
||||||
onMarkerPointSelected = { _, _ -> },
|
onMarkerPointSelected = { _, _ -> },
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.systemBars
|
import androidx.compose.foundation.layout.systemBars
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
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.extensions.resolveReference
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.features.markets.details.impl.ui.state.InfoBottomSheetContent
|
import com.tangem.features.markets.details.impl.ui.state.InfoBottomSheetContent
|
||||||
|
import dev.jeziellago.compose.markdowntext.MarkdownText
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun InfoBottomSheet(config: TangemBottomSheetConfig) {
|
internal fun InfoBottomSheet(config: TangemBottomSheetConfig) {
|
||||||
|
|
@ -35,10 +35,14 @@ internal fun InfoBottomSheet(config: TangemBottomSheetConfig) {
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing28),
|
.padding(horizontal = TangemTheme.dimens.spacing28),
|
||||||
) {
|
) {
|
||||||
Text(
|
MarkdownText(
|
||||||
text = it.body.resolveReference(),
|
markdown = it.body.resolveReference(),
|
||||||
style = TangemTheme.typography.body2,
|
disableLinkMovementMethod = true,
|
||||||
color = TangemTheme.colors.text.secondary,
|
linkifyMask = 0,
|
||||||
|
syntaxHighlightColor = TangemTheme.colors.text.secondary,
|
||||||
|
style = TangemTheme.typography.body2.copy(
|
||||||
|
color = TangemTheme.colors.text.secondary,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
SpacerH(bottomBarHeight)
|
SpacerH(bottomBarHeight)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastForEach
|
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.TextShimmer
|
||||||
import com.tangem.core.ui.components.block.information.InformationBlock
|
import com.tangem.core.ui.components.block.information.InformationBlock
|
||||||
import com.tangem.core.ui.components.buttons.chip.Chip
|
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),
|
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||||
) {
|
) {
|
||||||
repeat(times = 3) {
|
repeat(times = 3) {
|
||||||
SmallButtonShimmer(
|
ChipShimmer(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
withIcon = true,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ internal fun PricePerformanceBlockPlaceholder(modifier: Modifier = Modifier) {
|
||||||
},
|
},
|
||||||
content = {
|
content = {
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier.padding(vertical = TangemTheme.dimens.spacing8),
|
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing8),
|
||||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import com.tangem.features.markets.tokenlist.impl.ui.components.UnableToLoadData
|
||||||
|
|
||||||
internal fun LazyListScope.tokenMarketDetailsBody(
|
internal fun LazyListScope.tokenMarketDetailsBody(
|
||||||
state: MarketsTokenDetailsUM.Body,
|
state: MarketsTokenDetailsUM.Body,
|
||||||
portfolioBlock: @Composable (Modifier) -> Unit,
|
portfolioBlock: @Composable ((Modifier) -> Unit)?,
|
||||||
) {
|
) {
|
||||||
when (state) {
|
when (state) {
|
||||||
MarketsTokenDetailsUM.Body.Loading -> {
|
MarketsTokenDetailsUM.Body.Loading -> {
|
||||||
|
|
@ -21,8 +21,10 @@ internal fun LazyListScope.tokenMarketDetailsBody(
|
||||||
DescriptionPlaceholder(modifier = Modifier.blockPaddings())
|
DescriptionPlaceholder(modifier = Modifier.blockPaddings())
|
||||||
}
|
}
|
||||||
|
|
||||||
item(key = "portfolio") {
|
if (portfolioBlock != null) {
|
||||||
portfolioBlock(Modifier.blockPaddings())
|
item(key = "portfolio") {
|
||||||
|
portfolioBlock(Modifier.blockPaddings())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingInfoBlocks()
|
loadingInfoBlocks()
|
||||||
|
|
@ -32,8 +34,10 @@ internal fun LazyListScope.tokenMarketDetailsBody(
|
||||||
description(state.description)
|
description(state.description)
|
||||||
}
|
}
|
||||||
|
|
||||||
item(key = "portfolio") {
|
if (portfolioBlock != null) {
|
||||||
portfolioBlock(Modifier.blockPaddings())
|
item(key = "portfolio") {
|
||||||
|
portfolioBlock(Modifier.blockPaddings())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
infoBlocksList(state.infoBlocks)
|
infoBlocksList(state.infoBlocks)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.tangem.features.markets.details.impl.ui.state
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.tangem.common.ui.charts.state.MarketChartDataProducer
|
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.bottomsheets.TangemBottomSheetConfig
|
||||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||||
import com.tangem.core.ui.event.StateEvent
|
import com.tangem.core.ui.event.StateEvent
|
||||||
|
|
@ -15,7 +14,7 @@ internal data class MarketsTokenDetailsUM(
|
||||||
val priceText: String,
|
val priceText: String,
|
||||||
val iconUrl: String?,
|
val iconUrl: String?,
|
||||||
val dateTimeText: TextReference,
|
val dateTimeText: TextReference,
|
||||||
val priceChangePercentText: String,
|
val priceChangePercentText: String?,
|
||||||
val priceChangeType: PriceChangeType,
|
val priceChangeType: PriceChangeType,
|
||||||
val selectedInterval: PriceChangeInterval,
|
val selectedInterval: PriceChangeInterval,
|
||||||
val markerSet: Boolean,
|
val markerSet: Boolean,
|
||||||
|
|
@ -29,7 +28,6 @@ internal data class MarketsTokenDetailsUM(
|
||||||
data class ChartState(
|
data class ChartState(
|
||||||
val status: Status,
|
val status: Status,
|
||||||
val dataProducer: MarketChartDataProducer,
|
val dataProducer: MarketChartDataProducer,
|
||||||
val chartLook: MarketChartLook,
|
|
||||||
val onLoadRetryClick: () -> Unit,
|
val onLoadRetryClick: () -> Unit,
|
||||||
val onMarkerPointSelected: (time: BigDecimal?, price: BigDecimal?) -> Unit,
|
val onMarkerPointSelected: (time: BigDecimal?, price: BigDecimal?) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ internal class DefaultMarketsEntryComponent @AssistedInject constructor(
|
||||||
params = MarketsTokenDetailsComponent.Params(
|
params = MarketsTokenDetailsComponent.Params(
|
||||||
token = token.toSerializableParam(),
|
token = token.toSerializableParam(),
|
||||||
appCurrency = appCurrency,
|
appCurrency = appCurrency,
|
||||||
|
showPortfolio = true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -182,13 +182,12 @@ internal class TokenActionsHandler @AssistedInject constructor(
|
||||||
is TokenActionsState.ActionState.HideToken -> null
|
is TokenActionsState.ActionState.HideToken -> null
|
||||||
is TokenActionsState.ActionState.Receive -> TokenActionsBSContentUM.Action.Receive
|
is TokenActionsState.ActionState.Receive -> TokenActionsBSContentUM.Action.Receive
|
||||||
is TokenActionsState.ActionState.Sell -> TokenActionsBSContentUM.Action.Sell
|
is TokenActionsState.ActionState.Sell -> TokenActionsBSContentUM.Action.Sell
|
||||||
is TokenActionsState.ActionState.Send -> {
|
is TokenActionsState.ActionState.Send -> TokenActionsBSContentUM.Action.Send.takeIf {
|
||||||
TokenActionsBSContentUM.Action.Send.takeIf {
|
cryptoCurrencyData.status.value.amount.isNullOrZero().not()
|
||||||
cryptoCurrencyData.status.value.amount.isNullOrZero().not()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
is TokenActionsState.ActionState.Stake -> TokenActionsBSContentUM.Action.Stake
|
is TokenActionsState.ActionState.Stake -> TokenActionsBSContentUM.Action.Stake
|
||||||
is TokenActionsState.ActionState.Swap -> TokenActionsBSContentUM.Action.Exchange
|
is TokenActionsState.ActionState.Swap -> TokenActionsBSContentUM.Action.Exchange
|
||||||
|
is TokenActionsState.ActionState.Analytics -> null
|
||||||
}
|
}
|
||||||
.takeIf { this.unavailabilityReason == ScenarioUnavailabilityReason.None }
|
.takeIf { this.unavailabilityReason == ScenarioUnavailabilityReason.None }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.ArrowRow
|
||||||
import com.tangem.core.ui.components.rows.BlockchainRow
|
import com.tangem.core.ui.components.rows.BlockchainRow
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
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.TangemTheme
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
import com.tangem.features.markets.impl.R
|
import com.tangem.features.markets.impl.R
|
||||||
|
|
@ -168,6 +170,8 @@ private fun ContinueButton(
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
@Composable
|
@Composable
|
||||||
private fun NetworkSelection(state: SelectNetworkUM, modifier: Modifier = Modifier) {
|
private fun NetworkSelection(state: SelectNetworkUM, modifier: Modifier = Modifier) {
|
||||||
|
val hapticManager = LocalHapticManager.current
|
||||||
|
|
||||||
InformationBlock(
|
InformationBlock(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
title = {
|
title = {
|
||||||
|
|
@ -229,7 +233,15 @@ private fun NetworkSelection(state: SelectNetworkUM, modifier: Modifier = Modifi
|
||||||
} else {
|
} else {
|
||||||
TangemTheme.colors.icon.inactive
|
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,
|
enabled = network.isEnabled,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,7 @@ internal class TokenMarketBlockModel @Inject constructor(
|
||||||
AppRoute.MarketsTokenDetails(
|
AppRoute.MarketsTokenDetails(
|
||||||
token = tokenParam,
|
token = tokenParam,
|
||||||
appCurrency = currentAppCurrency.value,
|
appCurrency = currentAppCurrency.value,
|
||||||
|
showPortfolio = false,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ dependencies {
|
||||||
implementation(projects.domain.analytics)
|
implementation(projects.domain.analytics)
|
||||||
implementation(projects.domain.visa)
|
implementation(projects.domain.visa)
|
||||||
implementation(projects.domain.staking.models)
|
implementation(projects.domain.staking.models)
|
||||||
|
implementation(projects.domain.markets.models)
|
||||||
|
|
||||||
//TODO: Create api/impl modules for onboarding [REDACTED_JIRA]
|
//TODO: Create api/impl modules for onboarding [REDACTED_JIRA]
|
||||||
implementation(projects.features.onboarding)
|
implementation(projects.features.onboarding)
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,11 @@ internal class MultiWalletCurrencyActionsConverter(
|
||||||
icon = R.drawable.ic_hide_24
|
icon = R.drawable.ic_hide_24
|
||||||
action = { clickIntents.onHideTokensClick(cryptoCurrencyStatus) }
|
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(
|
return TokenActionButtonConfig(
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||||
import com.tangem.domain.appcurrency.extenstions.unwrap
|
import com.tangem.domain.appcurrency.extenstions.unwrap
|
||||||
import com.tangem.domain.common.util.cardTypesResolver
|
import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||||
|
import com.tangem.domain.markets.TokenMarketParams
|
||||||
import com.tangem.domain.redux.ReduxStateHolder
|
import com.tangem.domain.redux.ReduxStateHolder
|
||||||
import com.tangem.domain.staking.model.stakekit.Yield
|
import com.tangem.domain.staking.model.stakekit.Yield
|
||||||
import com.tangem.domain.tokens.*
|
import com.tangem.domain.tokens.*
|
||||||
|
|
@ -48,6 +49,7 @@ import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.take
|
import kotlinx.coroutines.flow.take
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import java.math.BigDecimal
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
interface WalletCurrencyActionsClickIntents {
|
interface WalletCurrencyActionsClickIntents {
|
||||||
|
|
@ -77,6 +79,8 @@ interface WalletCurrencyActionsClickIntents {
|
||||||
fun onPerformHideToken(cryptoCurrencyStatus: CryptoCurrencyStatus)
|
fun onPerformHideToken(cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||||
|
|
||||||
fun onExploreClick()
|
fun onExploreClick()
|
||||||
|
|
||||||
|
fun onAnalyticsClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongParameterList", "LargeClass")
|
@Suppress("LongParameterList", "LargeClass")
|
||||||
|
|
@ -378,6 +382,31 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
||||||
showErrorIfDemoModeOrElse(action = ::openExplorer)
|
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?) {
|
override fun onStakeClick(cryptoCurrencyStatus: CryptoCurrencyStatus, yield: Yield?) {
|
||||||
val userWallet = getSelectedWalletSyncUseCase.unwrap() ?: return
|
val userWallet = getSelectedWalletSyncUseCase.unwrap() ?: return
|
||||||
stateHolder.update(CloseBottomSheetTransformer(userWalletId = userWallet.walletId))
|
stateHolder.update(CloseBottomSheetTransformer(userWalletId = userWallet.walletId))
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ leakcanary = "2.13"
|
||||||
decompose = "2.2.2"
|
decompose = "2.2.2"
|
||||||
room = "2.6.1"
|
room = "2.6.1"
|
||||||
markdown = "0.7.2"
|
markdown = "0.7.2"
|
||||||
|
markdownComposeView = "0.5.4"
|
||||||
# endregion Other libraries
|
# endregion Other libraries
|
||||||
|
|
||||||
# region Tangem
|
# 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-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
|
||||||
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
|
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
|
||||||
markdown = { module = "org.jetbrains:markdown", version.ref = "markdown" }
|
markdown = { module = "org.jetbrains:markdown", version.ref = "markdown" }
|
||||||
|
markdown-composeview = { module = "com.github.jeziellago:compose-markdown", version.ref = "markdownComposeView" }
|
||||||
# endregion Other
|
# endregion Other
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue