[fix](trx-frontend-http): replay stored decodes onto the map when it loads
The map module is lazy: it arrives when the Map tab is first opened, which is normally long after startup restored the decode history. Until then aprsMapAddStation, aisMapAddVessel and vdesMapAddPoint are undefined, and the decoders' `if (lat != null && ... && fn)` guards quietly dropped every restored position. Nothing replayed them once the module did arrive, so the map came up empty and filled in only from decodes heard afterwards -- a station heard once was never plotted at all. A second reload appeared to fix it because the cached module then loaded early enough to win the race against the history fetch. Give DecoderPlugin an optional syncMap(), implement it for APRS, AIS and VDES over the history each already retains, and have map-core call trxPluginRuntime.syncMapAll() as it attaches. The add functions are keyed by callsign, MMSI and point, so replaying updates in place and cannot duplicate a marker; the replay runs oldest-first so tracks are rebuilt in the order they happened. Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -196,15 +196,17 @@ function pruneAprsHistoryView() {
|
||||
updateAprsBar();
|
||||
renderAprsHistory();
|
||||
}
|
||||
function plotAprsPacket(pkt) {
|
||||
if (pkt.lat == null || pkt.lon == null || !aprsWindow.aprsMapAddStation) return;
|
||||
aprsWindow.aprsMapAddStation(pkt.srcCall ?? "", pkt.lat, pkt.lon, pkt.info ?? "", pkt.symbolTable, pkt.symbolCode, pkt);
|
||||
}
|
||||
function addAprsPacket(pkt) {
|
||||
const tsMs = Number.isFinite(pkt.ts_ms) ? Number(pkt.ts_ms) : Date.now();
|
||||
pkt._tsMs = tsMs;
|
||||
pkt._ts = new Date(tsMs).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
||||
aprsPacketHistory.unshift(pkt);
|
||||
pruneAprsPacketHistory();
|
||||
if (pkt.lat != null && pkt.lon != null && aprsWindow.aprsMapAddStation) {
|
||||
aprsWindow.aprsMapAddStation(pkt.srcCall ?? "", pkt.lat, pkt.lon, pkt.info ?? "", pkt.symbolTable, pkt.symbolCode, pkt);
|
||||
}
|
||||
plotAprsPacket(pkt);
|
||||
if (pkt.crcOk) scheduleAprsBarUpdate();
|
||||
scheduleAprsHistoryRender();
|
||||
}
|
||||
@@ -221,9 +223,7 @@ function onServerAprsBatch(packets) {
|
||||
const tsMs = Number.isFinite(next.ts_ms) ? Number(next.ts_ms) : Date.now();
|
||||
next._tsMs = tsMs;
|
||||
next._ts = new Date(tsMs).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
||||
if (next.lat != null && next.lon != null && aprsWindow.aprsMapAddStation) {
|
||||
aprsWindow.aprsMapAddStation(next.srcCall ?? "", next.lat, next.lon, next.info ?? "", next.symbolTable, next.symbolCode, next);
|
||||
}
|
||||
plotAprsPacket(next);
|
||||
if (next.crcOk) hasCrcOk = true;
|
||||
normalized.push(next);
|
||||
}
|
||||
@@ -287,5 +287,9 @@ window.trxPluginRuntime.registerDecoder({
|
||||
onBatch: onServerAprsBatch,
|
||||
restore: onServerAprsBatch,
|
||||
reset: resetAprsHistoryView,
|
||||
prune: pruneAprsHistoryView
|
||||
prune: pruneAprsHistoryView,
|
||||
// Oldest first, so station tracks are rebuilt in the order they happened.
|
||||
syncMap: () => {
|
||||
for (const entry of [...aprsPacketHistory].reverse()) plotAprsPacket(entry);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user