mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
fix(street-level): sequence loads, playback and nearest-photo edge cases
From gekh's review of #768, each bug with a test that fails before: - P2: a failed sequence load clears the previous sequence's cones, resets the selection and can be retried; a second click while loading starts no second lookup. sequences.js had no tests: sequences.test.mjs now covers failure and retry, a superseded late answer, the cache and clearSelection. - P2: closing a photo stops MapillaryJS sequence playback, which kept the hidden viewer stepping and downloading images. - openNearest without the panel reports it instead of loading forever, and stops if the layer (or its provider) went off during the lookup; the mesh sampler's misses are bounded and forgotten with its samples; the sequence count is the union of ids across tiles; a provider withdraws only its own error, so a sequence error cannot mask KEY REJECTED; hover stays on (throttled) under an orbiting camera and re-picks when it stops; "since N days" follows the clock in a long-open tab. - A prewarm waits for one in flight and then builds if it gave up. - New coverage for the layer core (credits, KEY REJECTED vs REQUIRED, switching a provider off), the refresh wiring of the tilted-view fix and the draped-to-cast swap completion. - Cleanup: loading is derived from pending; freshStreet(); tile ranking computes distances once and shares one path for the date line; shared metresBetween / whenIdle / redrawTile; one NEAREST_RADIUS_M and one source method list; unused contract fields, exports, getImage and the decoder's image branch removed; PROVIDER_COLORS lists only Mapillary. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
48276450ec
commit
5f98b871e8
31 files changed
+1129
-470
No files matched your search
@@ -1,3 +1,5 @@
|
||||
import { freshStreet } from './state.js';
|
||||
|
||||
/**
|
||||
* Own the one viewer element in the panel and whichever provider's viewer
|
||||
* adapter is mounted in it. Poses the adapter emits become `state.street`,
|
||||
@@ -107,16 +109,20 @@ export function createViewerHost({ state, parts }) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an image from one provider. Returns once the first pose is in;
|
||||
* later poses stream through `state.street` as the user navigates.
|
||||
* Open an image from one provider. Resolves once the first pose is in
|
||||
* (true) or the open failed or was overtaken (false); later poses stream
|
||||
* through `state.street` as the user navigates.
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function open(providerId, imageId, { frame = true } = {}) {
|
||||
const entry = providerEntry(providerId);
|
||||
if (!entry || !imageId) return;
|
||||
if (!entry || !imageId) return false;
|
||||
if (!state.street.host) {
|
||||
// A nearest-image lookup may have set it; nothing is loading now.
|
||||
state.street.loading = false;
|
||||
state.street.error = 'Open the Street Level panel to view imagery';
|
||||
notify();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
const seq = ++openSeq;
|
||||
const current = () => seq === openSeq;
|
||||
@@ -131,9 +137,9 @@ export function createViewerHost({ state, parts }) {
|
||||
notify();
|
||||
try {
|
||||
const adapter = await mount(entry);
|
||||
if (!current()) return;
|
||||
if (!current()) return false;
|
||||
await adapter.open(String(imageId));
|
||||
if (!current()) return;
|
||||
if (!current()) return false;
|
||||
if (frame && !state.street.follow) parts.follow.lookAtPosition();
|
||||
} catch (error) {
|
||||
if (current())
|
||||
@@ -142,32 +148,16 @@ export function createViewerHost({ state, parts }) {
|
||||
if (current()) state.street.loading = false;
|
||||
notify();
|
||||
}
|
||||
if (current() && !state.street.error) selectCurrentSequence();
|
||||
if (!current() || state.street.error) return false;
|
||||
selectCurrentSequence();
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Close the image; the mounted adapter stays warm for the next open. */
|
||||
function close() {
|
||||
openSeq++;
|
||||
active?.adapter.close();
|
||||
Object.assign(state.street, {
|
||||
open: false,
|
||||
follow: false,
|
||||
providerId: null,
|
||||
providerName: null,
|
||||
providerLabel: null,
|
||||
imageId: null,
|
||||
position: null,
|
||||
bearing: null,
|
||||
tilt: null,
|
||||
altitude: null,
|
||||
isPano: false,
|
||||
capturedAt: null,
|
||||
sequenceId: null,
|
||||
creator: null,
|
||||
externalUrl: null,
|
||||
loading: false,
|
||||
error: null,
|
||||
});
|
||||
Object.assign(state.street, freshStreet());
|
||||
parts.marker.clear();
|
||||
notify();
|
||||
}
|
||||
@@ -248,6 +238,5 @@ export function createViewerHost({ state, parts }) {
|
||||
setRenderMode,
|
||||
prewarm,
|
||||
unmount,
|
||||
activeProviderId: () => active?.id || null,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user