diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawAppBar.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawAppBar.kt new file mode 100644 index 00000000..ea1df7ed --- /dev/null +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawAppBar.kt @@ -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") + } + } + }, + ) +} diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationBar.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationBar.kt index a41576b6..88a8e9d2 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationBar.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationBar.kt @@ -31,7 +31,6 @@ 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.ClawBackStack import dev.msfjarvis.claw.android.ui.navigation.Destination import dev.msfjarvis.claw.common.ui.FloatingNavigationBar import kotlinx.collections.immutable.ImmutableList @@ -40,8 +39,9 @@ const val AnimationDuration = 100 @Composable fun ClawNavigationBar( - backStack: ClawBackStack, items: ImmutableList, + currentDestination: Destination?, + navigateTo: (Destination) -> Unit, isVisible: Boolean, hazeState: HazeState, modifier: Modifier = Modifier, @@ -83,7 +83,6 @@ fun ClawNavigationBar( containerColor = if (HazeDefaults.blurEnabled()) Color.Transparent else MaterialTheme.colorScheme.surface, ) { - val currentDestination = backStack.firstOrNull() items.forEach { navItem -> val isSelected = currentDestination == navItem.destination NavigationBarItem( @@ -101,7 +100,7 @@ fun ClawNavigationBar( if (isSelected) { navItem.listStateResetCallback() } else { - backStack.add(navItem.destination) + navigateTo(navItem.destination) } }, modifier = Modifier.testTag(navItem.label.uppercase()), diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationRail.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationRail.kt index ff8aaf01..be8b3f6c 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationRail.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationRail.kt @@ -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.ClawBackStack import dev.msfjarvis.claw.android.ui.navigation.Destination import kotlinx.collections.immutable.ImmutableList @Composable fun ClawNavigationRail( - backStack: ClawBackStack, items: ImmutableList, + currentDestination: Destination?, + navigateTo: (Destination) -> Unit, isVisible: Boolean, modifier: Modifier = Modifier, ) { @@ -49,7 +49,6 @@ fun ClawNavigationRail( modifier = Modifier, ) { NavigationRail(modifier = modifier) { - val currentDestination = backStack.firstOrNull() Spacer(Modifier.weight(1f)) items.forEach { navItem -> val isSelected = currentDestination == navItem.destination @@ -68,7 +67,7 @@ fun ClawNavigationRail( if (isSelected) { navItem.listStateResetCallback() } else { - backStack.add(navItem.destination) + navigateTo(navItem.destination) } }, modifier = Modifier.testTag(navItem.label.uppercase()), diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/screens/Nav3Screen.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/screens/Nav3Screen.kt index 04673940..eafa9d5a 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/screens/Nav3Screen.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/screens/Nav3Screen.kt @@ -15,20 +15,11 @@ import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.size 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.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar import androidx.compose.material3.windowsizeclass.WindowSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -36,14 +27,9 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.shadow 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.testTagsAsResourceId -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation3.runtime.entry 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.hazeSource 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.decorations.ClawAppBar import dev.msfjarvis.claw.android.ui.decorations.ClawNavigationBar import dev.msfjarvis.claw.android.ui.decorations.NavigationItem import dev.msfjarvis.claw.android.ui.lists.DatabasePosts @@ -138,48 +124,20 @@ fun Nav3Screen( Scaffold( topBar = { - TopAppBar( - modifier = Modifier.shadow(8.dp), - navigationIcon = { - if (!(clawBackStack.isOnTopLevelDestination())) { - IconButton( - 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") - } - } - }, + ClawAppBar( + activity = activity, + isTopLevel = clawBackStack.isOnTopLevelDestination(), + navigateTo = { clawBackStack.add(it) }, + popBackStack = { clawBackStack.removeLastOrNull() }, ) }, bottomBar = { + val currentDestination = clawBackStack.firstOrNull() AnimatedVisibility(visible = navigationType == ClawNavigationType.BOTTOM_NAVIGATION) { ClawNavigationBar( - clawBackStack, items = navItems, + currentDestination = currentDestination, + navigateTo = { clawBackStack.add(it) }, isVisible = clawBackStack.isOnTopLevelDestination(), hazeState = hazeState, )