'use client'; import * as React from 'react'; import { Plus, Upload } from 'lucide-react'; import { Button } from '@/components/ui/Button'; import { Track } from './Track'; import { ImportTrackDialog } from './ImportTrackDialog'; import type { Track as TrackType } from '@/types/track'; import { createEffect, type EffectType, EFFECT_NAMES } from '@/lib/audio/effects/chain'; export interface TrackListProps { tracks: TrackType[]; zoom: number; currentTime: number; duration: number; selectedTrackId?: string | null; onSelectTrack?: (trackId: string | null) => void; onAddTrack: () => void; onImportTrack?: (buffer: AudioBuffer, name: string) => void; onRemoveTrack: (trackId: string) => void; onUpdateTrack: (trackId: string, updates: Partial) => void; onSeek?: (time: number) => void; onSelectionChange?: (trackId: string, selection: { start: number; end: number } | null) => void; onToggleRecordEnable?: (trackId: string) => void; recordingTrackId?: string | null; recordingLevel?: number; trackLevels?: Record; onParameterTouched?: (trackId: string, laneId: string, touched: boolean) => void; isPlaying?: boolean; } export function TrackList({ tracks, zoom, currentTime, duration, selectedTrackId, onSelectTrack, onAddTrack, onImportTrack, onRemoveTrack, onUpdateTrack, onSeek, onSelectionChange, onToggleRecordEnable, recordingTrackId, recordingLevel = 0, trackLevels = {}, onParameterTouched, isPlaying = false, }: TrackListProps) { const [importDialogOpen, setImportDialogOpen] = React.useState(false); const handleImportTrack = (buffer: AudioBuffer, name: string) => { if (onImportTrack) { onImportTrack(buffer, name); } }; if (tracks.length === 0) { return ( <>

No tracks yet. Add a track to get started.

{onImportTrack && ( )}
{onImportTrack && ( setImportDialogOpen(false)} onImportTrack={handleImportTrack} /> )} ); } return (
{/* Track List */}
{tracks.map((track) => ( onSelectTrack(track.id) : undefined} onToggleMute={() => onUpdateTrack(track.id, { mute: !track.mute }) } onToggleSolo={() => onUpdateTrack(track.id, { solo: !track.solo }) } onToggleCollapse={() => onUpdateTrack(track.id, { collapsed: !track.collapsed }) } onVolumeChange={(volume) => onUpdateTrack(track.id, { volume }) } onPanChange={(pan) => onUpdateTrack(track.id, { pan }) } onRemove={() => onRemoveTrack(track.id)} onNameChange={(name) => onUpdateTrack(track.id, { name }) } onUpdateTrack={onUpdateTrack} onSeek={onSeek} onLoadAudio={(buffer) => onUpdateTrack(track.id, { audioBuffer: buffer }) } onToggleEffect={(effectId) => { const updatedChain = { ...track.effectChain, effects: track.effectChain.effects.map((e) => e.id === effectId ? { ...e, enabled: !e.enabled } : e ), }; onUpdateTrack(track.id, { effectChain: updatedChain }); }} onRemoveEffect={(effectId) => { const updatedChain = { ...track.effectChain, effects: track.effectChain.effects.filter((e) => e.id !== effectId), }; onUpdateTrack(track.id, { effectChain: updatedChain }); }} onUpdateEffect={(effectId, parameters) => { const updatedChain = { ...track.effectChain, effects: track.effectChain.effects.map((e) => e.id === effectId ? { ...e, parameters } : e ), }; onUpdateTrack(track.id, { effectChain: updatedChain }); }} onAddEffect={(effectType) => { const newEffect = createEffect( effectType, EFFECT_NAMES[effectType] ); const updatedChain = { ...track.effectChain, effects: [...track.effectChain.effects, newEffect], }; onUpdateTrack(track.id, { effectChain: updatedChain }); }} onSelectionChange={ onSelectionChange ? (selection) => onSelectionChange(track.id, selection) : undefined } onToggleRecordEnable={ onToggleRecordEnable ? () => onToggleRecordEnable(track.id) : undefined } isRecording={recordingTrackId === track.id} recordingLevel={recordingTrackId === track.id ? recordingLevel : 0} playbackLevel={trackLevels[track.id] || 0} onParameterTouched={onParameterTouched} isPlaying={isPlaying} /> ))}
{/* Import Dialog */} {onImportTrack && ( setImportDialogOpen(false)} onImportTrack={handleImportTrack} /> )}
); }