"use client"; import type { Map as MapLibreMap, MapLayerMouseEvent } from "maplibre-gl"; import type { RefObject } from "react"; import { useEffect } from "react"; import type { DetailFeature } from "../types"; import { getFeatureId, toDetailFeature } from "../map/feature-adapter"; import { SOURCE_LAYERS } from "../map/sources"; const INTERACTIVE_LAYER_IDS = ["pipes-flow", "junctions"]; type UseMapInteractionsOptions = { mapRef: RefObject; mapReady: boolean; onSelectFeature: (feature: DetailFeature) => void; }; export function useMapInteractions({ mapRef, mapReady, onSelectFeature }: UseMapInteractionsOptions) { useEffect(() => { const map = mapRef.current; if (!mapReady || !map) { return; } const activeMap = map; function handleMouseMove(event: MapLayerMouseEvent) { activeMap.getCanvas().style.cursor = "pointer"; const feature = event.features?.[0]; if (!feature) { return; } const id = getFeatureId(feature); const layerId = feature.sourceLayer === SOURCE_LAYERS.pipes ? "pipes-hover" : "junctions-hover"; activeMap.setFilter(layerId, ["==", ["get", "id"], id]); } function handleMouseLeave() { activeMap.getCanvas().style.cursor = ""; activeMap.setFilter("pipes-hover", ["==", ["get", "id"], ""]); activeMap.setFilter("junctions-hover", ["==", ["get", "id"], ""]); } function handleClick(event: MapLayerMouseEvent) { const feature = event.features?.[0]; if (feature) { onSelectFeature(toDetailFeature(feature)); } } activeMap.on("mousemove", INTERACTIVE_LAYER_IDS, handleMouseMove); activeMap.on("mouseleave", INTERACTIVE_LAYER_IDS, handleMouseLeave); activeMap.on("click", INTERACTIVE_LAYER_IDS, handleClick); return () => { activeMap.off("mousemove", INTERACTIVE_LAYER_IDS, handleMouseMove); activeMap.off("mouseleave", INTERACTIVE_LAYER_IDS, handleMouseLeave); activeMap.off("click", INTERACTIVE_LAYER_IDS, handleClick); }; }, [mapRef, mapReady, onSelectFeature]); }