[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 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-03-22 14:05:14 +01:00
parent 189d27bac8
commit 1f6e3bb142
2 changed files with 63 additions and 0 deletions
@@ -2944,6 +2944,19 @@ function render(update) {
); );
} }
updateSdrSquelchControlVisibility(); 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 (typeof update.show_sdr_gain_control === "boolean") {
if (sdrSettingsRowEl) sdrSettingsRowEl.style.display = update.show_sdr_gain_control ? "" : "none"; 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_MIN_DB = -120;
const SDR_SQUELCH_MAX_DB = -30; const SDR_SQUELCH_MAX_DB = -30;
let syncFromServerSdrSquelch = false; 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 // Hide audio row if audio is not configured on the server
fetch("/audio", { method: "GET" }).then((r) => { 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() { function updateWfmControls() {
if (!wfmControlsCol) return; if (!wfmControlsCol) return;
const mode = (modeEl && modeEl.value ? modeEl.value : "").toUpperCase(); const mode = (modeEl && modeEl.value ? modeEl.value : "").toUpperCase();
@@ -284,6 +284,19 @@
</label> </label>
<button id="sdr-lna-gain-set" type="button" class="wfm-inline-btn">Set</button> <button id="sdr-lna-gain-set" type="button" class="wfm-inline-btn">Set</button>
</div> </div>
<label class="wfm-control" id="sdr-nb-wrap" style="display:none;">
<span class="wfm-control-label">Noise Blanker</span>
<div style="height:2.1rem; display:flex; align-items:center;">
<input type="checkbox" id="sdr-nb-enabled">
</div>
</label>
<div class="wfm-gain-group" id="sdr-nb-threshold-controls" style="display:none;">
<label class="wfm-control">
<span class="wfm-control-label">NB Threshold</span>
<input id="sdr-nb-threshold" class="status-input" type="number" min="1" max="100" step="1" inputmode="decimal">
</label>
<button id="sdr-nb-threshold-set" type="button" class="wfm-inline-btn">Set</button>
</div>
</div> </div>
</div> </div>
<div class="full-row label-below-row" id="vchan-row"> <div class="full-row label-below-row" id="vchan-row">