Keep Vue layer rows mounted through globe switches and rollback

This commit is contained in:
German Khokhlov committed 2026-11-03 02:38:25 +04:00
1 parent 2ee09c5911
commit d7ab85f5c4
4 files changed
+31 -5

No files matched your search

+7 -3
View File
@@ -34,10 +34,14 @@ export function createApplicationData({
`Data layers could not be destroyed: ${[...dataManager.layers.keys()].join(', ')}`,
);
});
const presentation = new LayerPresentation(dataManager, {
const presentation = layerSession?.presentation ?? new LayerPresentation(dataManager, {
weatherClock: catalog?.weatherClock,
});
defer(() => presentation.destroy());
if (layerSession) layerSession.presentation = presentation;
defer(() => {
if (layerSession && !layerSession.lifetime.signal.aborted) presentation.suspend();
else presentation.destroy();
});
onData?.(dataManager);
if (!catalog?.layers || !catalog?.metadata)
throw new TypeError('An application layer catalog is required');
@@ -66,7 +70,7 @@ export function createApplicationData({
delete window.__gevQaUnregisterLayer;
});
}
presentation.mount(document.getElementById('data-toggles'));
presentation.mount(document.getElementById('data-toggles'), catalog.weatherClock);
styleManager.attachDataManager(dataManager);
// The sonar scene draws on the viewer; the Navara engine has none.
if (viewer) defer(createCyberSonarScene(viewer, dataManager));
+9 -1
View File
@@ -17,6 +17,7 @@ export class LayerPresentation {
this._panel = null;
this.pendingVisible = false;
this._unsubscribe = manager.subscribeActivity((change) => {
if (this.suspended && change.type !== 'destroy-all') return;
if (change.type === 'status') this.refresh();
else if (change.type === 'destroy-all') this.destroy();
else {
@@ -67,9 +68,16 @@ export class LayerPresentation {
});
return this._panel;
}
mount(container) {
mount(container, weatherClock = this.weatherClock) {
this.weatherClock = weatherClock;
this.panel.weatherClock = weatherClock;
this.suspended = false;
this.panel.mount(container);
}
suspend() {
this.suspended = true;
this._panel?.suspend();
}
/** Hand the Recent Imagery readout factory to the panel (see LayerPanel). */
attachRecentImagery(factory) {
// Detaching never builds a panel that teardown already released.
+11 -1
View File
@@ -273,6 +273,7 @@ export class LayerPanel {
}
mount(container) {
if (this._destroyed) return;
this._suspended = false;
this._releaseBindings();
if (this._toggleContainer && this._toggleContainer !== container)
renderVue(null, this._toggleContainer);
@@ -315,6 +316,15 @@ export class LayerPanel {
this._cancelRowControlsRefresh = null;
for (const remove of this._removers.splice(0)) remove();
}
// During a globe switch the keyed Vue rows stay mounted. Their event
// generation expires here, before any legacy scene-owned modules are freed.
suspend() {
this._suspended = true;
this._releaseBindings();
this._weatherPanel?.destroy();
this._weatherPanel = null;
this.attachRecentImagery(null);
}
destroy() {
if (this._destroyed) return;
this._destroyed = true;
@@ -383,7 +393,7 @@ export class LayerPanel {
/** Present every row from the layers' current state and render them. */
_paint() {
if (this._destroyed || !this._toggleContainer) return;
if (this._destroyed || this._suspended || !this._toggleContainer) return;
const layers = new Map(this.getAll().map((layer) => [layer.id, layer]));
const items = this._rows.map((row) => {
if (row.heading) return { key: row.key, heading: t(row.heading) };