feat(ui): render the Cockpit utility launchers and compact Radio controls from a store

The Display and Radio launchers, their popovers and the compact Radio
transport, Enable button and volume now render from the Radio store.
RadioControls owns the disclosure state; Cockpit Escape and the Display
reveal read that state instead of the DOM, and the Enable toggle guards
re-presses synchronously. The compact transport reuses the panel's
transport state and adds only its glyph and title.
This commit is contained in:
Sameh Khamis committed 2026-10-31 16:53:28 -07:00
1 parent 58504e370c
commit b6d565a83f
20 files changed
+495 -205

No files matched your search

+1
View File
@@ -32,6 +32,7 @@
"src/ui/views/panels/CockpitRoute.vue",
"src/ui/views/panels/CockpitRollingValue.vue",
"src/ui/views/panels/CockpitSignalList.vue",
"src/ui/views/panels/CockpitUtilityControls.vue",
"src/ui/cockpitBriefPages.js",
"src/ui/cockpitContextState.js",
"src/ui/cockpitInstrumentState.js",
+7 -1
View File
@@ -1720,6 +1720,9 @@ try {
const priorSignalMaxHeight = signal.style.maxHeight;
signal.style.maxHeight = '150px';
manager._setCockpitDisclosure(kind, true);
// Let Vue render the disclosure, but not the scheduled layout frame: the
// first syncSignalLayout below must be the first pass.
await Promise.resolve();
// One pass must be enough. Record the result of the FIRST layout call, then
// confirm a second changes nothing, so a convergence regression cannot hide
// behind a repeated call.
@@ -1851,7 +1854,7 @@ try {
JSON.stringify(portalScroll),
);
const boundary = await page.evaluate(() => {
const boundary = await page.evaluate(async () => {
const manager = window.__godsEyeView.styleManager;
const hud = document.getElementById('cockpit-hud');
const signal = document.getElementById('cockpit-signal-stream');
@@ -1866,6 +1869,7 @@ try {
signal.hidden = false;
manager._setCockpitDisclosure('radio', false);
manager._setCockpitDisclosure('display', true);
await new Promise(requestAnimationFrame);
const priorSignalMaxHeight = signal.style.maxHeight;
const priorSignalHeight = signal.style.height;
// The strip is pinned to the viewport ceiling once the briefing card grows
@@ -2261,12 +2265,14 @@ try {
signal.hidden = false;
manager._setCockpitDisclosure('display', false);
manager._setCockpitDisclosure('radio', false);
await new Promise(requestAnimationFrame);
manager.cockpitView.syncSignalLayout();
const collapsed = {
display: displayControl.getBoundingClientRect().toJSON(),
radio: radioControl.getBoundingClientRect().toJSON(),
};
display.click();
await new Promise(requestAnimationFrame);
manager.cockpitView.syncSignalLayout();
return {
collapsed,
+4
View File
@@ -2154,16 +2154,20 @@ async function main() {
.every((control) => control.closest('.pp-toggle-group')?.parentElement
?.closest('#cockpit-display-panel'));
display.click();
await waitForLayout();
manager.cockpitView.syncSignalLayout();
radio.click();
await waitForLayout();
const radioOpened = radio.getAttribute('aria-expanded') === 'true'
&& !document.getElementById('cockpit-radio-panel').hidden;
const mutuallyExclusive = display.getAttribute('aria-expanded') === 'false';
radio.click();
await waitForLayout();
manager.cockpitView.syncSignalLayout();
radio.click();
await waitForLayout();
const radioNavigationAvailable = [
document.getElementById('cockpit-radio-prev-btn'),