From b0755b9063a60e0c8cded00fb4fa2777f6179f5d Mon Sep 17 00:00:00 2001 From: Kagamine Rin Date: Fri, 29 May 2026 20:35:00 -0400 Subject: [PATCH] feat: Add repeat button and fix skip-to-beginning icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Player.tsx updates: - Repeat button: ISO repeat indefinitely icon with glowing toggle state. When active: lyria-accent color, bg-lyria-accent/10, orange glow shadow. When inactive: muted gray, hover to white. Toggles audio.loop. - Skip to beginning: Now uses ISO skip-backwards icon (filled, two bars pointing left) instead of circular arrow. Title: 'Skip to beginning'. - Track end handler respects repeat state — if repeating, stays playing and loops; if not, pauses as before. - New state: isRepeating (useState), toggleRepeat function sets both React state and audioRef.current.loop. --- .../3f776e71-0c9c-44b5-bc9f-a796ec3159ef.svg | 203 ++++++++++++++++++ frontend/src/components/Player.tsx | 37 +++- 2 files changed, 236 insertions(+), 4 deletions(-) create mode 100644 data/waveforms/3f776e71-0c9c-44b5-bc9f-a796ec3159ef.svg diff --git a/data/waveforms/3f776e71-0c9c-44b5-bc9f-a796ec3159ef.svg b/data/waveforms/3f776e71-0c9c-44b5-bc9f-a796ec3159ef.svg new file mode 100644 index 0000000..e588d9e --- /dev/null +++ b/data/waveforms/3f776e71-0c9c-44b5-bc9f-a796ec3159ef.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/src/components/Player.tsx b/frontend/src/components/Player.tsx index 8e36f6e..07f20e2 100644 --- a/frontend/src/components/Player.tsx +++ b/frontend/src/components/Player.tsx @@ -28,6 +28,7 @@ export default function Player({ clip, isPlaying, onTogglePlay, onStop, onClose const [volume, setVolume] = useState(1) const [isMuted, setIsMuted] = useState(false) const [isDragging, setIsDragging] = useState(false) + const [isRepeating, setIsRepeating] = useState(false) const progressRef = useRef(null) // Sync play/pause with audio element @@ -59,10 +60,23 @@ export default function Player({ clip, isPlaying, onTogglePlay, onStop, onClose // Track ended const handleEnded = () => { - onTogglePlay() + if (!isRepeating) { + onTogglePlay() + } setCurrentTime(0) } + // Toggle repeat + const toggleRepeat = () => { + setIsRepeating(prev => { + const next = !prev + if (audioRef.current) { + audioRef.current.loop = next + } + return next + }) + } + // Seek to position const handleSeek = useCallback((clientX: number) => { if (!progressRef.current || !audioRef.current) return @@ -181,13 +195,28 @@ export default function Player({ clip, isPlaying, onTogglePlay, onStop, onClose - {/* Restart */} + {/* Restart — ISO skip backwards to beginning */} + + {/* Repeat — ISO repeat indefinitely with glowing toggle */} +