/* eslint-disable @typescript-eslint/no-explicit-any */ import { OSMWay } from "@repo/db"; import { useDispatchConnectionStore } from "_store/dispatch/connectionStore"; import { useMapStore } from "_store/mapStore"; import { usePannelStore } from "_store/pannelStore"; import { MapPin, MapPinned, Search, Car, Ambulance, Siren, Flame } from "lucide-react"; import { getOsmAddress } from "_querys/osm"; import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import { Popup, useMap } from "react-leaflet"; import { findClosestPolygon } from "_helpers/findClosestPolygon"; import { xPlaneObjectsAvailable } from "_helpers/xPlaneObjectsAvailable"; import { useQuery } from "@tanstack/react-query"; import { getConnectedAircraftsAPI } from "_querys/aircrafts"; export const ContextMenu = () => { const map = useMap(); const { data: aircrafts } = useQuery({ queryKey: ["connectedAircrafts"], queryFn: getConnectedAircraftsAPI, }); const { contextMenu, searchElements, setContextMenu, setSearchElements, setSearchPopup, toggleSearchElementSelection, } = useMapStore(); const { missionFormValues, setMissionFormValues, setOpen, isOpen: isPannelOpen, } = usePannelStore((state) => state); const [showObjectOptions, setShowObjectOptions] = useState(false); const [rulerHover, setRulerHover] = useState(false); const [rulerOptionsHover, setRulerOptionsHover] = useState(false); const dispatcherConnected = useDispatchConnectionStore((s) => s.status) === "connected"; useEffect(() => { const showObjectOptions = rulerHover || rulerOptionsHover; setShowObjectOptions(showObjectOptions); }, [isPannelOpen, rulerHover, rulerOptionsHover, setOpen]); useEffect(() => { const handleContextMenu = (e: any) => { setContextMenu({ lat: e.latlng.lat, lng: e.latlng.lng }); }; const handleClick = () => { setContextMenu(null); setSearchPopup(null); }; map.on("contextmenu", handleContextMenu); map.on("click", handleClick); return () => { map.off("contextmenu", handleContextMenu); map.off("click", handleClick); }; }, [map, contextMenu, setContextMenu, setSearchPopup]); if (!contextMenu || !dispatcherConnected) return null; const missionBtnText = missionFormValues && isPannelOpen ? "Position übernehmen" : "Einsatz erstellen"; const addOSMobjects = async (ignorePreviosSelected?: boolean) => { const res = await fetch( `https://overpass-api.de/api/interpreter?data=${encodeURIComponent(` [out:json]; ( way["building"](around:100, ${contextMenu.lat}, ${contextMenu.lng}); relation["building"](around:100, ${contextMenu.lat}, ${contextMenu.lng}); ); out body; >; out skel qt; `)}`, ); const data = await res.json(); const parsed: OSMWay[] = data.elements .filter((e: any) => e.type === "way") .map((e: any) => { const elementInMap = searchElements.find((el) => el.wayID === e.id); return { isSelected: ignorePreviosSelected ? false : (elementInMap?.isSelected ?? false), wayID: e.id, nodes: e.nodes.map((nodeId: string) => { const node = data.elements.find((element: any) => element.id === nodeId); return { lat: node.lat, lon: node.lon, }; }), tags: e.tags, type: e.type, } as OSMWay; }); setSearchElements(parsed); return parsed; }; return (
{/* Top Button */} {/* Left Button */} {/* Bottom Button */} {/* Right Button (original Search button) */} {/* XPlane Object Options - shown when Ruler button is hovered or options are hovered */} {showObjectOptions && (
setRulerOptionsHover(true)} onMouseLeave={() => setRulerOptionsHover(false)} >
)}
); };