Skip to content

Commit 745809c

Browse files
beetlebugorgclaude
andcommitted
fix(web): restore crosshair + cursor-pick (overlay-load guard bailed permanently)
The "don't add the catalog overlay before the style finishes loading" guard added an `if (!map.isStyleLoaded()) return` at the TOP of addCatalogOverlay — but that method's tail also wires the one-time map interaction listeners (the ECDIS crosshair cursor, the click → cursor-pick, coverage tap-to-fly). When the first onReady call hit a mid-rebuild style the guard bailed, and if no later style.load re-fired the whole block never ran: no crosshair, no pick, no coverage (focus source absent, _catalogMapWired stayed false). Fix: call addCatalogOverlay only on a LOADED style — directly when it already is, else on style.load — and drop the internal isStyleLoaded-and-return. This still avoids the "Style is not done loading" addSource throw, but never skips the wiring. Verified on the live app: crosshair restored, _catalogMapWired/coverage/focus all true, pick handler attached again. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 72eff4e commit 745809c

1 file changed

Lines changed: 16 additions & 16 deletions

File tree

web/src/chartplotter.mjs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -542,15 +542,18 @@ export class ChartPlotter extends HTMLElement {
542542
// Best-effort: if the style is mid-rebuild this no-ops (or throws on older
543543
// maps) — either way the style.load handler below re-adds the overlay once the
544544
// fresh style is ready, so never let it skip registering that listener.
545-
try { this.addCatalogOverlay(map); } catch (e) { console.warn("[overlay] deferring to style.load:", e); }
546-
// The plotter rebuilds the whole style (setStyle) when server sets load or the
547-
// SCAMIN buckets refresh, wiping every app-added overlay (coverage boxes, pick &
548-
// inspect highlights). Re-apply them after each rebuild, and repopulate the
549-
// coverage boxes — otherwise they vanish the moment a set renders.
550-
map.on("style.load", () => {
551-
this.addCatalogOverlay(map);
552-
this._refreshInstalledBounds();
553-
});
545+
// Add the app overlay (focus/inspect/pick sources + coverage) AND wire the map
546+
// interaction listeners (crosshair cursor, click → ECDIS pick). addSource throws
547+
// if the style isn't loaded, so call it only WHEN the style is ready: now if it
548+
// already is, plus on every style.load (the plotter rebuilds the whole style on
549+
// server-set load + SCAMIN refresh, wiping app-added overlays — re-apply each
550+
// time). This avoids the "Style is not done loading" throw WITHOUT ever skipping
551+
// the wiring — an earlier isStyleLoaded()-guard-and-RETURN inside addCatalogOverlay
552+
// left the cursor/pick/coverage permanently unwired whenever the first call hit a
553+
// mid-rebuild style and no later style.load re-fired.
554+
const ensureOverlay = () => { this.addCatalogOverlay(map); this._refreshInstalledBounds(); };
555+
if (map.isStyleLoaded()) ensureOverlay();
556+
map.on("style.load", ensureOverlay);
554557
// Hold the 1:MIN_DETAIL_SCALE max-zoom floor on EVERY view change. It's
555558
// latitude-dependent (recompute as the centre moves), and a fly-to-chart raises
556559
// the cap to reach a pack's detail — without re-enforcing here that raised cap
@@ -1102,13 +1105,10 @@ export class ChartPlotter extends HTMLElement {
11021105
// change and SCAMIN-bucket refresh, which drops all these app-added sources/
11031106
// layers. A style.load handler (see onReady) re-invokes this against the fresh
11041107
// style; the guard makes a redundant call (when the overlay is still present) a
1105-
// no-op so we never double-add.
1106-
//
1107-
// The style may still be REBUILDING when this first runs from onReady (a
1108-
// setStyle for the physical-scale restage / SCAMIN buckets can be in flight
1109-
// after the awaited catalog load) — addSource would throw "Style is not done
1110-
// loading". Bail; the onReady style.load handler re-invokes us once it's ready.
1111-
if (!map.isStyleLoaded()) return;
1108+
// no-op so we never double-add. The caller (onReady) only invokes this on a
1109+
// LOADED style — directly if ready, else on style.load — so addSource never
1110+
// throws "Style is not done loading"; do NOT add an isStyleLoaded()-guard return
1111+
// here (it silently skipped the cursor/pick/coverage wiring at the tail).
11121112
if (map.getSource("focus")) return;
11131113
const empty = { type: "FeatureCollection", features: [] };
11141114
map.addSource("focus", { type: "geojson", data: empty });

0 commit comments

Comments
 (0)