mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
feat(cockpit): teleport the shared Display groups into Cockpit's popover
The Cockpit display portal publishes the Display popover's slots to the gev-display store while Cockpit is on, and the Display panel teleports its HUD, Detection, Parameters and 3D groups into them and back, each only while its own slot is published. The portal no longer moves the groups: it keeps each surface's scroll position, puts back focus the move dropped, and lays the surfaces out once Vue has moved them. The popover's uses-shared-display-controls class renders from the store, and the right rail no longer re-homes the parameters panel the markup already places.
This commit is contained in:
1 parent
9ed9098593
commit
fd4b69ff52
12 files changed
+250
-49
No files matched your search
@@ -1,11 +1,25 @@
|
||||
import { displayPanelScroller } from './displayPanelScroll.js';
|
||||
|
||||
/** Move the existing Display groups between their two presentation surfaces. */
|
||||
/**
|
||||
* Show the existing Display groups in Cockpit's Display popover while Cockpit
|
||||
* is on. The portal publishes the popover's slots; the Display panel
|
||||
* teleports its groups into them and back. The portal keeps each surface's
|
||||
* scroll position and puts back focus the move dropped.
|
||||
*/
|
||||
export class CockpitDisplayPortal {
|
||||
constructor({ standardPanel, cockpitPanel, groups, layout }) {
|
||||
constructor({
|
||||
standardPanel,
|
||||
cockpitPanel,
|
||||
groups,
|
||||
layout,
|
||||
publish = () => {},
|
||||
afterRender = (callback) => callback(),
|
||||
}) {
|
||||
this.standardPanel = standardPanel;
|
||||
this.cockpitPanel = cockpitPanel;
|
||||
this.layout = layout;
|
||||
this.publish = publish;
|
||||
this.afterRender = afterRender;
|
||||
this.active = false;
|
||||
this.destroyed = false;
|
||||
this.stopped = false;
|
||||
@@ -17,11 +31,12 @@ export class CockpitDisplayPortal {
|
||||
const slot = cockpitPanel?.querySelector(
|
||||
`[data-cockpit-display-slot="${name}"]`,
|
||||
);
|
||||
if (!group || !slot || !group.parentNode) return [];
|
||||
const anchor = document.createComment(`cockpit-display-home:${name}`);
|
||||
group.before(anchor);
|
||||
return [{ name, group, slot, anchor }];
|
||||
if (!group || !slot) return [];
|
||||
return [{ name, group, slot }];
|
||||
});
|
||||
this.slots = Object.freeze(
|
||||
Object.fromEntries(this.records.map(({ name, slot }) => [name, slot])),
|
||||
);
|
||||
this.standardScrollTop =
|
||||
displayPanelScroller(standardPanel)?.scrollTop || 0;
|
||||
this.cockpitScrollTop = cockpitPanel?.scrollTop || 0;
|
||||
@@ -78,14 +93,7 @@ export class CockpitDisplayPortal {
|
||||
const focusedElement = focusedRecord ? document.activeElement : null;
|
||||
this.restoreOwner = nextActive ? 'cockpit' : 'standard';
|
||||
this.active = nextActive;
|
||||
for (const record of this.records) {
|
||||
if (nextActive) record.slot.append(record.group);
|
||||
else if (record.anchor.parentNode) record.anchor.after(record.group);
|
||||
}
|
||||
this.cockpitPanel?.classList.toggle(
|
||||
'uses-shared-display-controls',
|
||||
nextActive,
|
||||
);
|
||||
this.publish(nextActive ? this.slots : null);
|
||||
const restoreScroll = () => {
|
||||
if (nextActive && this.cockpitPanel)
|
||||
this.cockpitPanel.scrollTop = this.cockpitScrollTop;
|
||||
@@ -94,8 +102,11 @@ export class CockpitDisplayPortal {
|
||||
this.standardScrollTop;
|
||||
};
|
||||
if (!settle) {
|
||||
restoreScroll();
|
||||
this.restoreOwner = null;
|
||||
this.afterRender(() => {
|
||||
if (generation !== this.generation) return;
|
||||
restoreScroll();
|
||||
this.restoreOwner = null;
|
||||
});
|
||||
return;
|
||||
}
|
||||
this._frame(generation, () => {
|
||||
@@ -114,7 +125,10 @@ export class CockpitDisplayPortal {
|
||||
this.restoreOwner = null;
|
||||
});
|
||||
});
|
||||
this.layout();
|
||||
// The surfaces are measured once the groups have moved.
|
||||
this.afterRender(() => {
|
||||
if (!this.stopped && generation === this.generation) this.layout();
|
||||
});
|
||||
}
|
||||
|
||||
stop() {
|
||||
@@ -129,14 +143,12 @@ export class CockpitDisplayPortal {
|
||||
this.stop();
|
||||
this.destroyed = true;
|
||||
this.active = false;
|
||||
for (const record of this.records) {
|
||||
if (record.anchor.parentNode) record.anchor.after(record.group);
|
||||
record.anchor.remove();
|
||||
}
|
||||
this.cockpitPanel?.classList.remove('uses-shared-display-controls');
|
||||
if (this.standardPanel)
|
||||
displayPanelScroller(this.standardPanel).scrollTop =
|
||||
this.standardScrollTop;
|
||||
this.publish(null);
|
||||
const { standardPanel, standardScrollTop } = this;
|
||||
this.afterRender(() => {
|
||||
if (standardPanel)
|
||||
displayPanelScroller(standardPanel).scrollTop = standardScrollTop;
|
||||
});
|
||||
this.records = [];
|
||||
this.restoreOwner = null;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user