import { useEffect, useRef, type MutableRefObject } from 'react'; import type maplibregl from 'maplibre-gl'; import { applyEncVisibility, applyEncColors } from './encSettings'; import type { EncMapSettings } from './types'; /** * 스타일 로드 완료를 안정적으로 감지하여 callback 실행. * gc-wing-dev onMapStyleReady 패턴 이식. */ function onStyleReady(map: maplibregl.Map, callback: () => void): () => void { if (map.isStyleLoaded()) { callback(); return () => {}; } let fired = false; const runOnce = () => { if (fired || !map.isStyleLoaded()) return; fired = true; callback(); try { map.off('style.load', runOnce); map.off('styledata', runOnce); } catch { /* ignore */ } }; map.on('style.load', runOnce); map.on('styledata', runOnce); return () => { try { map.off('style.load', runOnce); map.off('styledata', runOnce); } catch { /* ignore */ } }; } export function useEncMapSettings( mapRef: MutableRefObject, mapMode: 'satellite' | 'enc', settings: EncMapSettings, syncEpoch = 0, ) { // settings를 ref로 유지 — style.load 콜백에서 최신값 참조 const settingsRef = useRef(settings); settingsRef.current = settings; // syncEpoch 변경 = 맵 로드 완료 → 전체 설정 재적용 // mapMode 변경 = 위성↔ENC 전환 → style.load 대기 후 적용 useEffect(() => { if (mapMode !== 'enc') return; const map = mapRef.current; if (!map) return; const applyAll = () => { const s = settingsRef.current; applyEncVisibility(map, s); applyEncColors(map, s); }; const stop = onStyleReady(map, applyAll); return stop; }, [mapMode, syncEpoch, mapRef]); // settings 변경 시 즉시 적용 (스타일이 이미 로드된 상태에서) useEffect(() => { if (mapMode !== 'enc') return; const map = mapRef.current; if (!map || !map.isStyleLoaded()) return; applyEncVisibility(map, settings); applyEncColors(map, settings); }, [settings, mapMode, mapRef]); }