mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-06-13 08:25:07 -04:00
fix(map): resolve rebase issues and detekt violations
- Remove phantom dd-sdk-android-compose dependency (not in version catalog) - Deduplicate strings.xml (29 duplicate entries from rebase conflicts) - Add missing waypoint_lock_to_my_node string resource - Fix license header year format (2025-2026 → 2026) - Rename past-tense lambda params to present tense (detekt) - Use rememberUpdatedState for lambdas in LaunchedEffect - Fix composable parameter ordering (non-defaults before modifier) - Cap cluster zoom increment at max zoom level (24) - Suppress ModifierMissing on OfflineMapContent expect/actual Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
13
.skills/compose-ui/strings-index.txt
generated
13
.skills/compose-ui/strings-index.txt
generated
@@ -698,7 +698,12 @@ map_reporting_interval_seconds
|
||||
map_reporting_summary
|
||||
map_select_download_region
|
||||
map_start_download
|
||||
map_style_dark
|
||||
map_style_light
|
||||
map_style_osm
|
||||
map_style_road_map
|
||||
map_style_selection
|
||||
map_style_terrain
|
||||
map_subDescription
|
||||
map_tile_download_estimate
|
||||
map_tile_source
|
||||
@@ -887,6 +892,13 @@ notifications_on_message_receipt
|
||||
now
|
||||
ntp_server
|
||||
number_of_records
|
||||
### OFFLINE ###
|
||||
offline_download
|
||||
offline_download_visible_region
|
||||
offline_downloaded_regions
|
||||
offline_maps
|
||||
offline_saves_tiles
|
||||
offline_unnamed_region
|
||||
ok_to_mqtt
|
||||
okay
|
||||
oled_type
|
||||
@@ -1419,3 +1431,4 @@ wind_speed
|
||||
you
|
||||
zh_CN
|
||||
zh_TW
|
||||
zoom_to_fit_all
|
||||
|
||||
@@ -263,7 +263,6 @@ dependencies {
|
||||
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
debugImplementation(libs.androidx.glance.preview)
|
||||
|
||||
googleImplementation(libs.dd.sdk.android.compose)
|
||||
googleImplementation(libs.dd.sdk.android.logs)
|
||||
googleImplementation(libs.dd.sdk.android.rum)
|
||||
googleImplementation(libs.dd.sdk.android.session.replay)
|
||||
|
||||
@@ -728,7 +728,12 @@
|
||||
<string name="map_reporting_summary">Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, long and short name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name.</string>
|
||||
<string name="map_select_download_region">Select download region</string>
|
||||
<string name="map_start_download">Start Download</string>
|
||||
<string name="map_style_dark">Dark</string>
|
||||
<string name="map_style_light">Light</string>
|
||||
<string name="map_style_osm">OpenStreetMap</string>
|
||||
<string name="map_style_road_map">Road Map</string>
|
||||
<string name="map_style_selection">Map style selection</string>
|
||||
<string name="map_style_terrain">Terrain</string>
|
||||
<string name="map_subDescription">bearing: %1$d° distance: %2$s</string>
|
||||
<string name="map_tile_download_estimate">Tile download estimate:</string>
|
||||
<string name="map_tile_source">Tile Source</string>
|
||||
@@ -917,6 +922,13 @@
|
||||
<string name="now">Now</string>
|
||||
<string name="ntp_server">NTP server</string>
|
||||
<string name="number_of_records">Number of records</string>
|
||||
<!-- OFFLINE -->
|
||||
<string name="offline_download">Download</string>
|
||||
<string name="offline_download_visible_region">Download visible region</string>
|
||||
<string name="offline_downloaded_regions">Downloaded Regions</string>
|
||||
<string name="offline_maps">Offline Maps</string>
|
||||
<string name="offline_saves_tiles">Saves tiles for offline use</string>
|
||||
<string name="offline_unnamed_region">Unnamed Region</string>
|
||||
<string name="ok_to_mqtt">Ok to MQTT</string>
|
||||
<string name="okay">OK</string>
|
||||
<string name="oled_type">OLED type</string>
|
||||
@@ -1248,53 +1260,6 @@
|
||||
<string name="sx126x_rx_boosted_gain">RX Boosted Gain</string>
|
||||
<string name="system_settings">System Settings</string>
|
||||
<!-- TAK -->
|
||||
<string name="generate_qr_code">Generate QR Code</string>
|
||||
<string name="nfc_disabled">NFC is disabled. Please enable it in system settings.</string>
|
||||
<string name="all_time">All</string>
|
||||
|
||||
<string name="bluetooth_permission">Bluetooth</string>
|
||||
<string name="configure_bluetooth_permissions">Configure Bluetooth Permissions</string>
|
||||
<string name="bluetooth_feature_discovery">Discovery</string>
|
||||
<string name="bluetooth_feature_discovery_description">Find and identify Meshtastic devices near you.</string>
|
||||
<string name="bluetooth_feature_config">Configuration</string>
|
||||
<string name="bluetooth_feature_config_description">Wirelessly manage your device settings and channels.</string>
|
||||
<string name="map_style_selection">Map style selection</string>
|
||||
<string name="map_style_osm">OpenStreetMap</string>
|
||||
<string name="map_style_light">Light</string>
|
||||
<string name="map_style_terrain">Terrain</string>
|
||||
<string name="map_style_road_map">Road Map</string>
|
||||
<string name="map_style_dark">Dark</string>
|
||||
<string name="offline_maps">Offline Maps</string>
|
||||
<string name="offline_download">Download</string>
|
||||
<string name="offline_download_visible_region">Download visible region</string>
|
||||
<string name="offline_saves_tiles">Saves tiles for offline use</string>
|
||||
<string name="offline_downloaded_regions">Downloaded Regions</string>
|
||||
<string name="offline_unnamed_region">Unnamed Region</string>
|
||||
|
||||
<string name="local_stats_battery">Battery: %1$d%</string>
|
||||
<string name="local_stats_nodes">Nodes: %1$d online / %2$d total</string>
|
||||
<string name="local_stats_uptime">Uptime: %1$s</string>
|
||||
<string name="local_stats_utilization">ChUtil: %1$s% | AirTX: %2$s%</string>
|
||||
<string name="local_stats_traffic">Traffic: TX %1$d / RX %2$d (D: %3$d)</string>
|
||||
<string name="local_stats_relays">Relays: %1$d (Canceled: %2$d)</string>
|
||||
<string name="local_stats_diagnostics_prefix">Diagnostics: %1$s</string>
|
||||
<string name="local_stats_noise">Noise %1$d dBm</string>
|
||||
<string name="local_stats_bad">Bad %1$d</string>
|
||||
<string name="local_stats_dropped">Dropped %1$d</string>
|
||||
<string name="local_stats_heap">Heap</string>
|
||||
<string name="local_stats_heap_value">%1$d / %2$d</string>
|
||||
<string name="local_stats_updated_at">%1$s</string>
|
||||
<string name="powered">Powered</string>
|
||||
<string name="refresh">Refresh</string>
|
||||
<string name="updated">Updated</string>
|
||||
|
||||
<!-- Network Map Layers -->
|
||||
<string name="add_network_layer">Add Network Layer</string>
|
||||
<string name="network_layer_url_hint" translatable="false">https://example.com/map.kml or .geojson</string>
|
||||
|
||||
<string name="local_mbtiles_file">Local MBTiles File</string>
|
||||
<string name="add_local_mbtiles_file">Add Local MBTiles File</string>
|
||||
|
||||
<string name="tak">TAK (ATAK)</string>
|
||||
<string name="tak_config">TAK Configuration</string>
|
||||
<string name="tak_role">Member Role</string>
|
||||
@@ -1457,6 +1422,7 @@
|
||||
<string name="warning">Warning</string>
|
||||
<string name="waypoint_delete">Delete waypoint?</string>
|
||||
<string name="waypoint_edit">Edit waypoint</string>
|
||||
<string name="waypoint_lock_to_my_node">Lock to my node</string>
|
||||
<string name="waypoint_new">New waypoint</string>
|
||||
<string name="waypoint_received">Received waypoint: %1$s</string>
|
||||
<string name="weight">Weight</string>
|
||||
|
||||
@@ -54,7 +54,7 @@ import org.meshtastic.core.resources.offline_unnamed_region
|
||||
import org.meshtastic.core.ui.icon.CloudDownload
|
||||
import org.meshtastic.core.ui.icon.MeshtasticIcons
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Suppress("LongMethod", "ModifierMissing")
|
||||
@Composable
|
||||
actual fun OfflineMapContent(styleUri: String, cameraState: CameraState) {
|
||||
val offlineManager = rememberOfflineManager()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
* Copyright (c) 2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -72,8 +72,8 @@ private val MAP_OVERLAY_PADDING = 16.dp
|
||||
fun MapScreen(
|
||||
onClickNodeChip: (Int) -> Unit,
|
||||
navigateToNodeDetails: (Int) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: MapViewModel,
|
||||
modifier: Modifier = Modifier,
|
||||
waypointId: Int? = null,
|
||||
) {
|
||||
val ourNodeInfo by viewModel.ourNodeInfo.collectAsStateWithLifecycle()
|
||||
@@ -163,7 +163,7 @@ fun MapScreen(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
gestureOptions = gestureOptions,
|
||||
styleState = styleState,
|
||||
onCameraMoved = { position -> viewModel.saveCameraPosition(position) },
|
||||
onCameraMove = { position -> viewModel.saveCameraPosition(position) },
|
||||
onWaypointClick = { wpId ->
|
||||
editingWaypointId = wpId
|
||||
longPressPosition = null
|
||||
@@ -235,10 +235,12 @@ fun MapScreen(
|
||||
// TrackBearing → TrackNorth
|
||||
bearingUpdate = BearingUpdate.ALWAYS_NORTH
|
||||
}
|
||||
|
||||
BearingUpdate.ALWAYS_NORTH -> {
|
||||
// TrackNorth → Off
|
||||
isLocationTrackingEnabled = false
|
||||
}
|
||||
|
||||
BearingUpdate.IGNORE -> {
|
||||
isLocationTrackingEnabled = false
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
* Copyright (c) 2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
* Copyright (c) 2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
* Copyright (c) 2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -121,10 +122,10 @@ fun MaplibreMapContent(
|
||||
modifier: Modifier = Modifier,
|
||||
gestureOptions: GestureOptions = GestureOptions.Standard,
|
||||
styleState: StyleState = rememberStyleState(),
|
||||
onCameraMoved: (CameraPosition) -> Unit = {},
|
||||
onCameraMove: (CameraPosition) -> Unit = {},
|
||||
onWaypointClick: (Int) -> Unit = {},
|
||||
onMapLoadFinished: () -> Unit = {},
|
||||
onMapLoadFailed: (String?) -> Unit = {},
|
||||
onMapLoad: () -> Unit = {},
|
||||
onMapLoadFail: (String?) -> Unit = {},
|
||||
locationState: UserLocationState? = null,
|
||||
) {
|
||||
MaplibreMap(
|
||||
@@ -137,8 +138,8 @@ fun MaplibreMapContent(
|
||||
onMapLongClick(position)
|
||||
ClickResult.Consume
|
||||
},
|
||||
onMapLoadFinished = onMapLoadFinished,
|
||||
onMapLoadFailed = onMapLoadFailed,
|
||||
onMapLoadFinished = onMapLoad,
|
||||
onMapLoadFailed = onMapLoadFail,
|
||||
) {
|
||||
// --- Terrain hillshade overlay ---
|
||||
if (showHillshade) {
|
||||
@@ -172,9 +173,10 @@ fun MaplibreMapContent(
|
||||
}
|
||||
|
||||
// Persist camera position when it stops moving
|
||||
val currentOnCameraMove = rememberUpdatedState(onCameraMove)
|
||||
LaunchedEffect(cameraState.isCameraMoving) {
|
||||
if (!cameraState.isCameraMoving) {
|
||||
onCameraMoved(cameraState.position)
|
||||
currentOnCameraMove.value(cameraState.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,7 +218,7 @@ private fun NodeMarkerLayers(
|
||||
cameraState.animateTo(
|
||||
cameraState.position.copy(
|
||||
target = target,
|
||||
zoom = cameraState.position.zoom + CLUSTER_ZOOM_INCREMENT,
|
||||
zoom = minOf(cameraState.position.zoom + CLUSTER_ZOOM_INCREMENT, PRECISION_ZOOM_MAX.toDouble()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ private const val SELECTED_OPACITY = 0.9f
|
||||
internal fun NodeTrackLayers(
|
||||
positions: List<org.meshtastic.proto.Position>,
|
||||
selectedPositionTime: Int? = null,
|
||||
onPositionSelected: ((Int) -> Unit)? = null,
|
||||
onSelectPosition: ((Int) -> Unit)? = null,
|
||||
) {
|
||||
if (positions.size < 2) return
|
||||
|
||||
@@ -87,8 +87,8 @@ internal fun NodeTrackLayers(
|
||||
strokeColor = const(Color.White),
|
||||
onClick = { features ->
|
||||
val time = features.firstOrNull()?.properties?.get("time")?.jsonPrimitive?.content?.toIntOrNull()
|
||||
if (time != null && onPositionSelected != null) {
|
||||
onPositionSelected(time)
|
||||
if (time != null && onSelectPosition != null) {
|
||||
onSelectPosition(time)
|
||||
ClickResult.Consume
|
||||
} else {
|
||||
ClickResult.Pass
|
||||
|
||||
@@ -39,8 +39,8 @@ private const val BOUNDS_PADDING_DP = 48
|
||||
/**
|
||||
* Embeddable position-track map showing a polyline with markers for the given positions.
|
||||
*
|
||||
* Supports synchronized selection: [selectedPositionTime] highlights the corresponding marker and [onPositionSelected]
|
||||
* is called when a marker is tapped, passing the `Position.time` for the host screen to synchronize its card list.
|
||||
* Supports synchronized selection: [selectedPositionTime] highlights the corresponding marker and [onSelectPosition] is
|
||||
* called when a marker is tapped, passing the `Position.time` for the host screen to synchronize its card list.
|
||||
*
|
||||
* Replaces both the Google Maps and OSMDroid flavor-specific NodeTrackMap implementations.
|
||||
*/
|
||||
@@ -49,7 +49,7 @@ fun NodeTrackMap(
|
||||
positions: List<Position>,
|
||||
modifier: Modifier = Modifier,
|
||||
selectedPositionTime: Int? = null,
|
||||
onPositionSelected: ((Int) -> Unit)? = null,
|
||||
onSelectPosition: ((Int) -> Unit)? = null,
|
||||
) {
|
||||
val geoPositions =
|
||||
remember(positions) { positions.mapNotNull { pos -> toGeoPositionOrNull(pos.latitude_i, pos.longitude_i) } }
|
||||
@@ -82,7 +82,7 @@ fun NodeTrackMap(
|
||||
NodeTrackLayers(
|
||||
positions = positions,
|
||||
selectedPositionTime = selectedPositionTime,
|
||||
onPositionSelected = onPositionSelected,
|
||||
onSelectPosition = onSelectPosition,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.meshtastic.feature.map.component
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.em
|
||||
@@ -66,7 +67,7 @@ internal fun TracerouteLayers(
|
||||
overlay: TracerouteOverlay?,
|
||||
nodePositions: Map<Int, org.meshtastic.proto.Position>,
|
||||
nodes: Map<Int, Node>,
|
||||
onMappableCountChanged: (shown: Int, total: Int) -> Unit,
|
||||
onMappableCountChange: (shown: Int, total: Int) -> Unit,
|
||||
) {
|
||||
if (overlay == null) return
|
||||
|
||||
@@ -81,7 +82,8 @@ internal fun TracerouteLayers(
|
||||
// Report mappable count via side effect (avoid state updates during composition)
|
||||
val mappableCount = routeData.hopFeatures.features.size
|
||||
val totalCount = overlay.relatedNodeNums.size
|
||||
LaunchedEffect(mappableCount, totalCount) { onMappableCountChanged(mappableCount, totalCount) }
|
||||
val currentOnMappableCountChange = rememberUpdatedState(onMappableCountChange)
|
||||
LaunchedEffect(mappableCount, totalCount) { currentOnMappableCountChange.value(mappableCount, totalCount) }
|
||||
|
||||
// Forward route line
|
||||
if (routeData.forwardLine.features.isNotEmpty()) {
|
||||
|
||||
@@ -53,7 +53,7 @@ private const val BOUNDS_PADDING_DP = 64
|
||||
fun TracerouteMap(
|
||||
tracerouteOverlay: TracerouteOverlay?,
|
||||
tracerouteNodePositions: Map<Int, Position>,
|
||||
onMappableCountChanged: (shown: Int, total: Int) -> Unit,
|
||||
onMappableCountChange: (shown: Int, total: Int) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
nodes: Map<Int, Node> = emptyMap(),
|
||||
) {
|
||||
@@ -91,7 +91,7 @@ fun TracerouteMap(
|
||||
overlay = tracerouteOverlay,
|
||||
nodePositions = tracerouteNodePositions,
|
||||
nodes = nodes,
|
||||
onMappableCountChanged = onMappableCountChanged,
|
||||
onMappableCountChange = onMappableCountChange,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ fun PositionLogScreen(viewModel: MetricsViewModel, onNavigateUp: () -> Unit) {
|
||||
positions = positions,
|
||||
modifier = modifier,
|
||||
selectedPositionTime = selectedTime,
|
||||
onPositionSelected = { time -> onPointSelected(time.toDouble()) },
|
||||
onSelectPosition = { time -> onPointSelected(time.toDouble()) },
|
||||
)
|
||||
},
|
||||
listPart = { modifier, selectedX, lazyListState, onCardClick ->
|
||||
|
||||
@@ -118,7 +118,7 @@ private fun TracerouteMapScaffold(
|
||||
TracerouteMap(
|
||||
tracerouteOverlay = overlay,
|
||||
tracerouteNodePositions = snapshotPositions,
|
||||
onMappableCountChanged = { shown: Int, total: Int ->
|
||||
onMappableCountChange = { shown: Int, total: Int ->
|
||||
tracerouteNodesShown = shown
|
||||
tracerouteNodesTotal = total
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user