[fix](trx-frontend): use server decode history only
Remove APRS client-side persistence, reset decode views before replay, and clear decode panes only after the server clears its history. Co-authored-by: OpenAI Codex <codex@openai.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -2373,6 +2373,31 @@ const locatorMarkers = new Map();
|
|||||||
const mapMarkers = new Set();
|
const mapMarkers = new Set();
|
||||||
const mapFilter = { aprs: true, ft8: true, wspr: true };
|
const mapFilter = { aprs: true, ft8: true, wspr: true };
|
||||||
|
|
||||||
|
window.clearMapMarkersByType = function(type) {
|
||||||
|
if (type === "aprs") {
|
||||||
|
stationMarkers.forEach((entry) => {
|
||||||
|
if (entry && entry.marker) {
|
||||||
|
if (aprsMap && aprsMap.hasLayer(entry.marker)) entry.marker.removeFrom(aprsMap);
|
||||||
|
mapMarkers.delete(entry.marker);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
stationMarkers.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === "ft8" || type === "wspr") {
|
||||||
|
const prefix = `${type}:`;
|
||||||
|
for (const [key, entry] of locatorMarkers.entries()) {
|
||||||
|
if (!key.startsWith(prefix)) continue;
|
||||||
|
if (entry && entry.marker) {
|
||||||
|
if (aprsMap && aprsMap.hasLayer(entry.marker)) entry.marker.removeFrom(aprsMap);
|
||||||
|
mapMarkers.delete(entry.marker);
|
||||||
|
}
|
||||||
|
locatorMarkers.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function mapTileSpecForTheme(theme) {
|
function mapTileSpecForTheme(theme) {
|
||||||
if (theme === "dark") {
|
if (theme === "dark") {
|
||||||
return {
|
return {
|
||||||
@@ -3336,6 +3361,10 @@ function updateDecodeStatus(text) {
|
|||||||
}
|
}
|
||||||
function connectDecode() {
|
function connectDecode() {
|
||||||
if (decodeSource) { decodeSource.close(); }
|
if (decodeSource) { decodeSource.close(); }
|
||||||
|
if (window.resetAprsHistoryView) window.resetAprsHistoryView();
|
||||||
|
if (window.resetCwHistoryView) window.resetCwHistoryView();
|
||||||
|
if (window.resetFt8HistoryView) window.resetFt8HistoryView();
|
||||||
|
if (window.resetWsprHistoryView) window.resetWsprHistoryView();
|
||||||
decodeSource = new EventSource("/decode");
|
decodeSource = new EventSource("/decode");
|
||||||
decodeSource.onopen = () => {
|
decodeSource.onopen = () => {
|
||||||
decodeConnected = true;
|
decodeConnected = true;
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ const aprsFilterInput = document.getElementById("aprs-filter");
|
|||||||
const aprsBarOverlay = document.getElementById("aprs-bar-overlay");
|
const aprsBarOverlay = document.getElementById("aprs-bar-overlay");
|
||||||
const APRS_MAX_PACKETS = 100;
|
const APRS_MAX_PACKETS = 100;
|
||||||
let aprsFilterText = "";
|
let aprsFilterText = "";
|
||||||
|
let aprsPacketHistory = [];
|
||||||
// Persistent packet history
|
|
||||||
let aprsPacketHistory = loadSetting("aprsPackets", []);
|
|
||||||
|
|
||||||
function renderAprsInfo(pkt) {
|
function renderAprsInfo(pkt) {
|
||||||
const bytes = Array.isArray(pkt.info_bytes) ? pkt.info_bytes : null;
|
const bytes = Array.isArray(pkt.info_bytes) ? pkt.info_bytes : null;
|
||||||
@@ -133,6 +131,13 @@ window.clearAprsBar = function() {
|
|||||||
document.getElementById("aprs-clear-btn")?.click();
|
document.getElementById("aprs-clear-btn")?.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.resetAprsHistoryView = function() {
|
||||||
|
aprsPacketsEl.innerHTML = "";
|
||||||
|
aprsPacketHistory = [];
|
||||||
|
updateAprsBar();
|
||||||
|
if (window.clearMapMarkersByType) window.clearMapMarkersByType("aprs");
|
||||||
|
};
|
||||||
|
|
||||||
function addAprsPacket(pkt) {
|
function addAprsPacket(pkt) {
|
||||||
const tag = pkt.crcOk ? "[APRS]" : "[APRS-CRC-FAIL]";
|
const tag = pkt.crcOk ? "[APRS]" : "[APRS-CRC-FAIL]";
|
||||||
console.log(tag, `${pkt.srcCall}>${pkt.destCall}${pkt.path ? "," + pkt.path : ""}: ${pkt.info}`, pkt);
|
console.log(tag, `${pkt.srcCall}>${pkt.destCall}${pkt.path ? "," + pkt.path : ""}: ${pkt.info}`, pkt);
|
||||||
@@ -141,10 +146,8 @@ function addAprsPacket(pkt) {
|
|||||||
pkt._ts = new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
pkt._ts = new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
||||||
pkt._tsMs = Date.now();
|
pkt._tsMs = Date.now();
|
||||||
|
|
||||||
// Persist to history
|
|
||||||
aprsPacketHistory.unshift(pkt);
|
aprsPacketHistory.unshift(pkt);
|
||||||
if (aprsPacketHistory.length > APRS_MAX_PACKETS) aprsPacketHistory.length = APRS_MAX_PACKETS;
|
if (aprsPacketHistory.length > APRS_MAX_PACKETS) aprsPacketHistory.length = APRS_MAX_PACKETS;
|
||||||
saveSetting("aprsPackets", aprsPacketHistory);
|
|
||||||
|
|
||||||
// Update overview bar (CRC-failed frames excluded)
|
// Update overview bar (CRC-failed frames excluded)
|
||||||
if (pkt.crcOk) updateAprsBar();
|
if (pkt.crcOk) updateAprsBar();
|
||||||
@@ -160,22 +163,13 @@ function addAprsPacket(pkt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("aprs-clear-btn").addEventListener("click", async () => {
|
document.getElementById("aprs-clear-btn").addEventListener("click", async () => {
|
||||||
aprsPacketsEl.innerHTML = "";
|
try {
|
||||||
aprsPacketHistory = [];
|
await postPath("/clear_aprs_decode");
|
||||||
saveSetting("aprsPackets", []);
|
window.resetAprsHistoryView();
|
||||||
updateAprsBar();
|
} catch (e) {
|
||||||
try { await postPath("/clear_aprs_decode"); } catch (e) { console.error("APRS clear failed", e); }
|
console.error("APRS clear failed", e);
|
||||||
});
|
|
||||||
|
|
||||||
// Restore saved packets and map markers on page load
|
|
||||||
for (let i = aprsPacketHistory.length - 1; i >= 0; i--) {
|
|
||||||
const pkt = aprsPacketHistory[i];
|
|
||||||
aprsPacketsEl.prepend(renderAprsRow(pkt));
|
|
||||||
if (pkt.lat != null && pkt.lon != null && window.aprsMapAddStation) {
|
|
||||||
window.aprsMapAddStation(pkt.srcCall, pkt.lat, pkt.lon, pkt.info, pkt.symbolTable, pkt.symbolCode, pkt);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
updateAprsBar();
|
|
||||||
|
|
||||||
if (aprsFilterInput) {
|
if (aprsFilterInput) {
|
||||||
aprsFilterInput.addEventListener("input", () => {
|
aprsFilterInput.addEventListener("input", () => {
|
||||||
|
|||||||
@@ -48,9 +48,18 @@ if (cwToneInput) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("cw-clear-btn").addEventListener("click", async () => {
|
window.resetCwHistoryView = function() {
|
||||||
cwOutputEl.innerHTML = "";
|
cwOutputEl.innerHTML = "";
|
||||||
try { await postPath("/clear_cw_decode"); } catch (e) { console.error("CW clear failed", e); }
|
cwLastAppendTime = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById("cw-clear-btn").addEventListener("click", async () => {
|
||||||
|
try {
|
||||||
|
await postPath("/clear_cw_decode");
|
||||||
|
window.resetCwHistoryView();
|
||||||
|
} catch (e) {
|
||||||
|
console.error("CW clear failed", e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- Server-side CW decode handler ---
|
// --- Server-side CW decode handler ---
|
||||||
|
|||||||
@@ -150,6 +150,11 @@ window.updateFt8RfDisplay = function() {
|
|||||||
rows.forEach((row) => updateFt8RowRf(row));
|
rows.forEach((row) => updateFt8RowRf(row));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.resetFt8HistoryView = function() {
|
||||||
|
ft8MessagesEl.innerHTML = "";
|
||||||
|
if (window.clearMapMarkersByType) window.clearMapMarkersByType("ft8");
|
||||||
|
};
|
||||||
|
|
||||||
if (ft8FilterInput) {
|
if (ft8FilterInput) {
|
||||||
ft8FilterInput.addEventListener("input", () => {
|
ft8FilterInput.addEventListener("input", () => {
|
||||||
ft8FilterText = ft8FilterInput.value.trim().toUpperCase();
|
ft8FilterText = ft8FilterInput.value.trim().toUpperCase();
|
||||||
@@ -162,8 +167,12 @@ document.getElementById("ft8-decode-toggle-btn").addEventListener("click", async
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById("ft8-clear-btn").addEventListener("click", async () => {
|
document.getElementById("ft8-clear-btn").addEventListener("click", async () => {
|
||||||
ft8MessagesEl.innerHTML = "";
|
try {
|
||||||
try { await postPath("/clear_ft8_decode"); } catch (e) { console.error("FT8 clear failed", e); }
|
await postPath("/clear_ft8_decode");
|
||||||
|
window.resetFt8HistoryView();
|
||||||
|
} catch (e) {
|
||||||
|
console.error("FT8 clear failed", e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- Server-side FT8 decode handler ---
|
// --- Server-side FT8 decode handler ---
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ function applyWsprFilterToAll() {
|
|||||||
rows.forEach((row) => applyWsprFilterToRow(row));
|
rows.forEach((row) => applyWsprFilterToRow(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.resetWsprHistoryView = function() {
|
||||||
|
wsprMessagesEl.innerHTML = "";
|
||||||
|
if (window.clearMapMarkersByType) window.clearMapMarkersByType("wspr");
|
||||||
|
};
|
||||||
|
|
||||||
if (wsprFilterInput) {
|
if (wsprFilterInput) {
|
||||||
wsprFilterInput.addEventListener("input", () => {
|
wsprFilterInput.addEventListener("input", () => {
|
||||||
wsprFilterText = wsprFilterInput.value.trim().toUpperCase();
|
wsprFilterText = wsprFilterInput.value.trim().toUpperCase();
|
||||||
@@ -109,8 +114,12 @@ document.getElementById("wspr-decode-toggle-btn").addEventListener("click", asyn
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById("wspr-clear-btn").addEventListener("click", async () => {
|
document.getElementById("wspr-clear-btn").addEventListener("click", async () => {
|
||||||
wsprMessagesEl.innerHTML = "";
|
try {
|
||||||
try { await postPath("/clear_wspr_decode"); } catch (e) { console.error("WSPR clear failed", e); }
|
await postPath("/clear_wspr_decode");
|
||||||
|
window.resetWsprHistoryView();
|
||||||
|
} catch (e) {
|
||||||
|
console.error("WSPR clear failed", e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.onServerWspr = function(msg) {
|
window.onServerWspr = function(msg) {
|
||||||
|
|||||||
Reference in New Issue
Block a user