import { useState, useEffect, useRef } from 'react'; import OctopusLogo from './OctopusLogo'; function formatTime(s) { const m = Math.floor(s / 60); const sec = Math.floor(s % 60); return `${m}:${sec.toString().padStart(2, '0')}`; } export default function Controls({ isPlaying, togglePlayPause, tempo, setTempo, currentTimeRef, totalDuration, seekTo, fileName, onNewSong, loopStart, loopEnd, isLooping, onSetLoopA, onSetLoopB, onClearLoop, originalAudioOn, setOriginalAudioOn, originalVolume, setOriginalVolume, }) { const [displayTime, setDisplayTime] = useState(0); const intervalRef = useRef(null); useEffect(() => { intervalRef.current = setInterval(() => { setDisplayTime(currentTimeRef.current); }, 50); return () => clearInterval(intervalRef.current); }, [currentTimeRef]); const progress = totalDuration > 0 ? (displayTime / totalDuration) * 100 : 0; // Loop region markers for the timeline const loopStartPct = loopStart !== null && totalDuration > 0 ? (loopStart / totalDuration) * 100 : null; const loopEndPct = loopEnd !== null && totalDuration > 0 ? (loopEnd / totalDuration) * 100 : null; // Build timeline background with loop region let timelineBg; if (loopStartPct !== null && loopEndPct !== null) { timelineBg = `linear-gradient(to right, var(--border) ${loopStartPct}%, rgba(139, 92, 246, 0.3) ${loopStartPct}%, var(--primary) ${Math.min(progress, loopEndPct)}%, rgba(139, 92, 246, 0.3) ${Math.min(progress, loopEndPct)}%, rgba(139, 92, 246, 0.3) ${loopEndPct}%, var(--border) ${loopEndPct}%)`; } else { timelineBg = `linear-gradient(to right, var(--primary) ${progress}%, var(--border) ${progress}%)`; } return (
{/* Main controls row */}
Mr. Octopus
{fileName && ( {fileName.replace(/\.[^.]+$/, '')} )}
{/* Loop controls */}
{isLooping ? ( <> Looping {formatTime(loopStart)} — {formatTime(loopEnd)} ) : loopStart !== null ? ( <> Start: {formatTime(loopStart)} ) : ( )}
{/* Original audio toggle + volume */} {setOriginalAudioOn && (
{originalAudioOn && ( setOriginalVolume(Number(e.target.value))} title={`Original volume: ${originalVolume}%`} /> )}
)}
Speed setTempo(Number(e.target.value))} /> {tempo}%
{onNewSong && ( )}
{/* Timeline row */}
{formatTime(displayTime)}
seekTo(Number(e.target.value))} style={{ background: timelineBg }} />
{formatTime(totalDuration)}
); }