[feat](trx-frontend-http): enhance header telemetry and responsive UX

Implement UI refinements for the HTTP frontend main and plugin views.\n\n- add dimmed header signal graph with live rendering and scale\n- make graph responsive, colorized by signal strength, and keep last 10s only\n- add APRS and WSPR text filtering, matching FT8 behavior\n- refine responsive layout for controls/map/header behavior\n- tune jog wheel/button sizing and mode selector height alignment\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
This commit is contained in:
2026-02-13 02:03:20 +01:00
parent 630a02789c
commit 53ce663adc
5 changed files with 240 additions and 16 deletions
@@ -1,7 +1,9 @@
// --- APRS Decoder Plugin (server-side decode) ---
const aprsStatus = document.getElementById("aprs-status");
const aprsPacketsEl = document.getElementById("aprs-packets");
const aprsFilterInput = document.getElementById("aprs-filter");
const APRS_MAX_PACKETS = 100;
let aprsFilterText = "";
// Persistent packet history
let aprsPacketHistory = loadSetting("aprsPackets", []);
@@ -66,10 +68,37 @@ function renderAprsRow(pkt) {
const osmUrl = `https://www.openstreetmap.org/?mlat=${pkt.lat}&mlon=${pkt.lon}#map=15/${pkt.lat}/${pkt.lon}`;
posHtml = ` <a class="aprs-pos" href="${osmUrl}" target="_blank">${pkt.lat.toFixed(4)}, ${pkt.lon.toFixed(4)}</a>`;
}
row.dataset.filterText = [
pkt.srcCall,
pkt.destCall,
pkt.path,
pkt.info,
pkt.type,
pkt.lat != null ? pkt.lat.toFixed(4) : "",
pkt.lon != null ? pkt.lon.toFixed(4) : "",
]
.filter(Boolean)
.join(" ")
.toUpperCase();
row.innerHTML = `<span class="aprs-time">${ts}</span>${symbolHtml}<span class="aprs-call">${pkt.srcCall}</span>&gt;${pkt.destCall}${pkt.path ? "," + pkt.path : ""}: <span title="${pkt.type}">${renderAprsInfo(pkt)}</span>${posHtml}${crcTag}`;
applyAprsFilterToRow(row);
return row;
}
function applyAprsFilterToRow(row) {
if (!aprsFilterText) {
row.style.display = "";
return;
}
const message = row.dataset.filterText || "";
row.style.display = message.includes(aprsFilterText) ? "" : "none";
}
function applyAprsFilterToAll() {
const rows = aprsPacketsEl.querySelectorAll(".aprs-packet");
rows.forEach((row) => applyAprsFilterToRow(row));
}
function addAprsPacket(pkt) {
const tag = pkt.crcOk ? "[APRS]" : "[APRS-CRC-FAIL]";
console.log(tag, `${pkt.srcCall}>${pkt.destCall}${pkt.path ? "," + pkt.path : ""}: ${pkt.info}`, pkt);
@@ -108,6 +137,13 @@ for (let i = aprsPacketHistory.length - 1; i >= 0; i--) {
}
}
if (aprsFilterInput) {
aprsFilterInput.addEventListener("input", () => {
aprsFilterText = aprsFilterInput.value.trim().toUpperCase();
applyAprsFilterToAll();
});
}
// --- Server-side APRS decode handler ---
window.onServerAprs = function(pkt) {
aprsStatus.textContent = "Receiving";