Files
audio-ui/components/dialogs/ImportDialog.tsx

157 lines
5.5 KiB
TypeScript
Raw Normal View History

'use client';
import { useState } from 'react';
import { ImportOptions } from '@/lib/audio/decoder';
export interface ImportDialogProps {
open: boolean;
onClose: () => void;
onImport: (options: ImportOptions) => void;
fileName?: string;
sampleRate?: number;
channels?: number;
}
export function ImportDialog({
open,
onClose,
onImport,
fileName,
sampleRate: originalSampleRate,
channels: originalChannels,
}: ImportDialogProps) {
// Don't render if not open
if (!open) return null;
const [options, setOptions] = useState<ImportOptions>({
convertToMono: false,
targetSampleRate: undefined,
normalizeOnImport: false,
});
const handleImport = () => {
onImport(options);
};
const sampleRateOptions = [44100, 48000, 88200, 96000, 176400, 192000];
return (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
<div className="bg-white dark:bg-gray-800 rounded-lg p-6 w-full max-w-md shadow-xl">
<h2 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">
Import Audio File
</h2>
<div className="mb-4">
<div className="text-sm text-gray-600 dark:text-gray-400 mb-2">
<strong>File:</strong> {fileName}
</div>
{originalSampleRate && (
<div className="text-sm text-gray-600 dark:text-gray-400 mb-1">
<strong>Sample Rate:</strong> {originalSampleRate} Hz
</div>
)}
{originalChannels && (
<div className="text-sm text-gray-600 dark:text-gray-400 mb-3">
<strong>Channels:</strong> {originalChannels === 1 ? 'Mono' : originalChannels === 2 ? 'Stereo' : `${originalChannels} channels`}
</div>
)}
</div>
<div className="space-y-4">
{/* Convert to Mono */}
{originalChannels && originalChannels > 1 && (
<div>
<label className="flex items-center space-x-2">
<input
type="checkbox"
checked={options.convertToMono}
onChange={(e) => setOptions({ ...options, convertToMono: e.target.checked })}
className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
/>
<span className="text-sm text-gray-700 dark:text-gray-300">
Convert to Mono
</span>
</label>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1 ml-6">
Mix all channels equally into a single mono channel
</p>
</div>
)}
{/* Resample */}
<div>
<label className="flex items-center space-x-2 mb-2">
<input
type="checkbox"
checked={options.targetSampleRate !== undefined}
onChange={(e) => setOptions({
...options,
targetSampleRate: e.target.checked ? 48000 : undefined
})}
className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
/>
<span className="text-sm text-gray-700 dark:text-gray-300">
Resample Audio
</span>
</label>
{options.targetSampleRate !== undefined && (
<select
value={options.targetSampleRate}
onChange={(e) => setOptions({
...options,
targetSampleRate: parseInt(e.target.value)
})}
className="ml-6 w-full max-w-xs px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
>
{sampleRateOptions.map((rate) => (
<option key={rate} value={rate}>
{rate} Hz {rate === originalSampleRate ? '(original)' : ''}
</option>
))}
</select>
)}
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1 ml-6">
Convert to a different sample rate (may affect quality)
</p>
</div>
{/* Normalize */}
<div>
<label className="flex items-center space-x-2">
<input
type="checkbox"
checked={options.normalizeOnImport}
onChange={(e) => setOptions({ ...options, normalizeOnImport: e.target.checked })}
className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
/>
<span className="text-sm text-gray-700 dark:text-gray-300">
Normalize on Import
</span>
</label>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1 ml-6">
Adjust peak amplitude to 99% (1% headroom)
</p>
</div>
</div>
<div className="flex justify-end space-x-3 mt-6">
<button
onClick={onClose}
className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded transition-colors"
>
Cancel
</button>
<button
onClick={handleImport}
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded transition-colors"
>
Import
</button>
</div>
</div>
</div>
);
}