mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
Decouple NodeMapScreen from MetricsViewModel (#3323)
Co-authored-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
8b4397a825
commit
ff95bc5311
7 changed files with 87 additions and 47 deletions
|
|
@ -24,9 +24,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.model.MetricsViewModel
|
||||
import org.meshtastic.feature.map.addCopyright
|
||||
import org.meshtastic.feature.map.addPolyline
|
||||
import org.meshtastic.feature.map.addPositionMarkers
|
||||
|
|
@ -39,20 +37,16 @@ import org.osmdroid.util.GeoPoint
|
|||
private const val DEG_D = 1e-7
|
||||
|
||||
@Composable
|
||||
fun NodeMapScreen(
|
||||
metricsViewModel: MetricsViewModel = hiltViewModel(),
|
||||
nodeMapViewModel: NodeMapViewModel = hiltViewModel(),
|
||||
onNavigateUp: () -> Unit,
|
||||
) {
|
||||
fun NodeMapScreen(nodeMapViewModel: NodeMapViewModel, onNavigateUp: () -> Unit) {
|
||||
val density = LocalDensity.current
|
||||
val state by metricsViewModel.state.collectAsStateWithLifecycle()
|
||||
val geoPoints = state.positionLogs.map { GeoPoint(it.latitudeI * DEG_D, it.longitudeI * DEG_D) }
|
||||
val positionLogs by nodeMapViewModel.positionLogs.collectAsStateWithLifecycle()
|
||||
val geoPoints = positionLogs.map { GeoPoint(it.latitudeI * DEG_D, it.longitudeI * DEG_D) }
|
||||
val cameraView = remember { BoundingBox.fromGeoPoints(geoPoints) }
|
||||
val mapView =
|
||||
rememberMapViewWithLifecycle(
|
||||
applicationId = nodeMapViewModel.applicationId,
|
||||
box = cameraView,
|
||||
tileSource = metricsViewModel.tileSource,
|
||||
tileSource = nodeMapViewModel.tileSource,
|
||||
)
|
||||
|
||||
AndroidView(
|
||||
|
|
@ -64,7 +58,7 @@ fun NodeMapScreen(
|
|||
map.addScaleBarOverlay(density)
|
||||
|
||||
map.addPolyline(density, geoPoints) {}
|
||||
map.addPositionMarkers(state.positionLogs) {}
|
||||
map.addPositionMarkers(positionLogs) {}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,32 +21,24 @@ import androidx.compose.foundation.layout.Box
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.model.MetricsViewModel
|
||||
import org.meshtastic.core.ui.component.MainAppBar
|
||||
import org.meshtastic.feature.map.MapView
|
||||
import org.meshtastic.feature.map.node.NodeMapViewModel
|
||||
|
||||
@Composable
|
||||
fun NodeMapScreen(
|
||||
metricsViewModel: MetricsViewModel = hiltViewModel(),
|
||||
nodeMapViewModel: NodeMapViewModel = hiltViewModel(),
|
||||
onNavigateUp: () -> Unit,
|
||||
) {
|
||||
val state by metricsViewModel.state.collectAsState()
|
||||
val positions = state.positionLogs
|
||||
val destNum = state.node?.num
|
||||
val ourNodeInfo by nodeMapViewModel.ourNodeInfo.collectAsStateWithLifecycle()
|
||||
fun NodeMapScreen(nodeMapViewModel: NodeMapViewModel, onNavigateUp: () -> Unit) {
|
||||
val node by nodeMapViewModel.node.collectAsStateWithLifecycle()
|
||||
val positions by nodeMapViewModel.positionLogs.collectAsStateWithLifecycle()
|
||||
val destNum = node?.num
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
MainAppBar(
|
||||
title = state.node?.user?.longName ?: "",
|
||||
ourNode = ourNodeInfo,
|
||||
title = node?.user?.longName ?: "",
|
||||
ourNode = null,
|
||||
showNodeChip = false,
|
||||
canNavigateUp = true,
|
||||
onNavigateUp = onNavigateUp,
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ import org.meshtastic.core.model.DataPacket
|
|||
import org.meshtastic.core.model.DeviceHardware
|
||||
import org.meshtastic.core.navigation.NodesRoutes
|
||||
import org.meshtastic.core.prefs.map.MapPrefs
|
||||
import org.meshtastic.core.proto.toPosition
|
||||
import org.meshtastic.core.service.ServiceAction
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.strings.R
|
||||
|
|
@ -190,12 +191,6 @@ enum class TimeFrame(val seconds: Long, @StringRes val strRes: Int) {
|
|||
private fun MeshPacket.hasValidSignal(): Boolean =
|
||||
rxTime > 0 && (rxSnr != 0f && rxRssi != 0) && (hopStart > 0 && hopStart - hopLimit == 0)
|
||||
|
||||
private fun MeshPacket.toPosition(): Position? = if (!decoded.wantResponse) {
|
||||
runCatching { Position.parseFrom(decoded.payload) }.getOrNull()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@HiltViewModel
|
||||
class MetricsViewModel
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ import org.meshtastic.core.navigation.NodeDetailRoutes
|
|||
import org.meshtastic.core.navigation.NodesRoutes
|
||||
import org.meshtastic.core.navigation.Route
|
||||
import org.meshtastic.core.strings.R
|
||||
import org.meshtastic.feature.map.node.NodeMapViewModel
|
||||
|
||||
fun NavGraphBuilder.nodesGraph(navController: NavHostController) {
|
||||
navigation<NodesRoutes.NodesGraph>(startDestination = NodesRoutes.Nodes) {
|
||||
|
|
@ -90,6 +91,21 @@ fun NavGraphBuilder.nodeDetailGraph(navController: NavHostController) {
|
|||
)
|
||||
}
|
||||
|
||||
composable<NodeDetailRoutes.NodeMap>(
|
||||
deepLinks =
|
||||
listOf(
|
||||
navDeepLink<NodeDetailRoutes.NodeMap>(basePath = "$DEEP_LINK_BASE_URI/node/{destNum}/node_map"),
|
||||
navDeepLink<NodeDetailRoutes.NodeMap>(basePath = "$DEEP_LINK_BASE_URI/node/node_map"),
|
||||
),
|
||||
) { backStackEntry ->
|
||||
val parentGraphBackStackEntry =
|
||||
remember(backStackEntry) { navController.getBackStackEntry(NodesRoutes.NodeDetailGraph::class) }
|
||||
NodeMapScreen(
|
||||
hiltViewModel<NodeMapViewModel>(parentGraphBackStackEntry),
|
||||
onNavigateUp = navController::navigateUp,
|
||||
)
|
||||
}
|
||||
|
||||
NodeDetailRoute.entries.forEach { entry ->
|
||||
when (entry.route) {
|
||||
is NodeDetailRoutes.DeviceMetrics ->
|
||||
|
|
@ -98,12 +114,6 @@ fun NavGraphBuilder.nodeDetailGraph(navController: NavHostController) {
|
|||
entry,
|
||||
entry.screenComposable,
|
||||
)
|
||||
is NodeDetailRoutes.NodeMap ->
|
||||
addNodeDetailScreenComposable<NodeDetailRoutes.NodeMap>(
|
||||
navController,
|
||||
entry,
|
||||
entry.screenComposable,
|
||||
)
|
||||
is NodeDetailRoutes.PositionLog ->
|
||||
addNodeDetailScreenComposable<NodeDetailRoutes.PositionLog>(
|
||||
navController,
|
||||
|
|
@ -199,12 +209,6 @@ enum class NodeDetailRoute(
|
|||
Icons.Default.Router,
|
||||
{ metricsVM, onNavigateUp -> DeviceMetricsScreen(metricsVM, onNavigateUp) },
|
||||
),
|
||||
NODE_MAP(
|
||||
R.string.node_map,
|
||||
NodeDetailRoutes.NodeMap,
|
||||
Icons.Default.LocationOn,
|
||||
{ metricsVM, onNavigateUp -> NodeMapScreen(metricsVM, onNavigateUp = onNavigateUp) },
|
||||
),
|
||||
POSITION_LOG(
|
||||
R.string.position_log,
|
||||
NodeDetailRoutes.PositionLog,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue