From 420e98de311ddc0f4e4c587fc6dc1751285c831b Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Sat, 28 Feb 2026 23:45:17 +0100 Subject: [PATCH] [feat](trx-client,trx-frontend-http): add default rig and hideable rf gain Co-authored-by: OpenAI Codex Signed-off-by: Stan Grams --- src/trx-client/src/config.rs | 13 +++++++++++++ src/trx-client/src/main.rs | 7 ++++++- src/trx-client/trx-frontend/src/lib.rs | 3 +++ .../trx-frontend-http/assets/web/app.js | 4 ++++ .../trx-frontend-http/assets/web/index.html | 10 ++++++---- .../trx-frontend/trx-frontend-http/src/api.rs | 12 ++++++++++++ 6 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/trx-client/src/config.rs b/src/trx-client/src/config.rs index ea6bd68..7aebda7 100644 --- a/src/trx-client/src/config.rs +++ b/src/trx-client/src/config.rs @@ -228,6 +228,10 @@ pub struct HttpFrontendConfig { pub listen: IpAddr, /// Listen port pub port: u16, + /// Default rig selected in the web UI on startup. + pub default_rig_id: Option, + /// Whether to expose the RF Gain control in the web UI. + pub show_sdr_gain_control: bool, /// Authentication settings pub auth: HttpAuthConfig, } @@ -238,6 +242,8 @@ impl Default for HttpFrontendConfig { enabled: true, listen: IpAddr::from([127, 0, 0, 1]), port: 8080, + default_rig_id: None, + show_sdr_gain_control: true, auth: HttpAuthConfig::default(), } } @@ -329,6 +335,11 @@ impl ClientConfig { if self.frontends.http.enabled && self.frontends.http.port == 0 { return Err("[frontends.http].port must be > 0 when enabled".to_string()); } + if let Some(rig_id) = &self.frontends.http.default_rig_id { + if rig_id.trim().is_empty() { + return Err("[frontends.http].default_rig_id must not be empty when set".to_string()); + } + } if self.frontends.rigctl.enabled && self.frontends.rigctl.rig_ports.is_empty() { return Err( "[frontends.rigctl].rig_ports must contain at least one rig when enabled" @@ -420,6 +431,8 @@ impl ClientConfig { enabled: true, listen: IpAddr::from([127, 0, 0, 1]), port: 8080, + default_rig_id: Some("hf".to_string()), + show_sdr_gain_control: true, auth: HttpAuthConfig { enabled: false, rx_passphrase: Some("rx-passphrase-example".to_string()), diff --git a/src/trx-client/src/main.rs b/src/trx-client/src/main.rs index 28d04ff..820536c 100644 --- a/src/trx-client/src/main.rs +++ b/src/trx-client/src/main.rs @@ -177,6 +177,7 @@ async fn async_init() -> DynResult { config::CookieSameSite::Lax => "Lax".to_string(), config::CookieSameSite::None => "None".to_string(), }; + frontend_runtime.http_show_sdr_gain_control = cfg.frontends.http.show_sdr_gain_control; // Resolve remote URL: CLI > config [remote] section > error let remote_url = cli @@ -189,7 +190,11 @@ async fn async_init() -> DynResult { parse_remote_url(&remote_url).map_err(|e| format!("Invalid remote URL: {}", e))?; let remote_token = cli.token.clone().or_else(|| cfg.remote.auth.token.clone()); - let remote_rig_id = cli.rig_id.clone().or_else(|| cfg.remote.rig_id.clone()); + let remote_rig_id = cli + .rig_id + .clone() + .or_else(|| cfg.frontends.http.default_rig_id.clone()) + .or_else(|| cfg.remote.rig_id.clone()); if let Ok(mut guard) = frontend_runtime.remote_active_rig_id.lock() { *guard = remote_rig_id.clone(); } diff --git a/src/trx-client/trx-frontend/src/lib.rs b/src/trx-client/trx-frontend/src/lib.rs index 1a115c9..7107dcb 100644 --- a/src/trx-client/trx-frontend/src/lib.rs +++ b/src/trx-client/trx-frontend/src/lib.rs @@ -166,6 +166,8 @@ pub struct FrontendRuntimeContext { pub http_auth_cookie_secure: bool, /// HTTP frontend auth cookie same-site policy pub http_auth_cookie_same_site: String, + /// Whether the HTTP UI should expose the RF Gain control. + pub http_show_sdr_gain_control: bool, /// Currently selected remote rig id (used by remote client routing). pub remote_active_rig_id: Arc>>, /// Cached remote rig list from GetRigs polling. @@ -199,6 +201,7 @@ impl FrontendRuntimeContext { http_auth_session_ttl_secs: 480 * 60, http_auth_cookie_secure: false, http_auth_cookie_same_site: "Lax".to_string(), + http_show_sdr_gain_control: true, remote_active_rig_id: Arc::new(Mutex::new(None)), remote_rigs: Arc::new(Mutex::new(Vec::new())), owner_callsign: None, 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 4269b59..e4a6d24 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 @@ -1281,6 +1281,9 @@ function render(update) { wfmStFlagEl.classList.toggle("wfm-st-flag-mono", !detected); } } + if (sdrGainControlsEl && typeof update.show_sdr_gain_control === "boolean") { + sdrGainControlsEl.style.display = update.show_sdr_gain_control ? "" : "none"; + } if (update.status && update.status.freq && typeof update.status.freq.hz === "number") { applyLocalTunedFrequency(update.status.freq.hz, true); } @@ -2574,6 +2577,7 @@ const audioRow = document.getElementById("audio-row"); const wfmControlsCol = document.getElementById("wfm-controls-col"); const wfmDeemphasisEl = document.getElementById("wfm-deemphasis"); const wfmAudioModeEl = document.getElementById("wfm-audio-mode"); +const sdrGainControlsEl = document.getElementById("sdr-gain-controls"); const sdrGainEl = document.getElementById("sdr-gain-db"); const sdrGainSetBtn = document.getElementById("sdr-gain-set"); const wfmStFlagEl = document.getElementById("wfm-st-flag"); 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 08fe3d9..0559ab8 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 @@ -165,10 +165,12 @@ - - +
+ + +
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/src/api.rs b/src/trx-client/trx-frontend/trx-frontend-http/src/api.rs index 28e7c14..ca514a6 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/src/api.rs +++ b/src/trx-client/trx-frontend/trx-frontend-http/src/api.rs @@ -45,6 +45,7 @@ pub async fn status_api( active_rig_id_from_context(context.get_ref().as_ref()), rig_ids_from_context(context.get_ref().as_ref()), owner_callsign_from_context(context.get_ref().as_ref()), + show_sdr_gain_control_from_context(context.get_ref().as_ref()), ); Ok(HttpResponse::Ok() .insert_header((header::CONTENT_TYPE, "application/json")) @@ -60,6 +61,7 @@ fn inject_frontend_meta( active_rig_id: Option, rig_ids: Vec, owner_callsign: Option, + show_sdr_gain_control: bool, ) -> String { let mut value: serde_json::Value = match serde_json::from_str(json) { Ok(v) => v, @@ -84,6 +86,10 @@ fn inject_frontend_meta( if let Some(owner) = owner_callsign { map.insert("owner_callsign".to_string(), serde_json::json!(owner)); } + map.insert( + "show_sdr_gain_control".to_string(), + serde_json::json!(show_sdr_gain_control), + ); serde_json::to_string(&value).unwrap_or_else(|_| json.to_string()) } @@ -118,6 +124,10 @@ fn owner_callsign_from_context(context: &FrontendRuntimeContext) -> Option bool { + context.http_show_sdr_gain_control +} + #[get("/events")] pub async fn events( state: web::Data>, @@ -140,6 +150,7 @@ pub async fn events( active_rig_id_from_context(context.get_ref().as_ref()), rig_ids_from_context(context.get_ref().as_ref()), owner_callsign_from_context(context.get_ref().as_ref()), + show_sdr_gain_control_from_context(context.get_ref().as_ref()), ); let initial_stream = once(async move { Ok::(Bytes::from(format!("data: {initial_json}\n\n"))) }); @@ -160,6 +171,7 @@ pub async fn events( active_rig_id_from_context(context.as_ref()), rig_ids_from_context(context.as_ref()), owner_callsign_from_context(context.as_ref()), + show_sdr_gain_control_from_context(context.as_ref()), ); Ok::(Bytes::from(format!("data: {json}\n\n"))) })