mirror of
https://github.com/pawelorzech/Swoosh.git
synced 2026-03-31 20:15:41 +00:00
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
This commit is contained in:
parent
c91ccd0afb
commit
3da3e97e77
4 changed files with 19 additions and 91 deletions
|
|
@ -249,6 +249,9 @@ fun FeedScreen(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
|
IconButton(onClick = { viewModel.activateSearch() }) {
|
||||||
|
Icon(Icons.Default.Search, contentDescription = "Search")
|
||||||
|
}
|
||||||
SortButton(
|
SortButton(
|
||||||
currentSort = sortOrder,
|
currentSort = sortOrder,
|
||||||
onSortSelected = { viewModel.setSortOrder(it) }
|
onSortSelected = { viewModel.setSortOrder(it) }
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import androidx.compose.animation.slideOutVertically
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
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.Home
|
||||||
import androidx.compose.material.icons.filled.Search
|
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
|
@ -56,12 +56,12 @@ data class BottomNavItem(
|
||||||
|
|
||||||
val bottomNavItems = listOf(
|
val bottomNavItems = listOf(
|
||||||
BottomNavItem(Routes.FEED, "Home", Icons.Default.Home),
|
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)
|
BottomNavItem(Routes.SETTINGS, "Settings", Icons.Default.Settings)
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Routes where the bottom navigation bar should be visible */
|
/** 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
|
@Composable
|
||||||
fun SwooshNavGraph(
|
fun SwooshNavGraph(
|
||||||
|
|
@ -93,17 +93,6 @@ fun SwooshNavGraph(
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
selected = selected,
|
selected = selected,
|
||||||
onClick = {
|
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) {
|
if (item.route == Routes.FEED) {
|
||||||
feedViewModel.deactivateSearch()
|
feedViewModel.deactivateSearch()
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +103,6 @@ fun SwooshNavGraph(
|
||||||
launchSingleTop = true
|
launchSingleTop = true
|
||||||
restoreState = true
|
restoreState = true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
icon = {
|
icon = {
|
||||||
Icon(
|
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(
|
composable(
|
||||||
Routes.COMPOSER,
|
Routes.COMPOSER,
|
||||||
enterTransition = { slideInVertically(initialOffsetY = { it }, animationSpec = tween(250)) + fadeIn(tween(200)) },
|
enterTransition = { slideInVertically(initialOffsetY = { it }, animationSpec = tween(250)) + fadeIn(tween(200)) },
|
||||||
|
|
@ -298,23 +255,18 @@ fun SwooshNavGraph(
|
||||||
navController.navigate(Routes.SETUP) {
|
navController.navigate(Routes.SETUP) {
|
||||||
popUpTo(0) { inclusive = true }
|
popUpTo(0) { inclusive = true }
|
||||||
}
|
}
|
||||||
},
|
|
||||||
onStatsClick = {
|
|
||||||
navController.navigate(Routes.STATS)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(
|
composable(
|
||||||
Routes.STATS,
|
Routes.STATS,
|
||||||
enterTransition = { slideInHorizontally(initialOffsetX = { it }, animationSpec = tween(250)) },
|
enterTransition = { fadeIn(tween(200)) },
|
||||||
exitTransition = { fadeOut(tween(150)) },
|
exitTransition = { fadeOut(tween(150)) },
|
||||||
popEnterTransition = { fadeIn(tween(200)) },
|
popEnterTransition = { fadeIn(tween(200)) },
|
||||||
popExitTransition = { slideOutHorizontally(targetOffsetX = { it }, animationSpec = tween(200)) }
|
popExitTransition = { fadeOut(tween(150)) }
|
||||||
) {
|
) {
|
||||||
StatsScreen(
|
StatsScreen()
|
||||||
onBack = { navController.popBackStack() }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(
|
composable(
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
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.BrightnessAuto
|
||||||
import androidx.compose.material.icons.filled.DarkMode
|
import androidx.compose.material.icons.filled.DarkMode
|
||||||
import androidx.compose.material.icons.filled.LightMode
|
import androidx.compose.material.icons.filled.LightMode
|
||||||
|
|
@ -31,8 +30,7 @@ import com.swoosh.microblog.ui.theme.ThemeViewModel
|
||||||
fun SettingsScreen(
|
fun SettingsScreen(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onLogout: () -> Unit,
|
onLogout: () -> Unit,
|
||||||
themeViewModel: ThemeViewModel? = null,
|
themeViewModel: ThemeViewModel? = null
|
||||||
onStatsClick: () -> Unit = {}
|
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val accountManager = remember { AccountManager(context) }
|
val accountManager = remember { AccountManager(context) }
|
||||||
|
|
@ -130,24 +128,6 @@ fun SettingsScreen(
|
||||||
HorizontalDivider()
|
HorizontalDivider()
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
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
|
// Disconnect current account
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = { showDisconnectDialog = true },
|
onClick = { showDisconnectDialog = true },
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
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.automirrored.filled.Article
|
||||||
import androidx.compose.material.icons.filled.Create
|
import androidx.compose.material.icons.filled.Create
|
||||||
import androidx.compose.material.icons.filled.Schedule
|
import androidx.compose.material.icons.filled.Schedule
|
||||||
|
|
@ -29,7 +28,6 @@ import kotlinx.coroutines.delay
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun StatsScreen(
|
fun StatsScreen(
|
||||||
onBack: () -> Unit,
|
|
||||||
viewModel: StatsViewModel = viewModel()
|
viewModel: StatsViewModel = viewModel()
|
||||||
) {
|
) {
|
||||||
val state by viewModel.uiState.collectAsStateWithLifecycle()
|
val state by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
|
@ -73,12 +71,7 @@ fun StatsScreen(
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text("Writing Statistics") },
|
title = { Text("Statistics") }
|
||||||
navigationIcon = {
|
|
||||||
IconButton(onClick = onBack) {
|
|
||||||
Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { padding ->
|
) { padding ->
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue