mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(street-level): viewer lifecycle, hover cost, keyboard focus, panel lift
From the IC8 review of #768 (P2s), each with a test that fails before: - Switching the layer off and on during the first photo download no longer leaves the viewer stuck on "not mounted": an outdated mount only unmounts an adapter nobody else holds and subscribes poses only once current, and the MapillaryJS adapter never builds a viewer after it was unmounted. - Hover picks at most every 120 ms (the CCTV convention), not while the camera moves or a button is held, and not after the layer went off. - Esc shrinks the expanded viewer wherever focus is (document capture), so the map keeps its selection, and Tab from outside returns into it. Closing a photo moves focus to the panel instead of dropping it on body. - Portable panels lift only after a mouse or pen moves past the drag threshold: a click on a docked panel's edge or a touch swipe on its header no longer turns it into a floating window, and pointercancel saves nothing and puts the panel back. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
b1924ebb3e
commit
539d514adb
10 files changed
+793
-101
No files matched your search
@@ -76,19 +76,19 @@ export function createViewerHost({ state, parts }) {
|
||||
}
|
||||
const adapter = entry.instance.viewer;
|
||||
const promise = (async () => {
|
||||
const unsubscribe = adapter.onPose(applyPose);
|
||||
try {
|
||||
await adapter.mount(state.street.host);
|
||||
} catch (error) {
|
||||
unsubscribe();
|
||||
throw error;
|
||||
}
|
||||
await adapter.mount(state.street.host);
|
||||
if (mounting?.promise !== promise) {
|
||||
// Unmounted (layer off, provider switched) while loading.
|
||||
unsubscribe();
|
||||
adapter.unmount();
|
||||
// Unmounted (layer off, provider switched) while loading. A newer
|
||||
// mount of this provider shares the adapter and its viewer: tearing
|
||||
// it down here would leave that mount active with no viewer.
|
||||
const reused =
|
||||
active?.id === entry.def.id || mounting?.id === entry.def.id;
|
||||
if (!reused) adapter.unmount();
|
||||
throw new Error('Street-level viewer was closed');
|
||||
}
|
||||
// Listen only once current: an outdated mount releasing the same
|
||||
// `applyPose` would otherwise unhook the mount that replaced it.
|
||||
const unsubscribe = adapter.onPose(applyPose);
|
||||
active = { id: entry.def.id, adapter, unsubscribe };
|
||||
warmed.delete(entry.def.id);
|
||||
adapter.setRenderMode?.(state.street.renderMode);
|
||||
|
||||
Reference in new issue
Block a user