feat: add export scope options (project/selection/tracks)

Implemented Phase 11.3 - Export Regions:
- Added export scope selector in ExportDialog
  - Entire Project: Mix all tracks into single file
  - Selected Region: Export only the selected region (disabled if no selection)
  - Individual Tracks: Export each track as separate file
- Updated ExportSettings interface with scope property
- Refactored handleExport to support all three export modes:
  - Project mode: Mix all tracks (existing behavior)
  - Selection mode: Extract selection from all tracks and mix
  - Tracks mode: Loop through tracks and export separately with sanitized filenames
- Added hasSelection prop to ExportDialog to enable/disable selection option
- Created helper function convertAndDownload to reduce code duplication
- Selection mode uses extractBufferSegment for precise region extraction
- Track names are sanitized for filenames (remove special characters)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-19 07:47:56 +01:00
parent c6ff313050
commit 38a2b2962d
2 changed files with 126 additions and 42 deletions

View File

@@ -7,6 +7,7 @@ import { cn } from '@/lib/utils/cn';
export interface ExportSettings {
format: 'wav' | 'mp3' | 'flac';
scope: 'project' | 'selection' | 'tracks'; // Export scope
bitDepth: 16 | 24 | 32;
bitrate: number; // For MP3: 128, 192, 256, 320 kbps
quality: number; // For FLAC: 0-9
@@ -19,11 +20,13 @@ export interface ExportDialogProps {
onClose: () => void;
onExport: (settings: ExportSettings) => void;
isExporting?: boolean;
hasSelection?: boolean; // Whether any track has a selection
}
export function ExportDialog({ open, onClose, onExport, isExporting }: ExportDialogProps) {
export function ExportDialog({ open, onClose, onExport, isExporting, hasSelection }: ExportDialogProps) {
const [settings, setSettings] = React.useState<ExportSettings>({
format: 'wav',
scope: 'project',
bitDepth: 16,
bitrate: 192, // Default MP3 bitrate
quality: 6, // Default FLAC quality
@@ -88,6 +91,30 @@ export function ExportDialog({ open, onClose, onExport, isExporting }: ExportDia
</select>
</div>
{/* Export Scope */}
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Export Scope
</label>
<select
value={settings.scope}
onChange={(e) => setSettings({ ...settings, scope: e.target.value as 'project' | 'selection' | 'tracks' })}
className="w-full px-3 py-2 bg-background border border-border rounded text-foreground focus:outline-none focus:ring-2 focus:ring-primary"
disabled={isExporting}
>
<option value="project">Entire Project (Mix All Tracks)</option>
<option value="selection" disabled={!hasSelection}>
Selected Region {!hasSelection && '(No selection)'}
</option>
<option value="tracks">Individual Tracks (Separate Files)</option>
</select>
<p className="text-xs text-muted-foreground mt-1">
{settings.scope === 'project' && 'Mix all tracks into a single file'}
{settings.scope === 'selection' && 'Export only the selected region'}
{settings.scope === 'tracks' && 'Export each track as a separate file'}
</p>
</div>
{/* Bit Depth (WAV and FLAC only) */}
{(settings.format === 'wav' || settings.format === 'flac') && (
<div>