refactor: organize navigation (#2042)

This commit is contained in:
James Rich 2025-06-06 20:45:26 +00:00 committed by GitHub
parent c757224269
commit 2a05fc072d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 306 additions and 265 deletions

View file

@ -27,17 +27,11 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navDeepLink
import androidx.navigation.toRoute
import com.geeksville.mesh.R
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.ui.TopLevelDestination.Companion.isTopLevel
import com.geeksville.mesh.ui.contact.ContactsScreen
import com.geeksville.mesh.ui.debug.DebugScreen
import com.geeksville.mesh.ui.map.MapView
import com.geeksville.mesh.ui.message.MessageScreen
import com.geeksville.mesh.ui.message.QuickChatScreen
import com.geeksville.mesh.ui.sharing.ShareScreen
import kotlinx.serialization.Serializable
enum class AdminRoute(@StringRes val title: Int) {
@ -50,129 +44,15 @@ enum class AdminRoute(@StringRes val title: Int) {
const val DEEP_LINK_BASE_URI = "meshtastic://meshtastic"
@Serializable
sealed interface Graph : Route {
@Serializable
data class RadioConfigGraph(val destNum: Int? = null) : Graph
}
sealed interface Graph : Route
@Serializable
sealed interface Route {
@Serializable
data object Contacts : Route
@Serializable
data object Map : Route
@Serializable
data object DebugPanel : Route
@Serializable
data class Messages(val contactKey: String, val message: String = "") : Route
@Serializable
data object QuickChat : Route
@Serializable
data class Share(val message: String) : Route
@Serializable
data class RadioConfig(val destNum: Int? = null) : Route
@Serializable
data object User : Route
@Serializable
data object ChannelConfig : Route
@Serializable
data object Device : Route
@Serializable
data object Position : Route
@Serializable
data object Power : Route
@Serializable
data object Network : Route
@Serializable
data object Display : Route
@Serializable
data object LoRa : Route
@Serializable
data object Bluetooth : Route
@Serializable
data object Security : Route
@Serializable
data object MQTT : Route
@Serializable
data object Serial : Route
@Serializable
data object ExtNotification : Route
@Serializable
data object StoreForward : Route
@Serializable
data object RangeTest : Route
@Serializable
data object Telemetry : Route
@Serializable
data object CannedMessage : Route
@Serializable
data object Audio : Route
@Serializable
data object RemoteHardware : Route
@Serializable
data object NeighborInfo : Route
@Serializable
data object AmbientLighting : Route
@Serializable
data object DetectionSensor : Route
@Serializable
data object Paxcounter : Route
@Serializable
data class NodeDetail(val destNum: Int? = null) : Route
@Serializable
data object DeviceMetrics : Route
@Serializable
data object NodeMap : Route
@Serializable
data object PositionLog : Route
@Serializable
data object EnvironmentMetrics : Route
@Serializable
data object SignalMetrics : Route
@Serializable
data object PowerMetrics : Route
@Serializable
data object TracerouteLog : Route
@Serializable
data object HostMetricsLog : Route
}
fun NavDestination.isConfigRoute(): Boolean {
@ -187,8 +67,8 @@ fun NavDestination.isNodeDetailRoute(): Boolean {
fun NavDestination.showLongNameTitle(): Boolean {
return !this.isTopLevel() && (
this.hasRoute<Route.RadioConfig>() ||
this.hasRoute<Route.NodeDetail>() ||
this.hasRoute<RadioConfigRoutes.RadioConfig>() ||
this.hasRoute<NodesRoutes.NodeDetail>() ||
this.isConfigRoute() ||
this.isNodeDetailRoute()
)
@ -203,70 +83,19 @@ fun NavGraph(
) {
NavHost(
navController = navController,
startDestination = if (uIViewModel.bondedAddress.isNullOrBlank()) {
startDestination = if (uIViewModel.isConnected()) {
ConnectionsRoutes.ConnectionsGraph
} else {
Route.Contacts
ContactsRoutes.ContactsGraph
},
modifier = modifier,
) {
composable<Route.Contacts> {
ContactsScreen(
uIViewModel,
onNavigate = { navController.navigate(Route.Messages(it)) }
)
}
composable<Route.Map> {
MapView(uIViewModel)
}
contactsGraph(navController, uIViewModel)
nodesGraph(navController, uIViewModel,)
composable<Route.Map> { MapView(uIViewModel) }
channelsGraph(navController, uIViewModel)
connectionsGraph(navController, uIViewModel)
composable<Route.DebugPanel> {
DebugScreen()
}
composable<Route.Messages>(
deepLinks = listOf(
navDeepLink {
uriPattern = "$DEEP_LINK_BASE_URI/messages/{contactKey}?message={message}"
action = "android.intent.action.VIEW"
},
)
) { backStackEntry ->
val args = backStackEntry.toRoute<Route.Messages>()
MessageScreen(
contactKey = args.contactKey,
message = args.message,
viewModel = uIViewModel,
navigateToMessages = { navController.navigate(Route.Messages(it)) },
navigateToNodeDetails = { navController.navigate(Route.NodeDetail(it)) },
onNavigateBack = navController::navigateUp,
)
}
composable<Route.QuickChat> {
QuickChatScreen()
}
nodesGraph(
navController,
uIViewModel,
)
composable<Route.DebugPanel> { DebugScreen() }
radioConfigGraph(navController, uIViewModel)
composable<Route.Share>(
deepLinks = listOf(
navDeepLink {
uriPattern = "$DEEP_LINK_BASE_URI/share?message={message}"
action = "android.intent.action.VIEW"
}
)
) { backStackEntry ->
val message = backStackEntry.toRoute<Route.Share>().message
ShareScreen(uIViewModel) {
navController.navigate(Route.Messages(it, message)) {
popUpTo<Route.Share> { inclusive = true }
}
}
}
}
}