From 2d740ec07ca2ff2d1a5615fce12b2123d82b55cb Mon Sep 17 00:00:00 2001 From: gadgethd <111318106+gadgethd@users.noreply.github.com> Date: Mon, 3 Aug 2026 20:14:22 +0100 Subject: [PATCH] =?UTF-8?q?fix(map):=20one-click=20node=20info=20=E2=80=94?= =?UTF-8?q?=20remove=20center-snap,=20enlarge=20click=20hitbox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Map/MapLibreMap.tsx | 12 +++--------- frontend/src/components/Map/mapSourceLayers.ts | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/Map/MapLibreMap.tsx b/frontend/src/components/Map/MapLibreMap.tsx index 40eebe0..fa8be9a 100644 --- a/frontend/src/components/Map/MapLibreMap.tsx +++ b/frontend/src/components/Map/MapLibreMap.tsx @@ -774,7 +774,7 @@ export function MapLibreMap({ openPlannedPopupRef.current(planId, { lng: coords[0], lat: coords[1] }); }); - map.on('click', 'node-dots', (e) => { + map.on('click', 'node-dots-hit', (e) => { const feature = e.features?.[0]; if (!feature) return; const props = feature.properties as NodeFeatureProps; @@ -807,12 +807,6 @@ export function MapLibreMap({ // but all our props are primitives so this is safe. setPopupLinks(null); onNodeSelectRef.current?.(props.node_id); - // Nudge the map so the tapped node clears the right-docked detail panel. - const coords = (feature.geometry as GeoJSON.Point).coordinates as [number, number]; - if (window.matchMedia('(min-width: 641px)').matches) { - const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; - map.easeTo({ center: coords, offset: [-170, 0], duration: reduceMotion ? 0 : 420 }); - } }); // General map click — used for custom LOS mode and plan repeater placement on empty areas @@ -845,10 +839,10 @@ export function MapLibreMap({ }); // Make cursor a pointer over node dots and planned pins - map.on('mouseenter', 'node-dots', () => { + map.on('mouseenter', 'node-dots-hit', () => { map.getCanvas().style.cursor = 'pointer'; }); - map.on('mouseleave', 'node-dots', () => { + map.on('mouseleave', 'node-dots-hit', () => { map.getCanvas().style.cursor = (viewshedEnabledRef.current && useOverlayStore.getState().planRepeaterMode) || useOverlayStore.getState().customLosMode ? 'crosshair' : ''; }); map.on('mouseenter', 'planned-pins-dot', () => { diff --git a/frontend/src/components/Map/mapSourceLayers.ts b/frontend/src/components/Map/mapSourceLayers.ts index e863fe2..ad51d1b 100644 --- a/frontend/src/components/Map/mapSourceLayers.ts +++ b/frontend/src/components/Map/mapSourceLayers.ts @@ -78,6 +78,21 @@ export function installMapSourcesAndLayers( // ── Node dots source + layer ─────────────────────────────────────────── map.addSource('nodes', { type: 'geojson', data: EMPTY_FC }); + map.addLayer({ + id: 'node-dots-hit', + type: 'circle', + source: 'nodes', + filter: ['==', ['get', 'visible'], true], + paint: { + 'circle-radius': [ + 'interpolate', ['linear'], ['zoom'], + 6, 8, 9, 10, 11, 12, 13, 14, 16, 16, + ], + 'circle-opacity': 0, + 'circle-stroke-opacity': 0, + }, + }); + map.addLayer({ id: 'node-dots', type: 'circle',