Skip to content

Commit

Permalink
Merge pull request #301 from l2hyunwoo/feature/#300
Browse files Browse the repository at this point in the history
[feature/#300] Apply Type Safe Navigation
  • Loading branch information
wisemuji authored May 31, 2024
2 parents fc51f86 + ee817b8 commit c081d4e
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 72 deletions.
5 changes: 5 additions & 0 deletions core/navigation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ import com.droidknights.app.setNamespace
plugins {
id("droidknights.android.library")
id("droidknights.android.compose")
alias(libs.plugins.kotlin.serialization)
}

android {
setNamespace("core.navigation")
}

dependencies {
implementation(libs.kotlinx.serialization.json)
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.droidknights.app.core.navigation

import kotlinx.serialization.Serializable

sealed interface Route {
@Serializable
data object Contributor : Route

@Serializable
data object Session : Route

@Serializable
data class SessionDetail(val sessionId: String) : Route
}

sealed interface MainTabRoute : Route {
@Serializable
data object Home : MainTabRoute

@Serializable
data object Setting : MainTabRoute

@Serializable
data object Bookmark : MainTabRoute
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.droidknights.app.core.navigation.MainTabRoute
import com.droidknights.app.feature.bookmark.BookmarkRoute

fun NavController.navigateBookmark(navOptions: NavOptions) {
navigate(BookmarkRoute.ROUTE, navOptions)
navigate(MainTabRoute.Bookmark, navOptions)
}

fun NavGraphBuilder.bookmarkNavGraph(
onShowErrorSnackBar: (throwable: Throwable?) -> Unit,
) {
composable(route = BookmarkRoute.ROUTE) {
composable<MainTabRoute.Bookmark> {
BookmarkRoute(onShowErrorSnackBar)
}
}

object BookmarkRoute {

const val ROUTE = "bookmark"
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,21 @@ package com.droidknights.app.feature.contributor.navigation
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.droidknights.app.core.navigation.Route
import com.droidknights.app.feature.contributor.ContributorRoute

fun NavController.navigateContributor() {
this.navigate(ContributorRoute.ROUTE)
this.navigate(Route.Contributor)
}

fun NavGraphBuilder.contributorNavGraph(
onBackClick: () -> Unit,
onShowErrorSnackBar: (throwable: Throwable?) -> Unit,
) {
composable(route = ContributorRoute.ROUTE) {
composable<Route.Contributor> {
ContributorRoute(
onBackClick = onBackClick,
onShowErrorSnackBar = onShowErrorSnackBar
)
}
}

object ContributorRoute {

const val ROUTE = "contributor"
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.droidknights.app.core.navigation.MainTabRoute
import com.droidknights.app.feature.home.HomeRoute

fun NavController.navigateHome(navOptions: NavOptions) {
navigate(HomeRoute.ROUTE, navOptions)
navigate(MainTabRoute.Home, navOptions)
}

fun NavGraphBuilder.homeNavGraph(
Expand All @@ -17,12 +18,7 @@ fun NavGraphBuilder.homeNavGraph(
onContributorClick: () -> Unit,
onShowErrorSnackBar: (throwable: Throwable?) -> Unit,
) {
composable(route = HomeRoute.ROUTE) {
composable<MainTabRoute.Home> {
HomeRoute(padding, onSessionClick, onContributorClick, onShowErrorSnackBar)
}
}

object HomeRoute {

const val ROUTE = "home"
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ package com.droidknights.app.feature.main
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hasRoute
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navOptions
import com.droidknights.app.core.navigation.MainTabRoute
import com.droidknights.app.core.navigation.Route
import com.droidknights.app.feature.bookmark.navigation.navigateBookmark
import com.droidknights.app.feature.contributor.navigation.navigateContributor
import com.droidknights.app.feature.home.navigation.HomeRoute
import com.droidknights.app.feature.home.navigation.navigateHome
import com.droidknights.app.feature.session.navigation.navigateSession
import com.droidknights.app.feature.session.navigation.navigateSessionDetail
Expand All @@ -26,9 +28,9 @@ internal class MainNavigator(
val startDestination = MainTab.HOME.route

val currentTab: MainTab?
@Composable get() = currentDestination
?.route
?.let(MainTab::find)
@Composable get() = MainTab.find { tab ->
currentDestination?.hasRoute(tab::class) == true
}

fun navigate(tab: MainTab) {
val navOptions = navOptions {
Expand Down Expand Up @@ -63,18 +65,18 @@ internal class MainNavigator(
}

fun popBackStackIfNotHome() {
if (!isSameCurrentDestination(HomeRoute.ROUTE)) {
if (!isSameCurrentDestination<MainTabRoute.Home>()) {
popBackStack()
}
}

private fun isSameCurrentDestination(route: String) =
navController.currentDestination?.route == route
private inline fun <reified T : Route> isSameCurrentDestination(): Boolean {
return navController.currentDestination?.hasRoute<T>() == true
}

@Composable
fun shouldShowBottomBar(): Boolean {
val currentRoute = currentDestination?.route ?: return false
return currentRoute in MainTab
fun shouldShowBottomBar() = MainTab.contains {
currentDestination?.hasRoute(it::class) == true
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
package com.droidknights.app.feature.main

import com.droidknights.app.feature.bookmark.navigation.BookmarkRoute
import com.droidknights.app.feature.home.navigation.HomeRoute
import com.droidknights.app.feature.setting.navigation.SettingRoute
import androidx.compose.runtime.Composable
import com.droidknights.app.core.navigation.MainTabRoute
import com.droidknights.app.core.navigation.Route

internal enum class MainTab(
val iconResId: Int,
internal val contentDescription: String,
val route: String,
val route: MainTabRoute,
) {
SETTING(
iconResId = R.drawable.ic_setting,
contentDescription = "설정",
SettingRoute.ROUTE_SETTING,
MainTabRoute.Setting,
),
HOME(
iconResId = R.drawable.ic_home,
contentDescription = "",
HomeRoute.ROUTE,
MainTabRoute.Home
),
BOOKMARK(
iconResId = R.drawable.ic_bookmark,
contentDescription = "북마크",
BookmarkRoute.ROUTE,
MainTabRoute.Bookmark,
);

companion object {

operator fun contains(route: String): Boolean {
return entries.map { it.route }.contains(route)
@Composable
fun find(predicate: @Composable (MainTabRoute) -> Boolean): MainTab? {
return entries.find { predicate(it.route) }
}

fun find(route: String): MainTab? {
return entries.find { it.route == route }
@Composable
fun contains(predicate: @Composable (Route) -> Boolean): Boolean {
return entries.map { it.route }.any { predicate(it) }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,40 @@ package com.droidknights.app.feature.session.navigation

import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavType
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import androidx.navigation.toRoute
import com.droidknights.app.core.model.Session
import com.droidknights.app.core.navigation.Route
import com.droidknights.app.feature.session.SessionDetailScreen
import com.droidknights.app.feature.session.SessionScreen
import com.droidknights.app.core.navigation.Route.Session as SessionRoute

fun NavController.navigateSession() {
navigate(SessionRoute.ROUTE)
navigate(SessionRoute)
}

fun NavController.navigateSessionDetail(sessionId: String) {
navigate(SessionRoute.detailRoute(sessionId))
navigate(Route.SessionDetail(sessionId))
}

fun NavGraphBuilder.sessionNavGraph(
onBackClick: () -> Unit,
onSessionClick: (Session) -> Unit,
onShowErrorSnackBar: (throwable: Throwable?) -> Unit,
) {
composable(SessionRoute.ROUTE) {
composable<SessionRoute> {
SessionScreen(
onBackClick = onBackClick,
onSessionClick = onSessionClick,
onShowErrorSnackBar = onShowErrorSnackBar
)
}

composable(
route = SessionRoute.detailRoute("{id}"),
arguments = listOf(
navArgument("id") {
type = NavType.StringType
}
)
) { navBackStackEntry ->
val sessionId = navBackStackEntry.arguments?.getString("id") ?: ""
composable<Route.SessionDetail> { navBackStackEntry ->
val sessionId = navBackStackEntry.toRoute<Route.SessionDetail>().sessionId
SessionDetailScreen(
sessionId = sessionId,
onBackClick = onBackClick
)
}
}

object SessionRoute {

const val ROUTE: String = "session"

fun detailRoute(sessionId: String): String = "$ROUTE/$sessionId"
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,18 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.droidknights.app.core.navigation.MainTabRoute
import com.droidknights.app.feature.setting.SettingScreen

fun NavController.navigateSetting(navOptions: NavOptions) {
navigate(SettingRoute.ROUTE_SETTING, navOptions)
navigate(MainTabRoute.Setting, navOptions)
}

fun NavGraphBuilder.settingNavGraph(
padding: PaddingValues,
onChangeDarkTheme: (Boolean) -> Unit
) {
composable(route = SettingRoute.ROUTE_SETTING) {
composable<MainTabRoute.Setting> {
SettingScreen(padding, onChangeDarkTheme)
}
}

object SettingRoute {

const val ROUTE_SETTING = "setting"
}
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ androidxComposeBom = "2024.05.00"
# https://developer.android.com/jetpack/androidx/releases/compose-kotlin
androidxComposeCompiler = "1.5.14"
# https://developer.android.com/jetpack/androidx/releases/navigation
androidxComposeNavigation = "2.7.7"
androidxComposeNavigation = "2.8.0-beta02"
# https://developer.android.com/jetpack/androidx/releases/compose-material3
androidxComposeMaterial3 = "1.2.1"

Expand Down

0 comments on commit c081d4e

Please sign in to comment.