From b4518e470530f5a14c98d76a1d73134875d05566 Mon Sep 17 00:00:00 2001 From: James Rich Date: Sat, 30 May 2026 12:09:33 -0500 Subject: [PATCH] chore: remove orphaned app/ discovery files from merge These files were duplicated in androidApp/ where they belong. The app/ module no longer exists (removed in AIDL removal PR). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../app/map/discovery/DiscoveryMap.kt | 32 ---- .../app/map/discovery/DiscoveryOsmMap.kt | 167 ------------------ .../app/map/discovery/DiscoveryGoogleMap.kt | 147 --------------- .../app/map/discovery/DiscoveryMap.kt | 32 ---- .../app/map/discovery/DiscoveryMarkerChip.kt | 54 ------ app/src/main/res/drawable/ic_person.xml | 9 - app/src/main/res/drawable/ic_thermostat.xml | 9 - core/proto/src/main/proto | 1 + 8 files changed, 1 insertion(+), 450 deletions(-) delete mode 100644 app/src/fdroid/kotlin/org/meshtastic/app/map/discovery/DiscoveryMap.kt delete mode 100644 app/src/fdroid/kotlin/org/meshtastic/app/map/discovery/DiscoveryOsmMap.kt delete mode 100644 app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryGoogleMap.kt delete mode 100644 app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryMap.kt delete mode 100644 app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryMarkerChip.kt delete mode 100644 app/src/main/res/drawable/ic_person.xml delete mode 100644 app/src/main/res/drawable/ic_thermostat.xml create mode 160000 core/proto/src/main/proto diff --git a/app/src/fdroid/kotlin/org/meshtastic/app/map/discovery/DiscoveryMap.kt b/app/src/fdroid/kotlin/org/meshtastic/app/map/discovery/DiscoveryMap.kt deleted file mode 100644 index bc5c4ec59..000000000 --- a/app/src/fdroid/kotlin/org/meshtastic/app/map/discovery/DiscoveryMap.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.meshtastic.app.map.discovery - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import org.meshtastic.core.ui.util.DiscoveryMapNode - -/** Flavor-unified entry point for the discovery map. OSMDroid implementation. */ -@Composable -fun DiscoveryMap( - userLatitude: Double, - userLongitude: Double, - nodes: List, - modifier: Modifier = Modifier, -) { - DiscoveryOsmMap(userLatitude = userLatitude, userLongitude = userLongitude, nodes = nodes, modifier = modifier) -} diff --git a/app/src/fdroid/kotlin/org/meshtastic/app/map/discovery/DiscoveryOsmMap.kt b/app/src/fdroid/kotlin/org/meshtastic/app/map/discovery/DiscoveryOsmMap.kt deleted file mode 100644 index 8b1692bc1..000000000 --- a/app/src/fdroid/kotlin/org/meshtastic/app/map/discovery/DiscoveryOsmMap.kt +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -@file:Suppress("MagicNumber") - -package org.meshtastic.app.map.discovery - -import android.graphics.Paint -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView -import org.meshtastic.app.map.addCopyright -import org.meshtastic.app.map.addScaleBarOverlay -import org.meshtastic.app.map.model.CustomTileSource -import org.meshtastic.app.map.rememberMapViewWithLifecycle -import org.meshtastic.app.map.zoomIn -import org.meshtastic.core.ui.theme.DiscoveryMapColors -import org.meshtastic.core.ui.util.DiscoveryMapNode -import org.meshtastic.core.ui.util.DiscoveryNeighborType -import org.osmdroid.util.BoundingBox -import org.osmdroid.util.GeoPoint -import org.osmdroid.views.overlay.Marker -import org.osmdroid.views.overlay.Polyline - -private const val SINGLE_POINT_ZOOM = 14.0 -private const val ZOOM_OUT_LEVELS = 0.5 - -/** - * OSMDroid implementation of the discovery map. Renders discovered node markers color-coded by neighbor type (green = - * direct, blue = mesh) with polylines from the user position to direct neighbors. Auto-zooms to fit all markers. - */ -@Composable -fun DiscoveryOsmMap( - userLatitude: Double, - userLongitude: Double, - nodes: List, - modifier: Modifier = Modifier, -) { - val context = LocalContext.current - val density = LocalDensity.current - val hasValidUserPosition = userLatitude != 0.0 || userLongitude != 0.0 - val userGeoPoint = remember(userLatitude, userLongitude) { GeoPoint(userLatitude, userLongitude) } - val validNodes = remember(nodes) { nodes.filter { it.latitude != 0.0 || it.longitude != 0.0 } } - - // Build bounding box from all points - val allGeoPoints = - remember(validNodes, hasValidUserPosition) { - buildList { - if (hasValidUserPosition) add(userGeoPoint) - validNodes.forEach { add(GeoPoint(it.latitude, it.longitude)) } - } - } - val initialBounds = - remember(allGeoPoints) { - if (allGeoPoints.isEmpty()) BoundingBox() else BoundingBox.fromGeoPoints(allGeoPoints) - } - - var hasCentered by remember { mutableStateOf(false) } - - val mapView = - rememberMapViewWithLifecycle( - applicationId = context.packageName, - box = initialBounds, - tileSource = CustomTileSource.getTileSource(0), - ) - - // Camera auto-center once - LaunchedEffect(allGeoPoints) { - if (hasCentered || allGeoPoints.isEmpty()) return@LaunchedEffect - if (allGeoPoints.size == 1) { - mapView.controller.setCenter(allGeoPoints.first()) - mapView.controller.setZoom(SINGLE_POINT_ZOOM) - } else { - mapView.zoomToBoundingBox(BoundingBox.fromGeoPoints(allGeoPoints).zoomIn(-ZOOM_OUT_LEVELS), true) - } - hasCentered = true - } - - AndroidView( - modifier = modifier, - factory = { mapView.apply { setDestroyMode(false) } }, - update = { map -> - map.overlays.clear() - map.addCopyright() - map.addScaleBarOverlay(density) - - // User position marker - if (hasValidUserPosition) { - val userMarker = - Marker(map).apply { - position = userGeoPoint - setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) - title = "Your Position" - icon = context.getDrawable(android.R.drawable.ic_menu_mylocation) - } - map.overlays.add(userMarker) - } - - // Node markers - validNodes.forEach { node -> - val nodeGeoPoint = GeoPoint(node.latitude, node.longitude) - val marker = - Marker(map).apply { - position = nodeGeoPoint - setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) - title = node.longName ?: node.shortName ?: "Unknown" - snippet = "SNR: ${node.snr} dB / RSSI: ${node.rssi} dBm" - - val drawableId = - if (node.isSensorNode) { - org.meshtastic.app.R.drawable.ic_thermostat - } else { - org.meshtastic.app.R.drawable.ic_person - } - icon = context.getDrawable(drawableId) - - // Default OSM marker handles color tinting via icon overlay or custom drawables if needed, - // but setting the icon directly overrides the default teardrop pin. - } - map.overlays.add(marker) - } - - // Polylines from user to direct neighbors - if (hasValidUserPosition) { - validNodes - .filter { it.neighborType == DiscoveryNeighborType.DIRECT } - .forEach { node -> - val polyline = - Polyline().apply { - setPoints(listOf(userGeoPoint, GeoPoint(node.latitude, node.longitude))) - outlinePaint.apply { - color = DiscoveryMapColors.DirectLine.toArgb() - strokeWidth = with(density) { 3.dp.toPx() } - strokeCap = Paint.Cap.ROUND - style = Paint.Style.STROKE - } - } - map.overlays.add(polyline) - } - } - - map.invalidate() - }, - ) -} diff --git a/app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryGoogleMap.kt b/app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryGoogleMap.kt deleted file mode 100644 index 492fc84d3..000000000 --- a/app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryGoogleMap.kt +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -@file:Suppress("MagicNumber") - -package org.meshtastic.app.map.discovery - -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import com.google.android.gms.maps.CameraUpdateFactory -import com.google.android.gms.maps.model.CameraPosition -import com.google.android.gms.maps.model.LatLng -import com.google.android.gms.maps.model.LatLngBounds -import com.google.maps.android.compose.ComposeMapColorScheme -import com.google.maps.android.compose.GoogleMap -import com.google.maps.android.compose.MapUiSettings -import com.google.maps.android.compose.MapsComposeExperimentalApi -import com.google.maps.android.compose.MarkerComposable -import com.google.maps.android.compose.Polyline -import com.google.maps.android.compose.rememberCameraPositionState -import com.google.maps.android.compose.rememberUpdatedMarkerState -import org.meshtastic.core.ui.icon.MeshtasticIcons -import org.meshtastic.core.ui.icon.Person -import org.meshtastic.core.ui.icon.Temperature -import org.meshtastic.core.ui.util.DiscoveryMapNode -import org.meshtastic.core.ui.util.DiscoveryNeighborType - -private const val DEFAULT_ZOOM = 12f -private const val BOUNDS_PADDING_PX = 100 - -private val DirectColor = Color(0xFF4CAF50) -private val MeshColor = Color(0xFF2196F3) -private val UserColor = Color(0xFFFF9800) -private val DirectLineColor = Color(0xFF4CAF50).copy(alpha = 0.5f) - -/** - * Google Maps implementation of the discovery map. Renders discovered node markers color-coded by neighbor type (green - * = direct, blue = mesh) with polylines from the user position to direct neighbors. Auto-zooms to fit all markers. - */ -@OptIn(MapsComposeExperimentalApi::class) -@Composable -fun DiscoveryGoogleMap( - userLatitude: Double, - userLongitude: Double, - nodes: List, - modifier: Modifier = Modifier, -) { - val dark = isSystemInDarkTheme() - val mapColorScheme = if (dark) ComposeMapColorScheme.DARK else ComposeMapColorScheme.LIGHT - - val userLatLng = remember(userLatitude, userLongitude) { LatLng(userLatitude, userLongitude) } - val hasValidUserPosition = userLatitude != 0.0 || userLongitude != 0.0 - val validNodes = remember(nodes) { nodes.filter { it.latitude != 0.0 || it.longitude != 0.0 } } - - val cameraState = rememberCameraPositionState { - position = - CameraPosition.fromLatLngZoom(if (hasValidUserPosition) userLatLng else LatLng(0.0, 0.0), DEFAULT_ZOOM) - } - - // Auto-fit bounds on first composition - LaunchedEffect(validNodes, hasValidUserPosition) { - val allPoints = buildList { - if (hasValidUserPosition) add(userLatLng) - validNodes.forEach { add(LatLng(it.latitude, it.longitude)) } - } - if (allPoints.size >= 2) { - val boundsBuilder = LatLngBounds.builder() - allPoints.forEach { boundsBuilder.include(it) } - cameraState.animate(CameraUpdateFactory.newLatLngBounds(boundsBuilder.build(), BOUNDS_PADDING_PX)) - } else if (allPoints.size == 1) { - cameraState.animate(CameraUpdateFactory.newLatLngZoom(allPoints.first(), DEFAULT_ZOOM)) - } - } - - GoogleMap( - mapColorScheme = mapColorScheme, - modifier = modifier, - uiSettings = - MapUiSettings( - zoomControlsEnabled = true, - mapToolbarEnabled = false, - compassEnabled = true, - myLocationButtonEnabled = false, - ), - cameraPositionState = cameraState, - ) { - // User position marker - if (hasValidUserPosition) { - MarkerComposable(state = rememberUpdatedMarkerState(position = userLatLng), title = "Your Position") { - DiscoveryMarkerChip(label = "You", color = UserColor) - } - } - - // Node markers - validNodes.forEach { node -> - val nodeLatLng = LatLng(node.latitude, node.longitude) - val markerColor = - when (node.neighborType) { - DiscoveryNeighborType.DIRECT -> DirectColor - DiscoveryNeighborType.MESH -> MeshColor - } - val nodeIcon = - if (node.isSensorNode) { - MeshtasticIcons.Temperature - } else { - MeshtasticIcons.Person - } - MarkerComposable( - state = rememberUpdatedMarkerState(position = nodeLatLng), - title = node.longName ?: node.shortName ?: "Unknown", - snippet = "SNR: ${node.snr} dB / RSSI: ${node.rssi} dBm", - ) { - DiscoveryMarkerChip(label = node.shortName ?: "?", color = markerColor, icon = nodeIcon) - } - } - - // Polylines from user to direct neighbors - if (hasValidUserPosition) { - validNodes - .filter { it.neighborType == DiscoveryNeighborType.DIRECT } - .forEach { node -> - Polyline( - points = listOf(userLatLng, LatLng(node.latitude, node.longitude)), - color = DirectLineColor, - width = 4f, - ) - } - } - } -} diff --git a/app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryMap.kt b/app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryMap.kt deleted file mode 100644 index 9dff45053..000000000 --- a/app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryMap.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.meshtastic.app.map.discovery - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import org.meshtastic.core.ui.util.DiscoveryMapNode - -/** Flavor-unified entry point for the discovery map. Google Maps implementation. */ -@Composable -fun DiscoveryMap( - userLatitude: Double, - userLongitude: Double, - nodes: List, - modifier: Modifier = Modifier, -) { - DiscoveryGoogleMap(userLatitude = userLatitude, userLongitude = userLongitude, nodes = nodes, modifier = modifier) -} diff --git a/app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryMarkerChip.kt b/app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryMarkerChip.kt deleted file mode 100644 index f1eaea766..000000000 --- a/app/src/google/kotlin/org/meshtastic/app/map/discovery/DiscoveryMarkerChip.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -@file:Suppress("MagicNumber") - -package org.meshtastic.app.map.discovery - -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.unit.dp - -/** Compact chip rendered as a Google Maps marker icon for discovery nodes. */ -@Composable -fun DiscoveryMarkerChip(label: String, color: Color, modifier: Modifier = Modifier, icon: ImageVector? = null) { - Box( - modifier = - modifier - .background(color = color, shape = RoundedCornerShape(12.dp)) - .border(width = 1.dp, color = Color.White, shape = RoundedCornerShape(12.dp)) - .padding(horizontal = 8.dp, vertical = 4.dp), - contentAlignment = Alignment.Center, - ) { - if (icon != null) { - Icon(imageVector = icon, contentDescription = label, tint = Color.White, modifier = Modifier.size(16.dp)) - } else { - Text(text = label, style = MaterialTheme.typography.labelSmall, color = Color.White) - } - } -} diff --git a/app/src/main/res/drawable/ic_person.xml b/app/src/main/res/drawable/ic_person.xml deleted file mode 100644 index 8e5be7ed1..000000000 --- a/app/src/main/res/drawable/ic_person.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_thermostat.xml b/app/src/main/res/drawable/ic_thermostat.xml deleted file mode 100644 index 5257f7fe6..000000000 --- a/app/src/main/res/drawable/ic_thermostat.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/core/proto/src/main/proto b/core/proto/src/main/proto new file mode 160000 index 000000000..79185c6fc --- /dev/null +++ b/core/proto/src/main/proto @@ -0,0 +1 @@ +Subproject commit 79185c6fc857b0df1ffa629196ac863fc04e800e