Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-12 14:42:17 +05:00
parent c6cdb300e6
commit f011cba752
23 changed files with 505 additions and 28 deletions

View file

@ -41,4 +41,10 @@ internal object OnrampDomainModule {
fun provideOnrampSaveDefaultCountryUseCase(onrampRepository: OnrampRepository): OnrampSaveDefaultCountryUseCase {
return OnrampSaveDefaultCountryUseCase(onrampRepository)
}
@Provides
@Singleton
fun provideCheckOnrampAvailabilityUseCase(onrampRepository: OnrampRepository): CheckOnrampAvailabilityUseCase {
return CheckOnrampAvailabilityUseCase(onrampRepository)
}
}

View file

@ -55,11 +55,15 @@ object TradeCryptoMiddleware {
private fun proceedBuyAction(state: () -> AppState?, action: TradeCryptoAction.Buy) {
val isOnrampEnabled = store.inject(DaggerGraphState::onrampFeatureToggles).isFeatureEnabled
if (isOnrampEnabled) proceedWithOnramp() else proceedWithLegacyBuyAction(state, action)
if (isOnrampEnabled) {
proceedWithOnramp(action.cryptoCurrencyStatus.currency)
} else {
proceedWithLegacyBuyAction(state, action)
}
}
private fun proceedWithOnramp() {
store.dispatchNavigationAction { push(AppRoute.Onramp) }
private fun proceedWithOnramp(cryptoCurrency: CryptoCurrency) {
store.dispatchNavigationAction { push(AppRoute.Onramp(cryptoCurrency)) }
}
private fun proceedWithLegacyBuyAction(state: () -> AppState?, action: TradeCryptoAction.Buy) {

View file

@ -199,7 +199,7 @@ internal class ChildFactory @Inject constructor(
is AppRoute.Onramp -> {
route.asComponentChild(
contextProvider = contextProvider(route, contextFactory),
params = OnrampComponent.Params(),
params = OnrampComponent.Params(route.currency.name),
componentFactory = onrampComponentFactory,
)
}

View file

@ -295,7 +295,9 @@ sealed class AppRoute(val path: String) : Route {
}
@Serializable
data object Onramp : AppRoute(path = "/onramp")
data class Onramp(val currency: CryptoCurrency) : AppRoute(path = "/onramp/${currency.symbol}"), RouteBundleParams {
override fun getBundle(): Bundle = bundle(serializer())
}
@Serializable
data class BuyCrypto(

View file

@ -0,0 +1,8 @@
package com.tangem.domain.onramp.model
sealed interface OnrampAvailability {
data object Available : OnrampAvailability
data class NotSupported(val country: OnrampCountry) : OnrampAvailability
data class ConfirmResidency(val country: OnrampCountry) : OnrampAvailability
}

View file

@ -1,5 +1,8 @@
package com.tangem.domain.onramp.model
import kotlinx.serialization.Serializable
@Serializable
data class OnrampCountry(
val id: String,
val name: String,

View file

@ -1,5 +1,8 @@
package com.tangem.domain.onramp.model
import kotlinx.serialization.Serializable
@Serializable
data class OnrampCurrency(
val name: String,
val code: String,

View file

@ -0,0 +1,24 @@
package com.tangem.domain.onramp
import arrow.core.Either
import com.tangem.domain.onramp.model.OnrampAvailability
import com.tangem.domain.onramp.repositories.OnrampRepository
class CheckOnrampAvailabilityUseCase(private val repository: OnrampRepository) {
suspend operator fun invoke(): Either<Throwable, OnrampAvailability> {
return Either.catch {
return@catch OnrampAvailability.Available
repository.getDefaultCountrySync()?.let { savedCountry ->
return@catch if (savedCountry.onrampAvailable) {
OnrampAvailability.Available
} else {
OnrampAvailability.NotSupported(savedCountry)
}
}
val detectedCountry = repository.getCountryByIp()
OnrampAvailability.ConfirmResidency(detectedCountry)
}
}
}

View file

@ -5,7 +5,7 @@ import com.tangem.core.ui.decompose.ComposableContentComponent
interface OnrampComponent : ComposableContentComponent {
class Params
data class Params(val currency: String)
interface Factory : ComponentFactory<Params, OnrampComponent>
}

View file

@ -2,15 +2,11 @@ package com.tangem.features.onramp.confirmresidency
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.domain.onramp.model.OnrampCountry
internal interface ConfirmResidencyComponent : ComposableBottomSheetComponent {
data class Params(
val countryName: String,
val isOnrampSupported: Boolean,
val countryFlagUrl: String,
val onDismiss: () -> Unit,
)
data class Params(val country: OnrampCountry, val onDismiss: (OnrampCountry) -> Unit)
interface Factory : ComponentFactory<Params, ConfirmResidencyComponent>
}

View file

@ -38,7 +38,7 @@ internal class DefaultConfirmResidencyComponent @AssistedInject constructor(
)
override fun dismiss() {
params.onDismiss()
router.pop()
}
@Composable

View file

@ -5,18 +5,24 @@ import com.arkivanov.decompose.router.slot.activate
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.onramp.GetOnrampCountryUseCase
import com.tangem.features.onramp.confirmresidency.ConfirmResidencyComponent
import com.tangem.features.onramp.confirmresidency.entity.ConfirmResidencyUM
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.entity.ConfirmResidencyBottomSheetConfig
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
@ComponentScoped
internal class ConfirmResidencyModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val router: Router,
getOnrampCountryUseCase: GetOnrampCountryUseCase,
paramsContainer: ParamsContainer,
) : Model() {
@ -24,9 +30,9 @@ internal class ConfirmResidencyModel @Inject constructor(
val bottomSheetNavigation: SlotNavigation<ConfirmResidencyBottomSheetConfig> = SlotNavigation()
val state: MutableStateFlow<ConfirmResidencyUM> = MutableStateFlow(
ConfirmResidencyUM(
country = params.countryName,
countryFlagUrl = params.countryFlagUrl,
isCountrySupported = params.isOnrampSupported,
country = params.country.name,
countryFlagUrl = params.country.image,
isCountrySupported = params.country.onrampAvailable,
primaryButtonConfig = getPrimaryButtonConfig(),
secondaryButtonConfig = ConfirmResidencyUM.ActionButtonConfig(
onClick = ::onChangeClick,
@ -35,22 +41,29 @@ internal class ConfirmResidencyModel @Inject constructor(
),
)
private fun getPrimaryButtonConfig() = if (params.isOnrampSupported) {
init {
getOnrampCountryUseCase.invoke()
.onEach { maybeCountry ->
val country = maybeCountry.getOrNull()
if (country != null) {
params.onDismiss(country)
}
}
.launchIn(modelScope)
}
private fun getPrimaryButtonConfig() = if (params.country.onrampAvailable) {
ConfirmResidencyUM.ActionButtonConfig(
onClick = params.onDismiss,
onClick = { params.onDismiss(params.country) },
text = resourceReference(R.string.common_confirm),
)
} else {
ConfirmResidencyUM.ActionButtonConfig(
onClick = ::onCloseClick,
onClick = router::pop,
text = resourceReference(R.string.common_close),
)
}
@Suppress("EmptyFunctionBlock")
private fun onCloseClick() {
}
private fun onChangeClick() {
bottomSheetNavigation.activate(ConfirmResidencyBottomSheetConfig.SelectCountry)
}

View file

@ -0,0 +1,66 @@
package com.tangem.features.onramp.main
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.features.onramp.confirmresidency.ConfirmResidencyComponent
import com.tangem.features.onramp.main.entity.OnrampMainBottomSheetConfig
import com.tangem.features.onramp.main.model.OnrampMainComponentModel
import com.tangem.features.onramp.main.ui.OnrampMainComponentContent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class DefaultOnrampMainComponent @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted params: OnrampMainComponent.Params,
private val confirmResidencyComponentFactory: ConfirmResidencyComponent.Factory,
) : OnrampMainComponent, AppComponentContext by appComponentContext {
private val model: OnrampMainComponentModel = getOrCreateModel(params)
private val bottomSheetSlot = childSlot(
source = model.bottomSheetNavigation,
serializer = null,
handleBackButton = false,
childFactory = ::bottomSheetChild,
)
@Composable
override fun Content(modifier: Modifier) {
val state by model.state.collectAsState()
val bottomSheet by bottomSheetSlot.subscribeAsState()
OnrampMainComponentContent(modifier = modifier, state = state)
bottomSheet.child?.instance?.BottomSheet()
}
private fun bottomSheetChild(
config: OnrampMainBottomSheetConfig,
componentContext: ComponentContext,
): ComposableBottomSheetComponent = when (config) {
is OnrampMainBottomSheetConfig.ConfirmResidency -> confirmResidencyComponentFactory.create(
context = childByContext(componentContext),
params = ConfirmResidencyComponent.Params(
country = config.country,
onDismiss = { model.bottomSheetNavigation.dismiss() },
),
)
}
@AssistedFactory
interface Factory : OnrampMainComponent.Factory {
override fun create(
context: AppComponentContext,
params: OnrampMainComponent.Params,
): DefaultOnrampMainComponent
}
}

View file

@ -0,0 +1,11 @@
package com.tangem.features.onramp.main
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
internal interface OnrampMainComponent : ComposableContentComponent {
class Params(val currency: String, val openSettings: () -> Unit)
interface Factory : ComponentFactory<Params, OnrampMainComponent>
}

View file

@ -0,0 +1,20 @@
package com.tangem.features.onramp.main.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.main.model.OnrampMainComponentModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
internal interface OnrampMainComponentModelModule {
@Binds
@IntoMap
@ClassKey(OnrampMainComponentModel::class)
fun bindOnrampSelectCountryModel(model: OnrampMainComponentModel): Model
}

View file

@ -0,0 +1,18 @@
package com.tangem.features.onramp.main.di
import com.tangem.features.onramp.main.DefaultOnrampMainComponent
import com.tangem.features.onramp.main.OnrampMainComponent
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface OnrampMainComponentModule {
@Binds
@Singleton
fun bindOnrampMainComponentFactory(factory: DefaultOnrampMainComponent.Factory): OnrampMainComponent.Factory
}

View file

@ -0,0 +1,10 @@
package com.tangem.features.onramp.main.entity
import com.tangem.domain.onramp.model.OnrampCountry
import kotlinx.serialization.Serializable
@Serializable
internal sealed interface OnrampMainBottomSheetConfig {
@Serializable
data class ConfirmResidency(val country: OnrampCountry) : OnrampMainBottomSheetConfig
}

View file

@ -0,0 +1,54 @@
package com.tangem.features.onramp.main.entity
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.combinedReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.features.onramp.impl.R
@Immutable
internal sealed interface OnrampMainComponentUM {
val topBarConfig: OnrampMainTopBarUM
val buyButtonConfig: BuyButtonConfig
data class InitialLoading(
val currency: String,
val onClose: () -> Unit,
val openSettings: () -> Unit,
val onBuyClick: () -> Unit,
) : OnrampMainComponentUM {
override val topBarConfig: OnrampMainTopBarUM = OnrampMainTopBarUM(
title = combinedReference(resourceReference(R.string.common_buy), stringReference(" $currency")),
startButtonUM = TopAppBarButtonUM(
iconRes = R.drawable.ic_close_24,
onIconClicked = onClose,
enabled = true,
),
endButtonUM = TopAppBarButtonUM(
iconRes = R.drawable.ic_more_vertical_24,
onIconClicked = openSettings,
enabled = false,
),
)
override val buyButtonConfig: BuyButtonConfig = BuyButtonConfig(
text = resourceReference(R.string.common_buy),
onClick = onBuyClick,
enabled = false,
)
}
data class Content(
override val topBarConfig: OnrampMainTopBarUM,
override val buyButtonConfig: BuyButtonConfig,
) : OnrampMainComponentUM
}
internal data class BuyButtonConfig(
val text: TextReference,
val onClick: () -> Unit,
val enabled: Boolean,
)

View file

@ -0,0 +1,10 @@
package com.tangem.features.onramp.main.entity
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
import com.tangem.core.ui.extensions.TextReference
data class OnrampMainTopBarUM(
val title: TextReference,
val startButtonUM: TopAppBarButtonUM,
val endButtonUM: TopAppBarButtonUM,
)

View file

@ -0,0 +1,53 @@
package com.tangem.features.onramp.main.entity.transformer
import arrow.core.Either
import com.tangem.domain.onramp.model.OnrampAvailability
import com.tangem.domain.onramp.model.OnrampCountry
import com.tangem.features.onramp.main.entity.OnrampMainBottomSheetConfig
import com.tangem.features.onramp.main.entity.OnrampMainComponentUM
import com.tangem.utils.transformer.Transformer
import timber.log.Timber
internal class OnrampAvailabilityTransformer(
private val maybeAvailabilityStatus: Either<Throwable, OnrampAvailability>,
private val openBottomSheet: (OnrampMainBottomSheetConfig) -> Unit,
) : Transformer<OnrampMainComponentUM> {
override fun transform(prevState: OnrampMainComponentUM): OnrampMainComponentUM {
return maybeAvailabilityStatus.fold(
ifLeft = {
Timber.e(it)
prevState
},
ifRight = { availability ->
when (availability) {
OnrampAvailability.Available -> handleAvailableStatus(prevState)
is OnrampAvailability.ConfirmResidency -> handleShowingConfirmResidency(
prevState = prevState,
country = availability.country,
)
is OnrampAvailability.NotSupported -> handleShowingConfirmResidency(
prevState = prevState,
country = availability.country,
)
}
},
)
}
private fun handleAvailableStatus(prevState: OnrampMainComponentUM): OnrampMainComponentUM {
val endButton = prevState.topBarConfig.endButtonUM.copy(enabled = true)
return OnrampMainComponentUM.Content(
topBarConfig = prevState.topBarConfig.copy(endButtonUM = endButton),
buyButtonConfig = prevState.buyButtonConfig,
)
}
private fun handleShowingConfirmResidency(
prevState: OnrampMainComponentUM,
country: OnrampCountry,
): OnrampMainComponentUM {
openBottomSheet.invoke(OnrampMainBottomSheetConfig.ConfirmResidency(country))
return prevState
}
}

View file

@ -0,0 +1,65 @@
package com.tangem.features.onramp.main.model
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.domain.onramp.CheckOnrampAvailabilityUseCase
import com.tangem.features.onramp.main.OnrampMainComponent
import com.tangem.features.onramp.main.entity.OnrampMainBottomSheetConfig
import com.tangem.features.onramp.main.entity.OnrampMainComponentUM
import com.tangem.features.onramp.main.entity.transformer.OnrampAvailabilityTransformer
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.transformer.Transformer
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
internal class OnrampMainComponentModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val router: Router,
private val checkOnrampAvailabilityUseCase: CheckOnrampAvailabilityUseCase,
paramsContainer: ParamsContainer,
) : Model() {
private val params: OnrampMainComponent.Params = paramsContainer.require()
private val _state: MutableStateFlow<OnrampMainComponentUM> = MutableStateFlow(
value = OnrampMainComponentUM.InitialLoading(
currency = params.currency,
onClose = router::pop,
openSettings = params.openSettings,
onBuyClick = ::onBuyClick,
),
)
val state: StateFlow<OnrampMainComponentUM> get() = _state.asStateFlow()
val bottomSheetNavigation: SlotNavigation<OnrampMainBottomSheetConfig> = SlotNavigation()
init {
checkResidenceCountry()
}
private fun checkResidenceCountry() {
modelScope.launch {
OnrampAvailabilityTransformer(
maybeAvailabilityStatus = checkOnrampAvailabilityUseCase.invoke(),
openBottomSheet = ::openBottomSheet,
).let(::updateState)
}
}
@Suppress("EmptyFunctionBlock")
private fun onBuyClick() {
}
private fun openBottomSheet(config: OnrampMainBottomSheetConfig) {
bottomSheetNavigation.activate(config)
}
private fun updateState(transformer: Transformer<OnrampMainComponentUM>) {
_state.update(transformer::transform)
}
}

View file

@ -0,0 +1,100 @@
package com.tangem.features.onramp.main.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.FabPosition
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import com.tangem.core.ui.components.CircleShimmer
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.RectangleShimmer
import com.tangem.core.ui.components.appbar.TangemTopAppBar
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.WindowInsetsZero
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.main.entity.OnrampMainComponentUM
@Composable
internal fun OnrampMainComponentContent(state: OnrampMainComponentUM, modifier: Modifier = Modifier) {
Scaffold(
modifier = modifier,
contentWindowInsets = WindowInsetsZero,
containerColor = TangemTheme.colors.background.secondary,
topBar = {
TangemTopAppBar(
modifier = Modifier.statusBarsPadding(),
startButton = state.topBarConfig.startButtonUM,
endButton = state.topBarConfig.endButtonUM,
title = state.topBarConfig.title.resolveReference(),
)
},
content = { innerPadding ->
val contentModifier = Modifier
.padding(innerPadding)
.padding(horizontal = TangemTheme.dimens.spacing16)
.fillMaxWidth()
.wrapContentHeight()
when (state) {
is OnrampMainComponentUM.InitialLoading -> InitialLoading(modifier = contentModifier)
is OnrampMainComponentUM.Content -> Content(modifier = contentModifier)
}
},
floatingActionButton = {
BuyButton(
modifier = Modifier
.navigationBarsPadding()
.padding(horizontal = TangemTheme.dimens.spacing16)
.fillMaxWidth(),
onClick = state.buyButtonConfig.onClick,
enabled = state.buyButtonConfig.enabled,
)
},
floatingActionButtonPosition = FabPosition.Center,
)
}
@Composable
private fun InitialLoading(modifier: Modifier = Modifier) {
Column(
modifier = modifier
.clip(shape = RoundedCornerShape(size = TangemTheme.dimens.radius16))
.background(TangemTheme.colors.background.action)
.padding(vertical = TangemTheme.dimens.spacing28),
horizontalAlignment = Alignment.CenterHorizontally,
) {
CircleShimmer(modifier = Modifier.size(TangemTheme.dimens.size40))
RectangleShimmer(
modifier = Modifier
.padding(top = TangemTheme.dimens.spacing16)
.size(width = TangemTheme.dimens.size96, height = TangemTheme.dimens.size24),
radius = TangemTheme.dimens.radius3,
)
RectangleShimmer(
modifier = Modifier
.padding(top = TangemTheme.dimens.spacing16)
.size(width = TangemTheme.dimens.size72, height = TangemTheme.dimens.size12),
radius = TangemTheme.dimens.radius3,
)
}
}
@Composable
private fun Content(modifier: Modifier = Modifier) {
Box(modifier = modifier)
}
@Composable
private fun BuyButton(onClick: () -> Unit, enabled: Boolean, modifier: Modifier = Modifier) {
PrimaryButton(
modifier = modifier,
text = stringResource(id = R.string.common_buy),
onClick = onClick,
enabled = enabled,
)
}

View file

@ -1,5 +1,6 @@
package com.tangem.features.onramp.root
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
@ -9,10 +10,13 @@ import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackA
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.childStack
import com.arkivanov.decompose.router.stack.pop
import com.arkivanov.decompose.router.stack.push
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.features.onramp.component.OnrampComponent
import com.tangem.features.onramp.main.OnrampMainComponent
import com.tangem.features.onramp.root.entity.OnrampChild
import com.tangem.features.onramp.settings.OnrampSettingsComponent
import dagger.assisted.Assisted
@ -22,8 +26,9 @@ import dagger.assisted.AssistedInject
@Suppress("UnusedPrivateMember")
internal class DefaultOnrampComponent @AssistedInject constructor(
@Assisted context: AppComponentContext,
@Assisted params: OnrampComponent.Params,
@Assisted private val params: OnrampComponent.Params,
private val settingsComponentFactory: OnrampSettingsComponent.Factory,
private val onrampMainComponentFactory: OnrampMainComponent.Factory,
) : OnrampComponent, AppComponentContext by context {
private val navigation = StackNavigation<OnrampChild>()
@ -31,7 +36,7 @@ internal class DefaultOnrampComponent @AssistedInject constructor(
key = "onramp_content_stack",
source = navigation,
serializer = OnrampChild.serializer(),
initialConfiguration = OnrampChild.Settings,
initialConfiguration = OnrampChild.Main,
handleBackButton = false,
childFactory = ::screenChild,
)
@ -40,6 +45,7 @@ internal class DefaultOnrampComponent @AssistedInject constructor(
override fun Content(modifier: Modifier) {
val childStack by contentStack.subscribeAsState()
BackHandler(onBack = router::pop)
Children(
stack = childStack,
animation = stackAnimation(),
@ -52,10 +58,15 @@ internal class DefaultOnrampComponent @AssistedInject constructor(
when (config) {
OnrampChild.Settings -> settingsComponentFactory.create(
context = childByContext(componentContext),
// params = OnrampSettingsComponent.Params(navigation::pop) // todo uncomment after [REDACTED_JIRA]
params = OnrampSettingsComponent.Params(router::pop),
params = OnrampSettingsComponent.Params(navigation::pop),
)
OnrampChild.Main -> onrampMainComponentFactory.create(
context = childByContext(componentContext),
params = OnrampMainComponent.Params(
currency = params.currency,
openSettings = { navigation.push(OnrampChild.Settings) },
),
)
OnrampChild.Main -> TODO("[REDACTED_JIRA]")
}
@AssistedFactory