import { RefObject, useCallback, useRef, useState } from "react"; import { FaMapPin } from "react-icons/fa"; import { FaClipboardCheck } from "react-icons/fa6"; import { Camera, Quaternion, Vector3 } from "three"; import { useSettings } from "./SettingsProvider"; import styles from "./CopyCoordinatesButton.module.css"; function encodeViewHash({ position, quaternion, }: { position: Vector3; quaternion: Quaternion; }) { const trunc = (num: number) => parseFloat(num.toFixed(3)); const encodedPosition = `${trunc(position.x)},${trunc(position.y)},${trunc(position.z)}`; const encodedQuaternion = `${trunc(quaternion.x)},${trunc(quaternion.y)},${trunc(quaternion.z)},${trunc(quaternion.w)}`; return `#c${encodedPosition}~${encodedQuaternion}`; } export function CopyCoordinatesButton({ cameraRef, missionName, missionType, disabled, }: { cameraRef: RefObject; missionName: string; missionType?: string; disabled?: boolean; }) { const { fogEnabled } = useSettings(); const [showCopied, setShowCopied] = useState(false); const timerRef = useRef | null>(null); const handleCopyLink = useCallback(async () => { if (timerRef.current) clearTimeout(timerRef.current); const camera = cameraRef.current; if (!camera) return; const hash = encodeViewHash(camera); const params = new URLSearchParams(); params.set("mission", `${missionName}~${missionType}`); params.set("fog", fogEnabled.toString()); const fullPath = `${window.location.pathname}?${params}${hash}`; const fullUrl = `${window.location.origin}${fullPath}`; window.history.replaceState(null, "", fullPath); try { await navigator.clipboard.writeText(fullUrl); setShowCopied(true); timerRef.current = setTimeout(() => { setShowCopied(false); }, 1100); } catch (err) { console.error(err); } }, [cameraRef, missionName, missionType, fogEnabled]); return ( ); }