[fix](trx-frontend-http): gate APRS bar to PKT mode, reject CRC failures

- Hide bar whenever mode != PKT; app.js calls window.updateAprsBar()
  on every server-pushed mode change so the bar disappears immediately
- CRC-failed frames are excluded from the bar (both live and history
  restore); the [CRC] rendering path is removed
- Offset bar 1.2 rem from left edge for visual breathing room

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 14:41:39 +01:00
parent cbefdc15c4
commit 350087855f
3 changed files with 14 additions and 10 deletions
@@ -1419,6 +1419,7 @@ function render(update) {
if (aprsStatus && modeUpper !== "PKT" && aprsStatus.textContent === "Receiving") { if (aprsStatus && modeUpper !== "PKT" && aprsStatus.textContent === "Receiving") {
aprsStatus.textContent = "Connected, listening for packets"; aprsStatus.textContent = "Connected, listening for packets";
} }
if (window.updateAprsBar) window.updateAprsBar();
if (cwStatus && modeUpper !== "CW" && modeUpper !== "CWR" && cwStatus.textContent === "Receiving") { if (cwStatus && modeUpper !== "CW" && modeUpper !== "CWR" && cwStatus.textContent === "Receiving") {
cwStatus.textContent = "Connected, listening for packets"; cwStatus.textContent = "Connected, listening for packets";
} }
@@ -109,7 +109,8 @@ function applyAprsFilterToAll() {
function updateAprsBar() { function updateAprsBar() {
if (!aprsBarOverlay) return; if (!aprsBarOverlay) return;
if (aprsBarFrames.length === 0) { const isPkt = (document.getElementById("mode")?.value || "").toUpperCase() === "PKT";
if (!isPkt || aprsBarFrames.length === 0) {
aprsBarOverlay.style.display = "none"; aprsBarOverlay.style.display = "none";
return; return;
} }
@@ -119,12 +120,12 @@ function updateAprsBar() {
const call = `<span class="aprs-bar-call">${escapeMapHtml(pkt.srcCall)}</span>`; const call = `<span class="aprs-bar-call">${escapeMapHtml(pkt.srcCall)}</span>`;
const dest = escapeMapHtml(pkt.destCall || ""); const dest = escapeMapHtml(pkt.destCall || "");
const info = escapeMapHtml((pkt.info || "").slice(0, 60)); const info = escapeMapHtml((pkt.info || "").slice(0, 60));
const crc = pkt.crcOk ? "" : '<span class="aprs-bar-crc">[CRC]</span>'; html += `<div class="aprs-bar-frame">${ts}${call}>${dest}: ${info}</div>`;
html += `<div class="aprs-bar-frame">${ts}${call}>${dest}: ${info}${crc}</div>`;
} }
aprsBarOverlay.innerHTML = html; aprsBarOverlay.innerHTML = html;
aprsBarOverlay.style.display = "flex"; aprsBarOverlay.style.display = "flex";
} }
window.updateAprsBar = updateAprsBar;
function addAprsPacket(pkt) { function addAprsPacket(pkt) {
const tag = pkt.crcOk ? "[APRS]" : "[APRS-CRC-FAIL]"; const tag = pkt.crcOk ? "[APRS]" : "[APRS-CRC-FAIL]";
@@ -138,10 +139,12 @@ function addAprsPacket(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); saveSetting("aprsPackets", aprsPacketHistory);
// Update overview bar // Update overview bar (CRC-failed frames excluded)
if (pkt.crcOk) {
aprsBarFrames.unshift(pkt); aprsBarFrames.unshift(pkt);
if (aprsBarFrames.length > APRS_BAR_MAX) aprsBarFrames.length = APRS_BAR_MAX; if (aprsBarFrames.length > APRS_BAR_MAX) aprsBarFrames.length = APRS_BAR_MAX;
updateAprsBar(); updateAprsBar();
}
const row = renderAprsRow(pkt); const row = renderAprsRow(pkt);
if (pkt.lat != null && pkt.lon != null && window.aprsMapAddStation) { if (pkt.lat != null && pkt.lon != null && window.aprsMapAddStation) {
@@ -170,8 +173,8 @@ for (let i = aprsPacketHistory.length - 1; i >= 0; i--) {
window.aprsMapAddStation(pkt.srcCall, pkt.lat, pkt.lon, pkt.info, pkt.symbolTable, pkt.symbolCode); window.aprsMapAddStation(pkt.srcCall, pkt.lat, pkt.lon, pkt.info, pkt.symbolTable, pkt.symbolCode);
} }
} }
// Pre-populate bar from history (most recent first) // Pre-populate bar from history (most recent first, CRC-ok only)
aprsBarFrames = aprsPacketHistory.slice(0, APRS_BAR_MAX); aprsBarFrames = aprsPacketHistory.filter((p) => p.crcOk).slice(0, APRS_BAR_MAX);
updateAprsBar(); updateAprsBar();
if (aprsFilterInput) { if (aprsFilterInput) {
@@ -621,7 +621,7 @@ small { color: var(--text-muted); }
display: none; display: none;
position: absolute; position: absolute;
bottom: 0.4rem; bottom: 0.4rem;
left: 0.4rem; left: 1.2rem;
z-index: 5; z-index: 5;
pointer-events: none; pointer-events: none;
color: var(--text-heading); color: var(--text-heading);