diff --git a/packages/frontend/component/src/ui/audio-player/audio-waveform.tsx b/packages/frontend/component/src/ui/audio-player/audio-waveform.tsx index b5a3bea63..f7ad63ba1 100644 --- a/packages/frontend/component/src/ui/audio-player/audio-waveform.tsx +++ b/packages/frontend/component/src/ui/audio-player/audio-waveform.tsx @@ -124,24 +124,56 @@ export const AudioWaveform = ({ }) => { const containerRef = useRef(null); const canvasRef = useRef(null); + const isDraggingRef = useRef(false); - // Handle click events for seeking - const handleClick = useCallback( - (e: React.MouseEvent) => { - if (!containerRef.current) return; - const rect = containerRef.current.getBoundingClientRect(); - const x = e.clientX - rect.left; - const availableWidth = rect.width - horizontalPadding * 2; - const newProgress = Math.max( - 0, - Math.min(1, (x - horizontalPadding) / availableWidth) - ); + // Calculate progress from pointer position + const calculateProgress = useCallback((clientX: number) => { + if (!containerRef.current) return 0; + const rect = containerRef.current.getBoundingClientRect(); + const x = clientX - rect.left; + const availableWidth = rect.width - horizontalPadding * 2; + return clamp((x - horizontalPadding) / availableWidth, 0, 1); + }, []); + + // Handle pointer events for seeking + const handlePointerDown = useCallback( + (e: React.PointerEvent) => { + const newProgress = calculateProgress(e.clientX); onManualSeek(newProgress); + isDraggingRef.current = true; + e.preventDefault(); + }, + [calculateProgress, onManualSeek] + ); + + const stopPropagation = useCallback( + (e: React.PointerEvent) => { e.stopPropagation(); }, - [onManualSeek] + [] ); + // Add and remove global event listeners + useEffect(() => { + const handlePointerMove = (e: PointerEvent) => { + if (!isDraggingRef.current) return; + const newProgress = calculateProgress(e.clientX); + onManualSeek(newProgress); + e.preventDefault(); + }; + + const handlePointerUp = () => { + isDraggingRef.current = false; + }; + + window.addEventListener('pointermove', handlePointerMove); + window.addEventListener('pointerup', handlePointerUp); + return () => { + window.removeEventListener('pointermove', handlePointerMove); + window.removeEventListener('pointerup', handlePointerUp); + }; + }, [calculateProgress, onManualSeek]); + // Draw on resize useEffect(() => { const draw = () => { @@ -173,11 +205,13 @@ export const AudioWaveform = ({
{loading ? (