From 3da3e97e77ad77f1effd400258383aef61316fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Orzech?= Date: Thu, 19 Mar 2026 14:57:44 +0100 Subject: [PATCH] feat: move search to top bar, replace with Stats tab in bottom nav - Bottom tabs: Home / Stats / Settings (was Home / Search / Settings) - Search icon back in feed top bar - Stats screen: no back button, tab-style fade transitions - Removed Stats link from Settings screen --- .../swoosh/microblog/ui/feed/FeedScreen.kt | 3 + .../microblog/ui/navigation/NavGraph.kt | 76 ++++--------------- .../microblog/ui/settings/SettingsScreen.kt | 22 +----- .../swoosh/microblog/ui/stats/StatsScreen.kt | 9 +-- 4 files changed, 19 insertions(+), 91 deletions(-) diff --git a/app/src/main/java/com/swoosh/microblog/ui/feed/FeedScreen.kt b/app/src/main/java/com/swoosh/microblog/ui/feed/FeedScreen.kt index be35099..2071001 100644 --- a/app/src/main/java/com/swoosh/microblog/ui/feed/FeedScreen.kt +++ b/app/src/main/java/com/swoosh/microblog/ui/feed/FeedScreen.kt @@ -249,6 +249,9 @@ fun FeedScreen( } }, actions = { + IconButton(onClick = { viewModel.activateSearch() }) { + Icon(Icons.Default.Search, contentDescription = "Search") + } SortButton( currentSort = sortOrder, onSortSelected = { viewModel.setSortOrder(it) } diff --git a/app/src/main/java/com/swoosh/microblog/ui/navigation/NavGraph.kt b/app/src/main/java/com/swoosh/microblog/ui/navigation/NavGraph.kt index 2d1e987..bb4c93f 100644 --- a/app/src/main/java/com/swoosh/microblog/ui/navigation/NavGraph.kt +++ b/app/src/main/java/com/swoosh/microblog/ui/navigation/NavGraph.kt @@ -10,8 +10,8 @@ import androidx.compose.animation.slideOutVertically import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.BarChart import androidx.compose.material.icons.filled.Home -import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.* import androidx.compose.runtime.* @@ -56,12 +56,12 @@ data class BottomNavItem( val bottomNavItems = listOf( BottomNavItem(Routes.FEED, "Home", Icons.Default.Home), - BottomNavItem(Routes.SEARCH, "Search", Icons.Default.Search), + BottomNavItem(Routes.STATS, "Stats", Icons.Default.BarChart), BottomNavItem(Routes.SETTINGS, "Settings", Icons.Default.Settings) ) /** Routes where the bottom navigation bar should be visible */ -private val bottomBarRoutes = setOf(Routes.FEED, Routes.SEARCH, Routes.SETTINGS) +private val bottomBarRoutes = setOf(Routes.FEED, Routes.STATS, Routes.SETTINGS) @Composable fun SwooshNavGraph( @@ -93,27 +93,15 @@ fun SwooshNavGraph( NavigationBarItem( selected = selected, onClick = { - if (item.route == Routes.SEARCH) { - // Navigate to feed with search mode active - feedViewModel.activateSearch() - navController.navigate(Routes.SEARCH) { - popUpTo(navController.graph.findStartDestination().id) { - saveState = true - } - launchSingleTop = true - restoreState = true - } - } else { - if (item.route == Routes.FEED) { - feedViewModel.deactivateSearch() - } - navController.navigate(item.route) { - popUpTo(navController.graph.findStartDestination().id) { - saveState = true - } - launchSingleTop = true - restoreState = true + if (item.route == Routes.FEED) { + feedViewModel.deactivateSearch() + } + navController.navigate(item.route) { + popUpTo(navController.graph.findStartDestination().id) { + saveState = true } + launchSingleTop = true + restoreState = true } }, icon = { @@ -189,37 +177,6 @@ fun SwooshNavGraph( ) } - composable( - Routes.SEARCH, - enterTransition = { fadeIn(tween(200)) }, - exitTransition = { fadeOut(tween(150)) }, - popEnterTransition = { fadeIn(tween(200)) }, - popExitTransition = { fadeOut(tween(150)) } - ) { - // Ensure search is active when this tab is shown - LaunchedEffect(Unit) { - feedViewModel.activateSearch() - } - FeedScreen( - viewModel = feedViewModel, - onPostClick = { post -> - selectedPost = post - navController.navigate(Routes.DETAIL) - }, - onCompose = { - editPost = null - navController.navigate(Routes.COMPOSER) - }, - onEditPost = { post -> - editPost = post - navController.navigate(Routes.COMPOSER) - }, - onAddAccount = { - navController.navigate(Routes.ADD_ACCOUNT) - } - ) - } - composable( Routes.COMPOSER, enterTransition = { slideInVertically(initialOffsetY = { it }, animationSpec = tween(250)) + fadeIn(tween(200)) }, @@ -298,23 +255,18 @@ fun SwooshNavGraph( navController.navigate(Routes.SETUP) { popUpTo(0) { inclusive = true } } - }, - onStatsClick = { - navController.navigate(Routes.STATS) } ) } composable( Routes.STATS, - enterTransition = { slideInHorizontally(initialOffsetX = { it }, animationSpec = tween(250)) }, + enterTransition = { fadeIn(tween(200)) }, exitTransition = { fadeOut(tween(150)) }, popEnterTransition = { fadeIn(tween(200)) }, - popExitTransition = { slideOutHorizontally(targetOffsetX = { it }, animationSpec = tween(200)) } + popExitTransition = { fadeOut(tween(150)) } ) { - StatsScreen( - onBack = { navController.popBackStack() } - ) + StatsScreen() } composable( diff --git a/app/src/main/java/com/swoosh/microblog/ui/settings/SettingsScreen.kt b/app/src/main/java/com/swoosh/microblog/ui/settings/SettingsScreen.kt index 18f75af..978561a 100644 --- a/app/src/main/java/com/swoosh/microblog/ui/settings/SettingsScreen.kt +++ b/app/src/main/java/com/swoosh/microblog/ui/settings/SettingsScreen.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.filled.BarChart import androidx.compose.material.icons.filled.BrightnessAuto import androidx.compose.material.icons.filled.DarkMode import androidx.compose.material.icons.filled.LightMode @@ -31,8 +30,7 @@ import com.swoosh.microblog.ui.theme.ThemeViewModel fun SettingsScreen( onBack: () -> Unit, onLogout: () -> Unit, - themeViewModel: ThemeViewModel? = null, - onStatsClick: () -> Unit = {} + themeViewModel: ThemeViewModel? = null ) { val context = LocalContext.current val accountManager = remember { AccountManager(context) } @@ -130,24 +128,6 @@ fun SettingsScreen( HorizontalDivider() Spacer(modifier = Modifier.height(16.dp)) - // Writing Statistics button - FilledTonalButton( - onClick = onStatsClick, - modifier = Modifier.fillMaxWidth() - ) { - Icon( - Icons.Default.BarChart, - contentDescription = null, - modifier = Modifier.size(18.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text("Writing Statistics") - } - - Spacer(modifier = Modifier.height(16.dp)) - HorizontalDivider() - Spacer(modifier = Modifier.height(16.dp)) - // Disconnect current account OutlinedButton( onClick = { showDisconnectDialog = true }, diff --git a/app/src/main/java/com/swoosh/microblog/ui/stats/StatsScreen.kt b/app/src/main/java/com/swoosh/microblog/ui/stats/StatsScreen.kt index 4ea2a15..e700d7b 100644 --- a/app/src/main/java/com/swoosh/microblog/ui/stats/StatsScreen.kt +++ b/app/src/main/java/com/swoosh/microblog/ui/stats/StatsScreen.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.Article import androidx.compose.material.icons.filled.Create import androidx.compose.material.icons.filled.Schedule @@ -29,7 +28,6 @@ import kotlinx.coroutines.delay @OptIn(ExperimentalMaterial3Api::class) @Composable fun StatsScreen( - onBack: () -> Unit, viewModel: StatsViewModel = viewModel() ) { val state by viewModel.uiState.collectAsStateWithLifecycle() @@ -73,12 +71,7 @@ fun StatsScreen( Scaffold( topBar = { TopAppBar( - title = { Text("Writing Statistics") }, - navigationIcon = { - IconButton(onClick = onBack) { - Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back") - } - } + title = { Text("Statistics") } ) } ) { padding ->