mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-15 00:37:03 +05:30
refactor: pull out ClawAppBar
Also change consumers of ClawBackStack to take delegating references
This commit is contained in:
parent
beb1943ee6
commit
9dce06ff80
4 changed files with 90 additions and 59 deletions
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 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.decorations
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.Search
|
||||||
|
import androidx.compose.material.icons.filled.Tune
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.shadow
|
||||||
|
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 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
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun ClawAppBar(
|
||||||
|
activity: Activity?,
|
||||||
|
isTopLevel: Boolean,
|
||||||
|
navigateTo: (Destination) -> Unit,
|
||||||
|
popBackStack: () -> Destination?,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
TopAppBar(
|
||||||
|
modifier = modifier.shadow(8.dp),
|
||||||
|
navigationIcon = {
|
||||||
|
if (!isTopLevel) {
|
||||||
|
IconButton(onClick = { if (popBackStack() == null) activity?.finish() }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
contentDescription = "Go back to previous screen",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_launcher_foreground),
|
||||||
|
contentDescription = "The app icon for Claw",
|
||||||
|
modifier = Modifier.size(48.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title = {
|
||||||
|
if (isTopLevel) {
|
||||||
|
Text(text = stringResource(R.string.app_name), fontWeight = FontWeight.Bold)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions = {
|
||||||
|
if (isTopLevel) {
|
||||||
|
IconButton(onClick = { navigateTo(Search) }) {
|
||||||
|
Icon(imageVector = Icons.Filled.Search, contentDescription = "Search posts")
|
||||||
|
}
|
||||||
|
IconButton(onClick = { navigateTo(Settings) }) {
|
||||||
|
Icon(imageVector = Icons.Filled.Tune, contentDescription = "Settings")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
|
@ -31,7 +31,6 @@ import dev.chrisbanes.haze.HazeState
|
||||||
import dev.chrisbanes.haze.HazeStyle
|
import dev.chrisbanes.haze.HazeStyle
|
||||||
import dev.chrisbanes.haze.hazeEffect
|
import dev.chrisbanes.haze.hazeEffect
|
||||||
import dev.msfjarvis.claw.android.ui.navigation.AppDestinations
|
import dev.msfjarvis.claw.android.ui.navigation.AppDestinations
|
||||||
import dev.msfjarvis.claw.android.ui.navigation.ClawBackStack
|
|
||||||
import dev.msfjarvis.claw.android.ui.navigation.Destination
|
import dev.msfjarvis.claw.android.ui.navigation.Destination
|
||||||
import dev.msfjarvis.claw.common.ui.FloatingNavigationBar
|
import dev.msfjarvis.claw.common.ui.FloatingNavigationBar
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
@ -40,8 +39,9 @@ const val AnimationDuration = 100
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ClawNavigationBar(
|
fun ClawNavigationBar(
|
||||||
backStack: ClawBackStack<Destination>,
|
|
||||||
items: ImmutableList<NavigationItem>,
|
items: ImmutableList<NavigationItem>,
|
||||||
|
currentDestination: Destination?,
|
||||||
|
navigateTo: (Destination) -> Unit,
|
||||||
isVisible: Boolean,
|
isVisible: Boolean,
|
||||||
hazeState: HazeState,
|
hazeState: HazeState,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
@ -83,7 +83,6 @@ fun ClawNavigationBar(
|
||||||
containerColor =
|
containerColor =
|
||||||
if (HazeDefaults.blurEnabled()) Color.Transparent else MaterialTheme.colorScheme.surface,
|
if (HazeDefaults.blurEnabled()) Color.Transparent else MaterialTheme.colorScheme.surface,
|
||||||
) {
|
) {
|
||||||
val currentDestination = backStack.firstOrNull()
|
|
||||||
items.forEach { navItem ->
|
items.forEach { navItem ->
|
||||||
val isSelected = currentDestination == navItem.destination
|
val isSelected = currentDestination == navItem.destination
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
|
@ -101,7 +100,7 @@ fun ClawNavigationBar(
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
navItem.listStateResetCallback()
|
navItem.listStateResetCallback()
|
||||||
} else {
|
} else {
|
||||||
backStack.add(navItem.destination)
|
navigateTo(navItem.destination)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modifier = Modifier.testTag(navItem.label.uppercase()),
|
modifier = Modifier.testTag(navItem.label.uppercase()),
|
||||||
|
|
|
@ -21,14 +21,14 @@ import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import dev.msfjarvis.claw.android.ui.navigation.ClawBackStack
|
|
||||||
import dev.msfjarvis.claw.android.ui.navigation.Destination
|
import dev.msfjarvis.claw.android.ui.navigation.Destination
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ClawNavigationRail(
|
fun ClawNavigationRail(
|
||||||
backStack: ClawBackStack<Destination>,
|
|
||||||
items: ImmutableList<NavigationItem>,
|
items: ImmutableList<NavigationItem>,
|
||||||
|
currentDestination: Destination?,
|
||||||
|
navigateTo: (Destination) -> Unit,
|
||||||
isVisible: Boolean,
|
isVisible: Boolean,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
@ -49,7 +49,6 @@ fun ClawNavigationRail(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
NavigationRail(modifier = modifier) {
|
NavigationRail(modifier = modifier) {
|
||||||
val currentDestination = backStack.firstOrNull()
|
|
||||||
Spacer(Modifier.weight(1f))
|
Spacer(Modifier.weight(1f))
|
||||||
items.forEach { navItem ->
|
items.forEach { navItem ->
|
||||||
val isSelected = currentDestination == navItem.destination
|
val isSelected = currentDestination == navItem.destination
|
||||||
|
@ -68,7 +67,7 @@ fun ClawNavigationRail(
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
navItem.listStateResetCallback()
|
navItem.listStateResetCallback()
|
||||||
} else {
|
} else {
|
||||||
backStack.add(navItem.destination)
|
navigateTo(navItem.destination)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modifier = Modifier.testTag(navItem.label.uppercase()),
|
modifier = Modifier.testTag(navItem.label.uppercase()),
|
||||||
|
|
|
@ -15,20 +15,11 @@ import androidx.compose.animation.slideInHorizontally
|
||||||
import androidx.compose.animation.slideOutHorizontally
|
import androidx.compose.animation.slideOutHorizontally
|
||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|
||||||
import androidx.compose.material.icons.filled.Search
|
|
||||||
import androidx.compose.material.icons.filled.Tune
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.SnackbarHost
|
import androidx.compose.material3.SnackbarHost
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TopAppBar
|
|
||||||
import androidx.compose.material3.windowsizeclass.WindowSizeClass
|
import androidx.compose.material3.windowsizeclass.WindowSizeClass
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
@ -36,14 +27,9 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.shadow
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.semantics.testTagsAsResourceId
|
import androidx.compose.ui.semantics.testTagsAsResourceId
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.navigation3.runtime.entry
|
import androidx.navigation3.runtime.entry
|
||||||
import androidx.navigation3.runtime.entryProvider
|
import androidx.navigation3.runtime.entryProvider
|
||||||
|
@ -54,8 +40,8 @@ import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
|
||||||
import dev.chrisbanes.haze.HazeState
|
import dev.chrisbanes.haze.HazeState
|
||||||
import dev.chrisbanes.haze.hazeSource
|
import dev.chrisbanes.haze.hazeSource
|
||||||
import dev.msfjarvis.claw.android.MainActivity
|
import dev.msfjarvis.claw.android.MainActivity
|
||||||
import dev.msfjarvis.claw.android.R
|
|
||||||
import dev.msfjarvis.claw.android.ui.PostActions
|
import dev.msfjarvis.claw.android.ui.PostActions
|
||||||
|
import dev.msfjarvis.claw.android.ui.decorations.ClawAppBar
|
||||||
import dev.msfjarvis.claw.android.ui.decorations.ClawNavigationBar
|
import dev.msfjarvis.claw.android.ui.decorations.ClawNavigationBar
|
||||||
import dev.msfjarvis.claw.android.ui.decorations.NavigationItem
|
import dev.msfjarvis.claw.android.ui.decorations.NavigationItem
|
||||||
import dev.msfjarvis.claw.android.ui.lists.DatabasePosts
|
import dev.msfjarvis.claw.android.ui.lists.DatabasePosts
|
||||||
|
@ -138,48 +124,20 @@ fun Nav3Screen(
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
ClawAppBar(
|
||||||
modifier = Modifier.shadow(8.dp),
|
activity = activity,
|
||||||
navigationIcon = {
|
isTopLevel = clawBackStack.isOnTopLevelDestination(),
|
||||||
if (!(clawBackStack.isOnTopLevelDestination())) {
|
navigateTo = { clawBackStack.add(it) },
|
||||||
IconButton(
|
popBackStack = { clawBackStack.removeLastOrNull() },
|
||||||
onClick = { if (clawBackStack.removeLastOrNull() == null) activity?.finish() }
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
|
||||||
contentDescription = "Go back to previous screen",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.ic_launcher_foreground),
|
|
||||||
contentDescription = "The app icon for Claw",
|
|
||||||
modifier = Modifier.size(48.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
title = {
|
|
||||||
if (clawBackStack.isOnTopLevelDestination()) {
|
|
||||||
Text(text = stringResource(R.string.app_name), fontWeight = FontWeight.Bold)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions = {
|
|
||||||
if (clawBackStack.isOnTopLevelDestination()) {
|
|
||||||
IconButton(onClick = { clawBackStack.add(Search) }) {
|
|
||||||
Icon(imageVector = Icons.Filled.Search, contentDescription = "Search posts")
|
|
||||||
}
|
|
||||||
IconButton(onClick = { clawBackStack.add(Settings) }) {
|
|
||||||
Icon(imageVector = Icons.Filled.Tune, contentDescription = "Settings")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
|
val currentDestination = clawBackStack.firstOrNull()
|
||||||
AnimatedVisibility(visible = navigationType == ClawNavigationType.BOTTOM_NAVIGATION) {
|
AnimatedVisibility(visible = navigationType == ClawNavigationType.BOTTOM_NAVIGATION) {
|
||||||
ClawNavigationBar(
|
ClawNavigationBar(
|
||||||
clawBackStack,
|
|
||||||
items = navItems,
|
items = navItems,
|
||||||
|
currentDestination = currentDestination,
|
||||||
|
navigateTo = { clawBackStack.add(it) },
|
||||||
isVisible = clawBackStack.isOnTopLevelDestination(),
|
isVisible = clawBackStack.isOnTopLevelDestination(),
|
||||||
hazeState = hazeState,
|
hazeState = hazeState,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue