[feat](trx-frontend-http): intercept freq/mode changes for virtual channels

When on a non-primary (virtual) channel, redirect freq and mode changes
to the channel metadata API instead of the server:

- vchan.js: add vchanIsOnVirtual(), vchanSetChannelFreq/Mode(); expose
  window.vchanInterceptMode() hook; wrap window.setRigFrequency so all
  callers (jog, freq input, bookmarks, spectrum click) are automatically
  redirected without modification
- app.js: check vchanInterceptMode() in applyModeFromPicker() before
  posting /set_mode
- bookmarks.js: check vchanInterceptMode() for mode in bmApply();
  setRigFrequency() redirect is automatic via the vchan.js wrapper;
  bandwidth and decoder toggles still apply regardless of channel

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-11 07:08:36 +01:00
parent 832e42ca3b
commit cef1741e40
3 changed files with 79 additions and 2 deletions
@@ -277,7 +277,11 @@ async function bmDelete(id) {
async function bmApply(bm) {
try {
await postPath("/set_mode?mode=" + encodeURIComponent(bm.mode));
const onVirtual = typeof vchanInterceptMode === "function"
&& await vchanInterceptMode(bm.mode);
if (!onVirtual) {
await postPath("/set_mode?mode=" + encodeURIComponent(bm.mode));
}
if (typeof modeEl !== "undefined" && modeEl) {
modeEl.value = String(bm.mode || "").toUpperCase();
}
@@ -290,12 +294,14 @@ async function bmApply(bm) {
syncBandwidthInput(bm.bandwidth_hz);
}
}
// setRigFrequency is wrapped by vchan.js to redirect to the channel API
// when on a virtual channel, so this call works correctly in both cases.
if (typeof setRigFrequency === "function") {
await setRigFrequency(bm.freq_hz);
} else {
await postPath("/set_freq?hz=" + bm.freq_hz);
}
// Toggle decoders when in DIG mode
// Toggle decoders when in DIG mode.
if (bm.mode === "DIG" && Array.isArray(bm.decoders)) {
const statusResp = await fetch("/status");
if (statusResp.ok) {