diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index 9f572fcd8..0747d446f 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -452,15 +452,6 @@ constructor( initialValue = 0, ) - val filteredNodeList: StateFlow> = - nodeList - .mapLatest { list -> list.filter { node -> !node.isIgnored } } - .stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(5_000), - initialValue = emptyList(), - ) - data class MapFilterState(val onlyFavorites: Boolean, val showWaypoints: Boolean, val showPrecisionCircle: Boolean) val mapFilterStateFlow: StateFlow = diff --git a/app/src/main/java/com/geeksville/mesh/ui/map/MapView.kt b/app/src/main/java/com/geeksville/mesh/ui/map/MapView.kt index afb7e1ac9..f337447cb 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/map/MapView.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/map/MapView.kt @@ -249,11 +249,13 @@ fun MapView(model: UIViewModel = viewModel(), navigateToNodeDetails: (Int) -> Un } } - val cameraView = remember { - val geoPoints = model.nodesWithPosition.map { GeoPoint(it.latitude, it.longitude) } + val initialCameraView = remember { + val nodes = model.nodeList.value + val nodesWithPosition = nodes.filter { it.validPosition != null } + val geoPoints = nodesWithPosition.map { GeoPoint(it.latitude, it.longitude) } BoundingBox.fromGeoPoints(geoPoints) } - val map = rememberMapViewWithLifecycle(cameraView, loadOnlineTileSourceBase()) + val map = rememberMapViewWithLifecycle(initialCameraView, loadOnlineTileSourceBase()) val nodeClusterer = remember { RadiusMarkerClusterer(context) } @@ -297,7 +299,7 @@ fun MapView(model: UIViewModel = viewModel(), navigateToNodeDetails: (Int) -> Un } } - val nodes by model.filteredNodeList.collectAsStateWithLifecycle() + val nodes by model.nodeList.collectAsStateWithLifecycle() val waypoints by model.waypoints.collectAsStateWithLifecycle(emptyMap()) val markerIcon = remember { AppCompatResources.getDrawable(context, R.drawable.ic_baseline_location_on_24) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/map/MapViewWithLifecycle.kt b/app/src/main/java/com/geeksville/mesh/ui/map/MapViewWithLifecycle.kt index 70181ed48..387533910 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/map/MapViewWithLifecycle.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/map/MapViewWithLifecycle.kt @@ -46,56 +46,67 @@ import org.osmdroid.views.MapView @SuppressLint("WakelockTimeout") private fun PowerManager.WakeLock.safeAcquire() { - if (!isHeld) try { - acquire() - } catch (e: SecurityException) { - errormsg("WakeLock permission exception: ${e.message}") - } catch (e: IllegalStateException) { - errormsg("WakeLock acquire() exception: ${e.message}") + if (!isHeld) { + try { + acquire() + } catch (e: SecurityException) { + errormsg("WakeLock permission exception: ${e.message}") + } catch (e: IllegalStateException) { + errormsg("WakeLock acquire() exception: ${e.message}") + } } } private fun PowerManager.WakeLock.safeRelease() { - if (isHeld) try { - release() - } catch (e: IllegalStateException) { - errormsg("WakeLock release() exception: ${e.message}") + if (isHeld) { + try { + release() + } catch (e: IllegalStateException) { + errormsg("WakeLock release() exception: ${e.message}") + } } } const val MAP_STYLE_ID = "map_style_id" -private const val MinZoomLevel = 1.5 -private const val MaxZoomLevel = 20.0 -private const val DefaultZoomLevel = 15.0 +private const val MIN_ZOOM_LEVEL = 1.5 +private const val MAX_ZOOM_LEVEL = 20.0 +private const val DEFAULT_ZOOM_LEVEL = 15.0 +@Suppress("MagicNumber") @Composable internal fun rememberMapViewWithLifecycle( box: BoundingBox, tileSource: ITileSource = TileSourceFactory.DEFAULT_TILE_SOURCE, ): MapView { - val zoom = if (box.requiredZoomLevel().isFinite()) { - box.requiredZoomLevel() - } else { - DefaultZoomLevel - } + val zoom = + if (box.requiredZoomLevel().isFinite()) { + (box.requiredZoomLevel() - 0.5).coerceAtLeast(MIN_ZOOM_LEVEL) + } else { + DEFAULT_ZOOM_LEVEL + } val center = GeoPoint(box.centerLatitude, box.centerLongitude) return rememberMapViewWithLifecycle(zoom, center, tileSource) } +@Suppress("LongMethod") @Composable internal fun rememberMapViewWithLifecycle( - zoomLevel: Double = MinZoomLevel, + zoomLevel: Double = MIN_ZOOM_LEVEL, mapCenter: GeoPoint = GeoPoint(0.0, 0.0), tileSource: ITileSource = TileSourceFactory.DEFAULT_TILE_SOURCE, ): MapView { var savedZoom by rememberSaveable { mutableDoubleStateOf(zoomLevel) } - var savedCenter by rememberSaveable( - stateSaver = Saver( - save = { mapOf("latitude" to it.latitude, "longitude" to it.longitude) }, - restore = { GeoPoint(it["latitude"] ?: 0.0, it["longitude"] ?: .0) } - ) - ) { mutableStateOf(mapCenter) } + var savedCenter by + rememberSaveable( + stateSaver = + Saver( + save = { mapOf("latitude" to it.latitude, "longitude" to it.longitude) }, + restore = { GeoPoint(it["latitude"] ?: 0.0, it["longitude"] ?: .0) }, + ), + ) { + mutableStateOf(mapCenter) + } val context = LocalContext.current val mapView = remember { @@ -112,8 +123,8 @@ internal fun rememberMapViewWithLifecycle( // scales the map tiles to the display density of the screen isTilesScaledToDpi = true // sets the minimum zoom level (the furthest out you can zoom) - minZoomLevel = MinZoomLevel - maxZoomLevel = MaxZoomLevel + minZoomLevel = MIN_ZOOM_LEVEL + maxZoomLevel = MAX_ZOOM_LEVEL // Disables default +/- button for zooming zoomController.setVisibility(CustomZoomButtonsController.Visibility.SHOW_AND_FADEOUT) @@ -126,8 +137,7 @@ internal fun rememberMapViewWithLifecycle( val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager @Suppress("DEPRECATION") - val wakeLock = - powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "Meshtastic:MapViewLock") + val wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "Meshtastic:MapViewLock") wakeLock.safeAcquire()