Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-27 12:06:20 +03:00
parent 12146c8981
commit 3e48a9ce0e
20 changed files with 402 additions and 17 deletions

View file

@ -272,6 +272,7 @@ class OnboardingWalletFragment :
onboardingManageTokensComponent = onboardingManageTokensComponentFactory.create(
context = onboardingComponentContext,
params = OnboardingManageTokensComponent.Params(userWalletId = userWalletId),
onDone = {},
)
}

View file

@ -21,6 +21,7 @@ dependencies {
/** AndroidX libraries */
implementation(deps.androidx.fragment.ktx)
implementation(deps.androidx.paging.runtime)
implementation(deps.lifecycle.runtime.ktx)
implementation(deps.androidx.palette)
implementation(deps.androidx.windowManager) {
exclude(

View file

@ -0,0 +1,123 @@
package com.tangem.core.ui.components
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.PixelFormat
import android.view.View
import android.view.WindowManager
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.platform.AbstractComposeView
import androidx.compose.ui.platform.LocalView
import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
import java.util.UUID
@Composable
fun FullScreen(notTouchable: Boolean = false, content: @Composable (() -> Unit) -> Unit) {
val view = LocalView.current
val parentComposition = rememberCompositionContext()
val currentContent by rememberUpdatedState(content)
val id = rememberSaveable { UUID.randomUUID() }
val fullScreenLayout = remember {
FullScreenLayout(
notTouchable = notTouchable,
composeView = view,
uniqueId = id,
).apply {
setContent(parentComposition) {
currentContent(::dismiss)
}
}
}
DisposableEffect(fullScreenLayout) {
fullScreenLayout.show()
onDispose { fullScreenLayout.dispose() }
}
}
@SuppressLint("ViewConstructor", "ClickableViewAccessibility")
private class FullScreenLayout(
private val notTouchable: Boolean,
private val composeView: View,
uniqueId: UUID,
) : AbstractComposeView(composeView.context) {
private val windowManager =
composeView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
private val params = createLayoutParams()
override var shouldCreateCompositionOnAttachedToWindow: Boolean = false
private set
private var viewShowing = false
init {
if (notTouchable) {
setOnTouchListener { _, _ -> false }
}
id = android.R.id.content
setTag(androidx.compose.ui.R.id.compose_view_saveable_id_tag, "CustomLayout:$uniqueId")
setViewTreeLifecycleOwner(composeView.findViewTreeLifecycleOwner())
setViewTreeSavedStateRegistryOwner(composeView.findViewTreeSavedStateRegistryOwner())
setViewTreeViewModelStoreOwner(composeView.findViewTreeViewModelStoreOwner())
}
private var content: @Composable () -> Unit by mutableStateOf({})
@Composable
override fun Content() {
content()
}
fun setContent(parent: CompositionContext, content: @Composable () -> Unit) {
setParentCompositionContext(parent)
this.content = content
shouldCreateCompositionOnAttachedToWindow = true
}
private fun createLayoutParams(): WindowManager.LayoutParams = WindowManager.LayoutParams().apply {
type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
token = composeView.applicationWindowToken
width = WindowManager.LayoutParams.MATCH_PARENT
height = WindowManager.LayoutParams.MATCH_PARENT
format = PixelFormat.TRANSLUCENT
flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
}
fun show() {
if (viewShowing) dismiss()
windowManager.addView(this, params)
params.flags = params.flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
if (notTouchable) {
params.flags = params.flags or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
}
windowManager.updateViewLayout(this, params)
viewShowing = true
}
fun dismiss() {
if (!viewShowing) return
disposeComposition()
windowManager.removeViewImmediate(this)
viewShowing = false
}
fun dispose() {
dismiss()
setViewTreeSavedStateRegistryOwner(null)
setViewTreeSavedStateRegistryOwner(null)
setViewTreeViewModelStoreOwner(null)
}
}

View file

@ -0,0 +1,24 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="76dp"
android:height="76dp"
android:viewportWidth="76"
android:viewportHeight="76">
<path
android:pathData="M38,16.571C32.317,16.571 26.866,18.829 22.848,22.848C18.829,26.866 16.571,32.317 16.571,38C16.571,43.683 18.829,49.134 22.848,53.152C26.866,57.171 32.317,59.429 38,59.429C43.683,59.429 49.134,57.171 53.152,53.152C57.171,49.134 59.429,43.683 59.429,38C59.429,32.317 57.171,26.866 53.152,22.848C49.134,18.829 43.683,16.571 38,16.571ZM16.787,16.787C22.413,11.161 30.044,8 38,8C45.957,8 53.587,11.161 59.213,16.787C64.839,22.413 68,30.044 68,38C68,45.957 64.839,53.587 59.213,59.213C53.587,64.839 45.957,68 38,68C30.044,68 22.413,64.839 16.787,59.213C11.161,53.587 8,45.957 8,38C8,30.044 11.161,22.413 16.787,16.787Z"
android:strokeAlpha="0.2"
android:fillColor="#0099FF"
android:fillType="evenOdd"
android:fillAlpha="0.2"/>
<path
android:pathData="M21.029,21.029C25.53,16.529 31.635,14 38,14C44.365,14 50.47,16.529 54.971,21.029C59.471,25.53 62,31.635 62,38C62,44.365 59.471,50.47 54.971,54.971C50.47,59.471 44.365,62 38,62C31.635,62 25.53,59.471 21.029,54.971C16.529,50.47 14,44.365 14,38C14,31.635 16.529,25.53 21.029,21.029ZM38,16.697C32.35,16.697 26.931,18.941 22.936,22.936C18.941,26.931 16.697,32.35 16.697,38C16.697,43.65 18.941,49.069 22.936,53.064C26.931,57.059 32.35,59.303 38,59.303C43.65,59.303 49.069,57.059 53.064,53.064C57.059,49.069 59.303,43.65 59.303,38C59.303,32.35 57.059,26.931 53.064,22.936C49.069,18.941 43.65,16.697 38,16.697Z"
android:fillColor="#0099FF"
android:fillType="evenOdd"/>
<path
android:pathData="M50.816,31.398C51.347,31.929 51.347,32.79 50.816,33.321L35.973,48.163L27.398,39.588C26.867,39.057 26.867,38.196 27.398,37.665C27.929,37.134 28.79,37.134 29.321,37.665L35.973,44.318L48.894,31.398C49.424,30.867 50.285,30.867 50.816,31.398Z"
android:fillColor="#0099FF"
android:fillType="evenOdd"/>
<path
android:pathData="M12.082,4.354C11.999,3.882 11.321,3.882 11.239,4.354L10.886,6.378C10.855,6.555 10.715,6.695 10.538,6.726L8.515,7.078C8.042,7.161 8.042,7.839 8.515,7.922L10.538,8.274C10.715,8.305 10.855,8.445 10.886,8.622L11.239,10.646C11.321,11.118 11.999,11.118 12.082,10.646L12.434,8.622C12.465,8.445 12.605,8.305 12.783,8.274L14.806,7.922C15.278,7.839 15.278,7.161 14.806,7.078L12.783,6.726C12.605,6.695 12.465,6.555 12.434,6.378L12.082,4.354ZM64.555,4.444C64.452,3.852 63.601,3.852 63.498,4.444L63.056,6.982C63.017,7.205 62.842,7.379 62.619,7.418L60.082,7.861C59.489,7.964 59.489,8.815 60.082,8.918L62.619,9.36C62.842,9.399 63.017,9.574 63.056,9.797L63.498,12.334C63.601,12.927 64.452,12.927 64.555,12.334L64.998,9.797C65.037,9.574 65.211,9.399 65.434,9.36L67.972,8.918C68.564,8.815 68.564,7.964 67.972,7.861L65.434,7.418C65.211,7.379 65.037,7.205 64.998,6.982L64.555,4.444ZM70.422,16.354C70.339,15.882 69.661,15.882 69.578,16.354L69.226,18.378C69.195,18.555 69.055,18.695 68.878,18.726L66.854,19.078C66.382,19.161 66.382,19.839 66.854,19.922L68.878,20.274C69.055,20.305 69.195,20.445 69.226,20.622L69.578,22.646C69.661,23.118 70.339,23.118 70.422,22.646L70.774,20.622C70.805,20.445 70.945,20.305 71.122,20.274L73.146,19.922C73.618,19.839 73.618,19.161 73.146,19.078L71.122,18.726C70.945,18.695 70.805,18.555 70.774,18.378L70.422,16.354ZM69.578,56.354C69.661,55.882 70.339,55.882 70.422,56.354L70.774,58.378C70.805,58.555 70.945,58.695 71.122,58.726L73.146,59.078C73.618,59.161 73.618,59.839 73.146,59.922L71.122,60.274C70.945,60.305 70.805,60.445 70.774,60.622L70.422,62.646C70.339,63.118 69.661,63.118 69.578,62.646L69.226,60.622C69.195,60.445 69.055,60.305 68.878,60.274L66.854,59.922C66.382,59.839 66.382,59.161 66.854,59.078L68.878,58.726C69.055,58.695 69.195,58.555 69.226,58.378L69.578,56.354Z"
android:fillColor="#0099FF"
android:fillType="evenOdd"/>
</vector>

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
package com.tangem.features.managetokens.component
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.wallets.models.UserWalletId
@ -8,5 +8,7 @@ interface OnboardingManageTokensComponent : ComposableContentComponent {
data class Params(val userWalletId: UserWalletId)
interface Factory : ComponentFactory<Params, OnboardingManageTokensComponent>
interface Factory {
fun create(context: AppComponentContext, params: Params, onDone: () -> Unit): OnboardingManageTokensComponent
}
}

View file

@ -12,14 +12,22 @@ import com.tangem.features.managetokens.ui.OnboardingManageTokensContent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.launch
internal class DefaultOnboardingManageTokensComponent @AssistedInject constructor(
@Assisted context: AppComponentContext,
@Assisted params: OnboardingManageTokensComponent.Params,
@Assisted onDone: () -> Unit,
) : OnboardingManageTokensComponent, AppComponentContext by context {
private val model: OnboardingManageTokensModel = getOrCreateModel(params)
init {
componentScope.launch {
model.returnToParentComponentFlow.collect { onDone() }
}
}
@Composable
override fun Content(modifier: Modifier) {
val state by model.state.collectAsStateWithLifecycle()
@ -32,6 +40,7 @@ internal class DefaultOnboardingManageTokensComponent @AssistedInject constructo
override fun create(
context: AppComponentContext,
params: OnboardingManageTokensComponent.Params,
onDone: () -> Unit,
): DefaultOnboardingManageTokensComponent
}
}

View file

@ -51,6 +51,7 @@ internal class OnboardingManageTokensModel @Inject constructor(
private val params: OnboardingManageTokensComponent.Params = paramsContainer.require()
val state: MutableStateFlow<OnboardingManageTokensUM> = MutableStateFlow(getInitialState())
val returnToParentComponentFlow = MutableSharedFlow<Unit>()
init {
manageTokensListManager.uiItems
@ -261,7 +262,7 @@ internal class OnboardingManageTokensModel @Inject constructor(
return@resource
}
reduxStateHolder.dispatch(OnboardingManageTokensAction.CurrenciesSaved)
returnToParentComponent()
}
private fun onLaterClick() = resource(
@ -287,7 +288,17 @@ internal class OnboardingManageTokensModel @Inject constructor(
return@resource
}
returnToParentComponent()
}
private fun returnToParentComponent() {
// old onboarding
reduxStateHolder.dispatch(OnboardingManageTokensAction.CurrenciesSaved)
// new one
modelScope.launch {
returnToParentComponentFlow.emit(Unit)
}
}
private fun searchCurrencies(query: String) {

View file

@ -1,10 +1,7 @@
package com.tangem.features.managetokens.ui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.FabPosition
import androidx.compose.material3.Scaffold
@ -71,7 +68,9 @@ internal fun OnboardingManageTokensContent(state: OnboardingManageTokensUM, modi
},
snackbarHost = {
TangemSnackbarHost(
modifier = Modifier.padding(all = TangemTheme.dimens.spacing16),
modifier = Modifier
.padding(all = TangemTheme.dimens.spacing16)
.navigationBarsPadding(),
hostState = LocalSnackbarHostState.current,
)
},
@ -80,7 +79,8 @@ internal fun OnboardingManageTokensContent(state: OnboardingManageTokensUM, modi
FloatingActionButton(
modifier = Modifier
.padding(horizontal = TangemTheme.dimens.spacing16)
.fillMaxWidth(),
.fillMaxWidth()
.navigationBarsPadding(),
config = state.actionButtonConfig,
)
},

View file

@ -28,6 +28,7 @@ dependencies {
/** Common */
implementation(projects.common.ui)
implementation(projects.common.routing)
/** Domain */
implementation(projects.domain.models)
@ -37,6 +38,7 @@ dependencies {
implementation(projects.domain.wallets)
implementation(projects.domain.wallets.models)
implementation(projects.domain.legacy)
implementation(projects.domain.settings)
/** Tangem libraries */
implementation(projects.libs.tangemSdkApi)
@ -57,6 +59,7 @@ dependencies {
implementation(deps.compose.ui)
implementation(deps.compose.ui.tooling)
implementation(deps.compose.coil)
implementation(deps.lottie.compose)
implementation(deps.decompose.ext.compose)
implementation(deps.androidx.activity.compose)

View file

@ -0,0 +1,11 @@
package com.tangem.features.onboarding.v2.done.api
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
interface OnboardingDoneComponent : ComposableContentComponent {
data class Params(val onDone: () -> Unit)
interface Factory : ComponentFactory<Params, OnboardingDoneComponent>
}

View file

@ -0,0 +1,32 @@
package com.tangem.features.onboarding.v2.done.impl
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.features.onboarding.v2.done.api.OnboardingDoneComponent
import com.tangem.features.onboarding.v2.done.impl.ui.OnboardingDone
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class DefaultOnboardingDoneComponent @AssistedInject constructor(
@Assisted context: AppComponentContext,
@Assisted private val params: OnboardingDoneComponent.Params,
) : OnboardingDoneComponent, AppComponentContext by context {
@Composable
override fun Content(modifier: Modifier) {
OnboardingDone(
onContinueClick = remember(this) { params.onDone },
)
}
@AssistedFactory
interface Factory : OnboardingDoneComponent.Factory {
override fun create(
context: AppComponentContext,
params: OnboardingDoneComponent.Params,
): DefaultOnboardingDoneComponent
}
}

View file

@ -0,0 +1,18 @@
package com.tangem.features.onboarding.v2.done.impl.di
import com.tangem.features.onboarding.v2.done.api.OnboardingDoneComponent
import com.tangem.features.onboarding.v2.done.impl.DefaultOnboardingDoneComponent
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 ComponentModule {
@Binds
@Singleton
fun componentFactory(factory: DefaultOnboardingDoneComponent.Factory): OnboardingDoneComponent.Factory
}

View file

@ -0,0 +1,105 @@
package com.tangem.features.onboarding.v2.done.impl.ui
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.animateLottieCompositionAsState
import com.airbnb.lottie.compose.rememberLottieComposition
import com.tangem.core.ui.components.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.onboarding.v2.impl.R
import kotlinx.coroutines.delay
@Composable
internal fun OnboardingDone(onContinueClick: () -> Unit, modifier: Modifier = Modifier) {
val composition by rememberLottieComposition(spec = LottieCompositionSpec.RawRes(R.raw.anim_confetti))
val progress by animateLottieCompositionAsState(composition)
var showConfetti by remember { mutableStateOf(false) }
Column(
modifier
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_success_blue_76),
tint = Color.Unspecified,
contentDescription = null,
modifier = Modifier
.size(76.dp),
)
SpacerH32()
Text(
modifier = Modifier.padding(horizontal = 32.dp),
text = stringResource(R.string.onboarding_done_header),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
)
SpacerH12()
Text(
modifier = Modifier.padding(horizontal = 32.dp),
text = stringResource(R.string.onboarding_subtitle_success_tangem_wallet_onboarding),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.secondary,
)
SpacerH(72.dp)
}
PrimaryButton(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.padding(bottom = 16.dp)
.navigationBarsPadding(),
text = stringResource(R.string.onboarding_button_continue_wallet),
onClick = onContinueClick,
)
}
if (showConfetti) {
FullScreen(notTouchable = true) {
LottieAnimation(
composition = composition,
progress = { progress },
)
}
}
LaunchedEffect(Unit) {
delay(timeMillis = 500)
showConfetti = true
}
LaunchedEffect(progress == 1f) {
if (progress == 1f) {
showConfetti = false
}
}
}
@Preview(showBackground = true)
@Composable
private fun Preview() {
TangemThemePreview {
OnboardingDone(onContinueClick = {})
}
}

View file

@ -65,6 +65,7 @@ internal class DefaultOnboardingEntryComponent @AssistedInject constructor(
onboardingChildFactory.createChild(
route = configuration,
childContext = childByContext(factoryContext),
onManageTokensDone = model::onManageTokensDone,
)
},
)

View file

@ -2,25 +2,35 @@ package com.tangem.features.onboarding.v2.entry.impl.model
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.navigate
import com.tangem.common.routing.AppRoute
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.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.onboarding.v2.TitleProvider
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
import com.tangem.features.onboarding.v2.entry.impl.routing.OnboardingRoute
import com.tangem.sdk.api.TangemSdkManager
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
internal class OnboardingEntryModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
private val router: Router,
private val tangemSdkManager: TangemSdkManager,
private val settingsRepository: SettingsRepository,
) : Model() {
private val params = paramsContainer.require<OnboardingEntryComponent.Params>()
@ -63,4 +73,20 @@ internal class OnboardingEntryModel @Inject constructor(
listOf(OnboardingRoute.ManageTokens(userWallet))
}
}
fun onManageTokensDone() {
stackNavigation.navigate {
listOf(OnboardingRoute.Done(onDone = ::navigateToWalletScreen))
}
}
private fun navigateToWalletScreen() {
modelScope.launch(NonCancellable) {
router.replaceAll(AppRoute.Wallet)
if (tangemSdkManager.checkCanUseBiometry() && settingsRepository.shouldShowSaveUserWalletScreen()) {
delay(timeMillis = 1_800)
router.push(AppRoute.SaveWallet)
}
}
}
}

View file

@ -1,17 +1,18 @@
package com.tangem.features.onboarding.v2.entry.impl.routing
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.features.managetokens.component.ManageTokensComponent
import com.tangem.features.managetokens.component.ManageTokensSource
import com.tangem.features.managetokens.component.OnboardingManageTokensComponent
import com.tangem.features.onboarding.v2.done.api.OnboardingDoneComponent
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
import javax.inject.Inject
internal class OnboardingChildFactory @Inject constructor(
private val multiWalletComponentFactory: OnboardingMultiWalletComponent.Factory,
private val manageTokensComponentFactory: ManageTokensComponent.Factory,
private val onboardingManageTokensComponentFactory: OnboardingManageTokensComponent.Factory,
private val onboardingDoneComponentFactory: OnboardingDoneComponent.Factory,
) {
fun createChild(route: OnboardingRoute, childContext: AppComponentContext): Any {
fun createChild(route: OnboardingRoute, childContext: AppComponentContext, onManageTokensDone: () -> Unit): Any {
return when (route) {
is OnboardingRoute.MultiWallet -> multiWalletComponentFactory.create(
context = childContext,
@ -22,11 +23,17 @@ internal class OnboardingChildFactory @Inject constructor(
onDone = route.onDone,
),
)
is OnboardingRoute.ManageTokens -> manageTokensComponentFactory.create( // TODO replace with wrapper
is OnboardingRoute.ManageTokens -> onboardingManageTokensComponentFactory.create(
context = childContext,
params = ManageTokensComponent.Params(
params = OnboardingManageTokensComponent.Params(
userWalletId = route.userWallet.walletId,
source = ManageTokensSource.ONBOARDING,
),
onDone = onManageTokensDone,
)
is OnboardingRoute.Done -> onboardingDoneComponentFactory.create(
context = childContext,
params = OnboardingDoneComponent.Params(
onDone = route.onDone,
),
)
else -> Unit

View file

@ -19,4 +19,8 @@ sealed class OnboardingRoute : Route {
data class ManageTokens(
val userWallet: UserWallet,
) : OnboardingRoute()
data class Done(
val onDone: () -> Unit,
) : OnboardingRoute()
}

View file

@ -42,6 +42,11 @@ internal inline fun OnboardingEntry(
modifier = modifier,
)
}
is OnboardingRoute.Done -> {
(it.instance as ComposableContentComponent).Content(
modifier = modifier,
)
}
OnboardingRoute.None -> {}
}
}

View file

@ -56,6 +56,7 @@ jodatime = "2.12.1"
kotlin-immutable-collections = "0.3.5"
kotsonGsonExt = "2.5.0"
lottie = "3.4.0"
lottie-compose = "6.6.0"
moshi = "1.12.0"
okhttp = "4.9.3"
rekotlin = "1.0.4"
@ -228,10 +229,10 @@ googlePlay-services-wallet = { module = "com.google.android.gms:play-services-wa
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
hilt-core = { module = "com.google.dagger:hilt-core", version.ref = "hilt" }
hilt-kapt = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
hilt-navigation = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
jodatime = { module = "joda-time:joda-time", version.ref = "jodatime" }
kotsonGson = { module = "com.github.salomonbrys.kotson:kotson", version.ref = "kotsonGsonExt" }
lottie = { module = "com.airbnb.android:lottie", version.ref = "lottie" }
lottie-compose = { module = "com.airbnb.android:lottie-compose", version.ref = "lottie-compose" }
material = { module = "com.google.android.material:material", version.ref = "googleMaterialComponent" }
moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" }
moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" }