refactor: consistently use destination over route

This commit is contained in:
Harsh Shandilya 2025-05-25 17:54:17 +05:30
parent 9c76617700
commit beb1943ee6
3 changed files with 26 additions and 25 deletions

View file

@ -22,41 +22,41 @@ import io.github.aakira.napier.Napier
* to the front while lists add behind. To counter these expectations with the actual backing data * to the front while lists add behind. To counter these expectations with the actual backing data
* structure, many APIs in this class inverse of identically named functions on [List]. * structure, many APIs in this class inverse of identically named functions on [List].
*/ */
class ClawBackStack<T : NavKey>(private val startRoute: T) { class ClawBackStack<T : NavKey>(private val initialDestination: T) {
/** /**
* Marker interface for routes that occupy the "top" level of the back stack. * Marker interface for destinations that occupy the "top" level of the back stack.
* *
* This is used by [dev.msfjarvis.claw.android.ui.navigation.ClawBackStack.add] to ensure that * This is used by [dev.msfjarvis.claw.android.ui.navigation.ClawBackStack.add] to ensure that
* duplicate instances of these routes do not end up in the back stack. * duplicate instances of these destinations do not end up in the back stack.
*/ */
interface TopLevelRoute interface TopLevelDestination
val backStack = mutableStateListOf(startRoute) val backStack = mutableStateListOf(initialDestination)
/** /**
* Pushes a new destination onto the stack. * Pushes a new destination onto the stack.
* *
* Top level routes are specially handled to ensure that the distance between the incoming [route] * Top level destinations are specially handled to ensure that the distance between the incoming
* and the [startRoute] cannot have anything in between. This prevents users from getting stuck in * [destination] and the [initialDestination] cannot have anything in between. This prevents users
* a frustratingly long stack of top level destinations that are so easily accessible that they * from getting stuck in a frustratingly long stack of top level destinations that are so easily
* have no reason to be on the stack. * accessible that they have no reason to be on the stack.
*/ */
fun add(route: T) { fun add(destination: T) {
logCurrentState("add") logCurrentState("add")
if (route is TopLevelRoute) { if (destination is TopLevelDestination) {
backStack.clear() backStack.clear()
if (route != startRoute) { if (destination != initialDestination) {
backStack.add(startRoute) backStack.add(initialDestination)
} }
} }
backStack.add(route) backStack.add(destination)
} }
/** Checks if the "top" item in the back stack is an instance of [TopLevelRoute]. */ /** Checks if the "top" item in the back stack is an instance of [TopLevelDestination]. */
fun isOnTopLevelRoute(): Boolean { fun isOnTopLevelDestination(): Boolean {
logCurrentState("hasTopLevelDestination") logCurrentState("isOnTopLevelDestination")
val top = firstOrNull() val top = firstOrNull()
return (top != null && top is TopLevelRoute) return (top != null && top is TopLevelDestination)
} }
fun firstOrNull(): T? { fun firstOrNull(): T? {

View file

@ -16,16 +16,17 @@ import androidx.compose.material.icons.outlined.NewReleases
import androidx.compose.material.icons.outlined.Whatshot import androidx.compose.material.icons.outlined.Whatshot
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.NavKey
import dev.msfjarvis.claw.android.ui.navigation.ClawBackStack.TopLevelDestination
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
sealed interface Destination : Parcelable, NavKey sealed interface Destination : Parcelable, NavKey
@Parcelize @Serializable data object Hottest : Destination, ClawBackStack.TopLevelRoute @Parcelize @Serializable data object Hottest : Destination, TopLevelDestination
@Parcelize @Serializable data object Newest : Destination, ClawBackStack.TopLevelRoute @Parcelize @Serializable data object Newest : Destination, TopLevelDestination
@Parcelize @Serializable data object Saved : Destination, ClawBackStack.TopLevelRoute @Parcelize @Serializable data object Saved : Destination, TopLevelDestination
@Parcelize @Serializable data class Comments(val postId: String) : Destination @Parcelize @Serializable data class Comments(val postId: String) : Destination

View file

@ -141,7 +141,7 @@ fun Nav3Screen(
TopAppBar( TopAppBar(
modifier = Modifier.shadow(8.dp), modifier = Modifier.shadow(8.dp),
navigationIcon = { navigationIcon = {
if (!(clawBackStack.isOnTopLevelRoute())) { if (!(clawBackStack.isOnTopLevelDestination())) {
IconButton( IconButton(
onClick = { if (clawBackStack.removeLastOrNull() == null) activity?.finish() } onClick = { if (clawBackStack.removeLastOrNull() == null) activity?.finish() }
) { ) {
@ -159,12 +159,12 @@ fun Nav3Screen(
} }
}, },
title = { title = {
if (clawBackStack.isOnTopLevelRoute()) { if (clawBackStack.isOnTopLevelDestination()) {
Text(text = stringResource(R.string.app_name), fontWeight = FontWeight.Bold) Text(text = stringResource(R.string.app_name), fontWeight = FontWeight.Bold)
} }
}, },
actions = { actions = {
if (clawBackStack.isOnTopLevelRoute()) { if (clawBackStack.isOnTopLevelDestination()) {
IconButton(onClick = { clawBackStack.add(Search) }) { IconButton(onClick = { clawBackStack.add(Search) }) {
Icon(imageVector = Icons.Filled.Search, contentDescription = "Search posts") Icon(imageVector = Icons.Filled.Search, contentDescription = "Search posts")
} }
@ -180,7 +180,7 @@ fun Nav3Screen(
ClawNavigationBar( ClawNavigationBar(
clawBackStack, clawBackStack,
items = navItems, items = navItems,
isVisible = clawBackStack.isOnTopLevelRoute(), isVisible = clawBackStack.isOnTopLevelDestination(),
hazeState = hazeState, hazeState = hazeState,
) )
} }