feat: add multi-track audio import functionality
Implemented comprehensive multi-file audio import system: - Created ImportTrackDialog component with drag-and-drop and file browser support - Updated TrackList to integrate import functionality with dedicated buttons - Added multi-track-demo page to test and demonstrate import features - Sequential file processing with automatic track naming from filenames - Error handling for non-audio files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
127
app/multi-track-demo/page.tsx
Normal file
127
app/multi-track-demo/page.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import { TrackList } from '@/components/tracks/TrackList';
|
||||
import { useMultiTrack } from '@/lib/hooks/useMultiTrack';
|
||||
import { useMultiTrackPlayer } from '@/lib/hooks/useMultiTrackPlayer';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { Play, Pause, Square, SkipBack } from 'lucide-react';
|
||||
import { formatDuration } from '@/lib/audio/decoder';
|
||||
|
||||
export default function MultiTrackDemoPage() {
|
||||
const {
|
||||
tracks,
|
||||
addTrack,
|
||||
addTrackFromBuffer,
|
||||
removeTrack,
|
||||
updateTrack,
|
||||
clearTracks,
|
||||
} = useMultiTrack();
|
||||
|
||||
const {
|
||||
isPlaying,
|
||||
currentTime,
|
||||
duration,
|
||||
play,
|
||||
pause,
|
||||
stop,
|
||||
seek,
|
||||
togglePlayPause,
|
||||
} = useMultiTrackPlayer(tracks);
|
||||
|
||||
const [zoom, setZoom] = React.useState(1);
|
||||
|
||||
return (
|
||||
<div className="h-screen flex flex-col bg-background">
|
||||
{/* Header */}
|
||||
<div className="h-14 border-b border-border bg-card flex items-center justify-between px-4">
|
||||
<h1 className="text-lg font-semibold">Multi-Track Demo</h1>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={clearTracks}
|
||||
disabled={tracks.length === 0}
|
||||
>
|
||||
Clear All Tracks
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setZoom((z) => Math.max(0.5, z - 0.5))}
|
||||
>
|
||||
Zoom Out
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setZoom((z) => Math.min(10, z + 0.5))}
|
||||
>
|
||||
Zoom In
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Track List */}
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<TrackList
|
||||
tracks={tracks}
|
||||
zoom={zoom}
|
||||
currentTime={currentTime}
|
||||
duration={duration}
|
||||
onAddTrack={() => addTrack()}
|
||||
onImportTrack={(buffer, name) => addTrackFromBuffer(buffer, name)}
|
||||
onRemoveTrack={removeTrack}
|
||||
onUpdateTrack={updateTrack}
|
||||
onSeek={seek}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Playback Controls */}
|
||||
<div className="h-16 border-t border-border bg-card flex items-center justify-between px-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={stop}
|
||||
disabled={!duration}
|
||||
title="Stop"
|
||||
>
|
||||
<Square className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={togglePlayPause}
|
||||
disabled={!duration}
|
||||
title={isPlaying ? 'Pause' : 'Play'}
|
||||
>
|
||||
{isPlaying ? (
|
||||
<Pause className="h-4 w-4" />
|
||||
) : (
|
||||
<Play className="h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => seek(0)}
|
||||
disabled={!duration}
|
||||
title="Skip to Start"
|
||||
>
|
||||
<SkipBack className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-sm font-mono">
|
||||
{formatDuration(currentTime)} / {formatDuration(duration)}
|
||||
</span>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{tracks.length} {tracks.length === 1 ? 'track' : 'tracks'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user