mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 22:17:03 +05:30
refactor: consistently use destination over route
This commit is contained in:
parent
9c76617700
commit
beb1943ee6
3 changed files with 26 additions and 25 deletions
|
@ -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? {
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue