import { useState, useEffect, useRef, useCallback } from 'react'; import type { ScatSegment } from './scatTypes'; interface ScatTimelineProps { segments: ScatSegment[]; currentIdx: number; onSeek: (idx: number) => void; } function ScatTimeline({ segments, currentIdx, onSeek }: ScatTimelineProps) { const [playing, setPlaying] = useState(false); const [speed, setSpeed] = useState(1); const intervalRef = useRef | null>(null); const total = Math.min(segments.length, 12); const displaySegs = segments.slice(0, total); const pct = ((currentIdx + 1) / total) * 100; const stop = useCallback(() => { if (intervalRef.current) { clearInterval(intervalRef.current); intervalRef.current = null; } setPlaying(false); }, []); const play = useCallback(() => { stop(); setPlaying(true); intervalRef.current = setInterval(() => { onSeek(-1); // signal to advance }, 800 / speed); }, [speed, stop, onSeek]); const togglePlay = () => { if (playing) stop(); else play(); }; useEffect(() => { if (playing && intervalRef.current) { clearInterval(intervalRef.current); intervalRef.current = setInterval(() => { onSeek(-1); }, 800 / speed); } }, [speed, playing, onSeek]); useEffect(() => { return () => { if (intervalRef.current) clearInterval(intervalRef.current); }; }, []); const cycleSpeed = () => { const speeds = [1, 2, 4]; setSpeed((s) => speeds[(speeds.indexOf(s) + 1) % speeds.length]); }; const doneCount = segments.filter((s) => s.status === '완료').length; const progCount = segments.filter((s) => s.status === '진행중').length; const totalLen = segments.reduce((a, s) => a + s.lengthM, 0); return (
{/* Controls */}
{/* Progress */}
{displaySegs.map((s, i) => ( onSeek(i)} > {s.code} ))}
{/* Markers */} {displaySegs.map((s, i) => { const x = ((i + 0.5) / total) * 100; return (
{s.status === '완료' && ( )} {s.status === '진행중' && ( )}
); })}
{/* Thumb */}
{/* Info */}
구간 {displaySegs[currentIdx]?.code || 'S-001'} / {total}개
완료 {doneCount}/{segments.length} 진행중 {progCount}/{segments.length} 총 해안선 {(totalLen / 1000).toFixed(1)} km
); } export default ScatTimeline;