Updated on 2026-08-14
This commit is contained in:
parent
e3b1480e32
commit
ad4e7e78e9
7 changed files with 96 additions and 24 deletions
|
|
@ -3,10 +3,10 @@ package com.tangem.tap.routing.utils
|
||||||
import com.tangem.common.routing.AppRoute
|
import com.tangem.common.routing.AppRoute
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.domain.qrscanning.models.SourceType
|
import com.tangem.domain.qrscanning.models.SourceType
|
||||||
import com.tangem.feature.usedesk.api.UsedeskComponent
|
|
||||||
import com.tangem.feature.qrscanning.QrScanningComponent
|
import com.tangem.feature.qrscanning.QrScanningComponent
|
||||||
import com.tangem.feature.referral.api.ReferralComponent
|
import com.tangem.feature.referral.api.ReferralComponent
|
||||||
import com.tangem.feature.stories.api.StoriesComponent
|
import com.tangem.feature.stories.api.StoriesComponent
|
||||||
|
import com.tangem.feature.usedesk.api.UsedeskComponent
|
||||||
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
|
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
|
||||||
import com.tangem.features.details.component.DetailsComponent
|
import com.tangem.features.details.component.DetailsComponent
|
||||||
import com.tangem.features.disclaimer.api.components.DisclaimerComponent
|
import com.tangem.features.disclaimer.api.components.DisclaimerComponent
|
||||||
|
|
@ -49,7 +49,7 @@ internal class ChildFactory @Inject constructor(
|
||||||
private val disclaimerComponentFactory: DisclaimerComponent.Factory,
|
private val disclaimerComponentFactory: DisclaimerComponent.Factory,
|
||||||
private val manageTokensComponentFactory: ManageTokensComponent.Factory,
|
private val manageTokensComponentFactory: ManageTokensComponent.Factory,
|
||||||
private val marketsTokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
|
private val marketsTokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
|
||||||
private val marketsTokenListComponentFactory: MarketsTokenListComponent.Factory,
|
private val marketsTokenListComponentFactory: MarketsTokenListComponent.FactoryScreen,
|
||||||
private val onrampComponentFactory: OnrampComponent.Factory,
|
private val onrampComponentFactory: OnrampComponent.Factory,
|
||||||
private val onrampSuccessComponentFactory: OnrampSuccessComponent.Factory,
|
private val onrampSuccessComponentFactory: OnrampSuccessComponent.Factory,
|
||||||
private val buyCryptoComponentFactory: BuyCryptoComponent.Factory,
|
private val buyCryptoComponentFactory: BuyCryptoComponent.Factory,
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,11 @@ import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.decompose.factory.ComponentFactory
|
import com.tangem.core.decompose.factory.ComponentFactory
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
|
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
|
import com.tangem.domain.markets.TokenMarketParams
|
||||||
import com.tangem.features.markets.entry.BottomSheetState
|
import com.tangem.features.markets.entry.BottomSheetState
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
|
|
@ -19,5 +22,13 @@ interface MarketsTokenListComponent : ComposableContentComponent {
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
)
|
)
|
||||||
|
|
||||||
interface Factory : ComponentFactory<Unit, MarketsTokenListComponent>
|
interface FactoryScreen : ComponentFactory<Unit, MarketsTokenListComponent>
|
||||||
|
|
||||||
|
interface FactoryBottomSheet {
|
||||||
|
fun create(
|
||||||
|
context: AppComponentContext,
|
||||||
|
params: Unit,
|
||||||
|
onTokenClick: ((TokenMarketParams, AppCurrency) -> Unit)?,
|
||||||
|
): MarketsTokenListComponent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import com.arkivanov.decompose.ExperimentalDecomposeApi
|
||||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||||
import com.arkivanov.decompose.router.stack.ChildStack
|
import com.arkivanov.decompose.router.stack.ChildStack
|
||||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||||
|
|
@ -14,6 +15,9 @@ import com.arkivanov.decompose.value.Value
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.decompose.context.childByContext
|
import com.tangem.core.decompose.context.childByContext
|
||||||
import com.tangem.core.decompose.navigation.inner.InnerRouter
|
import com.tangem.core.decompose.navigation.inner.InnerRouter
|
||||||
|
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
|
import com.tangem.domain.markets.TokenMarketParams
|
||||||
|
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
|
||||||
import com.tangem.features.markets.entry.BottomSheetState
|
import com.tangem.features.markets.entry.BottomSheetState
|
||||||
import com.tangem.features.markets.entry.MarketsEntryComponent
|
import com.tangem.features.markets.entry.MarketsEntryComponent
|
||||||
import com.tangem.features.markets.entry.impl.MarketsEntryChildFactory.Child
|
import com.tangem.features.markets.entry.impl.MarketsEntryChildFactory.Child
|
||||||
|
|
@ -48,6 +52,7 @@ internal class DefaultMarketsEntryComponent @AssistedInject constructor(
|
||||||
componentContext = factoryContext,
|
componentContext = factoryContext,
|
||||||
router = innerRouter,
|
router = innerRouter,
|
||||||
),
|
),
|
||||||
|
onTokenClick = ::marketsListTokenSelected,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -67,6 +72,23 @@ internal class DefaultMarketsEntryComponent @AssistedInject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalDecomposeApi::class)
|
||||||
|
private fun marketsListTokenSelected(token: TokenMarketParams, appCurrency: AppCurrency) {
|
||||||
|
innerRouter.push(
|
||||||
|
route = Child.TokenDetails(
|
||||||
|
params = MarketsTokenDetailsComponent.Params(
|
||||||
|
token = token,
|
||||||
|
appCurrency = appCurrency,
|
||||||
|
showPortfolio = true,
|
||||||
|
analyticsParams = MarketsTokenDetailsComponent.AnalyticsParams(
|
||||||
|
blockchain = null,
|
||||||
|
source = "Market",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun onChildBack() {
|
private fun onChildBack() {
|
||||||
if (stack.value.active.configuration !is Child.TokenList) {
|
if (stack.value.active.configuration !is Child.TokenList) {
|
||||||
stackNavigation.popWhile { it != Child.TokenList }
|
stackNavigation.popWhile { it != Child.TokenList }
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,15 @@ package com.tangem.features.markets.entry.impl
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.decompose.navigation.Route
|
import com.tangem.core.decompose.navigation.Route
|
||||||
|
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
|
import com.tangem.domain.markets.TokenMarketParams
|
||||||
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
|
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
|
||||||
import com.tangem.features.markets.tokenlist.MarketsTokenListComponent
|
import com.tangem.features.markets.tokenlist.MarketsTokenListComponent
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class MarketsEntryChildFactory @Inject constructor(
|
internal class MarketsEntryChildFactory @Inject constructor(
|
||||||
private val tokenListComponentFactory: MarketsTokenListComponent.Factory,
|
private val tokenListComponentFactory: MarketsTokenListComponent.FactoryBottomSheet,
|
||||||
private val tokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
|
private val tokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
@ -26,7 +28,11 @@ internal class MarketsEntryChildFactory @Inject constructor(
|
||||||
data class TokenDetails(val params: MarketsTokenDetailsComponent.Params) : Child
|
data class TokenDetails(val params: MarketsTokenDetailsComponent.Params) : Child
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createChild(child: Child, appComponentContext: AppComponentContext): Any {
|
fun createChild(
|
||||||
|
child: Child,
|
||||||
|
appComponentContext: AppComponentContext,
|
||||||
|
onTokenClick: (TokenMarketParams, AppCurrency) -> Unit,
|
||||||
|
): Any {
|
||||||
return when (child) {
|
return when (child) {
|
||||||
is Child.TokenDetails -> {
|
is Child.TokenDetails -> {
|
||||||
tokenDetailsComponentFactory.create(
|
tokenDetailsComponentFactory.create(
|
||||||
|
|
@ -38,6 +44,7 @@ internal class MarketsEntryChildFactory @Inject constructor(
|
||||||
tokenListComponentFactory.create(
|
tokenListComponentFactory.create(
|
||||||
context = appComponentContext,
|
context = appComponentContext,
|
||||||
params = Unit,
|
params = Unit,
|
||||||
|
onTokenClick = onTokenClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ internal fun EntryBottomSheetContent(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
MarketsEntryChildFactory.Child.TokenList -> {
|
is MarketsEntryChildFactory.Child.TokenList -> {
|
||||||
(it.instance as MarketsTokenListComponent).BottomSheetContent(
|
(it.instance as MarketsTokenListComponent).BottomSheetContent(
|
||||||
bottomSheetState = bottomSheetState,
|
bottomSheetState = bottomSheetState,
|
||||||
onHeaderSizeChange = onHeaderSizeChange,
|
onHeaderSizeChange = onHeaderSizeChange,
|
||||||
|
|
@ -84,7 +84,7 @@ private fun BackgroundColorEffects(
|
||||||
animationSpec = tween(durationMillis = 500),
|
animationSpec = tween(durationMillis = 500),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
MarketsEntryChildFactory.Child.TokenList -> {
|
is MarketsEntryChildFactory.Child.TokenList -> {
|
||||||
backgroundColor.animateTo(
|
backgroundColor.animateTo(
|
||||||
primary,
|
primary,
|
||||||
animationSpec = tween(durationMillis = 500),
|
animationSpec = tween(durationMillis = 500),
|
||||||
|
|
@ -119,7 +119,7 @@ private fun BackgroundColorEffects(
|
||||||
is MarketsEntryChildFactory.Child.TokenDetails -> {
|
is MarketsEntryChildFactory.Child.TokenDetails -> {
|
||||||
backgroundColor.snapTo(tertiary)
|
backgroundColor.snapTo(tertiary)
|
||||||
}
|
}
|
||||||
MarketsEntryChildFactory.Child.TokenList -> {
|
is MarketsEntryChildFactory.Child.TokenList -> {
|
||||||
backgroundColor.snapTo(primary)
|
backgroundColor.snapTo(primary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.decompose.model.getOrCreateModel
|
import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.utils.WindowInsetsZero
|
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||||
|
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
|
import com.tangem.domain.markets.TokenMarketParams
|
||||||
import com.tangem.domain.markets.toSerializableParam
|
import com.tangem.domain.markets.toSerializableParam
|
||||||
import com.tangem.features.markets.entry.BottomSheetState
|
import com.tangem.features.markets.entry.BottomSheetState
|
||||||
import com.tangem.features.markets.tokenlist.MarketsTokenListComponent
|
import com.tangem.features.markets.tokenlist.MarketsTokenListComponent
|
||||||
|
|
@ -31,9 +33,10 @@ import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
|
||||||
@Suppress("UnusedPrivateMember")
|
@Suppress("UnusedPrivateMember")
|
||||||
class DefaultMarketsTokenListComponent @AssistedInject constructor(
|
internal class DefaultMarketsTokenListComponent @AssistedInject constructor(
|
||||||
@Assisted appComponentContext: AppComponentContext,
|
@Assisted appComponentContext: AppComponentContext,
|
||||||
@Assisted params: Unit,
|
@Assisted params: Unit,
|
||||||
|
@Assisted onTokenClick: ((TokenMarketParams, AppCurrency) -> Unit)? = null,
|
||||||
) : AppComponentContext by appComponentContext, MarketsTokenListComponent {
|
) : AppComponentContext by appComponentContext, MarketsTokenListComponent {
|
||||||
|
|
||||||
private val model: MarketsListModel = getOrCreateModel()
|
private val model: MarketsListModel = getOrCreateModel()
|
||||||
|
|
@ -41,17 +44,23 @@ class DefaultMarketsTokenListComponent @AssistedInject constructor(
|
||||||
init {
|
init {
|
||||||
model.tokenSelected
|
model.tokenSelected
|
||||||
.onEach { (token, appCurrency) ->
|
.onEach { (token, appCurrency) ->
|
||||||
router.push(
|
// If specific routing call back is provided, invoke it (for example inner routing in Bottom Sheet)
|
||||||
AppRoute.MarketsTokenDetails(
|
// Otherwise navigate using app routing
|
||||||
token = token.toSerializableParam(),
|
if (onTokenClick != null) {
|
||||||
appCurrency = appCurrency,
|
onTokenClick(token.toSerializableParam(), appCurrency)
|
||||||
showPortfolio = true,
|
} else {
|
||||||
analyticsParams = AnalyticsParams(
|
router.push(
|
||||||
blockchain = null,
|
AppRoute.MarketsTokenDetails(
|
||||||
source = "Market",
|
token = token.toSerializableParam(),
|
||||||
|
appCurrency = appCurrency,
|
||||||
|
showPortfolio = true,
|
||||||
|
analyticsParams = AnalyticsParams(
|
||||||
|
blockchain = null,
|
||||||
|
source = "Market",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
.launchIn(componentScope)
|
.launchIn(componentScope)
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +121,11 @@ class DefaultMarketsTokenListComponent @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory : MarketsTokenListComponent.Factory {
|
interface FactoryBottomSheet : MarketsTokenListComponent.FactoryBottomSheet {
|
||||||
override fun create(context: AppComponentContext, params: Unit): DefaultMarketsTokenListComponent
|
override fun create(
|
||||||
|
context: AppComponentContext,
|
||||||
|
params: Unit,
|
||||||
|
onTokenClick: ((TokenMarketParams, AppCurrency) -> Unit)?,
|
||||||
|
): DefaultMarketsTokenListComponent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
package com.tangem.features.markets.tokenlist.impl.di
|
package com.tangem.features.markets.tokenlist.impl.di
|
||||||
|
|
||||||
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.features.markets.tokenlist.MarketsTokenListComponent
|
import com.tangem.features.markets.tokenlist.MarketsTokenListComponent
|
||||||
import com.tangem.features.markets.tokenlist.impl.DefaultMarketsTokenListComponent
|
import com.tangem.features.markets.tokenlist.impl.DefaultMarketsTokenListComponent
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
@ -14,7 +16,24 @@ internal interface ComponentModule {
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@Singleton
|
@Singleton
|
||||||
fun bindMarketsTokenListComponent(
|
fun bindMarketsTokenListBottomSheetComponent(
|
||||||
factory: DefaultMarketsTokenListComponent.Factory,
|
factory: DefaultMarketsTokenListComponent.FactoryBottomSheet,
|
||||||
): MarketsTokenListComponent.Factory
|
): MarketsTokenListComponent.FactoryBottomSheet
|
||||||
|
}
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal class ComponentProvideModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun providesMarketsTokenListScreenComponent(
|
||||||
|
factory: DefaultMarketsTokenListComponent.FactoryBottomSheet,
|
||||||
|
): MarketsTokenListComponent.FactoryScreen {
|
||||||
|
return object : MarketsTokenListComponent.FactoryScreen {
|
||||||
|
override fun create(context: AppComponentContext, params: Unit): MarketsTokenListComponent {
|
||||||
|
return factory.create(context, params, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue