Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions src/ui/map/HexGridLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function HexGridLayer() {
const selectedCellId = useBlockbusterStore((s) => s.selectedCellId);
const hoveredCellId = useBlockbusterStore((s) => s.hoveredCellId);
const waypoints = useBlockbusterStore((s) => s.waypoints);
const drawMode = useBlockbusterStore((s) => s.drawMode);
const selectCell = useBlockbusterStore((s) => s.selectCell);
const hoverCell = useBlockbusterStore((s) => s.hoverCell);

Expand All @@ -31,6 +32,13 @@ export function HexGridLayer() {

if (!grid || !showHexGrid) return null;
const waypointSet = new Set(waypoints);
// While an extra-risk draw tool is armed, taps must not select or hover a
// cell — on touch devices the click-through CSS (pointer-events: none) does
// not stop the polygon's own click, so a tap would otherwise select a cell
// instead of starting the shape. Disarming the handlers makes drawing behave
// identically on mouse and touch; Terra Draw still receives the gesture at the
// map-container level. See ExtraRiskDraw / app.css `.leaflet-drawing`.
const drawing = drawMode !== null;

// Own pane (below the pie + route panes) so the stack order survives toggling
// the grid off and on — Leaflet otherwise paints by DOM insertion order.
Expand All @@ -51,11 +59,13 @@ export function HexGridLayer() {
const isHovered = cell.id === hoveredCellId;
const isWaypoint = waypointSet.has(cell.id);

const handlers: LeafletEventHandlerFnMap = {
click: () => selectCell(cell.id),
mouseover: () => hoverCell(cell.id),
mouseout: () => hoverCell(null),
};
const handlers: LeafletEventHandlerFnMap = drawing
? {}
: {
click: () => selectCell(cell.id),
mouseover: () => hoverCell(cell.id),
mouseout: () => hoverCell(null),
};

return (
<Polygon
Expand Down
30 changes: 24 additions & 6 deletions src/ui/map/extra-risk/ExtraRiskDraw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,17 @@ export function ExtraRiskDraw() {
const draw = new TerraDraw({
adapter: new TerraDrawLeafletAdapter({ map, lib: L }),
modes: [
new TerraDrawRectangleMode({ styles }),
// 'click-move-or-drag' so a single drag draws the box (what touch users
// reach for) while two taps still work where dragging is awkward.
new TerraDrawRectangleMode({ styles, drawInteraction: 'click-move-or-drag' }),
// CRS.Simple is not web-mercator; we pick the planar projection (never
// 'globe'/haversine, which blows up here) and re-round circles on finish.
new TerraDrawCircleMode({ projection: 'web-mercator', segments: 64, styles }),
new TerraDrawCircleMode({
projection: 'web-mercator',
segments: 64,
styles,
drawInteraction: 'click-move-or-drag',
}),
new TerraDrawPolygonMode({ styles }),
],
});
Expand Down Expand Up @@ -85,17 +92,28 @@ export function ExtraRiskDraw() {
};
}, [map, addZone]);

// Arm or disarm the active tool.
// Arm or disarm the active tool. While a tool is armed we also disable
// Leaflet's own pan/zoom gestures: otherwise a drag (especially on touch,
// where there is no hover) is swallowed by the map's drag handler and pans
// the map instead of reaching Terra Draw to draw the shape. The cleanup
// re-enables them whenever the tool is disarmed or this layer unmounts (e.g.
// leaving the Extra-risk tab), so map panning is never left disabled.
useEffect(() => {
const draw = drawRef.current;
if (!draw) return;
if (drawMode) {
if (!draw.enabled) draw.start();
draw.setMode(drawMode);
} else if (draw.enabled) {
draw.stop();
map.dragging.disable();
map.doubleClickZoom.disable();
return () => {
map.dragging.enable();
map.doubleClickZoom.enable();
};
}
}, [drawMode]);
if (draw.enabled) draw.stop();
return undefined;
}, [drawMode, map]);

// While a tool is armed, flag the map container so its vector layers (hexes,
// zones) and markers become click-through (see app.css). Otherwise Leaflet
Expand Down
6 changes: 5 additions & 1 deletion src/ui/map/extra-risk/ExtraRiskLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ export function ExtraRiskLayer() {
const zones = useBlockbusterStore((s) => s.zones);
const selectedZoneId = useBlockbusterStore((s) => s.selectedZoneId);
const activeTab = useBlockbusterStore((s) => s.activeTab);
const drawMode = useBlockbusterStore((s) => s.drawMode);
const selectZone = useBlockbusterStore((s) => s.selectZone);
const interactive = activeTab === 'extra';
// Clickable to select only on the Extra-factors tab, and never while a draw
// tool is armed — on touch a tap inside a committed zone would otherwise
// select it instead of starting the new shape (see HexGridLayer).
const interactive = activeTab === 'extra' && drawMode === null;

if (zones.length === 0) return null;

Expand Down
Loading