mirror of
https://github.com/pe1hvh/meshcore-gui.git
synced 2026-08-07 17:33:16 +02:00
v1.13.2 BugFix
This commit is contained in:
@@ -6,6 +6,33 @@
|
||||
All notable changes to MeshCore GUI are documented in this file.
|
||||
Format follows [Keep a Changelog](https://keepachangelog.com/) and [Semantic Versioning](https://semver.org/).
|
||||
|
||||
---
|
||||
## [1.13.2] - 2026-03-11 — Map Display Bugfix
|
||||
|
||||
### Fixed
|
||||
- 🛠 **MAP panel blank when contacts list is empty at startup** — dashboard update loop
|
||||
had two separate conditional map-update blocks that both silently stopped firing after
|
||||
tick 1 when `data['contacts']` was empty (e.g. device just booted or no contacts
|
||||
stored). Map panel received no further snapshots and remained blank indefinitely.
|
||||
- 🛠 **Route map not rendered when no node has GPS coordinates** — `_render_map` in
|
||||
`route_page.py` returned early before creating the Leaflet container when
|
||||
`payload['nodes']` was empty. `MeshCoreRouteMapBoot` handles an empty nodes list
|
||||
correctly (renders map at home area), so the early return was incorrect.
|
||||
|
||||
### Changed
|
||||
- 🔄 `meshcore_gui/gui/dashboard.py` — Consolidated two conditional map-update blocks
|
||||
into a single unconditional `self._map.update(data)` that fires on every timer tick
|
||||
while the MAP panel is active. The JS runtime coalesces pending payloads so only the
|
||||
newest snapshot is ever applied; the extra calls are cheap.
|
||||
- 🔄 `meshcore_gui/gui/route_page.py` — Removed early `return` from `_render_map` when
|
||||
no GPS nodes are present. The Leaflet container is now always created. A small inline
|
||||
notice is shown when there is no location data instead of skipping the map entirely.
|
||||
|
||||
### Impact
|
||||
- MAP panel now renders reliably on first open regardless of contact/GPS availability
|
||||
- Route map now always shows even when route nodes carry no GPS coordinates
|
||||
- No breaking changes — only the two files above are modified
|
||||
|
||||
---
|
||||
## [1.13.1] - 2026-03-09 — Message Icon Consistency
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ from typing import Any, Dict, List
|
||||
# ==============================================================================
|
||||
|
||||
|
||||
VERSION: str = "1.13.1"
|
||||
VERSION: str = "1.13.2"
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
@@ -756,16 +756,14 @@ class DashboardPage:
|
||||
if data['device_updated'] or is_first:
|
||||
self._device.update(data)
|
||||
|
||||
# Map updates are intentionally limited to when the map panel
|
||||
# is visible. Updating Leaflet every 500 ms while hidden can
|
||||
# trigger excessive tile/layer work in the browser and make the
|
||||
# rest of the UI feel unresponsive (for example the hamburger
|
||||
# menu appearing to do nothing). The explicit update in
|
||||
# _show_panel('map') still refreshes and recenters the map when
|
||||
# the user opens it.
|
||||
if self._active_panel == 'map' and (
|
||||
data['device_updated'] or is_first
|
||||
):
|
||||
# Map: always send a snapshot while the panel is active.
|
||||
# The JS runtime coalesces pending payloads — only the newest
|
||||
# is ever applied — so calling update() on every tick is cheap.
|
||||
# This ensures the Leaflet runtime always gets at least one
|
||||
# valid snapshot after it finishes loading, regardless of
|
||||
# whether device_updated or is_first happened to be True
|
||||
# on the tick that fired before MeshCoreLeafletBoot was defined.
|
||||
if self._active_panel == 'map':
|
||||
self._map.update(data)
|
||||
|
||||
# Channel-dependent UI: always ensure consistency when
|
||||
@@ -790,18 +788,6 @@ class DashboardPage:
|
||||
if data['contacts_updated'] or is_first:
|
||||
self._contacts.update(data)
|
||||
|
||||
# Map
|
||||
if (
|
||||
self._active_panel == 'map'
|
||||
and data['contacts']
|
||||
and (
|
||||
data['contacts_updated']
|
||||
or not self._map.has_markers
|
||||
or is_first
|
||||
)
|
||||
):
|
||||
self._map.update(data)
|
||||
|
||||
# Messages (always — for live filter changes)
|
||||
self._messages.update(
|
||||
data,
|
||||
|
||||
@@ -230,14 +230,24 @@ class RoutePage:
|
||||
|
||||
@staticmethod
|
||||
def _render_map(data: Dict, route: Dict) -> None:
|
||||
"""Render the route map in browser JS using the shared MAP icons."""
|
||||
"""Render the route map in browser JS using the shared MAP icons.
|
||||
|
||||
The Leaflet container is always rendered. When no nodes carry GPS
|
||||
coordinates a notice is shown inside the card, but the map itself
|
||||
still initialises so the user sees the configured home area.
|
||||
MeshCoreRouteMapBoot handles an empty nodes array gracefully by
|
||||
displaying the map at payload.center with no markers.
|
||||
"""
|
||||
with ui.card().classes('w-full'):
|
||||
payload = RoutePage._build_route_map_payload(data, route)
|
||||
|
||||
# Show a notice when no node carries GPS, but do NOT skip the
|
||||
# Leaflet container. The JS runtime renders the map at the
|
||||
# configured home area (DEFAULT_MAP_CENTER) with no markers.
|
||||
if not payload['nodes']:
|
||||
ui.label(
|
||||
'📍 No location data available for map display'
|
||||
).classes('text-gray-500 italic p-4')
|
||||
return
|
||||
'📍 No GPS location data — map shows home area'
|
||||
).classes('text-xs text-gray-400 italic px-2 pt-2')
|
||||
|
||||
container_id = f'route-map-{uuid4().hex}'
|
||||
ui.html(
|
||||
|
||||
Reference in New Issue
Block a user