refactor(map): lightMode prop 제거, useThemeStore 기반 테마 전환으로 통합

This commit is contained in:
jeonghyo.k 2026-04-06 12:35:32 +09:00
부모 77d36ec8d0
커밋 7921bfef96
7개의 변경된 파일16개의 추가작업 그리고 32개의 파일을 삭제

파일 보기

@ -1,10 +1,10 @@
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import { useMap } from '@vis.gl/react-maplibre'; import { useMap } from '@vis.gl/react-maplibre';
import type { HydrDataStep } from '@tabs/prediction/services/predictionApi'; import type { HydrDataStep } from '@tabs/prediction/services/predictionApi';
import { useThemeStore } from '@common/store/themeStore';
interface HydrParticleOverlayProps { interface HydrParticleOverlayProps {
hydrStep: HydrDataStep | null; hydrStep: HydrDataStep | null;
lightMode?: boolean;
} }
const PARTICLE_COUNT = 3000; const PARTICLE_COUNT = 3000;
@ -27,8 +27,8 @@ interface Particle {
export default function HydrParticleOverlay({ export default function HydrParticleOverlay({
hydrStep, hydrStep,
lightMode = false,
}: HydrParticleOverlayProps) { }: HydrParticleOverlayProps) {
const lightMode = useThemeStore((s) => s.theme) === 'light';
const { current: map } = useMap(); const { current: map } = useMap();
const animRef = useRef<number>(); const animRef = useRef<number>();

파일 보기

@ -18,6 +18,7 @@ import { useMeasureTool } from '@common/hooks/useMeasureTool'
import { hexToRgba } from './mapUtils' import { hexToRgba } from './mapUtils'
import { S57EncOverlay } from './S57EncOverlay' import { S57EncOverlay } from './S57EncOverlay'
import { useMapStore } from '@common/store/mapStore' import { useMapStore } from '@common/store/mapStore'
import { useThemeStore } from '@common/store/themeStore'
import { useBaseMapStyle } from '@common/hooks/useBaseMapStyle' import { useBaseMapStyle } from '@common/hooks/useBaseMapStyle'
const GEOSERVER_URL = import.meta.env.VITE_GEOSERVER_URL || 'http://localhost:8080' const GEOSERVER_URL = import.meta.env.VITE_GEOSERVER_URL || 'http://localhost:8080'
@ -142,8 +143,6 @@ interface MapViewProps {
analysisPolygonPoints?: Array<{ lat: number; lon: number }> analysisPolygonPoints?: Array<{ lat: number; lon: number }>
analysisCircleCenter?: { lat: number; lon: number } | null analysisCircleCenter?: { lat: number; lon: number } | null
analysisCircleRadiusM?: number analysisCircleRadiusM?: number
/** 밝은 톤 지도 스타일 사용 (CartoDB Positron) */
lightMode?: boolean
/** false로 설정 시 WeatherInfoPanel, MapLegend, CoordinateDisplay 숨김 (기본: true) */ /** false로 설정 시 WeatherInfoPanel, MapLegend, CoordinateDisplay 숨김 (기본: true) */
showOverlays?: boolean showOverlays?: boolean
} }
@ -328,9 +327,9 @@ export function MapView({
analysisPolygonPoints = [], analysisPolygonPoints = [],
analysisCircleCenter, analysisCircleCenter,
analysisCircleRadiusM = 0, analysisCircleRadiusM = 0,
lightMode = false,
showOverlays = true, showOverlays = true,
}: MapViewProps) { }: MapViewProps) {
const lightMode = useThemeStore((s) => s.theme) === 'light'
const { mapToggles, measureMode, measureInProgress, measurements } = useMapStore() const { mapToggles, measureMode, measureInProgress, measurements } = useMapStore()
const { handleMeasureClick } = useMeasureTool() const { handleMeasureClick } = useMeasureTool()
const isControlled = externalCurrentTime !== undefined const isControlled = externalCurrentTime !== undefined
@ -1102,8 +1101,8 @@ export function MapView({
analysisPolygonPoints, analysisCircleCenter, analysisCircleRadiusM, lightMode, analysisPolygonPoints, analysisCircleCenter, analysisCircleRadiusM, lightMode,
]) ])
// 3D 모드 / 밝은 톤에 따른 지도 스타일 전환 // 3D 모드 / 테마에 따른 지도 스타일 전환
const currentMapStyle = useBaseMapStyle(lightMode) const currentMapStyle = useBaseMapStyle()
return ( return (
<div className="w-full h-full relative"> <div className="w-full h-full relative">
@ -1164,7 +1163,7 @@ export function MapView({
{/* 해류 파티클 오버레이 */} {/* 해류 파티클 오버레이 */}
{hydrData.length > 0 && showCurrent && ( {hydrData.length > 0 && showCurrent && (
<HydrParticleOverlay hydrStep={hydrData[currentTime] ?? null} lightMode={lightMode} /> <HydrParticleOverlay hydrStep={hydrData[currentTime] ?? null} />
)} )}
{/* 사고 위치 마커 (MapLibre Marker) */} {/* 사고 위치 마커 (MapLibre Marker) */}

파일 보기

@ -1,5 +1,6 @@
import type { StyleSpecification } from 'maplibre-gl'; import type { StyleSpecification } from 'maplibre-gl';
import { useMapStore } from '@common/store/mapStore'; import { useMapStore } from '@common/store/mapStore';
import { useThemeStore } from '@common/store/themeStore';
import { import {
BASE_STYLE, BASE_STYLE,
LIGHT_STYLE, LIGHT_STYLE,
@ -7,11 +8,12 @@ import {
ENC_EMPTY_STYLE, ENC_EMPTY_STYLE,
} from '@common/components/map/mapStyles'; } from '@common/components/map/mapStyles';
export function useBaseMapStyle(lightMode = false): StyleSpecification { export function useBaseMapStyle(): StyleSpecification {
const theme = useThemeStore((s) => s.theme);
const mapToggles = useMapStore((s) => s.mapToggles); const mapToggles = useMapStore((s) => s.mapToggles);
if (mapToggles.s57) return ENC_EMPTY_STYLE; if (mapToggles.s57) return ENC_EMPTY_STYLE;
if (mapToggles.threeD) return SATELLITE_3D_STYLE; if (mapToggles.threeD) return SATELLITE_3D_STYLE;
if (lightMode) return LIGHT_STYLE; if (theme === 'light') return LIGHT_STYLE;
return BASE_STYLE; return BASE_STYLE;
} }

파일 보기

@ -131,7 +131,7 @@ export function IncidentsView() {
const [baselineLoaded, setBaselineLoaded] = useState(() => getCachedBaseline() !== null && getCachedZones() !== null) const [baselineLoaded, setBaselineLoaded] = useState(() => getCachedBaseline() !== null && getCachedZones() !== null)
// Map style & toggles // Map style & toggles
const currentMapStyle = useBaseMapStyle(true) const currentMapStyle = useBaseMapStyle()
const mapToggles = useMapStore((s) => s.mapToggles) const mapToggles = useMapStore((s) => s.mapToggles)
// Measure tool // Measure tool

파일 보기

@ -1240,7 +1240,6 @@ export function OilSpillView() {
sensitiveResourceGeojson={ sensitiveResourceGeojson={
displayControls.showSensitiveResources ? sensitiveResourceGeojson : null displayControls.showSensitiveResources ? sensitiveResourceGeojson : null
} }
lightMode
centerPoints={centerPoints.filter((p) => centerPoints={centerPoints.filter((p) =>
visibleModels.has((p.model || 'OpenDrift') as PredictionModel), visibleModels.has((p.model || 'OpenDrift') as PredictionModel),
)} )}

파일 보기

@ -59,7 +59,6 @@ const MapSlot = ({ label, step, mapData, captured, onCapture, onReset }: MapSlot
simulationStartTime={mapData.simulationStartTime || undefined} simulationStartTime={mapData.simulationStartTime || undefined}
mapCaptureRef={captureRef} mapCaptureRef={captureRef}
showOverlays={false} showOverlays={false}
lightMode
/> />
{captured && ( {captured && (

파일 보기

@ -2,27 +2,10 @@ import { useState, useEffect } from 'react';
import { Map, useControl } from '@vis.gl/react-maplibre'; import { Map, useControl } from '@vis.gl/react-maplibre';
import { MapboxOverlay } from '@deck.gl/mapbox'; import { MapboxOverlay } from '@deck.gl/mapbox';
import { ScatterplotLayer } from '@deck.gl/layers'; import { ScatterplotLayer } from '@deck.gl/layers';
import type { StyleSpecification } from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css'; import 'maplibre-gl/dist/maplibre-gl.css';
import type { ScatDetail } from './scatTypes'; import type { ScatDetail } from './scatTypes';
import { hexToRgba } from '@common/components/map/mapUtils'; import { hexToRgba } from '@common/components/map/mapUtils';
import { useBaseMapStyle } from '@common/hooks/useBaseMapStyle';
// ── 베이스맵 스타일 ──────────────────────────────────────
const BASE_STYLE: StyleSpecification = {
version: 8,
sources: {
'carto-dark': {
type: 'raster',
tiles: [
'https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
'https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
'https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
],
tileSize: 256,
},
},
layers: [{ id: 'carto-dark-layer', type: 'raster', source: 'carto-dark' }],
};
// ── DeckGLOverlay ────────────────────────────────────── // ── DeckGLOverlay ──────────────────────────────────────
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -94,12 +77,14 @@ function PopupMap({
}), }),
]; ];
const currentMapStyle = useBaseMapStyle();
return ( return (
<div className="relative w-full h-full"> <div className="relative w-full h-full">
<Map <Map
key={`${lat}-${lng}`} key={`${lat}-${lng}`}
initialViewState={{ longitude: lng, latitude: lat, zoom: 15 }} initialViewState={{ longitude: lng, latitude: lat, zoom: 15 }}
mapStyle={BASE_STYLE} mapStyle={currentMapStyle}
style={{ width: '100%', height: '100%' }} style={{ width: '100%', height: '100%' }}
attributionControl={false} attributionControl={false}
onLoad={onMapLoad} onLoad={onMapLoad}