Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: kotlinx.serialization based navigation #119

Merged
merged 1 commit into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion navigation/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id(libs.plugins.configurations.compose.multiplatform.get().pluginId)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.kotlinx.serialization)
}

dependencies {
Expand All @@ -20,4 +20,6 @@ dependencies {

commonMainImplementation(projects.feature.system.domain)
commonMainImplementation(projects.feature.system.presentation)

commonMainImplementation(libs.kotlinx.serialization)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import com.arkivanov.decompose.extensions.compose.jetbrains.subscribeAsState
import com.arkivanov.decompose.router.stack.ChildStack
import com.arkivanov.decompose.router.stack.StackNavigationSource
import com.arkivanov.decompose.router.stack.childStack
import com.arkivanov.essenty.parcelable.Parcelable
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.nullable

val LocalComponentContext: ProvidableCompositionLocal<ComponentContext> =
staticCompositionLocalOf { error("Root component context was not provided") }
Expand All @@ -25,7 +26,7 @@ fun ProvideComponentContext(componentContext: ComponentContext, content: @Compos
}

@Composable
inline fun <reified C : Parcelable> ChildStack(
inline fun <reified C : Screen> ChildStack(
source: StackNavigationSource<C>,
noinline initialStack: () -> List<C>,
modifier: Modifier = Modifier,
Expand Down Expand Up @@ -66,21 +67,20 @@ fun <C : Any> ChildStack(
}

@Composable
inline fun <reified C : Parcelable> rememberChildStack(
inline fun <reified C : Screen> rememberChildStack(
source: StackNavigationSource<C>,
noinline initialStack: () -> List<C>,
key: String = "DefaultChildStack",
handleBackButton: Boolean = false,
): State<ChildStack<C, ComponentContext>> {
val componentContext = LocalComponentContext.current

return remember {
componentContext.childStack(
source = source,
initialStack = initialStack,
key = key,
handleBackButton = handleBackButton,
handleBackButton = true,
childFactory = { _, childComponentContext -> childComponentContext },
serializer = Screen.serializer() as KSerializer<C>,
)
}.subscribeAsState()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,49 @@ package io.timemates.app.navigation

import com.arkivanov.essenty.parcelable.Parcelable
import com.arkivanov.essenty.parcelable.Parcelize
import kotlinx.serialization.Serializable

sealed class Screen : Parcelable {
@Serializable
sealed class Screen {

@Parcelize
@Serializable
data object Startup : Screen() {
private fun readResolve(): Any = Startup
}

@Parcelize
@Serializable
data object InitialAuthorizationScreen : Screen() {
private fun readResolve(): Any = InitialAuthorizationScreen
}

@Parcelize
@Serializable
data object StartAuthorization : Screen() {
private fun readResolve(): Any = StartAuthorization
}

@Parcelize
@Serializable
data class AfterStart(val verificationHash: String) : Screen()

@Parcelize
@Serializable
data class ConfirmAuthorization(val verificationHash: String) : Screen()

@Parcelize
@Serializable
data class NewAccountInfo(val verificationHash: String) : Screen()

@Parcelize
@Serializable
data class NewAccount(val verificationHash: String) : Screen()

@Parcelize
@Serializable
data object TimersList : Screen() {
private fun readResolve(): Any = TimersList
}

@Parcelize
@Serializable
data object TimerCreation : Screen() {
private fun readResolve(): Any = TimerCreation
}

@Parcelize
@Serializable
data object TimerSettings : Screen() {
private fun readResolve(): Any = TimerSettings
}
Expand Down
6 changes: 6 additions & 0 deletions platforms/android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ android {
multiDexEnabled = true
}

packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_19
targetCompatibility = JavaVersion.VERSION_19
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ class TimeMatesApplication : MultiDexApplication() {
internal val onAuthFailedChannel: Channel<UnauthorizedException> = Channel()
}

override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)

override fun onCreate() {
super.onCreate()
val (authDriver, usersDriver) = listOf(
"authorization" to TimeMatesAuthorizations.Schema,
"users" to TimeMatesUsers.Schema,
Expand All @@ -45,4 +43,9 @@ class TimeMatesApplication : MultiDexApplication() {
credentialsStorage,
)
}

override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
}
Loading