mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(street-level): own the framing flight and the nearest-photo lookup
From the IC8 review of #768, each with tests that fail before: - P1: closing a photo, switching the layer off or destroying it stops the 1.6 s framing flight toward that photo. The flight is claimed with a token before flyToBoundingSphere and released by its complete/cancel callbacks, so cancelFraming() calls camera.cancelFlight() only while the flight is still Street Level's: a newer navigation flight (a search result, a scene) is never cancelled. Turning FOLLOW on also stops it, so the tween cannot overwrite the follow view. - P2: an older nearest-photo lookup can no longer replace a newer choice. The core owns one AbortController per lookup, aborted by a newer lookup, a direct open or cone click, closing the viewer, disable and destroy; the signal reaches source.nearestImages through the provider, and an aborted lookup never surfaces as an error. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
c2f1b54d00
commit
09fc10756c
8 files changed
+371
-27
No files matched your search
@@ -239,7 +239,21 @@ export function createStreetLevelLayer({
|
||||
parts.credits.hide(state.viewer, entry.def);
|
||||
}
|
||||
|
||||
/**
|
||||
* The nearest-image lookup in flight. Anything newer the user asks for (a
|
||||
* later lookup, a picked image, closing, the layer going off) aborts it,
|
||||
* so its late answer can never replace that choice.
|
||||
* @type {AbortController|null}
|
||||
*/
|
||||
let nearestLookup = null;
|
||||
|
||||
function abortNearest() {
|
||||
nearestLookup?.abort();
|
||||
nearestLookup = null;
|
||||
}
|
||||
|
||||
function openImage(providerId, imageId) {
|
||||
abortNearest();
|
||||
return parts.viewerHost.open(providerId, imageId);
|
||||
}
|
||||
|
||||
@@ -358,6 +372,7 @@ export function createStreetLevelLayer({
|
||||
|
||||
disable() {
|
||||
state.enabled = false;
|
||||
abortNearest();
|
||||
unwatchSurface();
|
||||
parts.viewerHost.unmount();
|
||||
for (const entry of state.providers.values()) entry.instance.deactivate();
|
||||
@@ -461,6 +476,10 @@ export function createStreetLevelLayer({
|
||||
const view = point || viewCentre(state.viewer);
|
||||
if (!Number.isFinite(view?.lat) || !Number.isFinite(view?.lon))
|
||||
return false;
|
||||
abortNearest();
|
||||
const lookup = new AbortController();
|
||||
nearestLookup = lookup;
|
||||
const { signal } = lookup;
|
||||
state.street.loading = true;
|
||||
state.street.error = null;
|
||||
notify();
|
||||
@@ -468,20 +487,25 @@ export function createStreetLevelLayer({
|
||||
for (const entry of activeEntries()) {
|
||||
let imageId = null;
|
||||
try {
|
||||
imageId = await entry.instance.nearestImage({
|
||||
lat: view.lat,
|
||||
lon: view.lon,
|
||||
});
|
||||
imageId = await entry.instance.nearestImage(
|
||||
{ lat: view.lat, lon: view.lon },
|
||||
{ signal },
|
||||
);
|
||||
} catch (error) {
|
||||
// Overtaken: whatever replaced it owns the panel, errors included.
|
||||
if (signal.aborted) return false;
|
||||
// One provider failing (no key, offline) must not hide the others.
|
||||
lastError = error;
|
||||
continue;
|
||||
}
|
||||
if (signal.aborted) return false;
|
||||
if (!state.enabled) break;
|
||||
// This provider was switched off while it looked: try the next.
|
||||
if (!imageId || !entry.on) continue;
|
||||
nearestLookup = null; // answered: nothing left to abort
|
||||
return openImage(entry.def.id, imageId);
|
||||
}
|
||||
if (nearestLookup === lookup) nearestLookup = null;
|
||||
// Switched off while it looked: nothing to open, nothing to report.
|
||||
if (state.enabled && activeEntries().length)
|
||||
state.street.error =
|
||||
@@ -493,6 +517,7 @@ export function createStreetLevelLayer({
|
||||
},
|
||||
/** Close the image and deselect it everywhere on the map. */
|
||||
closeViewer() {
|
||||
abortNearest();
|
||||
parts.viewerHost.close();
|
||||
parts.clearSequences();
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user