'use client'; import * as React from 'react'; import { Plus, ChevronDown, ChevronRight, Sparkles } from 'lucide-react'; import type { Track as TrackType } from '@/types/track'; import { Button } from '@/components/ui/Button'; import { cn } from '@/lib/utils/cn'; import { EffectDevice } from '@/components/effects/EffectDevice'; import { EffectBrowser } from '@/components/effects/EffectBrowser'; import type { EffectType } from '@/lib/audio/effects/chain'; export interface TrackExtensionsProps { track: TrackType; onUpdateTrack: (trackId: string, updates: Partial) => void; onToggleEffect?: (effectId: string) => void; onRemoveEffect?: (effectId: string) => void; onUpdateEffect?: (effectId: string, parameters: any) => void; onAddEffect?: (effectType: EffectType) => void; asOverlay?: boolean; // When true, renders as full overlay without header } export function TrackExtensions({ track, onUpdateTrack, onToggleEffect, onRemoveEffect, onUpdateEffect, onAddEffect, asOverlay = false, }: TrackExtensionsProps) { const [effectBrowserOpen, setEffectBrowserOpen] = React.useState(false); // Don't render if track is collapsed (unless it's an overlay, which handles its own visibility) if (!asOverlay && track.collapsed) { return null; } // Overlay mode: render full-screen effect rack if (asOverlay) { return ( <>
{/* Header with close button */}
Effects ({track.effectChain.effects.length})
{/* Effects rack */}
{track.effectChain.effects.length === 0 ? (

No effects yet

Click + to add an effect

) : ( track.effectChain.effects.map((effect) => ( onToggleEffect?.(effect.id)} onRemove={() => onRemoveEffect?.(effect.id)} onUpdateParameters={(params) => onUpdateEffect?.(effect.id, params)} onToggleExpanded={() => { const updatedEffects = track.effectChain.effects.map((e) => e.id === effect.id ? { ...e, expanded: !e.expanded } : e ); onUpdateTrack(track.id, { effectChain: { ...track.effectChain, effects: updatedEffects }, }); }} /> )) )}
{/* Effect Browser Dialog */} setEffectBrowserOpen(false)} onSelectEffect={(effectType) => { if (onAddEffect) { onAddEffect(effectType); } }} /> ); } // Original inline mode return ( <> {/* Effects Section (Collapsible, Full Width) */}
{/* Effects Header - clickable to toggle */}
{ onUpdateTrack(track.id, { showEffects: !track.showEffects, }); }} > {track.showEffects ? ( ) : ( )} {/* Show mini effect chain when collapsed */} {!track.showEffects && track.effectChain.effects.length > 0 ? (
{track.effectChain.effects.map((effect) => (
{effect.name}
))}
) : ( Devices ({track.effectChain.effects.length}) )}
{/* Horizontal scrolling device rack - expanded state */} {track.showEffects && (
{track.effectChain.effects.length === 0 ? (
No devices. Click + to add an effect.
) : ( track.effectChain.effects.map((effect) => ( onToggleEffect?.(effect.id)} onRemove={() => onRemoveEffect?.(effect.id)} onUpdateParameters={(params) => onUpdateEffect?.(effect.id, params)} onToggleExpanded={() => { const updatedEffects = track.effectChain.effects.map((e) => e.id === effect.id ? { ...e, expanded: !e.expanded } : e ); onUpdateTrack(track.id, { effectChain: { ...track.effectChain, effects: updatedEffects }, }); }} /> )) )}
)}
{/* Effect Browser Dialog */} setEffectBrowserOpen(false)} onSelectEffect={(effectType) => { if (onAddEffect) { onAddEffect(effectType); } }} /> ); }