[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 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-03-01 17:47:43 +01:00
parent 42e73f5eeb
commit 6e9d0040bb
@@ -2429,9 +2429,17 @@ function initAprsMap() {
const entry = stationMarkers.get(marker._aprsCall); const entry = stationMarkers.get(marker._aprsCall);
if (!entry) return; if (!entry) return;
const ll = marker.getLatLng(); 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 aprsFilter = document.getElementById("map-filter-aprs");
const ft8Filter = document.getElementById("map-filter-ft8"); const ft8Filter = document.getElementById("map-filter-ft8");
const wsprFilter = document.getElementById("map-filter-wspr"); const wsprFilter = document.getElementById("map-filter-wspr");
@@ -2552,27 +2560,41 @@ function buildAprsPopupHtml(call, lat, lon, info, pkt) {
`</div>`; `</div>`;
} }
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) { 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); const existing = stationMarkers.get(call);
if (existing) { if (existing) {
existing.marker.setLatLng([lat, lon]); // Update stored data (preserves original _tsMs if pkt is newer)
existing.marker.setPopupContent(popupContent);
existing.pkt = pkt; 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 { } else {
const icon = aprsSymbolIcon(symbolTable, symbolCode); const entry = { marker: null, type: "aprs", pkt, lat, lon, info, symbolTable, symbolCode };
const marker = icon stationMarkers.set(call, entry);
? L.marker([lat, lon], { icon }).addTo(aprsMap).bindPopup(popupContent) if (aprsMap) {
: L.circleMarker([lat, lon], { _aprsAddMarkerToMap(call, entry);
radius: 6, color: "#00d17f", fillColor: "#00d17f", fillOpacity: 0.8 applyMapFilter();
}).addTo(aprsMap).bindPopup(popupContent); }
marker.__trxType = "aprs";
marker._aprsCall = call;
stationMarkers.set(call, { marker, type: "aprs", pkt });
mapMarkers.add(marker);
applyMapFilter();
} }
}; };