From d2ec0119ceb28903f74db15fd4d2d7bfd263f492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=B6rdle=20Bot?= Date: Fri, 5 Dec 2025 21:47:57 +0100 Subject: [PATCH] Fix waveform editor: show end marker for last segment and fix play full section stop functionality --- components/WaveformEditor.tsx | 70 ++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/components/WaveformEditor.tsx b/components/WaveformEditor.tsx index 469b0a5..b85297b 100644 --- a/components/WaveformEditor.tsx +++ b/components/WaveformEditor.tsx @@ -133,6 +133,24 @@ export default function WaveformEditor({ audioUrl, startTime, duration, unlockSt cumulativeTime = step; }); + + // Draw end marker for the last segment (at startTime + duration) + const endTime = startTime + duration; + const endPx = ((endTime - visibleStart) / visibleDuration) * width; + if (endPx >= 0 && endPx <= width) { + ctx.beginPath(); + ctx.moveTo(endPx, 0); + ctx.lineTo(endPx, height); + ctx.stroke(); + + // Draw "End" label + ctx.setLineDash([]); + ctx.fillStyle = '#ef4444'; + ctx.font = 'bold 12px sans-serif'; + ctx.fillText('End', endPx + 3, 15); + ctx.setLineDash([5, 5]); + } + ctx.setLineDash([]); // Draw hover preview (semi-transparent) @@ -287,30 +305,38 @@ export default function WaveformEditor({ audioUrl, startTime, duration, unlockSt const handlePlayFull = () => { if (!audioBuffer || !audioContextRef.current) return; - if (isPlaying) { + // If full playback is already playing, stop it + if (isPlaying && playingSegment === null) { stopPlayback(); - } else { - const source = audioContextRef.current.createBufferSource(); - source.buffer = audioBuffer; - source.connect(audioContextRef.current.destination); - - playbackStartTimeRef.current = audioContextRef.current.currentTime; - playbackOffsetRef.current = startTime; - - source.start(0, startTime, duration); - sourceRef.current = source; - setIsPlaying(true); - setPlaybackPosition(startTime); - - source.onended = () => { - setIsPlaying(false); - setPlaybackPosition(null); - if (animationFrameRef.current) { - cancelAnimationFrame(animationFrameRef.current); - animationFrameRef.current = null; - } - }; + return; } + + // Stop any current playback (segment or full) + stopPlayback(); + + // Start full playback + const source = audioContextRef.current.createBufferSource(); + source.buffer = audioBuffer; + source.connect(audioContextRef.current.destination); + + playbackStartTimeRef.current = audioContextRef.current.currentTime; + playbackOffsetRef.current = startTime; + + source.start(0, startTime, duration); + sourceRef.current = source; + setIsPlaying(true); + setPlayingSegment(null); // Ensure playingSegment is null for full playback + setPlaybackPosition(startTime); + + source.onended = () => { + setIsPlaying(false); + setPlayingSegment(null); + setPlaybackPosition(null); + if (animationFrameRef.current) { + cancelAnimationFrame(animationFrameRef.current); + animationFrameRef.current = null; + } + }; }; const handleZoomIn = () => setZoom(prev => Math.min(prev * 1.5, 10));