merge: resolve PR #816 against upstream main (8b8ccc9a)

Retain upstream changes to the panel controller, formatting scope, changelog and docs. Preserve the #804 ownership fix and its rail restoration regression (original report: @raysung-2026).
This commit is contained in:
Kevin Rajan committed 2026-10-12 10:43:10 -05:00
commit 19372875e2
632 files changed
+93502 -5546

No files matched your search

+20 -5
View File
@@ -14,6 +14,7 @@ const SHARE_PANEL_STATE_SPECS = Object.freeze([
{ id: 'cctv-panel' },
{ id: 'weather-panel' },
{ id: 'recent-imagery-panel' },
{ id: 'street-level-panel' },
{ id: 'radio-panel' },
{ id: 'scene-panel' },
{ id: 'global-context-panel' },
@@ -26,6 +27,7 @@ const COCKPIT_ENTRY_COLLAPSE_PANEL_IDS = Object.freeze([
'cctv-panel',
'weather-panel',
'recent-imagery-panel',
'street-level-panel',
'scene-panel',
'pp-toggles',
'global-context-panel',
@@ -61,6 +63,7 @@ export class PanelChrome {
layoutRightPanels: () => this._layoutRightPanels(),
syncCctvPanelViewport: () => this._syncCctvPanelViewport(),
showToast: (message) => this._showToast(message),
onPanelResized: (panelId) => this._onPanelResized(panelId),
});
this._panelLayout = new PanelLayoutController({
readHud: () => ({
@@ -145,6 +148,7 @@ export class PanelChrome {
this._initCommandDockPins();
this._initCommandDockTrayMetrics();
this._maybeNotifyLayoutReset();
this._panelPosition._initPanelDrag();
}
_collapsePanelOnEscape(event, panelId) {
@@ -302,6 +306,7 @@ export class PanelChrome {
'cctv-panel',
'weather-panel',
'recent-imagery-panel',
'street-level-panel',
'global-context-panel',
].includes(panelEl?.id);
const collapsed = panelEl.classList.contains('collapsed');
@@ -397,6 +402,11 @@ export class PanelChrome {
this.shareLinkManager?.onPanelStateChange?.();
}
/** @returns {boolean} Whether the panel was floating and is now docked. */
dockPanel(panelId) {
return this._panelPosition?.dockPanel?.(panelId) === true;
}
setPanelCollapsed(
panelId,
collapsed,
@@ -419,17 +429,20 @@ export class PanelChrome {
panelEl.classList.contains('cyber-accordion-collapsed');
// A user opening a Cyber rail panel owns the whole accordion, including
// peers that were only presentation-collapsed during a saved-state restore.
// A floating window is outside the accordion both ways.
if (
explicit &&
!restore &&
!nextCollapsed &&
document.documentElement?.dataset.uiTheme === 'cyber' &&
panelEl.parentElement === this._rightPanelStack
panelEl.parentElement === this._rightPanelStack &&
!panelEl.classList.contains('panel-floating')
) {
for (const peer of this._rightPanelStack.children) {
if (
peer !== panelEl &&
peer.matches('[data-panel-id]') &&
!peer.classList.contains('panel-floating') &&
!peer.hidden
) {
this.setPanelCollapsed(peer.id, true, {
@@ -488,10 +501,8 @@ export class PanelChrome {
syncShare,
});
}
// Parent ownership is an invariant even on a no-op disclosure request.
// A stale compact Radio disclosure is absolutely positioned outside the
// measured Context rail; clear it before returning from an already-open
// Context request so it cannot paint over the active Context body.
// A repeated Context-open request must clear a stale compact Radio mini
// even when no collapsed class changes.
if (
!nextCollapsed &&
panelId === 'global-context-panel' &&
@@ -561,6 +572,10 @@ export class PanelChrome {
}
}
panelEl.classList.toggle('collapsed', nextCollapsed);
// Only a user's own collapse docks a floating window; restores, cockpit
// entry and accordion peers keep its place.
if (explicit && !restore)
this._panelPosition?.onPanelCollapsed?.(panelId, nextCollapsed);
if (
nextCollapsed &&
this.cockpitView?.active &&