import { useEffect } from "react"; import type { ReactNode } from "react"; import { Captions, Gauge, Hand, Laptop, Music2, RotateCcw, Server, Volume2, X, } from "lucide-react"; import { GRAPHICS_PRESET_KEYS, GRAPHICS_PRESETS, type GraphicsPreset, } from "@/data/world/graphicsConfig"; import { useDebugStore } from "@/hooks/debug/useDebugStore"; import { useGameStore } from "@/managers/stores/useGameStore"; import { useSettingsStore } from "@/managers/stores/useSettingsStore"; import { useWorldSettingsStore } from "@/managers/stores/useWorldSettingsStore"; import type { HandTrackingSource } from "@/types/handTracking/handTracking"; import type { SubtitleLanguage } from "@/types/settings/settings"; import { hasSiteBeenVisitedToday } from "@/utils/cookies/siteVisitCookie"; import { Debug } from "@/utils/debug/Debug"; function formatPercent(value: number): string { return `${Math.round(value * 100)}%`; } interface VolumeSliderProps { id: string; label: string; icon: ReactNode; value: number; onChange: (value: number) => void; } function VolumeSlider({ id, label, icon, value, onChange, }: VolumeSliderProps): React.JSX.Element { return ( ); } function formatChunkDistance(distance: number): string { return `${distance}m`; } const HAND_TRACKING_OPTIONS = [ { description: "Calcul local", icon: , label: "Sur cet ordi", source: "browser", }, { description: "Soulage l'ordi", icon: , label: "Mode assisté", source: "backend", }, ] as const satisfies readonly { description: string; icon: ReactNode; label: string; source: HandTrackingSource; }[]; interface GraphicsPresetButtonProps { active: boolean; preset: GraphicsPreset; onSelect: (preset: GraphicsPreset) => void; } function GraphicsPresetButton({ active, preset, onSelect, }: GraphicsPresetButtonProps): React.JSX.Element { const config = GRAPHICS_PRESETS[preset]; const lodLabel = config.forceLodModels ? "LOD forcé" : `HD ${config.lodHighDetailDistance}m`; const chunkLabel = config.chunkStreamingEnabled ? formatChunkDistance(config.chunkLoadRadius) : "All"; return ( ); } export function GameSettingsMenu(): React.JSX.Element | null { const resetGame = useGameStore((state) => state.resetGame); const handTrackingSource = useDebugStore((debug) => debug.getHandTrackingSource(), ); const graphicsPreset = useWorldSettingsStore( (state) => state.graphics.preset, ); const setGraphicsPreset = useWorldSettingsStore( (state) => state.setGraphicsPreset, ); const { isSettingsMenuOpen, musicVolume, sfxVolume, dialogueVolume, subtitlesEnabled, subtitleLanguage, setMusicVolume, setSfxVolume, setDialogueVolume, setSettingsMenuOpen, setSubtitlesEnabled, setSubtitleLanguage, } = useSettingsStore(); useEffect(() => { const handleKeyDown = (event: KeyboardEvent): void => { if (event.key === "Escape") { event.preventDefault(); event.stopPropagation(); if (!isSettingsMenuOpen) document.exitPointerLock(); setSettingsMenuOpen(!isSettingsMenuOpen); return; } }; window.addEventListener("keydown", handleKeyDown, { capture: true }); return () => { window.removeEventListener("keydown", handleKeyDown, { capture: true }); }; }, [isSettingsMenuOpen, setSettingsMenuOpen]); if (!isSettingsMenuOpen) return null; const handleRestart = (): void => { resetGame(); setSettingsMenuOpen(false); window.location.assign(hasSiteBeenVisitedToday() ? "/" : "/site"); }; const handleHandTrackingSourceChange = (source: HandTrackingSource): void => { Debug.getInstance().setHandTrackingSource(source); }; return (