'use client'; import { useCallback, useRef, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Repeat } from 'lucide-react'; import { cn } from '@/lib/utils'; import { LoopRegion } from '@/types/audio'; interface LoopBracketProps { region: LoopRegion; durationBars: number; pixelsPerBar: number; onChange: (region: LoopRegion) => void; className?: string; } export function LoopBracket({ region, durationBars, pixelsPerBar, onChange, className, }: LoopBracketProps) { const containerRef = useRef(null); const [dragging, setDragging] = useState<'start' | 'end' | 'region' | null>(null); const dragStart = useRef({ x: 0, region: { ...region } }); const left = region.start * pixelsPerBar; const width = (region.end - region.start) * pixelsPerBar; const handleMouseDown = useCallback( (type: 'start' | 'end' | 'region', e: React.MouseEvent) => { e.preventDefault(); setDragging(type); dragStart.current = { x: e.clientX, region: { ...region } }; const handleMouseMove = (e: MouseEvent) => { if (!containerRef.current) return; const deltaX = e.clientX - dragStart.current.x; const deltaBars = Math.round(deltaX / pixelsPerBar); const { start, end, enabled } = dragStart.current.region; let newStart = start; let newEnd = end; if (type === 'start') { newStart = Math.max(0, Math.min(end - 1, start + deltaBars)); } else if (type === 'end') { newEnd = Math.max(start + 1, Math.min(durationBars, end + deltaBars)); } else if (type === 'region') { const duration = end - start; newStart = Math.max(0, Math.min(durationBars - duration, start + deltaBars)); newEnd = newStart + duration; } onChange({ start: newStart, end: newEnd, enabled }); }; const handleMouseUp = () => { setDragging(null); document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); }; document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); }, [region, pixelsPerBar, durationBars, onChange] ); const toggleEnabled = useCallback(() => { onChange({ ...region, enabled: !region.enabled }); }, [region, onChange]); return (
handleMouseDown('start', e)} />
handleMouseDown('region', e)} />
handleMouseDown('end', e)} />
); }