Migrate topic feature to Nav3

dt/nav3-c
Don Turner 2 months ago
parent 6ebf665c09
commit 1e30bc49f0

@ -30,7 +30,7 @@ import com.google.samples.apps.nowinandroid.feature.foryou.navigation.forYouSect
import com.google.samples.apps.nowinandroid.feature.interests.navigation.InterestsRoute import com.google.samples.apps.nowinandroid.feature.interests.navigation.InterestsRoute
import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests
import com.google.samples.apps.nowinandroid.feature.search.navigation.searchScreen import com.google.samples.apps.nowinandroid.feature.search.navigation.searchScreen
import com.google.samples.apps.nowinandroid.feature.topic.navigation.navigateToTopic import com.google.samples.apps.nowinandroid.feature.topic.navigation.TopicRoute
import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination.INTERESTS import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination.INTERESTS
import com.google.samples.apps.nowinandroid.ui.NiaAppState import com.google.samples.apps.nowinandroid.ui.NiaAppState
@ -64,13 +64,11 @@ fun NiaNavHost(
modifier = modifier, modifier = modifier,
) { ) {
forYouSection( forYouSection(
onTopicClick = navController::navigateToTopic, onTopicClick = {
nav3Navigator.goTo(route = TopicRoute(it))
},
) { ) {
topicScreen( composable<TopicRoute>{}
showBackButton = true,
onBackClick = navController::popBackStack,
onTopicClick = navController::navigateToTopic,
)
} }
composable<BookmarksRoute> {} composable<BookmarksRoute> {}
searchScreen( searchScreen(
@ -89,6 +87,13 @@ fun NiaNavHost(
}, },
onShowSnackbar = onShowSnackbar onShowSnackbar = onShowSnackbar
) )
topicScreen(
showBackButton = true,
onBackClick = { nav3Navigator.goBack() },
onTopicClick = {
nav3Navigator.goTo(route = TopicRoute(it))
},
)
}, },
) )
} }

@ -30,8 +30,8 @@ import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.NavOptions import androidx.navigation.NavOptions
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import androidx.navigation.internalToRoute
import androidx.navigation.navOptions import androidx.navigation.navOptions
import androidx.navigation.toRoute
import androidx.tracing.trace import androidx.tracing.trace
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
@ -41,6 +41,7 @@ import com.google.samples.apps.nowinandroid.feature.bookmarks.api.navigation.Boo
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.navigateToForYou import com.google.samples.apps.nowinandroid.feature.foryou.navigation.navigateToForYou
import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests
import com.google.samples.apps.nowinandroid.feature.search.navigation.navigateToSearch import com.google.samples.apps.nowinandroid.feature.search.navigation.navigateToSearch
import com.google.samples.apps.nowinandroid.feature.topic.navigation.TopicRoute
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination.BOOKMARKS import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination.BOOKMARKS
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination.FOR_YOU import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination.FOR_YOU
@ -213,7 +214,8 @@ private fun NavigationTrackingSideEffect(navController: NavHostController) {
class Nav3NavigatorSimple(val navController: NavHostController){ class Nav3NavigatorSimple(val navController: NavHostController){
private val migratedRoutes = listOf( private val migratedRoutes = listOf(
BookmarksRoute::class BookmarksRoute::class,
TopicRoute::class
).associateBy { it.qualifiedName } ).associateBy { it.qualifiedName }
// TODO: We are using Dispatchers.Main so that we can access SavedStateHandle in toRoute, // TODO: We are using Dispatchers.Main so that we can access SavedStateHandle in toRoute,
@ -231,16 +233,17 @@ class Nav3NavigatorSimple(val navController: NavHostController){
if (backStack.isNotEmpty()){ if (backStack.isNotEmpty()){
clear() clear()
val entriesToAdd = nav2BackStack.mapNotNull { entry -> val entriesToAdd = nav2BackStack.mapNotNull { entry ->
println("Evaluating: ${entry.destination::class.qualifiedName}")
val className = entry.destination.route?.substringBefore('/')
println("Evaluating: $className")
// Ignore nav graph root entries // Ignore nav graph root entries
if (entry.destination::class.qualifiedName == "androidx.navigation.compose.ComposeNavGraphNavigator.ComposeNavGraph"){ if (entry.destination::class.qualifiedName == "androidx.navigation.compose.ComposeNavGraphNavigator.ComposeNavGraph"){
null null
} else { } else {
val migratedRouteClass = migratedRoutes[entry.destination.route] when (className) {
if (migratedRouteClass != null){ BookmarksRoute::class.qualifiedName -> entry.toRoute<BookmarksRoute>()
entry.savedStateHandle.internalToRoute(route = migratedRouteClass, typeMap = emptyMap()) TopicRoute::class.qualifiedName -> entry.toRoute<TopicRoute>()
} else { else -> entry
entry
} }
} }
} }

@ -26,6 +26,7 @@ android {
dependencies { dependencies {
implementation(projects.core.data) implementation(projects.core.data)
implementation(projects.core.navigation)
testImplementation(projects.core.testing) testImplementation(projects.core.testing)
testImplementation(libs.robolectric) testImplementation(libs.robolectric)

@ -17,30 +17,21 @@
package com.google.samples.apps.nowinandroid.feature.topic.navigation package com.google.samples.apps.nowinandroid.feature.topic.navigation
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController import androidx.navigation3.runtime.EntryProviderBuilder
import androidx.navigation.NavGraphBuilder import androidx.navigation3.runtime.entry
import androidx.navigation.NavOptionsBuilder
import androidx.navigation.compose.composable
import androidx.navigation.toRoute
import com.google.samples.apps.nowinandroid.feature.topic.TopicScreen import com.google.samples.apps.nowinandroid.feature.topic.TopicScreen
import com.google.samples.apps.nowinandroid.feature.topic.TopicViewModel import com.google.samples.apps.nowinandroid.feature.topic.TopicViewModel
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable data class TopicRoute(val id: String) @Serializable data class TopicRoute(val id: String)
fun NavController.navigateToTopic(topicId: String, navOptions: NavOptionsBuilder.() -> Unit = {}) { fun EntryProviderBuilder<Any>.topicScreen(
navigate(route = TopicRoute(topicId)) {
navOptions()
}
}
fun NavGraphBuilder.topicScreen(
showBackButton: Boolean, showBackButton: Boolean,
onBackClick: () -> Unit, onBackClick: () -> Unit,
onTopicClick: (String) -> Unit, onTopicClick: (String) -> Unit,
) { ) {
composable<TopicRoute> { entry -> entry<TopicRoute> { entry ->
val id = entry.toRoute<TopicRoute>().id val id = entry.id
TopicScreen( TopicScreen(
showBackButton = showBackButton, showBackButton = showBackButton,
onBackClick = onBackClick, onBackClick = onBackClick,

Loading…
Cancel
Save