From 1f6e3bb142750c358d73a604906ae97663de07ab Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Sun, 22 Mar 2026 14:05:14 +0100 Subject: [PATCH] [feat](trx-frontend-http): add noise blanker controls to SDR settings UI Add checkbox to enable/disable NB and number input for threshold (1-100). Controls are hidden by default and shown when the server reports NB support via SSE filter state updates. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Stan Grams --- .../trx-frontend-http/assets/web/app.js | 50 +++++++++++++++++++ .../trx-frontend-http/assets/web/index.html | 13 +++++ 2 files changed, 63 insertions(+) diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js index eeca0b4..ffb58a4 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js @@ -2944,6 +2944,19 @@ function render(update) { ); } updateSdrSquelchControlVisibility(); + const hasSdrNbEnabled = typeof update.filter.sdr_nb_enabled === "boolean"; + const hasSdrNbThreshold = typeof update.filter.sdr_nb_threshold === "number"; + if (hasSdrNbEnabled || hasSdrNbThreshold) { + sdrNbSupported = true; + if (sdrNbWrapEl) sdrNbWrapEl.style.display = ""; + if (sdrNbThresholdControlsEl) sdrNbThresholdControlsEl.style.display = ""; + if (hasSdrNbEnabled && sdrNbEnabledEl) { + sdrNbEnabledEl.checked = update.filter.sdr_nb_enabled; + } + if (hasSdrNbThreshold && sdrNbThresholdEl && document.activeElement !== sdrNbThresholdEl) { + sdrNbThresholdEl.value = String(Math.round(update.filter.sdr_nb_threshold)); + } + } } if (typeof update.show_sdr_gain_control === "boolean") { if (sdrSettingsRowEl) sdrSettingsRowEl.style.display = update.show_sdr_gain_control ? "" : "none"; @@ -7281,6 +7294,12 @@ const sdrSquelchPctEl = document.getElementById("sdr-squelch-pct"); const SDR_SQUELCH_MIN_DB = -120; const SDR_SQUELCH_MAX_DB = -30; let syncFromServerSdrSquelch = false; +const sdrNbWrapEl = document.getElementById("sdr-nb-wrap"); +const sdrNbEnabledEl = document.getElementById("sdr-nb-enabled"); +const sdrNbThresholdControlsEl = document.getElementById("sdr-nb-threshold-controls"); +const sdrNbThresholdEl = document.getElementById("sdr-nb-threshold"); +const sdrNbThresholdSetBtn = document.getElementById("sdr-nb-threshold-set"); +let sdrNbSupported = false; // Hide audio row if audio is not configured on the server fetch("/audio", { method: "GET" }).then((r) => { @@ -7490,6 +7509,37 @@ if (sdrLnaGainEl) { } }); } +function submitSdrNbState() { + if (!sdrNbSupported) return; + const enabled = sdrNbEnabledEl ? sdrNbEnabledEl.checked : false; + const threshold = sdrNbThresholdEl ? Number.parseFloat(sdrNbThresholdEl.value) : 10; + if (!Number.isFinite(threshold) || threshold < 1 || threshold > 100) return; + postPath( + `/set_sdr_noise_blanker?enabled=${enabled ? "true" : "false"}&threshold=${encodeURIComponent(threshold)}`, + ).catch(() => {}); +} +if (sdrNbEnabledEl) { + sdrNbEnabledEl.addEventListener("change", () => { + submitSdrNbState(); + }); +} +function submitSdrNbThreshold() { + if (!sdrNbThresholdEl) return; + const parsed = Number.parseFloat(sdrNbThresholdEl.value); + if (!Number.isFinite(parsed) || parsed < 1 || parsed > 100) return; + submitSdrNbState(); +} +if (sdrNbThresholdSetBtn) { + sdrNbThresholdSetBtn.addEventListener("click", submitSdrNbThreshold); +} +if (sdrNbThresholdEl) { + sdrNbThresholdEl.addEventListener("keydown", (ev) => { + if (ev.key === "Enter") { + ev.preventDefault(); + submitSdrNbThreshold(); + } + }); +} function updateWfmControls() { if (!wfmControlsCol) return; const mode = (modeEl && modeEl.value ? modeEl.value : "").toUpperCase(); diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html index 75d39b7..f25a00f 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html @@ -284,6 +284,19 @@ + +