From 6e9d0040bb64742b0e5e67e7445b4729227629c2 Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Sun, 1 Mar 2026 17:47:43 +0100 Subject: [PATCH] [fix](trx-frontend): preserve APRS reception timestamp across page refresh Previously aprsMapAddStation forced Leaflet map init on a hidden element during history restore. When live packets later arrived they stamped a fresh _tsMs, resetting the displayed age to "0s ago". Decouple data storage from Leaflet rendering: - aprsMapAddStation now stores station data in stationMarkers immediately (with the original _tsMs from localStorage) without touching the map - _aprsAddMarkerToMap creates Leaflet markers only when the map is ready - initAprsMap materialises all buffered APRS entries on first open Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Stan Grams --- .../trx-frontend-http/assets/web/app.js | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js index 3cee5c4..a0fe753 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js @@ -2429,9 +2429,17 @@ function initAprsMap() { const entry = stationMarkers.get(marker._aprsCall); if (!entry) return; const ll = marker.getLatLng(); - e.popup.setContent(buildAprsPopupHtml(marker._aprsCall, ll.lat, ll.lng, entry.pkt?.info || "", entry.pkt)); + e.popup.setContent(buildAprsPopupHtml(marker._aprsCall, ll.lat, ll.lng, entry.info || "", entry.pkt)); }); + // Materialise any stations that were buffered before the map was ready + for (const [call, entry] of stationMarkers) { + if (entry.type === "aprs" && !entry.marker && entry.lat != null && entry.lon != null) { + _aprsAddMarkerToMap(call, entry); + } + } + applyMapFilter(); + const aprsFilter = document.getElementById("map-filter-aprs"); const ft8Filter = document.getElementById("map-filter-ft8"); const wsprFilter = document.getElementById("map-filter-wspr"); @@ -2552,27 +2560,41 @@ function buildAprsPopupHtml(call, lat, lon, info, pkt) { ``; } +function _aprsAddMarkerToMap(call, entry) { + const icon = aprsSymbolIcon(entry.symbolTable, entry.symbolCode); + const popupContent = buildAprsPopupHtml(call, entry.lat, entry.lon, entry.info || "", entry.pkt); + const marker = icon + ? L.marker([entry.lat, entry.lon], { icon }).addTo(aprsMap).bindPopup(popupContent) + : L.circleMarker([entry.lat, entry.lon], { + radius: 6, color: "#00d17f", fillColor: "#00d17f", fillOpacity: 0.8 + }).addTo(aprsMap).bindPopup(popupContent); + marker.__trxType = "aprs"; + marker._aprsCall = call; + entry.marker = marker; + mapMarkers.add(marker); +} + window.aprsMapAddStation = function(call, lat, lon, info, symbolTable, symbolCode, pkt) { - if (!aprsMap) initAprsMap(); - if (!aprsMap) return; - const popupContent = buildAprsPopupHtml(call, lat, lon, info, pkt); const existing = stationMarkers.get(call); if (existing) { - existing.marker.setLatLng([lat, lon]); - existing.marker.setPopupContent(popupContent); + // Update stored data (preserves original _tsMs if pkt is newer) existing.pkt = pkt; + existing.lat = lat; + existing.lon = lon; + existing.info = info; + existing.symbolTable = symbolTable; + existing.symbolCode = symbolCode; + if (aprsMap && existing.marker) { + existing.marker.setLatLng([lat, lon]); + existing.marker.setPopupContent(buildAprsPopupHtml(call, lat, lon, info, pkt)); + } } else { - const icon = aprsSymbolIcon(symbolTable, symbolCode); - const marker = icon - ? L.marker([lat, lon], { icon }).addTo(aprsMap).bindPopup(popupContent) - : L.circleMarker([lat, lon], { - radius: 6, color: "#00d17f", fillColor: "#00d17f", fillOpacity: 0.8 - }).addTo(aprsMap).bindPopup(popupContent); - marker.__trxType = "aprs"; - marker._aprsCall = call; - stationMarkers.set(call, { marker, type: "aprs", pkt }); - mapMarkers.add(marker); - applyMapFilter(); + const entry = { marker: null, type: "aprs", pkt, lat, lon, info, symbolTable, symbolCode }; + stationMarkers.set(call, entry); + if (aprsMap) { + _aprsAddMarkerToMap(call, entry); + applyMapFilter(); + } } };