Updated on 2026-08-14

This commit is contained in:
Tangem 2025-03-04 14:27:13 +03:00
parent 15a0d9c00b
commit 540a938993
4 changed files with 128 additions and 5 deletions

View file

@ -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 <reified M : Model> AppComponentContext.getOrCreateModel(): M = getOr
* @param params The parameters to store in the [ParamsContainer],
*/
inline fun <reified M : Model, reified P : Any> AppComponentContext.getOrCreateModel(params: P?): M {
val entryPoint = instanceKeeper.getOrCreateSimple(key = "modelsEntryPoint") {
inline fun <reified M : Model, reified P : Any> 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()

View file

@ -24,7 +24,7 @@ internal class DefaultRouter(
navigation.navigate(
transformer = { newRoutes },
onComplete = { newStack, _ -> onComplete(newStack.size == newRoutes.size) },
onComplete = { newStack, _ -> newStack == newRoutes },
)
}

View file

@ -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<out Route>, onComplete: (Boolean) -> Unit) {
router.popTo(routeClass, onComplete)
}
}

View file

@ -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 <reified T : Route> AppComponentContext.InnerRouter(
stackNavigation: StackNavigation<T>,
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<T>()
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<out Route>, 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)
}
}
}