mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
refactor: drive share, location and scene controls through product state
This commit is contained in:
1 parent
21a0d0c74e
commit
45d97376d0
21 files changed
+606
-96
No files matched your search
@@ -343,7 +343,8 @@
|
||||
"src/ui/location.js",
|
||||
"src/ui/locationControls.js",
|
||||
"src/ui/locationSearch.js",
|
||||
"src/locationStatus.js"
|
||||
"src/locationStatus.js",
|
||||
"src/app/stateChannel.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
@@ -518,7 +519,8 @@
|
||||
"src/ui/visualInput.js",
|
||||
"src/ui/visualPresets.js",
|
||||
"src/worldFocus.js",
|
||||
"src/ui/uiLifetime.js"
|
||||
"src/ui/uiLifetime.js",
|
||||
"src/app/stateChannel.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
},
|
||||
@@ -548,5 +550,19 @@
|
||||
"src/ui/styles/provider-settings.css"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
"scenes": {
|
||||
"exports": ["./scenes"],
|
||||
"modules": [
|
||||
"src/scenes/director.js",
|
||||
"src/scenes/recipes.js",
|
||||
"src/scenes/scenePolicy.js",
|
||||
"src/bloom.js",
|
||||
"src/app/stateChannel.js",
|
||||
"src/ui/scenes.js",
|
||||
"src/ui/sceneControls.js",
|
||||
"src/ui/scenePresentation.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,8 @@ try {
|
||||
await page.evaluate(() => {
|
||||
const lookup = window.__godsEyeView.styleManager._locationLookup;
|
||||
window.__qaSearchRequests = [];
|
||||
window.__qaLocationState = [];
|
||||
window.__godsEyeView.styleManager.subscribeLocationSearch((notification) => window.__qaLocationState.push(notification));
|
||||
lookup.search = (query, options) =>
|
||||
new Promise((resolve) =>
|
||||
window.__qaSearchRequests.push({ query, options, resolve }),
|
||||
@@ -139,6 +141,14 @@ try {
|
||||
);
|
||||
}),
|
||||
);
|
||||
check('Location subscriptions accept only the current result and retain request identities', await page.evaluate(() => {
|
||||
const seen = window.__qaLocationState;
|
||||
const started = seen.filter(({ change }) => change?.type === 'started');
|
||||
const found = seen.filter(({ change }) => change?.type === 'found');
|
||||
return seen[0].initial && started.length === 2 && found.length === 1 &&
|
||||
found[0].change.requestId === started[1].change.requestId &&
|
||||
found[0].state.destination.label === 'Second landmark, Test city' && Object.isFrozen(found[0].state.destination);
|
||||
}));
|
||||
check(
|
||||
'cancelled POI expansion stays closed after a frame',
|
||||
await page.evaluate(async (id) => {
|
||||
|
||||
@@ -39,6 +39,10 @@ try {
|
||||
document.getElementById('loading-screen')?.classList.contains('hidden'),
|
||||
{ timeout: 60000 },
|
||||
);
|
||||
await page.evaluate(() => {
|
||||
window.__qaSceneState = [];
|
||||
window.__godsEyeView.sceneDirector.subscribe((notification) => window.__qaSceneState.push(notification));
|
||||
});
|
||||
await page.click('[data-collapse-target="scene-panel"]');
|
||||
await page.click('#scene-new-btn');
|
||||
await page.waitForFunction(
|
||||
@@ -303,6 +307,13 @@ try {
|
||||
document.querySelectorAll('#scene-select option').length > 0,
|
||||
),
|
||||
);
|
||||
check('Scene subscriptions include current state and the completed native editing actions', await page.evaluate(() => {
|
||||
const seen = window.__qaSceneState;
|
||||
const types = new Set(seen.map(({ change }) => change?.type));
|
||||
return seen[0].initial && Object.isFrozen(seen[0].state) &&
|
||||
['scene-created', 'shot-captured', 'shot-renamed', 'shot-updated', 'project-exported', 'project-imported', 'shot-deleted', 'scene-deleted', 'run-event'].every((type) => types.has(type)) &&
|
||||
seen.filter(({ change }) => change?.shot).every(({ change }) => Object.isFrozen(change.shot));
|
||||
}));
|
||||
const teardown = await page.evaluate(async () => {
|
||||
const director = window.__godsEyeView.sceneDirector;
|
||||
const controls = director._controls;
|
||||
@@ -320,6 +331,7 @@ try {
|
||||
},
|
||||
});
|
||||
const stopping = director.destroy();
|
||||
const notificationsAtStop = window.__qaSceneState.length;
|
||||
const stoppedSynchronously =
|
||||
controls.destroyed &&
|
||||
controls.removers.length === 0 &&
|
||||
@@ -332,6 +344,7 @@ try {
|
||||
await director.destroy();
|
||||
return {
|
||||
stoppedSynchronously,
|
||||
stateStopped: window.__qaSceneState.length === notificationsAtStop,
|
||||
sameProject: director._project === project,
|
||||
noLateStatus:
|
||||
document.getElementById('scene-status').textContent === previousStatus,
|
||||
@@ -346,6 +359,7 @@ try {
|
||||
'Late import completion cannot replace the disposed project or status',
|
||||
teardown.sameProject && teardown.noLateStatus,
|
||||
);
|
||||
check('Scene subscriptions stop before late imports settle', teardown.stateStopped);
|
||||
check(
|
||||
'Scene control interaction produces no uncaught browser errors',
|
||||
errors.length === 0,
|
||||
|
||||
@@ -119,6 +119,9 @@ try {
|
||||
setSplitFlapText(feedbackLabel, 'LOAD COMPLETE');
|
||||
const permanentText =
|
||||
feedbackLabel.querySelector('.gev-flap-text')?.firstChild;
|
||||
let stateNotifications = 0;
|
||||
ui.subscribeShareState(() => stateNotifications++, { emitCurrent: false });
|
||||
ui.subscribeLocationSearch(() => stateNotifications++, { emitCurrent: false });
|
||||
try {
|
||||
const disposal = ui.dispose();
|
||||
const focusBefore = document.activeElement;
|
||||
@@ -139,6 +142,9 @@ try {
|
||||
const noDeferredFocus = document.activeElement === focusBefore;
|
||||
releaseRestoration();
|
||||
await disposal;
|
||||
ui._syncShareState();
|
||||
ui.subscribeShareState(() => stateNotifications++);
|
||||
ui.subscribeLocationSearch(() => stateNotifications++);
|
||||
const once = JSON.stringify(counts);
|
||||
await ui.dispose();
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
@@ -202,6 +208,7 @@ try {
|
||||
ui._lifetime.frames.size === 0 &&
|
||||
ui._lifetime.timers.size === 0 &&
|
||||
ui._lifetime.removers.size === 0,
|
||||
stateStopped: stateNotifications === 0,
|
||||
idempotent: once === JSON.stringify(counts),
|
||||
};
|
||||
} finally {
|
||||
@@ -249,6 +256,7 @@ try {
|
||||
'shell teardown cancels deferred work and releases listeners',
|
||||
result.shellWorkReleased,
|
||||
);
|
||||
check('state subscriptions stop synchronously with UI disposal', result.stateStopped);
|
||||
check('repeated UI disposal is inert', result.idempotent);
|
||||
check(
|
||||
'disposal and subsequent resize produce no uncaught browser errors',
|
||||
|
||||
@@ -152,9 +152,15 @@ try {
|
||||
'bloom actions, effect state and saved snapshot agree',
|
||||
await page.evaluate(() => {
|
||||
const manager = window.__godsEyeView.styleManager;
|
||||
const states = [];
|
||||
const unsubscribe = manager.subscribeShareState((value) => states.push(value));
|
||||
const result = manager.setBloom({ enabled: true, intensityPct: 98 });
|
||||
unsubscribe();
|
||||
const published = states.at(-1);
|
||||
const snapshot = manager.getVisualState();
|
||||
return (
|
||||
states[0].initial && states.length > 1 && Object.isFrozen(published.state.options) &&
|
||||
published.state.bloomEnabled && published.state.options.bloomIntensity === 98 &&
|
||||
result.ok &&
|
||||
result.bloom.intensityPct === 98 &&
|
||||
snapshot.bloom.intensity === 98 &&
|
||||
|
||||
Reference in new issue
Block a user