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 30d841ad..b41fdb46 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 @@ -334,13 +334,18 @@ function applyCapabilities(caps) { const txAudioBtn = document.getElementById("tx-audio-btn"); const txVolSlider = document.getElementById("tx-vol"); const txVolControl = txVolSlider ? txVolSlider.closest(".vol-label") : null; + const hasPowerControl = !caps.filter_controls; if (txPowerCol) { - txPowerCol.style.display = ""; + txPowerCol.style.display = (caps.tx || hasPowerControl || caps.lockable) ? "" : "none"; const label = txPowerCol.querySelector(".label span"); - if (label) label.textContent = caps.tx ? "Transmit / Power" : "Power / Tuning"; + if (label) { + label.textContent = caps.tx && hasPowerControl ? "Transmit / Power" + : caps.tx ? "Transmit / Tuning" + : hasPowerControl ? "Power / Tuning" : "Tuning"; + } } if (pttBtn) pttBtn.style.display = caps.tx ? "" : "none"; - if (powerBtn) powerBtn.style.display = ""; + if (powerBtn) powerBtn.style.display = hasPowerControl ? "" : "none"; if (lockBtn) lockBtn.style.display = caps.lockable ? "" : "none"; if (txMetersRow) txMetersRow.style.display = caps.tx ? "" : "none"; if (txAudioBtn) txAudioBtn.style.display = caps.tx ? "" : "none"; diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css index 7ce96bb0..cca883ee 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css @@ -1231,7 +1231,7 @@ small { color: var(--text-muted); } } .top-bar-actions { display: flex; - align-items: center; + align-items: flex-start; gap: 0.45rem 0.6rem; min-width: 0; flex-wrap: wrap; @@ -1406,7 +1406,7 @@ small { color: var(--text-muted); } .header-rig-switch { display: grid; grid-template-columns: minmax(0, 1fr); - align-items: center; + align-items: start; gap: 0.35rem; } .header-rig-summary { @@ -1428,6 +1428,7 @@ small { color: var(--text-muted); } background: var(--input-bg); color: var(--text); font-size: 0.85rem; + align-self: start; } .header-rig-switch button { height: 2rem; @@ -2948,8 +2949,7 @@ button.is-active { #ptt-btn.is-active { background: var(--accent-red) !important; border-color: var(--accent-red) !important; color: white !important; } .is-busy { cursor: progress !important; opacity: 0.68; } .operator-layout-picker { - display: inline-grid; - grid-template-columns: auto auto; + display: inline-flex; align-items: center; min-height: 2rem; padding-left: 0.6rem; @@ -2979,17 +2979,6 @@ button.is-active { } .operator-layout-picker:focus-within { border-color: var(--accent-green); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-green) 20%, transparent); } .operator-layout-picker select:focus-visible { outline: 0; } -.operator-layout-description { - grid-column: 1 / -1; - max-width: 22rem; - padding: 0 0.55rem 0.35rem 0; - color: var(--text-muted); - font-size: var(--fs-xs); - font-weight: 500; - letter-spacing: 0; - line-height: 1.35; - text-transform: none; -} .advanced-radio-controls { margin-top: var(--space-3); border: 1px solid color-mix(in srgb, var(--border-light) 75%, transparent); 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 3d256f0e..69f1d74f 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 @@ -126,10 +126,10 @@ }; 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", 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" }, + compact: { label: "Compact", advanced: false, preferredTab: "main" }, + broadcast: { label: "Broadcast", unavailable: "Broadcast requires an enumerated WFM-capable receiver", advanced: false, preferredTab: "main", capability: "broadcast" }, + digital: { label: "Digital", unavailable: "Digital requires a compatible rig mode and an available decoder", advanced: false, preferredTab: "digital-modes", capability: "digital" }, + full: { label: "Full controls", advanced: true, preferredTab: "main" }, }; const layoutCapabilities = { broadcast: false, digital: false }; let activeRigId = null; @@ -151,12 +151,6 @@ 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; @@ -170,7 +164,6 @@ 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 = {}) { @@ -202,7 +195,6 @@ if (options.persist !== false) localStorage.setItem(layoutStorageKey(), document.body.dataset.operatorLayout); const details = document.getElementById("advanced-radio-controls"); if (details) details.open = layout.advanced; - updateLayoutDescription(layout); if (options.navigate && typeof window.navigateToTab === "function") { window.navigateToTab(layout.preferredTab); } @@ -213,7 +205,7 @@ if (actions && !document.getElementById("operator-layout-select")) { const label = document.createElement("label"); label.className = "operator-layout-picker"; - label.innerHTML = 'Operator layout'; + label.innerHTML = 'Operator layout'; const select = label.querySelector("select"); const savedLayout = savedLayoutName(); actions.insertBefore(label, actions.firstChild);