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 2e9792dc..814e2735 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,8 +127,8 @@ const layouts = { compact: { label: "Compact", description: "Essential tuning and audio controls", advanced: false, preferredTab: "main" }, - broadcast: { label: "Broadcast", description: "WFM, RDS, stereo and interference monitoring", advanced: false, preferredTab: "main", capability: "broadcast" }, - digital: { label: "Digital", description: "Decoder status, messages and background decoding", advanced: false, preferredTab: "digital-modes", capability: "digital" }, + broadcast: { label: "Broadcast", description: "WFM, RDS, stereo and interference monitoring", unavailable: "Broadcast requires an enumerated WFM-capable receiver", advanced: false, preferredTab: "main", capability: "broadcast" }, + digital: { label: "Digital", description: "Decoder status, messages and background decoding", unavailable: "Digital requires a compatible rig mode and an available decoder", advanced: false, preferredTab: "digital-modes", capability: "digital" }, full: { label: "Full controls", description: "Every control supported by the selected rig", advanced: true, preferredTab: "main" }, }; const layoutCapabilities = { broadcast: false, digital: false }; @@ -146,6 +146,17 @@ return !layout.capability || layoutCapabilities[layout.capability] === true; } + function unavailableLayoutMessage() { + const unavailable = Object.values(layouts).filter(layout => !layoutAvailable(layout) && layout.unavailable); + return unavailable.length ? `Unavailable: ${unavailable.map(layout => layout.unavailable).join("; ")}.` : ""; + } + + function updateLayoutDescription(layout) { + const description = document.getElementById("operator-layout-description"); + if (!description) return; + description.textContent = [layout.description, unavailableLayoutMessage()].filter(Boolean).join(" ยท "); + } + function refreshLayoutOptions() { const select = document.getElementById("operator-layout-select"); if (!select) return; @@ -158,6 +169,8 @@ const available = Array.from(select.options).some(option => option.value === previous); select.value = available ? previous : "compact"; if (!available && previous !== "compact") api.applyLayout("compact", { persist: false }); + select.title = unavailableLayoutMessage(); + updateLayoutDescription(layouts[select.value] || layouts.compact); } api.setLayoutCapabilities = function setLayoutCapabilities(capabilities = {}) { @@ -189,8 +202,7 @@ if (options.persist !== false) localStorage.setItem(layoutStorageKey(), document.body.dataset.operatorLayout); const details = document.getElementById("advanced-radio-controls"); if (details) details.open = layout.advanced; - const description = document.getElementById("operator-layout-description"); - if (description) description.textContent = layout.description; + updateLayoutDescription(layout); if (options.navigate && typeof window.navigateToTab === "function") { window.navigateToTab(layout.preferredTab); }