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 173fa189..7114fd45 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
@@ -1305,6 +1305,10 @@ async function refreshRigList() {
}
});
serverRigs = rigs;
+ window.trxUi?.setBroadcastLayoutAvailable(rigs.some((rig) =>
+ Array.isArray(rig?.supported_modes)
+ && rig.supported_modes.map(normalizeMode).includes("WFM")
+ ));
serverActiveRigId = data.active_remote || null;
applyRigList(data.active_remote, rigIds, displayNames);
window.trx.modules.map?.syncAprsReceiverMarker();
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/ui-core.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/ui-core.js
index 0471b366..fb72d6cd 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/ui-core.js
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/ui-core.js
@@ -127,14 +127,39 @@
const layouts = {
compact: { label: "Compact", advanced: false, preferredTab: "main" },
- broadcast: { label: "Broadcast", advanced: false, preferredTab: "main" },
+ broadcast: { label: "Broadcast", advanced: false, preferredTab: "main", capability: "broadcast" },
digital: { label: "Digital", advanced: false, preferredTab: "digital-modes" },
full: { label: "Full controls", advanced: true, preferredTab: "main" },
};
+ let hasBroadcastRig = false;
+
+ function broadcastLayoutAvailable() {
+ return hasBroadcastRig;
+ }
+
+ function refreshLayoutOptions() {
+ const select = document.getElementById("operator-layout-select");
+ if (!select) return;
+ const previous = select.value || document.body.dataset.operatorLayout || "compact";
+ select.replaceChildren();
+ Object.entries(layouts).forEach(([value, layout]) => {
+ if (layout.capability === "broadcast" && !broadcastLayoutAvailable()) return;
+ select.add(new Option(layout.label, value));
+ });
+ const available = Array.from(select.options).some(option => option.value === previous);
+ select.value = available ? previous : "compact";
+ if (!available && previous === "broadcast") api.applyLayout("compact");
+ }
+
+ api.setBroadcastLayoutAvailable = function setBroadcastLayoutAvailable(available) {
+ hasBroadcastRig = Boolean(available);
+ refreshLayoutOptions();
+ };
api.applyLayout = function applyLayout(name, options = {}) {
- const layout = layouts[name] || layouts.compact;
- document.body.dataset.operatorLayout = name in layouts ? name : "compact";
+ const permittedName = name === "broadcast" && !broadcastLayoutAvailable() ? "compact" : name;
+ const layout = layouts[permittedName] || layouts.compact;
+ document.body.dataset.operatorLayout = permittedName in layouts ? permittedName : "compact";
localStorage.setItem("trxOperatorLayout", document.body.dataset.operatorLayout);
const details = document.getElementById("advanced-radio-controls");
if (details) details.open = layout.advanced;
@@ -150,10 +175,12 @@
label.className = "operator-layout-picker";
label.innerHTML = 'Operator layout';
const select = label.querySelector("select");
- Object.entries(layouts).forEach(([value, layout]) => select.add(new Option(layout.label, value)));
- select.value = localStorage.getItem("trxOperatorLayout") || "compact";
- select.addEventListener("change", () => api.applyLayout(select.value, { navigate: true }));
+ const savedLayout = localStorage.getItem("trxOperatorLayout") || "compact";
actions.insertBefore(label, actions.firstChild);
+ select.value = savedLayout;
+ refreshLayoutOptions();
+ if (savedLayout !== "broadcast" && layouts[savedLayout]) select.value = savedLayout;
+ select.addEventListener("change", () => api.applyLayout(select.value, { navigate: true }));
api.applyLayout(select.value);
}
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/src/api/rig.rs b/src/trx-client/trx-frontend/trx-frontend-http/src/api/rig.rs
index 4a92eaff..7504926d 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/src/api/rig.rs
+++ b/src/trx-client/trx-frontend/trx-frontend-http/src/api/rig.rs
@@ -388,6 +388,7 @@ struct RigListItem {
display_name: Option,
manufacturer: String,
model: String,
+ supported_modes: Vec,
initialized: bool,
#[serde(skip_serializing_if = "Option::is_none")]
latitude: Option,
@@ -422,6 +423,7 @@ fn map_rig_entry(entry: &RemoteRigEntry) -> RigListItem {
display_name: entry.display_name.clone(),
manufacturer: entry.state.info.manufacturer.clone(),
model: entry.state.info.model.clone(),
+ supported_modes: entry.state.info.capabilities.supported_modes.clone(),
initialized: entry.state.initialized,
latitude: entry.state.server_latitude,
longitude: entry.state.server_longitude,