fix: run zoom handler synchronously #33
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/m1-zoom-movement-debounce"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes M1 and M2 from bugs.md.
M1:
zoomendandmoveendsharedboundsTimer, and Leaflet firesmoveendsynchronously afterzoomend, so the zoom handler's timer was always cleared microseconds after arming — its body never ran. Trails were only attached at init when the page loaded at zoom >= 11,lastZoomnever updated, and the OMS rebuild on crossing the clustering threshold never fired. The zoom logic now runs synchronously inzoomend; onlysaveMapStatestays debounced inmoveend.M2: with the body now actually running, the
pushEvent("refresh_markers")on zoom jumps > 2 would crash the LiveView — the server has no handler for it. Deleted the push and the dead client-siderefresh_markersregistration; the zoom handler now trims out-of-viewport markers locally viaremoveMarkersOutsideBounds, mirroring what the dead handler did.Verification:
mix esbuild map_jsbuilds (190.4kb), full suite 2235 passed, grep confirms zero remainingrefresh_markersreferences andboundsTimerused only by the moveend debounce.🤖 Skippy PR review
1 finding — 1 blocking before merge.
assets/js/map.ts:564Reviewed
59dc71f20a91. Commentskippy reviewto re-run.@ -556,3 +561,4 @@// `saveMapState` stays debounced, in `moveend`.const zoomEndHandler = () => {// Skip if this is a programmatic move from the serverif (self.programmaticMoveId) {🟡 Warning — Programmatic zooms still skip the handler this PR just activated
The
programmaticMoveIdearly return stays in front of the body you just made synchronous, so every server-driven zoom still bypasses it — including the trail-layer sync andlastZoom.Concretely: load the map at the default zoom 5 (trail layer not attached —
trailLayer.addToonly happens at init map.ts:408 and in this handler), then press Locate.set_locationpusheszoom_to_locationat zoom 12 (events.ex:45), the client handler setsprogrammaticMoveIdand callssetView, sozoomendreturns here andself.map.hasLayer(self.trailLayer)is never re-checked. The map sits at zoom 12 with trails permanently hidden until the user zooms by hand — the same symptom M1 was opened for.lastZoomis also left at 5, so the next real zoom computeszoomDifferenceand thewasUnclustered/isUnclusteredcomparison against a zoom the map left long ago, firing the newremoveMarkersOutsideBoundsprune (and, in the other direction, the OMS rebuild) on a false baseline.Fix: update
self.lastZoom = currentZoomand run the trail-layer sync before theprogrammaticMoveIdcheck, or clear the flag when thesetViewanimation ends so the handler sees the real zoom.Resolved 1 of 1 earlier findings:
programmaticMoveIdno longer guardszoomEndHandler, so server-driven zooms now updatelastZoomand re-check the trail layer (both axes of the earlier warning). 0 still open.Nothing new in
59dc71f..733fdb4- the only change is the comment block documenting the removal. Re-checked the M2 premise independently at this head: norefresh_markerspush or registration remains anywhere in the tree (only the explanatory comment), andboundsTimeris used solely by themoveenddebounce plus its cleanup.Nothing new in
733fdb4..9945f36- the only change is the corrected suppression comment atmap.ts:983("moveend was suppressed", which matches the code: themoveendhandler still early-returns onprogrammaticMoveIdwhile the timeout is what reports the final state).0 findings open. Re-verified the M2 premise independently at this head: zero
refresh_markerspushes or registrations anywhere in the tree (one explanatory comment),boundsTimeronly feeds themoveenddebounce plus cleanup, and the zoom-time prune atmap.ts:626mirrors the server-drivenfilter_markers_by_boundshandler atmap.ts:1551.