feat: refactor navigation structure by replacing AppNavigation with MainApp and updating ListDetailScreen and ListsScreen for improved functionality
This commit is contained in:
@@ -10,7 +10,7 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.collabtable.app.data.preferences.PreferencesManager
|
||||
import com.collabtable.app.ui.navigation.AppNavigation
|
||||
import com.collabtable.app.ui.navigation.MainApp
|
||||
import com.collabtable.app.ui.theme.CollabTableTheme
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
@@ -34,7 +34,7 @@ class MainActivity : ComponentActivity() {
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
) {
|
||||
AppNavigation()
|
||||
MainApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.collabtable.app.ui.navigation
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Home
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.NavigationBar
|
||||
import androidx.compose.material3.NavigationBarItem
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.navArgument
|
||||
import androidx.navigation.NavType
|
||||
import com.collabtable.app.data.preferences.PreferencesManager
|
||||
import com.collabtable.app.ui.screens.ListDetailScreen
|
||||
import com.collabtable.app.ui.screens.ListsScreen
|
||||
import com.collabtable.app.ui.screens.LogsScreen
|
||||
import com.collabtable.app.ui.screens.ServerSetupScreen
|
||||
import com.collabtable.app.ui.screens.SettingsScreen
|
||||
|
||||
private object Routes {
|
||||
const val Setup = "server_setup"
|
||||
const val MainRoot = "main_root"
|
||||
const val Tables = "tables"
|
||||
const val Settings = "settings"
|
||||
const val ListDetail = "list/{listId}"
|
||||
const val Logs = "logs"
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MainApp() {
|
||||
val context = LocalContext.current
|
||||
val prefs = remember { PreferencesManager.getInstance(context) }
|
||||
|
||||
// Show setup flow until completed; then show main app with bottom nav
|
||||
if (prefs.isFirstRun()) {
|
||||
val navController = rememberNavController()
|
||||
NavHost(navController, startDestination = Routes.Setup) {
|
||||
composable(Routes.Setup) {
|
||||
ServerSetupScreen(
|
||||
onSetupComplete = {
|
||||
// Mark not first run and trigger recomposition to show main UI
|
||||
prefs.setIsFirstRun(false)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val navController = rememberNavController()
|
||||
val backStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentRoute = backStackEntry?.destination?.route
|
||||
|
||||
Scaffold(
|
||||
bottomBar = {
|
||||
NavigationBar {
|
||||
NavigationBarItem(
|
||||
selected = currentRoute == Routes.Tables || currentRoute?.startsWith("list/") == true,
|
||||
onClick = {
|
||||
navController.navigate(Routes.Tables) {
|
||||
popUpTo(navController.graph.findStartDestination().id) { saveState = true }
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
},
|
||||
icon = { androidx.compose.material3.Icon(Icons.Default.Home, contentDescription = null) },
|
||||
label = { Text("Tables") },
|
||||
)
|
||||
NavigationBarItem(
|
||||
selected = currentRoute == Routes.Settings,
|
||||
onClick = {
|
||||
navController.navigate(Routes.Settings) {
|
||||
popUpTo(navController.graph.findStartDestination().id) { saveState = true }
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
},
|
||||
icon = { androidx.compose.material3.Icon(Icons.Default.Settings, contentDescription = null) },
|
||||
label = { Text("Settings") },
|
||||
)
|
||||
}
|
||||
},
|
||||
) { innerPadding ->
|
||||
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = Routes.Tables,
|
||||
) {
|
||||
composable(Routes.Tables) {
|
||||
ListsScreen(
|
||||
onNavigateToList = { listId -> navController.navigate("list/$listId") },
|
||||
onNavigateToSettings = { navController.navigate(Routes.Settings) },
|
||||
onNavigateToLogs = { navController.navigate(Routes.Logs) },
|
||||
)
|
||||
}
|
||||
composable(Routes.Settings) {
|
||||
SettingsScreen(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
onNavigateToLogs = { navController.navigate(Routes.Logs) },
|
||||
onLeaveServer = {
|
||||
// Reset to setup flow by toggling the flag and rebuilding graph via recomposition
|
||||
prefs.setIsFirstRun(true)
|
||||
},
|
||||
)
|
||||
}
|
||||
composable(Routes.Logs) {
|
||||
LogsScreen(onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
composable(
|
||||
route = Routes.ListDetail,
|
||||
arguments = listOf(navArgument("listId") { type = NavType.StringType }),
|
||||
) { backStackEntry ->
|
||||
val listId = backStackEntry.arguments?.getString("listId") ?: return@composable
|
||||
ListDetailScreen(listId = listId, onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-10
@@ -188,8 +188,8 @@ fun ListDetailScreen(
|
||||
val localCtx = LocalContext.current
|
||||
val localPrefs = remember { PreferencesManager.getInstance(localCtx) }
|
||||
ConnectionStatusAction(prefs = localPrefs)
|
||||
IconButton(onClick = { showManageColumnsDialog = true }) {
|
||||
Icon(Icons.Default.Settings, contentDescription = "Manage Columns")
|
||||
IconButton(onClick = { showAddItemDialog = true }) {
|
||||
Icon(Icons.Default.Add, contentDescription = stringResource(R.string.add_item))
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
@@ -198,13 +198,7 @@ fun ListDetailScreen(
|
||||
),
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(
|
||||
onClick = { showAddItemDialog = true },
|
||||
) {
|
||||
Icon(Icons.Default.Add, contentDescription = stringResource(R.string.add_item))
|
||||
}
|
||||
},
|
||||
floatingActionButton = {},
|
||||
) { padding ->
|
||||
// Apply filtering, sorting, and grouping to items
|
||||
fun valueFor(item: ItemWithValues, field: Field?): String {
|
||||
@@ -527,6 +521,7 @@ fun ListDetailScreen(
|
||||
},
|
||||
scrollState = horizontalScrollState,
|
||||
isLast = (field.id == stableFields.lastOrNull()?.id),
|
||||
onHeaderClick = { showManageColumnsDialog = true },
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -741,6 +736,7 @@ fun FieldHeader(
|
||||
onWidthChange: (Float) -> Unit,
|
||||
scrollState: androidx.compose.foundation.ScrollState,
|
||||
isLast: Boolean,
|
||||
onHeaderClick: () -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -767,7 +763,9 @@ fun FieldHeader(
|
||||
Text(
|
||||
text = field.name,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
modifier = Modifier.weight(1f),
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.clickable { onHeaderClick() },
|
||||
)
|
||||
|
||||
// Resize handle
|
||||
|
||||
@@ -23,7 +23,6 @@ import androidx.compose.material.icons.filled.DragHandle
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material.icons.filled.List
|
||||
import androidx.compose.material.icons.filled.Refresh
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material.icons.filled.Sort
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
@@ -69,6 +68,7 @@ import org.burnoutcrew.reorderable.reorderable
|
||||
@Composable
|
||||
fun ListsScreen(
|
||||
onNavigateToList: (String) -> Unit,
|
||||
// Settings now accessed via bottom navigation; keep param for backward compat (unused)
|
||||
onNavigateToSettings: () -> Unit,
|
||||
onNavigateToLogs: () -> Unit = {},
|
||||
) {
|
||||
@@ -108,10 +108,10 @@ fun ListsScreen(
|
||||
val context = LocalContext.current
|
||||
val prefsLocal = remember { PreferencesManager.getInstance(context) }
|
||||
ConnectionStatusAction(prefs = prefsLocal)
|
||||
IconButton(onClick = onNavigateToSettings) {
|
||||
IconButton(onClick = { showCreateDialog = true }) {
|
||||
Icon(
|
||||
Icons.Default.Settings,
|
||||
contentDescription = stringResource(R.string.settings),
|
||||
Icons.Default.Add,
|
||||
contentDescription = stringResource(R.string.create_list),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -122,11 +122,7 @@ fun ListsScreen(
|
||||
),
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(onClick = { showCreateDialog = true }) {
|
||||
Icon(Icons.Default.Add, contentDescription = stringResource(R.string.create_list))
|
||||
}
|
||||
},
|
||||
floatingActionButton = {},
|
||||
) { padding ->
|
||||
Box(
|
||||
modifier =
|
||||
|
||||
Reference in New Issue
Block a user