Skip to content

Commit

Permalink
[#552] Define a "mainNavGraph" in sample-compose
Browse files Browse the repository at this point in the history
  • Loading branch information
luongvo committed Oct 31, 2023
1 parent 01beb6e commit ad26c24
Show file tree
Hide file tree
Showing 16 changed files with 142 additions and 93 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package co.nimblehq.sample.compose.ui

import androidx.navigation.*
import androidx.navigation.NamedNavArgument
import androidx.navigation.NavType
import androidx.navigation.navArgument
import co.nimblehq.sample.compose.model.UiModel

const val KeyId = "id"
Expand All @@ -16,6 +18,10 @@ sealed class AppDestination(val route: String = "") {

object Up : AppDestination()

object RootNavGraph : AppDestination("rootNavGraph")

object MainNavGraph : AppDestination("mainNavGraph")

object Home : AppDestination("home")

object Second : AppDestination("second/{$KeyId}") {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package co.nimblehq.sample.compose.ui

import androidx.compose.runtime.Composable
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDeepLink
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import co.nimblehq.sample.compose.ui.screens.main.mainNavGraph

@Composable
fun AppNavigation(
navController: NavHostController,
) {
NavHost(
navController = navController,
route = AppDestination.RootNavGraph.route,
startDestination = AppDestination.MainNavGraph.destination
) {
mainNavGraph(navController = navController)
}
}

fun NavGraphBuilder.composable(
destination: AppDestination,
deepLinks: List<NavDeepLink> = emptyList(),
content: @Composable (NavBackStackEntry) -> Unit,
) {
composable(
route = destination.route,
arguments = destination.arguments,
deepLinks = deepLinks,
content = content
)
}

/**
* Navigate to provided [AppDestination] with a Pair of key value String and Data [parcel]
* Caution to use this method. This method use savedStateHandle to store the Parcelable data.
* When previousBackstackEntry is popped out from navigation stack, savedStateHandle will return null and cannot retrieve data.
* eg.Login -> Home, the Login screen will be popped from the back-stack on logging in successfully.
*/
fun NavHostController.navigate(appDestination: AppDestination, parcel: Pair<String, Any?>? = null) {
when (appDestination) {
is AppDestination.Up -> navigateUp()
else -> {
parcel?.let { (key, value) ->
currentBackStackEntry?.savedStateHandle?.set(key, value)
}
navigate(route = appDestination.destination)
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens
package co.nimblehq.sample.compose.ui.common

import androidx.annotation.StringRes
import androidx.compose.material.Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package co.nimblehq.sample.compose.ui.screens
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.navigation.compose.rememberNavController
import co.nimblehq.sample.compose.ui.AppNavigation
import co.nimblehq.sample.compose.ui.theme.ComposeTheme
import dagger.hilt.android.AndroidEntryPoint
Expand All @@ -14,7 +15,7 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
setContent {
ComposeTheme {
AppNavigation()
AppNavigation(navController = rememberNavController())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package co.nimblehq.sample.compose.ui.screens.main

import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.navigation
import co.nimblehq.sample.compose.model.UiModel
import co.nimblehq.sample.compose.ui.AppDestination
import co.nimblehq.sample.compose.ui.KeyId
import co.nimblehq.sample.compose.ui.KeyModel
import co.nimblehq.sample.compose.ui.composable
import co.nimblehq.sample.compose.ui.navigate
import co.nimblehq.sample.compose.ui.screens.main.home.HomeScreen
import co.nimblehq.sample.compose.ui.screens.main.second.SecondScreen
import co.nimblehq.sample.compose.ui.screens.main.third.ThirdScreen

fun NavGraphBuilder.mainNavGraph(
navController: NavHostController,
) {
navigation(
route = AppDestination.MainNavGraph.route,
startDestination = AppDestination.Home.destination
) {
composable(destination = AppDestination.Home) {
HomeScreen(
navigator = { destination ->
navController.navigate(destination, destination.parcelableArgument)
}
)
}

composable(destination = AppDestination.Second) { backStackEntry ->
SecondScreen(
navigator = { destination -> navController.navigate(destination) },
id = backStackEntry.arguments?.getString(KeyId).orEmpty()
)
}

composable(destination = AppDestination.Third) {
ThirdScreen(
navigator = { destination -> navController.navigate(destination) },
model = navController.previousBackStackEntry?.savedStateHandle?.get<UiModel>(
KeyModel
)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens.home
package co.nimblehq.sample.compose.ui.screens.main.home

import android.Manifest.permission.*
import androidx.compose.foundation.layout.*
Expand All @@ -17,7 +17,7 @@ import co.nimblehq.sample.compose.extensions.showToast
import co.nimblehq.sample.compose.lib.IsLoading
import co.nimblehq.sample.compose.model.UiModel
import co.nimblehq.sample.compose.ui.AppDestination
import co.nimblehq.sample.compose.ui.screens.AppBar
import co.nimblehq.sample.compose.ui.common.AppBar
import co.nimblehq.sample.compose.ui.showToast
import co.nimblehq.sample.compose.ui.theme.ComposeTheme
import com.google.accompanist.permissions.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens.home
package co.nimblehq.sample.compose.ui.screens.main.home

import androidx.lifecycle.viewModelScope
import co.nimblehq.sample.compose.domain.usecase.GetModelsUseCase
Expand All @@ -10,7 +10,12 @@ import co.nimblehq.sample.compose.ui.AppDestination
import co.nimblehq.sample.compose.ui.base.BaseViewModel
import co.nimblehq.sample.compose.util.DispatchersProvider
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject

@HiltViewModel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens.home
package co.nimblehq.sample.compose.ui.screens.main.home

import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens.home
package co.nimblehq.sample.compose.ui.screens.main.home

import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package co.nimblehq.sample.compose.ui.screens.second
package co.nimblehq.sample.compose.ui.screens.main.second

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
Expand All @@ -11,7 +13,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import co.nimblehq.sample.compose.R
import co.nimblehq.sample.compose.ui.AppDestination
import co.nimblehq.sample.compose.ui.screens.AppBar
import co.nimblehq.sample.compose.ui.common.AppBar
import co.nimblehq.sample.compose.ui.theme.ComposeTheme

@Composable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens.second
package co.nimblehq.sample.compose.ui.screens.main.second

import co.nimblehq.sample.compose.ui.base.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens.third
package co.nimblehq.sample.compose.ui.screens.main.third

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
Expand All @@ -15,7 +15,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import co.nimblehq.sample.compose.R
import co.nimblehq.sample.compose.model.UiModel
import co.nimblehq.sample.compose.ui.AppDestination
import co.nimblehq.sample.compose.ui.screens.AppBar
import co.nimblehq.sample.compose.ui.common.AppBar
import co.nimblehq.sample.compose.ui.theme.ComposeTheme

@Composable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens.third
package co.nimblehq.sample.compose.ui.screens.main.third

import co.nimblehq.sample.compose.ui.base.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens.home
package co.nimblehq.sample.compose.ui.screens.main.home

import androidx.activity.compose.setContent
import androidx.compose.ui.test.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package co.nimblehq.sample.compose.ui.screens.home
package co.nimblehq.sample.compose.ui.screens.main.home

import app.cash.turbine.test
import co.nimblehq.sample.compose.domain.usecase.GetModelsUseCase
Expand All @@ -10,9 +10,16 @@ import co.nimblehq.sample.compose.test.MockUtil
import co.nimblehq.sample.compose.ui.AppDestination
import co.nimblehq.sample.compose.util.DispatchersProvider
import io.kotest.matchers.shouldBe
import io.mockk.*
import io.mockk.Runs
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
Expand Down

0 comments on commit ad26c24

Please sign in to comment.