[feat](trx-frontend-http): add dedicated WSPR plugin tab
Expose a WSPR subtab in the Plugins view with its own controls and message list, wire a dedicated wspr.js asset endpoint, and route WSPR decode events to the new panel. This makes WSPR visible in the HTTP frontend instead of reusing the FT8 panel for WSPR messages. Co-authored-by: Codex <codex@openai.com> Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
// --- WSPR Decoder Plugin (server-side decode) ---
|
||||
const wsprStatus = document.getElementById("wspr-status");
|
||||
const wsprMessagesEl = document.getElementById("wspr-messages");
|
||||
const WSPR_MAX_MESSAGES = 200;
|
||||
|
||||
function fmtWsprTime(tsMs) {
|
||||
if (!tsMs) return "--:--:--";
|
||||
return new Date(tsMs).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
||||
}
|
||||
|
||||
function renderWsprRow(msg) {
|
||||
const row = document.createElement("div");
|
||||
row.className = "ft8-row";
|
||||
const snr = Number.isFinite(msg.snr_db) ? msg.snr_db.toFixed(1) : "--";
|
||||
const dt = Number.isFinite(msg.dt_s) ? msg.dt_s.toFixed(2) : "--";
|
||||
const baseHz = Number.isFinite(window.ft8BaseHz) ? window.ft8BaseHz : null;
|
||||
const rfHz = Number.isFinite(msg.freq_hz) && Number.isFinite(baseHz) ? (baseHz + msg.freq_hz) : null;
|
||||
const freq = Number.isFinite(rfHz) ? rfHz.toFixed(0) : "--";
|
||||
const message = (msg.message || "").toString();
|
||||
row.innerHTML = `<span class="ft8-time">${fmtWsprTime(msg.ts_ms)}</span><span class="ft8-snr">${snr}</span><span class="ft8-dt">${dt}</span><span class="ft8-freq">${freq}</span><span class="ft8-msg">${escapeWsprHtml(message)}</span>`;
|
||||
return row;
|
||||
}
|
||||
|
||||
function addWsprMessage(msg) {
|
||||
wsprMessagesEl.prepend(renderWsprRow(msg));
|
||||
while (wsprMessagesEl.children.length > WSPR_MAX_MESSAGES) {
|
||||
wsprMessagesEl.removeChild(wsprMessagesEl.lastChild);
|
||||
}
|
||||
}
|
||||
|
||||
function escapeWsprHtml(input) {
|
||||
return input
|
||||
.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">")
|
||||
.replaceAll("\"", """);
|
||||
}
|
||||
|
||||
document.getElementById("wspr-decode-toggle-btn").addEventListener("click", async () => {
|
||||
try { await postPath("/toggle_wspr_decode"); } catch (e) { console.error("WSPR toggle failed", e); }
|
||||
});
|
||||
|
||||
document.getElementById("wspr-clear-btn").addEventListener("click", async () => {
|
||||
wsprMessagesEl.innerHTML = "";
|
||||
try { await postPath("/clear_wspr_decode"); } catch (e) { console.error("WSPR clear failed", e); }
|
||||
});
|
||||
|
||||
window.onServerWspr = function(msg) {
|
||||
wsprStatus.textContent = "Receiving";
|
||||
addWsprMessage({
|
||||
ts_ms: msg.ts_ms,
|
||||
snr_db: msg.snr_db,
|
||||
dt_s: msg.dt_s,
|
||||
freq_hz: msg.freq_hz,
|
||||
message: msg.message,
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user