Updated on 2026-08-14
This commit is contained in:
parent
2c29708284
commit
e6416ab4c6
8 changed files with 91 additions and 10 deletions
|
|
@ -6,24 +6,47 @@ import androidx.compose.ui.unit.Dp
|
|||
import androidx.lifecycle.compose.LifecycleStartEffect
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.features.markets.component.BottomSheetState
|
||||
import com.tangem.features.markets.details.api.MarketsTokenDetailsComponent
|
||||
import com.tangem.features.markets.details.impl.model.MarketsTokenDetailsModel
|
||||
import com.tangem.features.markets.details.impl.model.state.TokenNetworksState
|
||||
import com.tangem.features.markets.details.impl.ui.MarketsTokenDetailsContent
|
||||
import com.tangem.features.markets.portfolio.api.MarketsPortfolioComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Stable
|
||||
internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted params: MarketsTokenDetailsComponent.Params,
|
||||
@Assisted private val onBack: () -> Unit,
|
||||
portfolioComponentFactory: MarketsPortfolioComponent.Factory,
|
||||
) : AppComponentContext by appComponentContext, MarketsTokenDetailsComponent {
|
||||
|
||||
private val model: MarketsTokenDetailsModel = getOrCreateModel(params)
|
||||
|
||||
private val portfolioComponent = portfolioComponentFactory.create(
|
||||
context = child("my_portfolio"),
|
||||
params = MarketsPortfolioComponent.Params(params.token.id),
|
||||
)
|
||||
|
||||
init {
|
||||
componentScope.launch {
|
||||
model.networksState.collectLatest {
|
||||
when (it) {
|
||||
is TokenNetworksState.NetworksAvailable -> portfolioComponent.setTokenNetworks(it.networks)
|
||||
TokenNetworksState.NoNetworksAvailable -> portfolioComponent.setNoNetworksAvailable()
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun BottomSheetContent(
|
||||
bottomSheetState: State<BottomSheetState>,
|
||||
|
|
@ -48,6 +71,9 @@ internal class DefaultMarketsTokenDetailsComponent @AssistedInject constructor(
|
|||
state = state,
|
||||
onBackClick = onBack,
|
||||
onHeaderSizeChange = onHeaderSizeChange,
|
||||
portfolioBlock = { modifier ->
|
||||
portfolioComponent.Content(modifier)
|
||||
},
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ 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
|
||||
|
|
@ -119,6 +120,7 @@ internal class MarketsTokenDetailsModel @Inject constructor(
|
|||
|
||||
val containerBottomSheetState = MutableStateFlow(BottomSheetState.COLLAPSED)
|
||||
val isVisibleOnScreen = MutableStateFlow(false)
|
||||
val networksState = MutableStateFlow<TokenNetworksState>(TokenNetworksState.Loading)
|
||||
|
||||
val state = MutableStateFlow(
|
||||
MarketsTokenDetailsUM(
|
||||
|
|
@ -294,6 +296,14 @@ internal class MarketsTokenDetailsModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
val networks = result.networks
|
||||
|
||||
networksState.value = if (networks.isNullOrEmpty()) {
|
||||
TokenNetworksState.NoNetworksAvailable
|
||||
} else {
|
||||
TokenNetworksState.NetworksAvailable(networks)
|
||||
}
|
||||
|
||||
chartDataProducer.runTransaction {
|
||||
updateLook {
|
||||
it.copy(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.features.markets.details.impl.model.state
|
||||
|
||||
import com.tangem.domain.markets.TokenMarketInfo
|
||||
|
||||
internal sealed class TokenNetworksState {
|
||||
|
||||
data object Loading : TokenNetworksState()
|
||||
|
||||
data object NoNetworksAvailable : TokenNetworksState()
|
||||
|
||||
data class NetworksAvailable(val networks: List<TokenMarketInfo.Network>) : TokenNetworksState()
|
||||
}
|
||||
|
|
@ -51,6 +51,7 @@ internal fun MarketsTokenDetailsContent(
|
|||
state: MarketsTokenDetailsUM,
|
||||
onBackClick: () -> Unit,
|
||||
onHeaderSizeChange: (Dp) -> Unit,
|
||||
portfolioBlock: @Composable (Modifier) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Content(
|
||||
|
|
@ -58,6 +59,7 @@ internal fun MarketsTokenDetailsContent(
|
|||
state = state,
|
||||
onBackClick = onBackClick,
|
||||
onHeaderSizeChange = onHeaderSizeChange,
|
||||
portfolioBlock = portfolioBlock,
|
||||
)
|
||||
|
||||
InfoBottomSheet(config = state.infoBottomSheet)
|
||||
|
|
@ -69,6 +71,7 @@ private fun Content(
|
|||
state: MarketsTokenDetailsUM,
|
||||
onBackClick: () -> Unit,
|
||||
onHeaderSizeChange: (Dp) -> Unit,
|
||||
portfolioBlock: @Composable (Modifier) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val backgroundColor = LocalMainBottomSheetColor.current.value
|
||||
|
|
@ -129,6 +132,7 @@ private fun Content(
|
|||
|
||||
tokenMarketDetailsBody(
|
||||
state = state.body,
|
||||
portfolioBlock = portfolioBlock,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -288,6 +292,7 @@ private fun Preview() {
|
|||
),
|
||||
onHeaderSizeChange = {},
|
||||
onBackClick = {},
|
||||
portfolioBlock = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -11,16 +11,31 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
import com.tangem.features.markets.details.impl.ui.state.MarketsTokenDetailsUM
|
||||
import com.tangem.features.markets.tokenlist.impl.ui.components.UnableToLoadData
|
||||
|
||||
internal fun LazyListScope.tokenMarketDetailsBody(state: MarketsTokenDetailsUM.Body) {
|
||||
internal fun LazyListScope.tokenMarketDetailsBody(
|
||||
state: MarketsTokenDetailsUM.Body,
|
||||
portfolioBlock: @Composable (Modifier) -> Unit,
|
||||
) {
|
||||
when (state) {
|
||||
MarketsTokenDetailsUM.Body.Loading -> {
|
||||
loading()
|
||||
item("description-loading") {
|
||||
DescriptionPlaceholder(modifier = Modifier.blockPaddings())
|
||||
}
|
||||
|
||||
item(key = "portfolio") {
|
||||
portfolioBlock(Modifier.blockPaddings())
|
||||
}
|
||||
|
||||
loadingInfoBlocks()
|
||||
}
|
||||
is MarketsTokenDetailsUM.Body.Content -> {
|
||||
if (state.description != null) {
|
||||
description(state.description)
|
||||
}
|
||||
|
||||
item(key = "portfolio") {
|
||||
portfolioBlock(Modifier.blockPaddings())
|
||||
}
|
||||
|
||||
infoBlocksList(state.infoBlocks)
|
||||
}
|
||||
is MarketsTokenDetailsUM.Body.Error -> {
|
||||
|
|
@ -106,11 +121,7 @@ internal fun LazyListScope.infoBlocksList(state: MarketsTokenDetailsUM.Informati
|
|||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.loading() {
|
||||
item("description-loading") {
|
||||
DescriptionPlaceholder(modifier = Modifier.blockPaddings())
|
||||
}
|
||||
|
||||
private fun LazyListScope.loadingInfoBlocks() {
|
||||
item("insights-loading") {
|
||||
InsightsBlockPlaceholder(modifier = Modifier.blockPaddings())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,18 @@ package com.tangem.features.markets.portfolio.api
|
|||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.markets.TokenMarketInfo
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Stable
|
||||
interface MarketsPortfolioComponent : ComposableContentComponent {
|
||||
|
||||
@Serializable
|
||||
data class Params(
|
||||
val tokenId: String,
|
||||
)
|
||||
data class Params(val tokenId: String)
|
||||
|
||||
fun setTokenNetworks(networks: List<TokenMarketInfo.Network>)
|
||||
|
||||
fun setNoNetworksAvailable()
|
||||
|
||||
interface Factory : ComponentFactory<Params, MarketsPortfolioComponent>
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import androidx.compose.runtime.Stable
|
|||
import androidx.compose.ui.Modifier
|
||||
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
|
||||
|
|
@ -21,6 +22,9 @@ internal class DefaultMarketsPortfolioComponent @AssistedInject constructor(
|
|||
|
||||
private val model: MarketsPortfolioModel = getOrCreateModel(params)
|
||||
|
||||
override fun setTokenNetworks(networks: List<TokenMarketInfo.Network>) = model.setTokenNetworks(networks)
|
||||
override fun setNoNetworksAvailable() = model.setNoNetworksAvailable()
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
MyPortfolio(
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import androidx.compose.runtime.Stable
|
|||
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.markets.TokenMarketInfo
|
||||
import com.tangem.features.markets.portfolio.api.MarketsPortfolioComponent
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import javax.inject.Inject
|
||||
|
|
@ -17,4 +18,13 @@ internal class MarketsPortfolioModel @Inject constructor(
|
|||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
private val params = paramsContainer.require<MarketsPortfolioComponent.Params>()
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
fun setTokenNetworks(networks: List<TokenMarketInfo.Network>) {
|
||||
// TODO [REDACTED_TASK_KEY]
|
||||
}
|
||||
|
||||
fun setNoNetworksAvailable() {
|
||||
// TODO [REDACTED_TASK_KEY]
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue