feat(ui): drive workspaces from rig capabilities
This commit is contained in:
@@ -23,6 +23,7 @@ window.onDecoderRegistryReady = function (fn) {
|
|||||||
for (const fn of _decoderRegistryReadyCallbacks) fn();
|
for (const fn of _decoderRegistryReadyCallbacks) fn();
|
||||||
_decoderRegistryReadyCallbacks.length = 0;
|
_decoderRegistryReadyCallbacks.length = 0;
|
||||||
hideUnsupportedDecoderTabs();
|
hideUnsupportedDecoderTabs();
|
||||||
|
refreshOperatorLayoutCapabilities();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Failed to fetch decoder registry:", e);
|
console.error("Failed to fetch decoder registry:", e);
|
||||||
@@ -333,8 +334,14 @@ function applyCapabilities(caps) {
|
|||||||
const txAudioBtn = document.getElementById("tx-audio-btn");
|
const txAudioBtn = document.getElementById("tx-audio-btn");
|
||||||
const txVolSlider = document.getElementById("tx-vol");
|
const txVolSlider = document.getElementById("tx-vol");
|
||||||
const txVolControl = txVolSlider ? txVolSlider.closest(".vol-label") : null;
|
const txVolControl = txVolSlider ? txVolSlider.closest(".vol-label") : null;
|
||||||
if (txPowerCol) txPowerCol.style.display = caps.tx ? "" : "none";
|
if (txPowerCol) {
|
||||||
|
txPowerCol.style.display = "";
|
||||||
|
const label = txPowerCol.querySelector(".label span");
|
||||||
|
if (label) label.textContent = caps.tx ? "Transmit / Power" : "Power / Tuning";
|
||||||
|
}
|
||||||
if (pttBtn) pttBtn.style.display = caps.tx ? "" : "none";
|
if (pttBtn) pttBtn.style.display = caps.tx ? "" : "none";
|
||||||
|
if (powerBtn) powerBtn.style.display = "";
|
||||||
|
if (lockBtn) lockBtn.style.display = caps.lockable ? "" : "none";
|
||||||
if (txMetersRow) txMetersRow.style.display = caps.tx ? "" : "none";
|
if (txMetersRow) txMetersRow.style.display = caps.tx ? "" : "none";
|
||||||
if (txAudioBtn) txAudioBtn.style.display = caps.tx ? "" : "none";
|
if (txAudioBtn) txAudioBtn.style.display = caps.tx ? "" : "none";
|
||||||
if (txVolControl) txVolControl.style.display = caps.tx ? "" : "none";
|
if (txVolControl) txVolControl.style.display = caps.tx ? "" : "none";
|
||||||
@@ -344,7 +351,7 @@ function applyCapabilities(caps) {
|
|||||||
|
|
||||||
// TX limit row
|
// TX limit row
|
||||||
const txLimitRow = document.getElementById("tx-limit-row");
|
const txLimitRow = document.getElementById("tx-limit-row");
|
||||||
if (txLimitRow && !caps.tx_limit) txLimitRow.style.display = "none";
|
if (txLimitRow) txLimitRow.style.display = caps.tx_limit ? "" : "none";
|
||||||
|
|
||||||
// VFO row
|
// VFO row
|
||||||
const vfoRow = document.getElementById("vfo-row");
|
const vfoRow = document.getElementById("vfo-row");
|
||||||
@@ -1305,10 +1312,7 @@ async function refreshRigList() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
serverRigs = rigs;
|
serverRigs = rigs;
|
||||||
window.trxUi?.setBroadcastLayoutAvailable(rigs.some((rig) =>
|
refreshOperatorLayoutCapabilities();
|
||||||
Array.isArray(rig?.supported_modes)
|
|
||||||
&& rig.supported_modes.map(normalizeMode).includes("WFM")
|
|
||||||
));
|
|
||||||
serverActiveRigId = data.active_remote || null;
|
serverActiveRigId = data.active_remote || null;
|
||||||
applyRigList(data.active_remote, rigIds, displayNames);
|
applyRigList(data.active_remote, rigIds, displayNames);
|
||||||
window.trx.modules.map?.syncAprsReceiverMarker();
|
window.trx.modules.map?.syncAprsReceiverMarker();
|
||||||
@@ -1317,6 +1321,19 @@ async function refreshRigList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshOperatorLayoutCapabilities() {
|
||||||
|
const rigModes = serverRigs.map((rig) =>
|
||||||
|
Array.isArray(rig?.supported_modes) ? rig.supported_modes.map(normalizeMode).filter(Boolean) : []
|
||||||
|
);
|
||||||
|
const decoderModes = new Set(decoderRegistry.flatMap((decoder) =>
|
||||||
|
Array.isArray(decoder?.active_modes) ? decoder.active_modes.map(normalizeMode).filter(Boolean) : []
|
||||||
|
));
|
||||||
|
window.trxUi?.setLayoutCapabilities({
|
||||||
|
broadcast: rigModes.some((modes) => modes.includes("WFM")),
|
||||||
|
digital: decoderModes.size > 0 && rigModes.some((modes) => modes.some((mode) => decoderModes.has(mode))),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function showHint(msg, duration) {
|
function showHint(msg, duration) {
|
||||||
powerHint.textContent = msg;
|
powerHint.textContent = msg;
|
||||||
if (hintTimer) clearTimeout(hintTimer);
|
if (hintTimer) clearTimeout(hintTimer);
|
||||||
|
|||||||
@@ -128,13 +128,13 @@
|
|||||||
const layouts = {
|
const layouts = {
|
||||||
compact: { label: "Compact", advanced: false, preferredTab: "main" },
|
compact: { label: "Compact", advanced: false, preferredTab: "main" },
|
||||||
broadcast: { label: "Broadcast", advanced: false, preferredTab: "main", capability: "broadcast" },
|
broadcast: { label: "Broadcast", advanced: false, preferredTab: "main", capability: "broadcast" },
|
||||||
digital: { label: "Digital", advanced: false, preferredTab: "digital-modes" },
|
digital: { label: "Digital", advanced: false, preferredTab: "digital-modes", capability: "digital" },
|
||||||
full: { label: "Full controls", advanced: true, preferredTab: "main" },
|
full: { label: "Full controls", advanced: true, preferredTab: "main" },
|
||||||
};
|
};
|
||||||
let hasBroadcastRig = false;
|
const layoutCapabilities = { broadcast: false, digital: false };
|
||||||
|
|
||||||
function broadcastLayoutAvailable() {
|
function layoutAvailable(layout) {
|
||||||
return hasBroadcastRig;
|
return !layout.capability || layoutCapabilities[layout.capability] === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshLayoutOptions() {
|
function refreshLayoutOptions() {
|
||||||
@@ -143,7 +143,7 @@
|
|||||||
const previous = select.value || document.body.dataset.operatorLayout || "compact";
|
const previous = select.value || document.body.dataset.operatorLayout || "compact";
|
||||||
select.replaceChildren();
|
select.replaceChildren();
|
||||||
Object.entries(layouts).forEach(([value, layout]) => {
|
Object.entries(layouts).forEach(([value, layout]) => {
|
||||||
if (layout.capability === "broadcast" && !broadcastLayoutAvailable()) return;
|
if (!layoutAvailable(layout)) return;
|
||||||
select.add(new Option(layout.label, value));
|
select.add(new Option(layout.label, value));
|
||||||
});
|
});
|
||||||
const available = Array.from(select.options).some(option => option.value === previous);
|
const available = Array.from(select.options).some(option => option.value === previous);
|
||||||
@@ -151,14 +151,17 @@
|
|||||||
if (!available && previous === "broadcast") api.applyLayout("compact");
|
if (!available && previous === "broadcast") api.applyLayout("compact");
|
||||||
}
|
}
|
||||||
|
|
||||||
api.setBroadcastLayoutAvailable = function setBroadcastLayoutAvailable(available) {
|
api.setLayoutCapabilities = function setLayoutCapabilities(capabilities = {}) {
|
||||||
hasBroadcastRig = Boolean(available);
|
Object.keys(layoutCapabilities).forEach((name) => {
|
||||||
|
if (name in capabilities) layoutCapabilities[name] = Boolean(capabilities[name]);
|
||||||
|
});
|
||||||
refreshLayoutOptions();
|
refreshLayoutOptions();
|
||||||
};
|
};
|
||||||
|
|
||||||
api.applyLayout = function applyLayout(name, options = {}) {
|
api.applyLayout = function applyLayout(name, options = {}) {
|
||||||
const permittedName = name === "broadcast" && !broadcastLayoutAvailable() ? "compact" : name;
|
const requestedLayout = layouts[name];
|
||||||
const layout = layouts[permittedName] || layouts.compact;
|
const permittedName = requestedLayout && layoutAvailable(requestedLayout) ? name : "compact";
|
||||||
|
const layout = layouts[permittedName];
|
||||||
document.body.dataset.operatorLayout = permittedName in layouts ? permittedName : "compact";
|
document.body.dataset.operatorLayout = permittedName in layouts ? permittedName : "compact";
|
||||||
localStorage.setItem("trxOperatorLayout", document.body.dataset.operatorLayout);
|
localStorage.setItem("trxOperatorLayout", document.body.dataset.operatorLayout);
|
||||||
const details = document.getElementById("advanced-radio-controls");
|
const details = document.getElementById("advanced-radio-controls");
|
||||||
|
|||||||
Reference in New Issue
Block a user