mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 18:47:03 +05:30
refactor: eliminate Destination indirection
This commit is contained in:
parent
9dce06ff80
commit
f64d4ab9a1
7 changed files with 34 additions and 40 deletions
|
@ -17,7 +17,6 @@ plugins {
|
|||
id("dev.msfjarvis.claw.kotlin-kapt")
|
||||
id("dev.msfjarvis.claw.sentry")
|
||||
id("dev.msfjarvis.claw.versioning-plugin")
|
||||
id("kotlin-parcelize")
|
||||
alias(libs.plugins.aboutlibraries)
|
||||
alias(libs.plugins.android.junit5)
|
||||
alias(libs.plugins.anvil)
|
||||
|
|
|
@ -24,8 +24,8 @@ import androidx.compose.ui.res.painterResource
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation3.runtime.NavKey
|
||||
import dev.msfjarvis.claw.android.R
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destination
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Search
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Settings
|
||||
|
||||
|
@ -34,8 +34,8 @@ import dev.msfjarvis.claw.android.ui.navigation.Settings
|
|||
fun ClawAppBar(
|
||||
activity: Activity?,
|
||||
isTopLevel: Boolean,
|
||||
navigateTo: (Destination) -> Unit,
|
||||
popBackStack: () -> Destination?,
|
||||
navigateTo: (NavKey) -> Unit,
|
||||
popBackStack: () -> NavKey?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
TopAppBar(
|
||||
|
|
|
@ -26,12 +26,12 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation3.runtime.NavKey
|
||||
import dev.chrisbanes.haze.HazeDefaults
|
||||
import dev.chrisbanes.haze.HazeState
|
||||
import dev.chrisbanes.haze.HazeStyle
|
||||
import dev.chrisbanes.haze.hazeEffect
|
||||
import dev.msfjarvis.claw.android.ui.navigation.AppDestinations
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destination
|
||||
import dev.msfjarvis.claw.common.ui.FloatingNavigationBar
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
|
@ -40,8 +40,8 @@ const val AnimationDuration = 100
|
|||
@Composable
|
||||
fun ClawNavigationBar(
|
||||
items: ImmutableList<NavigationItem>,
|
||||
currentDestination: Destination?,
|
||||
navigateTo: (Destination) -> Unit,
|
||||
currentNavKey: NavKey?,
|
||||
navigateTo: (NavKey) -> Unit,
|
||||
isVisible: Boolean,
|
||||
hazeState: HazeState,
|
||||
modifier: Modifier = Modifier,
|
||||
|
@ -84,7 +84,7 @@ fun ClawNavigationBar(
|
|||
if (HazeDefaults.blurEnabled()) Color.Transparent else MaterialTheme.colorScheme.surface,
|
||||
) {
|
||||
items.forEach { navItem ->
|
||||
val isSelected = currentDestination == navItem.destination
|
||||
val isSelected = currentNavKey == navItem.navKey
|
||||
NavigationBarItem(
|
||||
icon = {
|
||||
Crossfade(isSelected, label = "nav-label") {
|
||||
|
@ -100,7 +100,7 @@ fun ClawNavigationBar(
|
|||
if (isSelected) {
|
||||
navItem.listStateResetCallback()
|
||||
} else {
|
||||
navigateTo(navItem.destination)
|
||||
navigateTo(navItem.navKey)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.testTag(navItem.label.uppercase()),
|
||||
|
@ -115,7 +115,7 @@ class NavigationItem
|
|||
private constructor(
|
||||
val icon: ImageVector,
|
||||
val label: String,
|
||||
val destination: Destination,
|
||||
val navKey: NavKey,
|
||||
val selectedIcon: ImageVector,
|
||||
val listStateResetCallback: () -> Unit,
|
||||
) {
|
||||
|
@ -125,7 +125,7 @@ private constructor(
|
|||
) : this(
|
||||
destination.icon,
|
||||
destination.label,
|
||||
destination.destination,
|
||||
destination.navKey,
|
||||
destination.selectedIcon,
|
||||
listStateResetCallback,
|
||||
) {}
|
||||
|
|
|
@ -21,14 +21,14 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destination
|
||||
import androidx.navigation3.runtime.NavKey
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Composable
|
||||
fun ClawNavigationRail(
|
||||
items: ImmutableList<NavigationItem>,
|
||||
currentDestination: Destination?,
|
||||
navigateTo: (Destination) -> Unit,
|
||||
currentNavKey: NavKey?,
|
||||
navigateTo: (NavKey) -> Unit,
|
||||
isVisible: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
@ -51,7 +51,7 @@ fun ClawNavigationRail(
|
|||
NavigationRail(modifier = modifier) {
|
||||
Spacer(Modifier.weight(1f))
|
||||
items.forEach { navItem ->
|
||||
val isSelected = currentDestination == navItem.destination
|
||||
val isSelected = currentNavKey == navItem.navKey
|
||||
NavigationRailItem(
|
||||
icon = {
|
||||
Crossfade(isSelected, label = "nav-label") {
|
||||
|
@ -67,7 +67,7 @@ fun ClawNavigationRail(
|
|||
if (isSelected) {
|
||||
navItem.listStateResetCallback()
|
||||
} else {
|
||||
navigateTo(navItem.destination)
|
||||
navigateTo(navItem.navKey)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.testTag(navItem.label.uppercase()),
|
||||
|
|
|
@ -22,7 +22,7 @@ import io.github.aakira.napier.Napier
|
|||
* 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].
|
||||
*/
|
||||
class ClawBackStack<T : NavKey>(private val initialDestination: T) {
|
||||
class ClawBackStack(private val initialDestination: NavKey) {
|
||||
/**
|
||||
* Marker interface for destinations that occupy the "top" level of the back stack.
|
||||
*
|
||||
|
@ -41,7 +41,7 @@ class ClawBackStack<T : NavKey>(private val initialDestination: T) {
|
|||
* from getting stuck in a frustratingly long stack of top level destinations that are so easily
|
||||
* accessible that they have no reason to be on the stack.
|
||||
*/
|
||||
fun add(destination: T) {
|
||||
fun add(destination: NavKey) {
|
||||
logCurrentState("add")
|
||||
if (destination is TopLevelDestination) {
|
||||
backStack.clear()
|
||||
|
@ -59,17 +59,17 @@ class ClawBackStack<T : NavKey>(private val initialDestination: T) {
|
|||
return (top != null && top is TopLevelDestination)
|
||||
}
|
||||
|
||||
fun firstOrNull(): T? {
|
||||
fun firstOrNull(): NavKey? {
|
||||
logCurrentState("firstOrNull")
|
||||
return backStack.lastOrNull()
|
||||
}
|
||||
|
||||
fun lastOrNull(): T? {
|
||||
fun lastOrNull(): NavKey? {
|
||||
logCurrentState("lastOrNull")
|
||||
return backStack.firstOrNull()
|
||||
}
|
||||
|
||||
fun removeLastOrNull(): T? {
|
||||
fun removeLastOrNull(): NavKey? {
|
||||
logCurrentState("removeLastOrNull")
|
||||
return backStack.removeLastOrNull()
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package dev.msfjarvis.claw.android.ui.navigation
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Favorite
|
||||
import androidx.compose.material.icons.filled.NewReleases
|
||||
|
@ -17,49 +16,46 @@ import androidx.compose.material.icons.outlined.Whatshot
|
|||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.navigation3.runtime.NavKey
|
||||
import dev.msfjarvis.claw.android.ui.navigation.ClawBackStack.TopLevelDestination
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
sealed interface Destination : Parcelable, NavKey
|
||||
@Serializable data object Hottest : NavKey, TopLevelDestination
|
||||
|
||||
@Parcelize @Serializable data object Hottest : Destination, TopLevelDestination
|
||||
@Serializable data object Newest : NavKey, TopLevelDestination
|
||||
|
||||
@Parcelize @Serializable data object Newest : Destination, TopLevelDestination
|
||||
@Serializable data object Saved : NavKey, TopLevelDestination
|
||||
|
||||
@Parcelize @Serializable data object Saved : Destination, TopLevelDestination
|
||||
@Serializable data class Comments(val postId: String) : NavKey
|
||||
|
||||
@Parcelize @Serializable data class Comments(val postId: String) : Destination
|
||||
@Serializable data class User(val username: String) : NavKey
|
||||
|
||||
@Parcelize @Serializable data class User(val username: String) : Destination
|
||||
@Serializable data object Search : NavKey
|
||||
|
||||
@Parcelize @Serializable data object Search : Destination
|
||||
@Serializable data object Settings : NavKey
|
||||
|
||||
@Parcelize @Serializable data object Settings : Destination
|
||||
|
||||
@Parcelize @Serializable data object AboutLibraries : Destination
|
||||
@Serializable data object AboutLibraries : NavKey
|
||||
|
||||
enum class AppDestinations(
|
||||
val icon: ImageVector,
|
||||
val label: String,
|
||||
val destination: Destination,
|
||||
val navKey: NavKey,
|
||||
val selectedIcon: ImageVector,
|
||||
) {
|
||||
HOTTEST(
|
||||
icon = Icons.Outlined.Whatshot,
|
||||
label = "Hottest",
|
||||
destination = Hottest,
|
||||
navKey = Hottest,
|
||||
selectedIcon = Icons.Filled.Whatshot,
|
||||
),
|
||||
NEWEST(
|
||||
icon = Icons.Outlined.NewReleases,
|
||||
label = "Newest",
|
||||
destination = Newest,
|
||||
navKey = Newest,
|
||||
selectedIcon = Icons.Filled.NewReleases,
|
||||
),
|
||||
SAVED(
|
||||
icon = Icons.Outlined.FavoriteBorder,
|
||||
label = "Saved",
|
||||
destination = Saved,
|
||||
navKey = Saved,
|
||||
selectedIcon = Icons.Filled.Favorite,
|
||||
),
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ import dev.msfjarvis.claw.android.ui.navigation.AppDestinations
|
|||
import dev.msfjarvis.claw.android.ui.navigation.ClawBackStack
|
||||
import dev.msfjarvis.claw.android.ui.navigation.ClawNavigationType
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Comments
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Destination
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Hottest
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Newest
|
||||
import dev.msfjarvis.claw.android.ui.navigation.Saved
|
||||
|
@ -75,7 +74,7 @@ fun Nav3Screen(
|
|||
modifier: Modifier = Modifier,
|
||||
viewModel: ClawViewModel = injectedViewModel(),
|
||||
) {
|
||||
val clawBackStack = ClawBackStack<Destination>(Hottest)
|
||||
val clawBackStack = ClawBackStack(Hottest)
|
||||
|
||||
// region Pain
|
||||
val context = LocalContext.current
|
||||
|
@ -136,7 +135,7 @@ fun Nav3Screen(
|
|||
AnimatedVisibility(visible = navigationType == ClawNavigationType.BOTTOM_NAVIGATION) {
|
||||
ClawNavigationBar(
|
||||
items = navItems,
|
||||
currentDestination = currentDestination,
|
||||
currentNavKey = currentDestination,
|
||||
navigateTo = { clawBackStack.add(it) },
|
||||
isVisible = clawBackStack.isOnTopLevelDestination(),
|
||||
hazeState = hazeState,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue