mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 23:27:04 +05:30
Reapply "refactor(android): migrate to navigation safe-args"
This reverts commit 6296afe51a
.
This commit is contained in:
parent
a7dd2c52f5
commit
8f69490c11
11 changed files with 140 additions and 161 deletions
|
@ -24,6 +24,8 @@ plugins {
|
|||
alias(libs.plugins.licensee)
|
||||
alias(libs.plugins.tracelog)
|
||||
alias(libs.plugins.kotlin.composeCompiler)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.navigation.safeargs)
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
|
@ -22,7 +22,9 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.navigation.NavController
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destinations
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destination
|
||||
import dev.msfjarvis.claw.android.ui.navigation.matches
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
const val AnimationDuration = 100
|
||||
|
@ -51,11 +53,13 @@ fun ClawNavigationBar(
|
|||
modifier = Modifier,
|
||||
) {
|
||||
NavigationBar(modifier = modifier) {
|
||||
val navBackStackEntry = navController.currentBackStackEntryAsState().value
|
||||
val currentDestination = navBackStackEntry?.destination
|
||||
items.forEach { navItem ->
|
||||
val isCurrentDestination = navController.currentDestination?.route == navItem.route
|
||||
val isSelected = currentDestination.matches(navItem.destination)
|
||||
NavigationBarItem(
|
||||
icon = {
|
||||
Crossfade(isCurrentDestination, label = "nav-label") {
|
||||
Crossfade(isSelected, label = "nav-label") {
|
||||
Icon(
|
||||
imageVector = if (it) navItem.selectedIcon else navItem.icon,
|
||||
contentDescription = navItem.label.replaceFirstChar(Char::uppercase),
|
||||
|
@ -63,16 +67,15 @@ fun ClawNavigationBar(
|
|||
}
|
||||
},
|
||||
label = { Text(text = navItem.label) },
|
||||
selected = isCurrentDestination,
|
||||
selected = isSelected,
|
||||
onClick = {
|
||||
if (isCurrentDestination) {
|
||||
if (isSelected) {
|
||||
navItem.listStateResetCallback()
|
||||
} else {
|
||||
navController.graph.startDestinationRoute?.let { startDestination ->
|
||||
navController.popBackStack(startDestination, false)
|
||||
}
|
||||
if (navItem.route != Destinations.startDestination.route) {
|
||||
navController.navigate(navItem.route)
|
||||
navController.navigate(navItem.destination) {
|
||||
popUpTo(navController.graph.startDestinationId) { saveState = true }
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -85,7 +88,7 @@ fun ClawNavigationBar(
|
|||
|
||||
class NavigationItem(
|
||||
val label: String,
|
||||
val route: String,
|
||||
val destination: Destination,
|
||||
val icon: ImageVector,
|
||||
val selectedIcon: ImageVector,
|
||||
val listStateResetCallback: () -> Unit,
|
||||
|
|
|
@ -22,7 +22,8 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.navigation.NavController
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destinations
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import dev.msfjarvis.claw.android.ui.navigation.matches
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Composable
|
||||
|
@ -49,12 +50,14 @@ fun ClawNavigationRail(
|
|||
modifier = Modifier,
|
||||
) {
|
||||
NavigationRail(modifier = modifier) {
|
||||
val navBackStackEntry = navController.currentBackStackEntryAsState().value
|
||||
val currentDestination = navBackStackEntry?.destination
|
||||
Spacer(Modifier.weight(1f))
|
||||
items.forEach { navItem ->
|
||||
val isCurrentDestination = navController.currentDestination?.route == navItem.route
|
||||
val isSelected = currentDestination.matches(navItem.destination)
|
||||
NavigationRailItem(
|
||||
icon = {
|
||||
Crossfade(isCurrentDestination, label = "nav-label") {
|
||||
Crossfade(isSelected, label = "nav-label") {
|
||||
Icon(
|
||||
imageVector = if (it) navItem.selectedIcon else navItem.icon,
|
||||
contentDescription = navItem.label.replaceFirstChar(Char::uppercase),
|
||||
|
@ -62,16 +65,15 @@ fun ClawNavigationRail(
|
|||
}
|
||||
},
|
||||
label = { Text(text = navItem.label) },
|
||||
selected = isCurrentDestination,
|
||||
selected = isSelected,
|
||||
onClick = {
|
||||
if (isCurrentDestination) {
|
||||
if (isSelected) {
|
||||
navItem.listStateResetCallback()
|
||||
} else {
|
||||
navController.graph.startDestinationRoute?.let { startDestination ->
|
||||
navController.popBackStack(startDestination, false)
|
||||
}
|
||||
if (navItem.route != Destinations.startDestination.route) {
|
||||
navController.navigate(navItem.route)
|
||||
navController.navigate(navItem.destination) {
|
||||
popUpTo(navController.graph.startDestinationId) { saveState = true }
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -14,7 +14,7 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.navigation.NavController
|
||||
import com.slack.eithernet.ApiResult
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destinations
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Comments
|
||||
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
|
||||
import dev.msfjarvis.claw.common.posts.PostActions
|
||||
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
||||
|
@ -47,10 +47,7 @@ fun rememberPostActions(
|
|||
|
||||
override fun viewComments(postId: String) {
|
||||
viewModel.markPostAsRead(postId)
|
||||
val currentRoute = navController.currentDestination?.route
|
||||
val newRoute =
|
||||
Destinations.Comments.route.replace(Destinations.Comments.PLACEHOLDER, postId)
|
||||
if (currentRoute != Destinations.Comments.route) navController.navigate(newRoute)
|
||||
navController.navigate(Comments(postId))
|
||||
}
|
||||
|
||||
override fun viewCommentsPage(post: UIPost) {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright © 2024 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.android.ui.navigation
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
sealed interface Destination
|
||||
|
||||
@Serializable data object Hottest : Destination
|
||||
|
||||
@Serializable data object Newest : Destination
|
||||
|
||||
@Serializable data object Saved : Destination
|
||||
|
||||
@Serializable data class Comments(val postId: String) : Destination
|
||||
|
||||
@Serializable data class User(val username: String) : Destination
|
||||
|
||||
@Serializable data object Search : Destination
|
||||
|
||||
@Serializable data object Settings : Destination
|
||||
|
||||
@Serializable data object AboutLibraries : Destination
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2024 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.android.ui.navigation
|
||||
|
||||
sealed class Destinations {
|
||||
abstract val route: String
|
||||
|
||||
data object Hottest : Destinations() {
|
||||
override val route = "hottest"
|
||||
}
|
||||
|
||||
data object Newest : Destinations() {
|
||||
override val route = "newest"
|
||||
}
|
||||
|
||||
data object Saved : Destinations() {
|
||||
override val route = "saved"
|
||||
}
|
||||
|
||||
data object Comments : Destinations() {
|
||||
const val PLACEHOLDER = "{postId}"
|
||||
override val route = "comments/$PLACEHOLDER"
|
||||
}
|
||||
|
||||
data object User : Destinations() {
|
||||
const val PLACEHOLDER = "{username}"
|
||||
override val route = "user/$PLACEHOLDER"
|
||||
}
|
||||
|
||||
data object Search : Destinations() {
|
||||
override val route = "search"
|
||||
}
|
||||
|
||||
data object Settings : Destinations() {
|
||||
override val route = "settings"
|
||||
}
|
||||
|
||||
data object AboutLibraries : Destinations() {
|
||||
override val route = "about_libraries"
|
||||
}
|
||||
|
||||
companion object {
|
||||
val startDestination
|
||||
get() = Hottest
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright © 2024 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
package dev.msfjarvis.claw.android.ui.navigation
|
||||
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.NavDestination.Companion.hasRoute
|
||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
/**
|
||||
* Walk through the [NavDestination]'s [hierarchy] to see if it has any destination that matches the
|
||||
* route defined by [dest].
|
||||
*/
|
||||
fun NavDestination?.matches(dest: Destination): Boolean {
|
||||
return this?.hierarchy?.any { it.hasRoute(dest::class) } == true
|
||||
}
|
||||
|
||||
/** Check if this [NavDestination] [matches] any of the potential navigation [destinations]. */
|
||||
fun NavDestination?.any(destinations: ImmutableList<Destination>): Boolean {
|
||||
return destinations.any { this?.matches(it) == true }
|
||||
}
|
||||
|
||||
/** Check if this [NavDestination] [matches] none of the potential navigation [destinations]. */
|
||||
fun NavDestination?.none(destinations: ImmutableList<Destination>): Boolean {
|
||||
return destinations.none { this?.matches(it) == true }
|
||||
}
|
|
@ -51,12 +51,11 @@ import androidx.compose.ui.semantics.semantics
|
|||
import androidx.compose.ui.semantics.testTagsAsResourceId
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.navArgument
|
||||
import androidx.navigation.toRoute
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.deliveryhero.whetstone.compose.injectedViewModel
|
||||
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
|
||||
|
@ -69,8 +68,16 @@ import dev.msfjarvis.claw.android.ui.decorations.NavigationItem
|
|||
import dev.msfjarvis.claw.android.ui.getActivity
|
||||
import dev.msfjarvis.claw.android.ui.lists.DatabasePosts
|
||||
import dev.msfjarvis.claw.android.ui.lists.NetworkPosts
|
||||
import dev.msfjarvis.claw.android.ui.navigation.AboutLibraries
|
||||
import dev.msfjarvis.claw.android.ui.navigation.ClawNavigationType
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destinations
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Comments
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Hottest
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Newest
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Saved
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Settings
|
||||
import dev.msfjarvis.claw.android.ui.navigation.User
|
||||
import dev.msfjarvis.claw.android.ui.navigation.any
|
||||
import dev.msfjarvis.claw.android.ui.navigation.none
|
||||
import dev.msfjarvis.claw.android.ui.rememberPostActions
|
||||
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
|
||||
import dev.msfjarvis.claw.common.comments.CommentsPage
|
||||
|
@ -79,6 +86,7 @@ import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
|||
import dev.msfjarvis.claw.common.user.UserProfile
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class)
|
||||
|
@ -96,11 +104,11 @@ fun LobstersPostsScreen(
|
|||
val newestListState = rememberLazyListState()
|
||||
val savedListState = rememberLazyListState()
|
||||
val navController = rememberNavController()
|
||||
val navBackStackEntry = navController.currentBackStackEntryAsState().value
|
||||
val currentDestination = navBackStackEntry?.destination
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val postActions = rememberPostActions(context, urlLauncher, navController, viewModel)
|
||||
val backStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentDestination = backStackEntry?.destination?.route
|
||||
|
||||
val hottestPosts = viewModel.hottestPosts.collectAsLazyPagingItems()
|
||||
val newestPosts = viewModel.newestPosts.collectAsLazyPagingItems()
|
||||
|
@ -111,9 +119,7 @@ fun LobstersPostsScreen(
|
|||
val postIdOverride = context.getActivity()?.intent?.extras?.getString(MainActivity.NAVIGATION_KEY)
|
||||
LaunchedEffect(Unit) {
|
||||
if (postIdOverride != null) {
|
||||
navController.navigate(
|
||||
Destinations.Comments.route.replace(Destinations.Comments.PLACEHOLDER, postIdOverride)
|
||||
)
|
||||
navController.navigate(Comments(postIdOverride))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,7 +127,7 @@ fun LobstersPostsScreen(
|
|||
persistentListOf(
|
||||
NavigationItem(
|
||||
label = "Hottest",
|
||||
route = Destinations.Hottest.route,
|
||||
destination = Hottest,
|
||||
icon = Icons.Outlined.Whatshot,
|
||||
selectedIcon = Icons.Filled.Whatshot,
|
||||
) {
|
||||
|
@ -131,7 +137,7 @@ fun LobstersPostsScreen(
|
|||
},
|
||||
NavigationItem(
|
||||
label = "Newest",
|
||||
route = Destinations.Newest.route,
|
||||
destination = Newest,
|
||||
icon = Icons.Outlined.NewReleases,
|
||||
selectedIcon = Icons.Filled.NewReleases,
|
||||
) {
|
||||
|
@ -141,13 +147,14 @@ fun LobstersPostsScreen(
|
|||
},
|
||||
NavigationItem(
|
||||
label = "Saved",
|
||||
route = Destinations.Saved.route,
|
||||
destination = Saved,
|
||||
icon = Icons.Outlined.FavoriteBorder,
|
||||
selectedIcon = Icons.Filled.Favorite,
|
||||
) {
|
||||
coroutineScope.launch { if (savedPosts.isNotEmpty()) savedListState.scrollToItem(0) }
|
||||
},
|
||||
)
|
||||
val navDestinations = navItems.map(NavigationItem::destination).toPersistentList()
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
|
@ -155,8 +162,7 @@ fun LobstersPostsScreen(
|
|||
modifier = Modifier.shadow(8.dp),
|
||||
navigationIcon = {
|
||||
if (
|
||||
navController.previousBackStackEntry != null &&
|
||||
navItems.none { it.route == currentDestination }
|
||||
navController.previousBackStackEntry != null && currentDestination.none(navDestinations)
|
||||
) {
|
||||
IconButton(
|
||||
onClick = { if (!navController.popBackStack()) context.getActivity()?.finish() }
|
||||
|
@ -175,18 +181,18 @@ fun LobstersPostsScreen(
|
|||
}
|
||||
},
|
||||
title = {
|
||||
if (navItems.any { it.route == currentDestination }) {
|
||||
if (currentDestination.any(navDestinations)) {
|
||||
Text(text = stringResource(R.string.app_name), fontWeight = FontWeight.Bold)
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
if (navItems.any { it.route == currentDestination }) {
|
||||
if (currentDestination.any(navDestinations)) {
|
||||
IconButton(
|
||||
onClick = { context.startActivity(Intent(context, SearchActivity::class.java)) }
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.Search, contentDescription = "Search posts")
|
||||
}
|
||||
IconButton(onClick = { navController.navigate(Destinations.Settings.route) }) {
|
||||
IconButton(onClick = { navController.navigate(Settings) }) {
|
||||
Icon(imageVector = Icons.Filled.Tune, contentDescription = "Settings")
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +204,7 @@ fun LobstersPostsScreen(
|
|||
ClawNavigationBar(
|
||||
navController = navController,
|
||||
items = navItems,
|
||||
isVisible = navItems.any { it.route == currentDestination },
|
||||
isVisible = currentDestination.any(navDestinations),
|
||||
)
|
||||
}
|
||||
},
|
||||
|
@ -210,18 +216,18 @@ fun LobstersPostsScreen(
|
|||
ClawNavigationRail(
|
||||
navController = navController,
|
||||
items = navItems,
|
||||
isVisible = navItems.any { it.route == currentDestination },
|
||||
isVisible = currentDestination.any(navDestinations),
|
||||
)
|
||||
}
|
||||
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = Destinations.startDestination.route,
|
||||
startDestination = Hottest,
|
||||
// Make animations 2x faster than default specs
|
||||
enterTransition = { fadeIn(animationSpec = tween(350)) },
|
||||
exitTransition = { fadeOut(animationSpec = tween(350)) },
|
||||
) {
|
||||
composable(route = Destinations.Hottest.route) {
|
||||
composable<Hottest> {
|
||||
setWebUri("https://lobste.rs/")
|
||||
NetworkPosts(
|
||||
lazyPagingItems = hottestPosts,
|
||||
|
@ -229,7 +235,7 @@ fun LobstersPostsScreen(
|
|||
postActions = postActions,
|
||||
)
|
||||
}
|
||||
composable(route = Destinations.Newest.route) {
|
||||
composable<Newest> {
|
||||
setWebUri("https://lobste.rs/")
|
||||
NetworkPosts(
|
||||
lazyPagingItems = newestPosts,
|
||||
|
@ -237,18 +243,12 @@ fun LobstersPostsScreen(
|
|||
postActions = postActions,
|
||||
)
|
||||
}
|
||||
composable(route = Destinations.Saved.route) {
|
||||
composable<Saved> {
|
||||
setWebUri(null)
|
||||
DatabasePosts(items = savedPosts, listState = savedListState, postActions = postActions)
|
||||
}
|
||||
composable(
|
||||
route = Destinations.Comments.route,
|
||||
arguments = listOf(navArgument("postId") { type = NavType.StringType }),
|
||||
) { backStackEntry ->
|
||||
val postId =
|
||||
requireNotNull(backStackEntry.arguments?.getString("postId")) {
|
||||
"Navigating to ${Destinations.Comments.route} without necessary 'postId' argument"
|
||||
}
|
||||
composable<Comments> { backStackEntry ->
|
||||
val postId = backStackEntry.toRoute<Comments>().postId
|
||||
setWebUri("https://lobste.rs/s/$postId")
|
||||
CommentsPage(
|
||||
postId = postId,
|
||||
|
@ -256,45 +256,29 @@ fun LobstersPostsScreen(
|
|||
htmlConverter = htmlConverter,
|
||||
getSeenComments = viewModel::getSeenComments,
|
||||
markSeenComments = viewModel::markSeenComments,
|
||||
openUserProfile = {
|
||||
navController.navigate(
|
||||
Destinations.User.route.replace(Destinations.User.PLACEHOLDER, it)
|
||||
)
|
||||
},
|
||||
openUserProfile = { navController.navigate(User(it)) },
|
||||
)
|
||||
}
|
||||
composable(
|
||||
route = Destinations.User.route,
|
||||
arguments = listOf(navArgument("username") { type = NavType.StringType }),
|
||||
) { backStackEntry ->
|
||||
val username =
|
||||
requireNotNull(backStackEntry.arguments?.getString("username")) {
|
||||
"Navigating to ${Destinations.User.route} without necessary 'username' argument"
|
||||
}
|
||||
composable<User> { backStackEntry ->
|
||||
val username = backStackEntry.toRoute<User>().username
|
||||
setWebUri("https://lobste.rs/u/$username")
|
||||
UserProfile(
|
||||
username = username,
|
||||
getProfile = viewModel::getUserProfile,
|
||||
openUserProfile = {
|
||||
navController.navigate(
|
||||
Destinations.User.route.replace(Destinations.User.PLACEHOLDER, it)
|
||||
)
|
||||
},
|
||||
openUserProfile = { navController.navigate(User(it)) },
|
||||
)
|
||||
}
|
||||
composable(route = Destinations.Settings.route) {
|
||||
composable<Settings> {
|
||||
SettingsScreen(
|
||||
context = context,
|
||||
openLibrariesScreen = { navController.navigate(Destinations.AboutLibraries.route) },
|
||||
openLibrariesScreen = { navController.navigate(AboutLibraries) },
|
||||
importPosts = viewModel::importPosts,
|
||||
exportPostsAsJson = viewModel::exportPostsAsJson,
|
||||
exportPostsAsHtml = viewModel::exportPostsAsHtml,
|
||||
snackbarHostState = snackbarHostState,
|
||||
)
|
||||
}
|
||||
composable(route = Destinations.AboutLibraries.route) {
|
||||
LibrariesContainer(modifier = Modifier.fillMaxSize())
|
||||
}
|
||||
composable<AboutLibraries> { LibrariesContainer(modifier = Modifier.fillMaxSize()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,14 +12,15 @@ import androidx.compose.material3.Scaffold
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.navArgument
|
||||
import androidx.navigation.toRoute
|
||||
import com.deliveryhero.whetstone.compose.injectedViewModel
|
||||
import dev.msfjarvis.claw.android.ui.lists.SearchList
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destinations
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Comments
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Search
|
||||
import dev.msfjarvis.claw.android.ui.navigation.User
|
||||
import dev.msfjarvis.claw.android.ui.rememberPostActions
|
||||
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
|
||||
import dev.msfjarvis.claw.common.comments.CommentsPage
|
||||
|
@ -41,10 +42,10 @@ fun SearchScreen(
|
|||
Scaffold(modifier = modifier) { paddingValues ->
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = Destinations.Search.route,
|
||||
startDestination = Search,
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
) {
|
||||
composable(route = Destinations.Search.route) {
|
||||
composable<Search> {
|
||||
setWebUri("https://lobste.rs/search")
|
||||
SearchList(
|
||||
items = viewModel.searchResults,
|
||||
|
@ -54,14 +55,8 @@ fun SearchScreen(
|
|||
setSearchQuery = { query -> viewModel.searchQuery = query },
|
||||
)
|
||||
}
|
||||
composable(
|
||||
route = Destinations.Comments.route,
|
||||
arguments = listOf(navArgument("postId") { type = NavType.StringType }),
|
||||
) { backStackEntry ->
|
||||
val postId =
|
||||
requireNotNull(backStackEntry.arguments?.getString("postId")) {
|
||||
"Navigating to ${Destinations.Comments.route} without necessary 'postId' argument"
|
||||
}
|
||||
composable<Comments> { backStackEntry ->
|
||||
val postId = backStackEntry.toRoute<Comments>().postId
|
||||
setWebUri("https://lobste.rs/s/$postId")
|
||||
CommentsPage(
|
||||
postId = postId,
|
||||
|
@ -69,30 +64,16 @@ fun SearchScreen(
|
|||
htmlConverter = htmlConverter,
|
||||
getSeenComments = viewModel::getSeenComments,
|
||||
markSeenComments = viewModel::markSeenComments,
|
||||
openUserProfile = { username: String ->
|
||||
navController.navigate(
|
||||
Destinations.User.route.replace(Destinations.User.PLACEHOLDER, username)
|
||||
)
|
||||
},
|
||||
openUserProfile = { navController.navigate(User(it)) },
|
||||
)
|
||||
}
|
||||
composable(
|
||||
route = Destinations.User.route,
|
||||
arguments = listOf(navArgument("username") { type = NavType.StringType }),
|
||||
) { backStackEntry ->
|
||||
val username =
|
||||
requireNotNull(backStackEntry.arguments?.getString("username")) {
|
||||
"Navigating to ${Destinations.User.route} without necessary 'username' argument"
|
||||
}
|
||||
composable<User> { backStackEntry ->
|
||||
val username = backStackEntry.toRoute<User>().username
|
||||
setWebUri("https://lobste.rs/u/$username")
|
||||
UserProfile(
|
||||
username = username,
|
||||
getProfile = viewModel::getUserProfile,
|
||||
openUserProfile = {
|
||||
navController.navigate(
|
||||
Destinations.User.route.replace(Destinations.User.PLACEHOLDER, it)
|
||||
)
|
||||
},
|
||||
openUserProfile = { navController.navigate(User(it)) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue