27 Commits

Author SHA1 Message Date
e34456020c feat: align conversion history width with upload container
Added max-w-4xl container constraint to ConversionHistory component to match
the FileConverter component width, creating a more consistent and aligned layout.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 14:12:30 +01:00
a7a46a8ebc fix: correct success/failure toast message for batch conversions
Fixed bug where conversion success toast was always showing "all conversions failed"
even when conversions succeeded. The issue was that the completion message was checking
the local jobs array (which still had status: 'pending') instead of tracking actual
conversion results.

Now using local successCount and failureCount variables that are incremented during
the conversion loop to accurately reflect conversion outcomes.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 14:07:53 +01:00
8110992aca feat: add comprehensive user settings system
Settings features:
**Quality Preferences:**
- Default quality preset (High Quality, Balanced, Small File, Web Optimized)

**Behavior Preferences:**
- Auto-start conversion when files are selected
- Show/hide conversion history
- Clear history on reset

**Default Output Formats:**
- Set default format for video conversions (MP4, WebM, AVI, MOV)
- Set default format for audio conversions (MP3, WAV, OGG, AAC)
- Set default format for image conversions (WebP, PNG, JPG, GIF)

Implementation:
- Created settings storage system with localStorage
- SettingsModal component with categorized settings
- Settings button in app header
- Real-time settings updates across components
- Custom event system for settings synchronization
- Reset to defaults functionality
- Professional UI with checkboxes and selects

User experience:
- Settings persist across sessions
- Changes apply immediately
- Clear categorization (Quality, Behavior, Formats)
- Easy reset to defaults with confirmation
- Conditional history display based on settings
- Clean modal interface

Technical features:
- Type-safe settings interface
- Event-driven updates
- Graceful fallback to defaults
- Error handling for localStorage
- Platform-aware functionality

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 13:36:48 +01:00
3f4fcf39bc feat: add comprehensive keyboard shortcuts system
Keyboard shortcuts:
- **Ctrl/Cmd + O**: Open file dialog
- **Ctrl/Cmd + Enter**: Start conversion
- **Ctrl/Cmd + S**: Download results (ZIP if multiple)
- **Ctrl/Cmd + R**: Reset converter
- **Ctrl/Cmd + /**: Show keyboard shortcuts help
- **?**: Show keyboard shortcuts help
- **Escape**: Close shortcuts modal

Implementation:
- Created useKeyboardShortcuts custom hook
- Platform-aware keyboard handling (Cmd on Mac, Ctrl elsewhere)
- KeyboardShortcutsModal component with beautiful UI
- Floating keyboard icon button (bottom-right)
- Visual shortcut display with kbd tags
- Context-aware shortcut execution (respects disabled states)
- Prevents default browser behavior for shortcuts

User experience:
- Floating help button always accessible
- Clean modal with shortcut descriptions
- Platform-specific key symbols (⌘ on Mac)
- Shortcuts disabled when modal is open
- Clear visual feedback for shortcuts
- Non-intrusive button placement

Features:
- Smart ref forwarding to FileUpload component
- Conditional shortcut execution based on app state
- Professional kbd styling for key combinations
- Responsive modal with backdrop
- Smooth animations

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 13:34:11 +01:00
6b0bda05db 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>
2025-11-17 13:30:35 +01:00
ba2e011f4a feat: add error recovery with retry functionality
Error recovery features:
- **Retry button**: Appears on failed conversions
- **Smart retry logic**: Re-attempts conversion with same settings
- **State management**: Properly resets job state before retry
- **Progress tracking**: Shows progress during retry attempt
- **Toast notifications**: Informs user of retry success/failure
- **History updates**: Successful retries added to history
- **Visual feedback**: RefreshCw icon with clear button label

Implementation:
- Added onRetry prop to ConversionPreview component
- Implemented handleRetry function in FileConverter
- Reuses existing conversion logic for consistency
- Maintains all conversion options during retry
- Updates job status through proper state flow:
  error → loading → processing → completed/error

User experience:
- One-click retry for failed conversions
- No need to re-upload file or reconfigure settings
- Clear visual indication when retry is in progress
- Helpful error messages if retry also fails

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 13:22:44 +01:00
649cd3cd7b feat: enhance mobile responsiveness across all components
Mobile optimizations:
- **Header**: Reduced padding on mobile (px-3), smaller text sizes
- **Main content**: Optimized padding (px-3 sm:px-4) and spacing
- **Format selector**: Added downward arrow for mobile flow
- **Conversion progress**: Time indicators stack vertically on mobile
- **Page layout**: Responsive spacing throughout (space-y-6 sm:space-y-8)
- **Footer**: Smaller text and reduced margins on mobile

Key improvements:
- Better use of screen space on small devices
- Improved touch targets and readability
- Consistent responsive breakpoints (sm:, md:)
- Vertical arrow (↓) on mobile, horizontal (→) on desktop
- All text scales appropriately for mobile screens

Tested on:
- Mobile viewport (< 640px)
- Tablet viewport (640px - 768px)
- Desktop viewport (> 768px)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 13:20:39 +01:00
cbaa4361cd feat: add conversion history view with real-time updates
Features:
- Created ConversionHistory component showing recent conversions
- Displays input/output formats, file sizes, and timestamps
- Relative time display (e.g., "5 minutes ago", "2 hours ago")
- Clear all history functionality with confirmation
- Individual history item removal
- Real-time updates when new conversions complete
- Custom event system for same-page updates
- Storage event listener for cross-tab synchronization
- Empty state with helpful messaging
- Clean, organized card-based layout
- Responsive design with proper spacing

Technical improvements:
- Enhanced history storage to dispatch custom events
- History component auto-refreshes on new conversions
- Maintains up to 10 most recent conversions
- Integrated seamlessly into main page layout

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 13:18:02 +01:00
67a1c47396 feat: add batch conversion support with multi-file upload and ZIP download
Major improvements:
- Updated FileUpload component to support multiple file selection
  - Added drag-and-drop for multiple files
  - Individual file removal
  - "Add More Files" button when files are selected
- Modified FileConverter to handle batch conversions
  - Sequential conversion of multiple files
  - Progress tracking for each file individually
  - All files share same output format and settings
- Added batch download functionality
  - Single file: direct download
  - Multiple files: ZIP archive download
  - Uses jszip library for ZIP creation
- Enhanced UI/UX
  - Show count of selected files in convert button
  - Display all conversion jobs with individual previews
  - "Download All" button for completed conversions
  - Conversion status messages show success/failure counts

Dependencies added:
- jszip@3.10.1 for ZIP file creation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 13:13:52 +01:00
a43a336965 fix: pass format as first argument to image.write()
The correct ImageMagick WASM API is:
image.write(format, callback)

Where the format is passed as the first argument and the callback
receives the encoded data. This should produce valid WebP with
correct RIFF headers.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:49:41 +01:00
7a15a15e50 fix: set image format before calling write() in ImageMagick
The correct API pattern is:
1. Set image.format = outputFormatEnum first
2. Then call image.write(callback) with the format already set

This ensures the image is written in the correct format with proper
headers (RIFF for WebP, etc.)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:46:08 +01:00
58206d5b18 fix: use correct ImageMagick write API to produce valid output format
Changed from image.write((data) => data) callback pattern to
image.write(outputFormatEnum) which correctly writes the image data
in the specified format. This should now produce valid WebP files
with proper RIFF headers (52 19 46 46 magic bytes).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:37:13 +01:00
b9f9a7bea6 fix: correct ImageMagick write API to produce valid WebP data
The previous implementation was producing invalid image data with
wrong magic bytes (d0 e5 67 00 instead of 52 49 46 46 for WebP).

Root cause: Incorrect usage of ImageMagick write API.

Changes:
- Set image.format BEFORE writing (tells ImageMagick the output format)
- Simplified write() call to: image.write((data) => data)
- This returns the correctly formatted image data

The proper pattern is:
1. Set image.format = outputFormatEnum
2. Apply transformations (quality, resize)
3. Call image.write() which returns the encoded data

This should now produce valid WebP files with correct RIFF header
(52 49 46 46) and allow the preview to display properly.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:25:31 +01:00
00c0522b85 debug: verify WebP blob data integrity and URL lifecycle 2025-11-17 12:19:25 +01:00
edbb5d1388 debug: add comprehensive logging for image preview issue
Added detailed logging at every step of the image conversion and preview:

ImageMagick Service:
- Log input and output sizes
- Log applied quality settings
- Verify result is not empty before creating blob
- Log created blob size and MIME type
- Fail early if conversion produces empty result

Preview Component:
- Log blob details (size, type, URL)
- Add onError handler to img tag with detailed error info
- Add onLoad handler to confirm successful loading
- Console logs will help identify:
  - Is the blob empty?
  - Is the MIME type correct?
  - Is the object URL valid?
  - What error occurs when loading?

TypeScript Fix:
- Changed result type to `Uint8Array | undefined`
- Allows proper checking before blob creation

This will help diagnose why the preview image appears broken
despite successful conversion.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:16:37 +01:00
4e6c68a855 debug: add detailed WASM loading diagnostics for ImageMagick
Added comprehensive logging to diagnose the WASM loading issue:
- Log the WASM URL being fetched
- Log fetch response (status, content-type, content-length)
- Log actual WASM file size after fetching
- Verify the buffer is not empty before initialization
- Pass ArrayBuffer directly to initializeImageMagick
- Better error messages with context

This will help identify why the WASM file appears empty:
- Is the fetch failing? (wrong path, 404, CORS)
- Is the response empty? (server issue)
- Is the content-type wrong? (misconfigured server)

The logs will appear in the browser console when converting images.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:13:01 +01:00
63cb9bcff5 fix: properly initialize ImageMagick WASM by serving from public directory
The previous approach tried to load the WASM file from a CDN or node_modules,
which resulted in an empty buffer error. This fix copies the WASM file to the
public directory so it can be served alongside the static export.

Changes:
- Copy magick.wasm (16MB) to public/wasm/ directory
- Update wasmLoader.ts to initialize with '/wasm/magick.wasm' URL
- Initialize ImageMagick only once in loadImageMagick()
- Remove redundant initialization from imagemagickService.ts
- WASM file is now served from static assets in production

This ensures:
- WASM file is accessible at runtime
- Proper initialization before image conversions
- No "empty buffer" compilation errors
- Works in both dev and production (static export)

The 16MB WASM file includes the full ImageMagick library with all
image format support and processing capabilities.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:09:49 +01:00
9eb66b4fa3 fix: add proper ImageMagick WASM initialization with CDN URL
The initializeImageMagick() function requires a URL argument pointing
to the WASM file. Without it, the library won't properly load and
conversions may fail.

Changes:
- Add initializeImageMagick() call with CDN URL
- Use jsDelivr CDN for magick.wasm file
- Matches the installed package version (0.0.30)

This ensures ImageMagick WASM is properly initialized before performing
image conversions, preventing potential runtime errors.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:02:05 +01:00
78394b7e97 fix: implement actual ImageMagick WASM conversion with quality settings
Previously, the ImageMagick service was just a placeholder that returned
the input data unchanged. This caused PNG to WebP conversions to have
the same file size.

Changes:
- Properly implement ImageMagick.read() with conversion logic
- Apply imageQuality option to control compression
- Apply imageWidth/imageHeight options with aspect ratio preservation
- Use correct MagickFormat enum values for output formats
- Fix write() method signature (format comes before callback)
- Remove unnecessary initializeImageMagick() call

Image conversion now properly applies:
- Quality settings (1-100%)
- Resolution/resize options
- Format-specific compression

This fixes the issue where quality settings had no effect on output
file size. Users will now see proper file size reduction when using
lower quality settings or converting to compressed formats like WebP.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 11:56:54 +01:00
f253285c25 feat: add comprehensive conversion options and enhanced UI
This major update adds powerful format-specific controls, quality presets,
file metadata display, and enhanced progress feedback to significantly
improve the user experience.

New Components:
- ConversionOptionsPanel: Format-specific controls with collapsible advanced options
  - Video options: codec selection (H.264, H.265, VP8, VP9), bitrate, resolution, FPS
  - Audio options: codec selection, bitrate, sample rate, channels
  - Image options: quality slider, width/height controls
- Quality Presets: One-click presets (High Quality, Balanced, Small File, Web Optimized)
- FileInfo: Displays file metadata including size, duration, dimensions
- Slider: Reusable slider component for quality/bitrate controls
- Select: Reusable dropdown component for codec/format selection

Enhanced Features:
- ConversionPreview improvements:
  - Real-time elapsed time display
  - Estimated time remaining calculation
  - File size comparison (input vs output with % reduction/increase)
  - Better visual status indicators with icons
  - Enhanced loading states with detailed progress
- FileConverter integration:
  - Passes conversion options to converter services
  - Manages conversion options state
  - Resets options on file reset

UI/UX Improvements:
- Format-specific option panels that adapt to selected output format
- Visual preset buttons with icons and descriptions
- Collapsible advanced options to reduce clutter
- Better progress feedback with time estimates
- File size comparison badges showing compression results
- Smooth animations and transitions (existing animations already in place)
- Responsive design for all new components

Technical Details:
- Options are properly typed and integrated with ConversionOptions interface
- All components support disabled states during conversion
- Preview component calculates speed and estimates remaining time
- Metadata extraction for video/audio/image files using browser APIs
- Proper cleanup of object URLs and timers

User Benefits:
- Power users can fine-tune codec, bitrate, resolution settings
- Beginners can use quality presets with confidence
- Better understanding of conversion progress and file size impact
- Informed decisions with file metadata display
- Professional-grade control over output quality

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 11:46:10 +01:00
594a0ca314 refactor: remove all document conversion support, keep only media conversions
This commit completely removes document conversion functionality to focus
exclusively on media file conversions (video, audio, images).

Changes:
- Remove all document converter services (pandocService.ts, pdfService.ts, docxService.ts)
- Uninstall document-related packages: marked, turndown, dompurify, jspdf, pdfjs-dist, docx, mammoth, @types/turndown
- Remove document formats (PDF, DOCX, Markdown, HTML, TXT) from formatMappings.ts
- Remove pandoc converter from FileConverter.tsx
- Remove pandoc loader and references from wasmLoader.ts
- Update TypeScript types to remove 'pandoc' from ConverterEngine and 'document' from FileCategory
- Remove pandoc from WASMModuleState interface
- Update README.md to remove all document conversion documentation
- Update UI descriptions to reflect media-only conversions

Supported conversions now:
- Video: MP4, WebM, AVI, MOV, MKV, GIF
- Audio: MP3, WAV, OGG, AAC, FLAC
- Images: PNG, JPG, WebP, GIF, BMP, TIFF, SVG

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 11:35:20 +01:00
de3997f4df feat: add comprehensive DOCX document support
- Install docx (v9.5.1) and mammoth (v1.11.0) packages
- Create docxService.ts with full DOCX read/write functionality:
  - Extract text, HTML, and Markdown from DOCX files using mammoth
  - Generate DOCX files from Markdown with proper heading levels (H1-H3)
  - Generate DOCX files from HTML and plain text
  - Automatic paragraph formatting and spacing
- Integrate DOCX conversions into pandocService.ts
- Update README with DOCX support documentation
- Add DOCX libraries to tech stack section

Supported DOCX conversions:
- DOCX → Text/HTML/Markdown
- Markdown/HTML/Text → DOCX

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 11:25:23 +01:00
b899989b3e feat: add comprehensive PDF support
- Add jsPDF for PDF generation from text/Markdown/HTML
- Add PDF.js for PDF text extraction (read PDFs)
- Support PDF → Text/Markdown conversions
- Support Markdown/HTML/Text → PDF conversions
- Implement page-by-page PDF text extraction
- Automatic pagination and formatting for generated PDFs

Supported PDF operations:
- Extract text from PDF files (all pages)
- Convert PDF to Markdown or plain text
- Create formatted PDFs from Markdown, HTML, or plain text
- Automatic text wrapping and page breaks

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 11:13:09 +01:00
9de639b138 feat: add document conversion support (Markdown, HTML, Plain Text)
- Add marked for Markdown to HTML conversion with GFM support
- Add turndown for HTML to Markdown conversion
- Add DOMPurify for HTML sanitization (security)
- Support Markdown ↔ HTML ↔ Plain Text conversions
- Add styled HTML output with responsive design
- Use client-side only DOMPurify to fix SSR issues

Supported conversions:
- Markdown → HTML (with code syntax, tables, blockquotes)
- HTML → Markdown (clean formatting preservation)
- Markdown/HTML → Plain Text (strip formatting)
- Plain Text → HTML/Markdown (basic formatting)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 11:01:08 +01:00
1d9f10fd32 fix: optimize FFmpeg encoding to reduce memory usage
- Switch from VP9 to VP8 codec for WebM (less memory-intensive)
- Add realtime encoding deadline and fast CPU preset
- Add ultrafast preset for x264 encoding
- Set explicit bitrates to control memory usage
- Use libvorbis instead of libopus for better compatibility

This fixes "memory access out of bounds" errors during video conversion
in browser environments with limited WASM memory.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 10:54:03 +01:00
fc02b2d9af feat: add Docker deployment configuration
- Add multi-stage Dockerfile for static build
- Add nginx configuration with COOP/COEP headers for FFmpeg.wasm
- Add .dockerignore for optimized builds
- Enable SharedArrayBuffer support via security headers

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 10:46:38 +01:00
1771ca42eb feat: initialize Convert UI - browser-based file conversion app
- Add Next.js 16 with Turbopack and React 19
- Add Tailwind CSS 4 with OKLCH color system
- Implement FFmpeg.wasm for video/audio conversion
- Implement ImageMagick WASM for image conversion
- Add file upload with drag-and-drop
- Add format selector with fuzzy search
- Add conversion preview and download
- Add conversion history with localStorage
- Add dark/light theme support
- Support 22+ file formats across video, audio, and images

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 10:44:49 +01:00