feat: add format presets for common conversion scenarios

Format presets included:
**Video Presets:**
- YouTube Video (1080p, H.264, optimized)
- Instagram Video (Square format, 1:1)
- Twitter Video (720p, small file)
- Web Optimized (Streaming, low bitrate)

**Audio Presets:**
- Podcast (MP3, voice optimized, 128k)
- High Quality Music (MP3, 320k)
- Audiobook (Mono, 64k, small size)

**Image Presets:**
- Web Thumbnail (JPG, 800px width)
- HD Image (PNG, lossless, high quality)
- Social Media (JPG, 1200px, optimized)
- Web Optimized (WebP, small size)

Implementation:
- Created formatPresets.ts with 11 predefined presets
- FormatPresets component with responsive grid layout
- One-click preset application
- Automatically configures format and options
- Toast notification on preset selection
- Visual feedback with ring highlight
- Organized by category (video/audio/image)
- Emoji icons for visual appeal

User experience:
- Quick access to common conversion scenarios
- No need to manually configure complex settings
- Preset descriptions explain use case
- Disabled during active conversion
- Clear visual indication of selected preset

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-17 13:30:35 +01:00
parent ba2e011f4a
commit 6b0bda05db
3 changed files with 277 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ import { FormatSelector } from './FormatSelector';
import { ConversionPreview } from './ConversionPreview';
import { ConversionOptionsPanel } from './ConversionOptions';
import { FileInfo } from './FileInfo';
import { FormatPresets } from './FormatPresets';
import { useToast } from '@/components/ui/Toast';
import {
SUPPORTED_FORMATS,
@@ -20,6 +21,7 @@ import { convertWithFFmpeg } from '@/lib/converters/ffmpegService';
import { convertWithImageMagick } from '@/lib/converters/imagemagickService';
import { addToHistory } from '@/lib/storage/history';
import { downloadBlobsAsZip, generateOutputFilename } from '@/lib/utils/fileUtils';
import { getPresetById, type FormatPreset } from '@/lib/utils/formatPresets';
import type { ConversionJob, ConversionFormat, ConversionOptions } from '@/types/conversion';
export function FileConverter() {
@@ -209,6 +211,17 @@ export function FileConverter() {
setSelectedFiles((prev) => prev.filter((_, i) => i !== index));
};
const handlePresetSelect = (preset: FormatPreset) => {
// Find the output format that matches the preset
const format = compatibleFormats.find(f => f.extension === preset.outputFormat);
if (format) {
setOutputFormat(format);
setConversionOptions(preset.options);
addToast(`Applied ${preset.name} preset`, 'success');
}
};
const handleDownloadAll = async () => {
if (!outputFormat) return;
@@ -375,6 +388,15 @@ export function FileConverter() {
<FileInfo file={selectedFiles[0]} format={inputFormat} />
)}
{/* Format Presets */}
{inputFormat && (
<FormatPresets
inputFormat={inputFormat}
onPresetSelect={handlePresetSelect}
disabled={isConverting}
/>
)}
{/* Format selection */}
{inputFormat && compatibleFormats.length > 0 && (
<div className="grid grid-cols-1 md:grid-cols-[1fr_auto_1fr] gap-4 items-start">