refactor: maps (#2097)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich 2025-08-13 12:51:19 -05:00 committed by GitHub
parent c05f434ff2
commit 87e50e03ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
76 changed files with 4188 additions and 1830 deletions

View file

@ -22,23 +22,19 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.ui.map.MapView
import com.geeksville.mesh.ui.map.MapViewModel
import kotlinx.serialization.Serializable
sealed class MapRoutes {
@Serializable
data object Map : Route
@Serializable data object Map : Route
}
fun NavGraphBuilder.mapGraph(
navController: NavHostController,
uiViewModel: UIViewModel,
) {
fun NavGraphBuilder.mapGraph(navController: NavHostController, uiViewModel: UIViewModel, mapViewModel: MapViewModel) {
composable<MapRoutes.Map> {
MapView(
model = uiViewModel,
navigateToNodeDetails = {
navController.navigate(NodesRoutes.NodeDetailGraph(it))
},
uiViewModel = uiViewModel,
mapViewModel = mapViewModel,
navigateToNodeDetails = { navController.navigate(NodesRoutes.NodeDetailGraph(it)) },
)
}
}

View file

@ -34,6 +34,7 @@ import com.geeksville.mesh.model.BluetoothViewModel
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.ui.TopLevelDestination.Companion.isTopLevel
import com.geeksville.mesh.ui.debug.DebugScreen
import com.geeksville.mesh.ui.map.MapViewModel
import kotlinx.serialization.Serializable
enum class AdminRoute(@StringRes val title: Int) {
@ -71,6 +72,7 @@ fun NavGraph(
modifier: Modifier = Modifier,
uIViewModel: UIViewModel = hiltViewModel(),
bluetoothViewModel: BluetoothViewModel = hiltViewModel(),
mapViewModel: MapViewModel = hiltViewModel(),
navController: NavHostController = rememberNavController(),
) {
val isConnected by uIViewModel.isConnectedStateFlow.collectAsStateWithLifecycle(false)
@ -86,7 +88,7 @@ fun NavGraph(
) {
contactsGraph(navController, uIViewModel)
nodesGraph(navController, uIViewModel)
mapGraph(navController, uIViewModel)
mapGraph(navController, uIViewModel, mapViewModel)
channelsGraph(navController, uIViewModel)
connectionsGraph(navController, uIViewModel, bluetoothViewModel)
composable<Route.DebugPanel> { DebugScreen() }

View file

@ -23,8 +23,8 @@ import androidx.compose.material.icons.filled.CellTower
import androidx.compose.material.icons.filled.LightMode
import androidx.compose.material.icons.filled.LocationOn
import androidx.compose.material.icons.filled.Memory
import androidx.compose.material.icons.filled.PermScanWifi
import androidx.compose.material.icons.filled.People
import androidx.compose.material.icons.filled.PermScanWifi
import androidx.compose.material.icons.filled.Power
import androidx.compose.material.icons.filled.Router
import androidx.compose.runtime.remember
@ -39,130 +39,91 @@ import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.ui.metrics.DeviceMetricsScreen
import com.geeksville.mesh.ui.metrics.EnvironmentMetricsScreen
import com.geeksville.mesh.ui.metrics.HostMetricsLogScreen
import com.geeksville.mesh.ui.metrics.PaxMetricsScreen
import com.geeksville.mesh.ui.metrics.PositionLogScreen
import com.geeksville.mesh.ui.metrics.PowerMetricsScreen
import com.geeksville.mesh.ui.metrics.SignalMetricsScreen
import com.geeksville.mesh.ui.metrics.TracerouteLogScreen
import com.geeksville.mesh.ui.metrics.PaxMetricsScreen
import com.geeksville.mesh.ui.node.NodeDetailScreen
import com.geeksville.mesh.ui.node.NodeMapScreen
import com.geeksville.mesh.ui.node.NodeScreen
import kotlinx.serialization.Serializable
sealed class NodesRoutes {
@Serializable
data object Nodes : Route
@Serializable data object Nodes : Route
@Serializable
data object NodesGraph : Graph
@Serializable data object NodesGraph : Graph
@Serializable
data class NodeDetailGraph(val destNum: Int? = null) : Graph
@Serializable data class NodeDetailGraph(val destNum: Int? = null) : Graph
@Serializable
data class NodeDetail(val destNum: Int? = null) : Route
@Serializable data class NodeDetail(val destNum: Int? = null) : Route
}
sealed class NodeDetailRoutes {
@Serializable
data object DeviceMetrics : Route
@Serializable data object DeviceMetrics : Route
@Serializable
data object NodeMap : Route
@Serializable data object NodeMap : Route
@Serializable
data object PositionLog : Route
@Serializable data object PositionLog : Route
@Serializable
data object EnvironmentMetrics : Route
@Serializable data object EnvironmentMetrics : Route
@Serializable
data object SignalMetrics : Route
@Serializable data object SignalMetrics : Route
@Serializable
data object PowerMetrics : Route
@Serializable data object PowerMetrics : Route
@Serializable
data object TracerouteLog : Route
@Serializable data object TracerouteLog : Route
@Serializable
data object HostMetricsLog : Route
@Serializable data object HostMetricsLog : Route
@Serializable
data object PaxMetrics : Route
@Serializable data object PaxMetrics : Route
}
fun NavGraphBuilder.nodesGraph(
navController: NavHostController,
uiViewModel: UIViewModel,
) {
navigation<NodesRoutes.NodesGraph>(
startDestination = NodesRoutes.Nodes,
) {
fun NavGraphBuilder.nodesGraph(navController: NavHostController, uiViewModel: UIViewModel) {
navigation<NodesRoutes.NodesGraph>(startDestination = NodesRoutes.Nodes) {
composable<NodesRoutes.Nodes> {
NodeScreen(
model = uiViewModel,
navigateToMessages = {
navController.navigate(ContactsRoutes.Messages(it))
},
navigateToNodeDetails = {
navController.navigate(NodesRoutes.NodeDetailGraph(it))
},
navigateToMessages = { navController.navigate(ContactsRoutes.Messages(it)) },
navigateToNodeDetails = { navController.navigate(NodesRoutes.NodeDetailGraph(it)) },
)
}
nodeDetailGraph(navController, uiViewModel)
}
}
fun NavGraphBuilder.nodeDetailGraph(
navController: NavHostController,
uiViewModel: UIViewModel,
) {
navigation<NodesRoutes.NodeDetailGraph>(
startDestination = NodesRoutes.NodeDetail(),
) {
fun NavGraphBuilder.nodeDetailGraph(navController: NavHostController, uiViewModel: UIViewModel) {
navigation<NodesRoutes.NodeDetailGraph>(startDestination = NodesRoutes.NodeDetail()) {
composable<NodesRoutes.NodeDetail> { backStackEntry ->
val parentEntry = remember(backStackEntry) {
val parentRoute = backStackEntry.destination.parent!!.route!!
navController.getBackStackEntry(parentRoute)
}
val parentEntry =
remember(backStackEntry) {
val parentRoute = backStackEntry.destination.parent!!.route!!
navController.getBackStackEntry(parentRoute)
}
NodeDetailScreen(
uiViewModel = uiViewModel,
navigateToMessages = {
navController.navigate(ContactsRoutes.Messages(it))
},
onNavigate = {
navController.navigate(it)
},
onNavigateUp = {
navController.navigateUp()
},
navigateToMessages = { navController.navigate(ContactsRoutes.Messages(it)) },
onNavigate = { navController.navigate(it) },
onNavigateUp = { navController.navigateUp() },
viewModel = hiltViewModel(parentEntry),
)
}
NodeDetailRoute.entries.forEach { nodeDetailRoute ->
composable(nodeDetailRoute.route::class) { backStackEntry ->
val parentEntry = remember(backStackEntry) {
val parentRoute = backStackEntry.destination.parent!!.route!!
navController.getBackStackEntry(parentRoute)
}
val parentEntry =
remember(backStackEntry) {
val parentRoute = backStackEntry.destination.parent!!.route!!
navController.getBackStackEntry(parentRoute)
}
when (nodeDetailRoute) {
NodeDetailRoute.DEVICE -> DeviceMetricsScreen(hiltViewModel(parentEntry))
NodeDetailRoute.NODE_MAP -> NodeMapScreen(hiltViewModel(parentEntry))
NodeDetailRoute.NODE_MAP -> NodeMapScreen(uiViewModel, hiltViewModel(parentEntry))
NodeDetailRoute.POSITION_LOG -> PositionLogScreen(hiltViewModel(parentEntry))
NodeDetailRoute.ENVIRONMENT -> EnvironmentMetricsScreen(
hiltViewModel(
parentEntry
)
)
NodeDetailRoute.ENVIRONMENT -> EnvironmentMetricsScreen(hiltViewModel(parentEntry))
NodeDetailRoute.SIGNAL -> SignalMetricsScreen(hiltViewModel(parentEntry))
NodeDetailRoute.TRACEROUTE -> TracerouteLogScreen(
viewModel = hiltViewModel(
parentEntry
)
)
NodeDetailRoute.TRACEROUTE -> TracerouteLogScreen(viewModel = hiltViewModel(parentEntry))
NodeDetailRoute.POWER -> PowerMetricsScreen(hiltViewModel(parentEntry))
NodeDetailRoute.HOST -> HostMetricsLogScreen(hiltViewModel(parentEntry))
@ -173,11 +134,7 @@ fun NavGraphBuilder.nodeDetailGraph(
}
}
enum class NodeDetailRoute(
@StringRes val title: Int,
val route: Route,
val icon: ImageVector?,
) {
enum class NodeDetailRoute(@StringRes val title: Int, val route: Route, val icon: ImageVector?) {
DEVICE(R.string.device, NodeDetailRoutes.DeviceMetrics, Icons.Default.Router),
NODE_MAP(R.string.node_map, NodeDetailRoutes.NodeMap, Icons.Default.LocationOn),
POSITION_LOG(R.string.position_log, NodeDetailRoutes.PositionLog, Icons.Default.LocationOn),