|
|
|
@ -18,14 +18,21 @@ package com.google.samples.apps.nowinandroid.ui.interests2pane
|
|
|
|
|
|
|
|
|
|
import androidx.activity.compose.BackHandler
|
|
|
|
|
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
|
|
|
|
|
import androidx.compose.material3.adaptive.layout.AnimatedPane
|
|
|
|
|
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
|
|
|
|
|
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
|
|
|
|
|
import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
|
|
|
|
|
import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
|
|
|
|
|
import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator
|
|
|
|
|
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
|
|
|
|
|
import androidx.compose.runtime.Composable
|
|
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
|
|
|
import androidx.compose.runtime.getValue
|
|
|
|
|
import androidx.compose.runtime.key
|
|
|
|
|
import androidx.compose.runtime.mutableStateOf
|
|
|
|
|
import androidx.compose.runtime.remember
|
|
|
|
|
import androidx.compose.runtime.saveable.Saver
|
|
|
|
|
import androidx.compose.runtime.saveable.rememberSaveable
|
|
|
|
|
import androidx.compose.runtime.setValue
|
|
|
|
|
import androidx.hilt.navigation.compose.hiltViewModel
|
|
|
|
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|
|
|
|
import androidx.navigation.NavGraphBuilder
|
|
|
|
@ -39,8 +46,10 @@ import com.google.samples.apps.nowinandroid.feature.interests.navigation.INTERES
|
|
|
|
|
import com.google.samples.apps.nowinandroid.feature.interests.navigation.TOPIC_ID_ARG
|
|
|
|
|
import com.google.samples.apps.nowinandroid.feature.topic.TopicDetailPlaceholder
|
|
|
|
|
import com.google.samples.apps.nowinandroid.feature.topic.navigation.TOPIC_ROUTE
|
|
|
|
|
import com.google.samples.apps.nowinandroid.feature.topic.navigation.createTopicRoute
|
|
|
|
|
import com.google.samples.apps.nowinandroid.feature.topic.navigation.navigateToTopic
|
|
|
|
|
import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen
|
|
|
|
|
import java.util.UUID
|
|
|
|
|
|
|
|
|
|
private const val DETAIL_PANE_NAVHOST_ROUTE = "detail_pane_route"
|
|
|
|
|
|
|
|
|
@ -76,17 +85,42 @@ internal fun InterestsListDetailScreen(
|
|
|
|
|
selectedTopicId: String?,
|
|
|
|
|
onTopicClick: (String) -> Unit,
|
|
|
|
|
) {
|
|
|
|
|
val listDetailNavigator = rememberListDetailPaneScaffoldNavigator()
|
|
|
|
|
val listDetailNavigator = rememberListDetailPaneScaffoldNavigator(
|
|
|
|
|
initialDestinationHistory = listOfNotNull(
|
|
|
|
|
ThreePaneScaffoldDestinationItem(ListDetailPaneScaffoldRole.List),
|
|
|
|
|
ThreePaneScaffoldDestinationItem<Nothing>(ListDetailPaneScaffoldRole.Detail).takeIf {
|
|
|
|
|
selectedTopicId != null
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
BackHandler(listDetailNavigator.canNavigateBack()) {
|
|
|
|
|
listDetailNavigator.navigateBack()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val nestedNavController = rememberNavController()
|
|
|
|
|
var nestedNavHostStartDestination by remember {
|
|
|
|
|
mutableStateOf(selectedTopicId?.let(::createTopicRoute) ?: TOPIC_ROUTE)
|
|
|
|
|
}
|
|
|
|
|
var nestedNavKey by rememberSaveable(
|
|
|
|
|
stateSaver = Saver({ it.toString() }, UUID::fromString),
|
|
|
|
|
) {
|
|
|
|
|
mutableStateOf(UUID.randomUUID())
|
|
|
|
|
}
|
|
|
|
|
val nestedNavController = key(nestedNavKey) {
|
|
|
|
|
rememberNavController()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onTopicClickShowDetailPane(topicId: String) {
|
|
|
|
|
onTopicClick(topicId)
|
|
|
|
|
nestedNavController.navigateToTopic(topicId) {
|
|
|
|
|
popUpTo(DETAIL_PANE_NAVHOST_ROUTE)
|
|
|
|
|
if (listDetailNavigator.isDetailPaneVisible()) {
|
|
|
|
|
// If the detail pane was visible, then use the nestedNavController navigate call
|
|
|
|
|
// directly
|
|
|
|
|
nestedNavController.navigateToTopic(topicId) {
|
|
|
|
|
popUpTo(DETAIL_PANE_NAVHOST_ROUTE)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Otherwise, recreate the NavHost entirely, and start at the new destination
|
|
|
|
|
nestedNavHostStartDestination = createTopicRoute(topicId)
|
|
|
|
|
nestedNavKey = UUID.randomUUID()
|
|
|
|
|
}
|
|
|
|
|
listDetailNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
|
|
|
|
|
}
|
|
|
|
@ -95,34 +129,34 @@ internal fun InterestsListDetailScreen(
|
|
|
|
|
value = listDetailNavigator.scaffoldValue,
|
|
|
|
|
directive = listDetailNavigator.scaffoldDirective,
|
|
|
|
|
listPane = {
|
|
|
|
|
InterestsRoute(
|
|
|
|
|
onTopicClick = ::onTopicClickShowDetailPane,
|
|
|
|
|
highlightSelectedTopic = listDetailNavigator.isDetailPaneVisible(),
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
detailPane = {
|
|
|
|
|
NavHost(
|
|
|
|
|
navController = nestedNavController,
|
|
|
|
|
startDestination = TOPIC_ROUTE,
|
|
|
|
|
route = DETAIL_PANE_NAVHOST_ROUTE,
|
|
|
|
|
) {
|
|
|
|
|
topicScreen(
|
|
|
|
|
showBackButton = !listDetailNavigator.isListPaneVisible(),
|
|
|
|
|
onBackClick = listDetailNavigator::navigateBack,
|
|
|
|
|
AnimatedPane {
|
|
|
|
|
InterestsRoute(
|
|
|
|
|
onTopicClick = ::onTopicClickShowDetailPane,
|
|
|
|
|
highlightSelectedTopic = listDetailNavigator.isDetailPaneVisible(),
|
|
|
|
|
)
|
|
|
|
|
composable(route = TOPIC_ROUTE) {
|
|
|
|
|
TopicDetailPlaceholder()
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
detailPane = {
|
|
|
|
|
AnimatedPane {
|
|
|
|
|
key(nestedNavKey) {
|
|
|
|
|
NavHost(
|
|
|
|
|
navController = nestedNavController,
|
|
|
|
|
startDestination = nestedNavHostStartDestination,
|
|
|
|
|
route = DETAIL_PANE_NAVHOST_ROUTE,
|
|
|
|
|
) {
|
|
|
|
|
topicScreen(
|
|
|
|
|
showBackButton = !listDetailNavigator.isListPaneVisible(),
|
|
|
|
|
onBackClick = listDetailNavigator::navigateBack,
|
|
|
|
|
onTopicClick = ::onTopicClickShowDetailPane,
|
|
|
|
|
)
|
|
|
|
|
composable(route = TOPIC_ROUTE) {
|
|
|
|
|
TopicDetailPlaceholder()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
LaunchedEffect(Unit) {
|
|
|
|
|
if (selectedTopicId != null) {
|
|
|
|
|
// Initial topic ID was provided when navigating to Interests, so show its details.
|
|
|
|
|
onTopicClickShowDetailPane(selectedTopicId)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
|
|
|
|
|