diff --git a/core/decompose/src/main/kotlin/com/tangem/core/decompose/model/ModelEntryPoint.kt b/core/decompose/src/main/kotlin/com/tangem/core/decompose/model/ModelEntryPoint.kt index d37de64a00..329556fff3 100644 --- a/core/decompose/src/main/kotlin/com/tangem/core/decompose/model/ModelEntryPoint.kt +++ b/core/decompose/src/main/kotlin/com/tangem/core/decompose/model/ModelEntryPoint.kt @@ -4,6 +4,8 @@ import com.arkivanov.essenty.instancekeeper.getOrCreate import com.arkivanov.essenty.instancekeeper.getOrCreateSimple import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.di.ModelComponent +import com.tangem.core.decompose.navigation.Router +import com.tangem.core.decompose.ui.UiMessageSender import dagger.hilt.EntryPoint import dagger.hilt.EntryPoints import dagger.hilt.InstallIn @@ -35,11 +37,15 @@ inline fun AppComponentContext.getOrCreateModel(): M = getOr * @param params The parameters to store in the [ParamsContainer], */ -inline fun AppComponentContext.getOrCreateModel(params: P?): M { - val entryPoint = instanceKeeper.getOrCreateSimple(key = "modelsEntryPoint") { +inline fun AppComponentContext.getOrCreateModel( + params: P?, + messageSender: UiMessageSender? = null, + router: Router? = null, +): M { + val entryPoint = instanceKeeper.getOrCreateSimple(key = "modelsEntryPoint_${M::class.simpleName}") { val hiltComponent = hiltComponentBuilder - .router(router) - .uiMessageSender(messageSender) + .router(router ?: this@getOrCreateModel.router) + .uiMessageSender(messageSender ?: this@getOrCreateModel.messageSender) .paramsContainer(MutableParamsContainer(params ?: Unit)) .build() diff --git a/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/DefaultRouter.kt b/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/DefaultRouter.kt index d2d4fb95e7..ed5cb7be3f 100644 --- a/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/DefaultRouter.kt +++ b/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/DefaultRouter.kt @@ -24,7 +24,7 @@ internal class DefaultRouter( navigation.navigate( transformer = { newRoutes }, - onComplete = { newStack, _ -> onComplete(newStack.size == newRoutes.size) }, + onComplete = { newStack, _ -> newStack == newRoutes }, ) } diff --git a/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/inner/InnerPopRouter.kt b/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/inner/InnerPopRouter.kt new file mode 100644 index 0000000000..12242d09b7 --- /dev/null +++ b/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/inner/InnerPopRouter.kt @@ -0,0 +1,36 @@ +package com.tangem.core.decompose.navigation.inner + +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.navigation.Route +import com.tangem.core.decompose.navigation.Router +import kotlin.reflect.KClass + +/** + * Creates an router for overriding the pop operation. + * + * @param popCallback The callback to pop the route. + */ +@Suppress("FunctionName") +inline fun AppComponentContext.InnerPopRouter( + crossinline popCallback: ((onComplete: (Boolean) -> Unit) -> Unit), +): Router = object : Router { + override fun push(route: Route, onComplete: (Boolean) -> Unit) { + router.push(route, onComplete) + } + + override fun replaceAll(vararg routes: Route, onComplete: (Boolean) -> Unit) { + router.replaceAll(*routes, onComplete = onComplete) + } + + override fun pop(onComplete: (Boolean) -> Unit) { + popCallback(onComplete) + } + + override fun popTo(route: Route, onComplete: (Boolean) -> Unit) { + router.popTo(route, onComplete) + } + + override fun popTo(routeClass: KClass, onComplete: (Boolean) -> Unit) { + router.popTo(routeClass, onComplete) + } +} \ No newline at end of file diff --git a/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/inner/InnerRouter.kt b/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/inner/InnerRouter.kt new file mode 100644 index 0000000000..788afecd42 --- /dev/null +++ b/core/decompose/src/main/kotlin/com/tangem/core/decompose/navigation/inner/InnerRouter.kt @@ -0,0 +1,81 @@ +package com.tangem.core.decompose.navigation.inner + +import com.arkivanov.decompose.router.stack.StackNavigation +import com.arkivanov.decompose.router.stack.pop +import com.arkivanov.decompose.router.stack.pushNew +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.navigation.Route +import com.tangem.core.decompose.navigation.Router +import kotlin.reflect.KClass + +/** + * Creates a router that can handle a specific type of route. + * + * @param stackNavigation The stack navigation instance. + * @param popCallback The callback to pop the route. + * @param fallBackRouter The fallback router. + * @return The router. + */ +@Suppress("FunctionName") +inline fun AppComponentContext.InnerRouter( + stackNavigation: StackNavigation, + fallBackRouter: Router = router, + noinline popCallback: ((onComplete: (Boolean) -> Unit) -> Unit) = + { onComplete -> stackNavigation.pop(onComplete) }, +): Router = object : Router { + + override fun push(route: Route, onComplete: (Boolean) -> Unit) { + if (route is T) { + stackNavigation.pushNew(route, onComplete) + } else { + fallBackRouter.push(route, onComplete) + } + } + + override fun replaceAll(vararg routes: Route, onComplete: (Boolean) -> Unit) { + if (routes.any { it is T }) { + val newRoutes = routes.toList().filterIsInstance() + + stackNavigation.navigate( + transformer = { newRoutes }, + onComplete = { newStack, _ -> onComplete(newStack == newRoutes) }, + ) + } else { + fallBackRouter.replaceAll(*routes, onComplete = onComplete) + } + } + + override fun pop(onComplete: (Boolean) -> Unit) { + popCallback(onComplete) + } + + override fun popTo(route: Route, onComplete: (Boolean) -> Unit) { + if (route is T) { + stackNavigation.navigate( + transformer = { stack -> + stack + .dropLastWhile { it != route } + .ifEmpty { stack } + }, + onComplete = { newStack, oldStack -> onComplete(newStack.size < oldStack.size) }, + ) + } else { + fallBackRouter.popTo(route, onComplete) + } + } + + override fun popTo(routeClass: KClass, onComplete: (Boolean) -> Unit) { + if (routeClass == T::class) { + stackNavigation.navigate( + transformer = { stack -> + stack + .dropLastWhile { it::class != routeClass } + .ifEmpty { stack } + }, + onComplete = { newStack, oldStack -> onComplete(newStack.size < oldStack.size) }, + ) + } else { + fallBackRouter.popTo(routeClass, onComplete) + } + } +} \ No newline at end of file