- App is a work in progress, nothing is ever 'final'
- Changed size references to just state the values without 'final'
- More accurate and less presumptive
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extract reset defaults logic to resetConvertDefaults function
- Add setTargetFileSize helper with syncing guard
- Add syncingTargetSize flag to prevent update loops
- Consolidate reset button handlers to call shared function
- Improves code organization and maintainability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
UI Scaling Improvements:
- Reduce module tiles from 160x80 to 150x65
- Reduce title from 20 to 18
- Reduce queue tile from 140x50 to 120x40
- Reduce category labels to 12px
- Reduce padding from 8 to 4px
- Remove scrolling, everything fits in 800x600
Preset UX Improvements:
- Move "Manual" to bottom of all preset dropdowns
- Default bitrate preset: "2.5 Mbps - Medium Quality"
- Default target size: "100MB"
- Manual input fields hidden by default
- Show manual fields only when "Manual" selected
Encoding Preset Order:
- Reverse order: veryslow first, ultrafast last
- Better quality options now appear first
- Applied to both simple and advanced mode
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
UI Scaling:
- Reduce module tiles from 220x110 to 160x80
- Reduce title size from 28 to 20
- Reduce queue tile from 160x60 to 140x50 with smaller text
- Reduce section padding from 14 to 8 pixels
- Remove extra padding wrapper around tiles
Header Layout Improvements:
- Use border layout with title on left, controls on right
- Compact button labels: "☰ History" → "☰", "Run Benchmark" → "Benchmark"
- Eliminates wasted space in header
Queue Behavior Fix:
- "Clear Completed" always returns to main menu (not last module)
- "Clear All" always returns to main menu
- Prevents unwanted navigation to convert module after clearing
All changes work together to fit app within 800x600 default window
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Wrap module sections in NewVScroll container
- Use border layout with fixed header and scrollable content
- Allows all modules to be accessible within 800x600 window
- Header and controls remain visible while content scrolls
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace layout.NewHBoxLayout() with container.NewHBox() for header
- Replace layout.NewVBoxLayout() with container.NewVBox() for body
- Prevents unwanted stretching and improves alignment with rest of UI
- Elements now use natural sizing instead of filling available space
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove Show()/Hide() calls from Layout() method
- These methods must only be called from main UI thread
- Layout() can be called from any thread during resize/redraw
- Show/Hide logic remains in Refresh() which uses DoFromGoroutine
Fixes threading warnings from Fyne when stats bar updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Update LoadAppIcon() to search for PNG first (better Linux support)
- Add FyneApp.toml for icon metadata and Windows embedding
- Create VideoTools.desktop for Linux application launcher integration
- Change default window size from 1200x700 to 800x600
- Icon now appears in taskbar, app switcher, and Windows title bar
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Issue: ICO file had white background instead of transparency
Solution: Regenerated from PNG source using ImageMagick with
-alpha on -background transparent flags
Verification:
- Corner pixels are srgba(0,0,0,0) - fully transparent
- All icon sizes (256, 128, 64, 48, 32, 16) have alpha channel
- Backup saved as VT_Icon.ico.backup
Command used:
magick VT_Icon.png -alpha on -background transparent \
-define icon:auto-resize=256,128,64,48,32,16 VT_Icon.ico
This ensures the app icon displays properly with transparent
background on all platforms.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
In Progress Tab Enhancements:
- Added animated striped progress bars to in-progress jobs
- Exported ModuleColor function for reuse across modules
- Shows real-time progress (0-100%) with module-specific colors
- Progress updates automatically as jobs run
- Maintains consistent visual style with queue view
Lossless Quality Preset Improvements:
- H.265 and AV1 now support all bitrate modes with lossless quality
- Lossless with Target Size mode now works for H.265/AV1
- H.264 and MPEG-2 no longer show "Lossless" option (codec limitation)
- Dynamic quality dropdown updates based on selected codec
- Automatic fallback to "Near-Lossless" when switching from lossless-capable
codec to non-lossless codec
Quality Options Logic:
- Base options: Draft, Standard, Balanced, High, Near-Lossless
- "Lossless" only appears for H.265 and AV1
- codecSupportsLossless() helper function checks compatibility
- updateQualityOptions() refreshes dropdown when codec changes
Lossless + Bitrate Mode Combinations:
- Lossless + CRF: Forces CRF 0 for perfect quality
- Lossless + CBR: Constant bitrate with lossless quality
- Lossless + VBR: Variable bitrate with lossless quality
- Lossless + Target Size: Calculates bitrate for exact file size with
best possible quality (now allowed for H.265/AV1)
Technical Implementation:
- Added Progress field to ui.HistoryEntry struct
- Exported StripedProgress widget and ModuleColor function
- updateQualityOptions() function dynamically filters quality presets
- updateEncodingControls() handles lossless modes per codec
- Descriptive hints explain each lossless+bitrate combination
This allows professional workflows where lossless quality is desired
but file size constraints still need to be met using Target Size mode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Features:
- New "In Progress" tab shows running/pending jobs
- Displays active jobs without opening full queue
- Tab positioned first for quick visibility
- Shows "Running..." or "Pending" status
- No delete button on active jobs (only completed/failed)
Implementation:
- Updated BuildHistorySidebar to accept activeJobs parameter
- Converts queue.Job to ui.HistoryEntry for display
- Filters running/pending jobs from queue
- Conditional delete button (nil check)
- Dynamic status text based on job state
UX Improvements:
- Quick glance at current activity without queue view
- Three-tab layout: In Progress → Completed → Failed
- Consistent styling with existing history entries
- Tappable entries to view full job details
This allows users to monitor active conversions directly
from the history sidebar, reducing the need to constantly
check the full job queue view.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Bitrate Mode Options Now Show:
- CRF (Constant Rate Factor)
- CBR (Constant Bitrate)
- VBR (Variable Bitrate)
- Target Size (Calculate from file size)
Implementation:
- Added bidirectional mapping between short codes and full labels
- Internally still uses short codes (CRF, CBR, VBR, Target Size)
- Preserves compatibility with existing config files
- Maps display label to internal code on selection
- Maps internal code to display label when loading
Makes it immediately clear what each bitrate mode does without
needing to reference documentation or tooltips.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Command Preview Button:
- Disabled when no video source is loaded
- Shows "Show Preview" when preview is hidden
- Shows "Hide Preview" when preview is visible
- Makes it clear when and why the button can be used
Format Options Reorganization:
- Grouped formats by codec family for better readability
- Order: H.264 → H.265 → AV1 → VP9 → ProRes → MPEG-2
- Added comments explaining each codec family
- Makes it easier to find and compare similar codecs
This improves discoverability and reduces user confusion about
when the command preview is available and which format to choose.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Features:
- Add "×" delete button to each history entry in sidebar
- Click to remove individual entries from history
- Automatically saves and refreshes sidebar after deletion
Bug Fixes:
- Fix nil pointer crash when opening Convert module
- Fixed widget initialization order: bitrateContainer now created
AFTER bitratePresetSelect is initialized
- Prevented "invalid memory address" panic in tabs layout
Technical Details:
- Added deleteHistoryEntry() method to remove entries by ID
- Updated BuildHistorySidebar signature to accept onEntryDelete callback
- Moved bitrateContainer creation from line 5742 to 5794
- All Select widgets now properly initialized before container creation
The crash was caused by bitrateContainer containing a nil
bitratePresetSelect widget, which crashed when Fyne's layout system
called .Visible() during tab initialization.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix panic when closing log viewer (duplicate channel close)
- Improve CBR: Set bufsize to 2x bitrate for better encoder handling
- Improve VBR: Increase maxrate cap from 1.5x to 2x target bitrate
- Add bufsize to VBR at 4x target (2x maxrate) to enforce caps
- Update VBR hint to reflect 2x peak cap and 2-pass encoding
This eliminates runaway bitrates while maintaining quality peaks.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Restructured bitrate controls to hide unused options based on mode,
and improved VBR encoding to use 2-pass for accurate bitrate targeting.
UI Improvements:
- Wrapped CRF, bitrate, and target size controls in hideable containers
- Only show relevant controls based on selected bitrate mode:
* CRF mode: Show only CRF entry
* CBR mode: Show only bitrate entry and presets
* VBR mode: Show only bitrate entry and presets
* Target Size mode: Show only target size controls
- Added descriptive hints for each mode explaining behavior
- Updated DVD mode to work with new container structure
- Made command preview update when bitrate settings change
Encoding Improvements:
- VBR now uses maxrate at 1.5x target for quality peaks
- VBR automatically enables 2-pass encoding for accuracy
- CBR remains strict (minrate=maxrate=target) for guaranteed bitrate
- Target Size mode continues to calculate exact bitrate from duration
This addresses runaway bitrate issues by:
1. Making it clear which mode is active
2. Hiding confusing unused controls
3. Ensuring VBR hits target average bitrate with 2-pass
4. Keeping CBR strict for exact constant bitrate
Pros of manual bitrate targeting:
- Predictable file sizes
- Meets strict size requirements
- Good for streaming with bandwidth constraints
Cons of manual bitrate targeting:
- Variable quality (simple scenes waste bits, complex scenes starve)
- Less efficient than CRF overall
- Requires 2-pass for VBR accuracy (slower)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added support for modern video codecs and containers, and made the
FFmpeg command preview update in real-time as settings change.
Format additions:
- MP4 (AV1) - AV1 codec in MP4 container
- MKV (AV1) - AV1 codec in Matroska container
- WebM (VP9) - VP9 codec for web video
- WebM (AV1) - AV1 codec for web video
- MOV (H.264) - H.264 in QuickTime for Apple compatibility
- MOV (H.265) - H.265 in QuickTime for Apple compatibility
Command preview improvements:
- Added forward declaration for buildCommandPreview function
- Command preview now updates live when changing:
* Format selection
* Video codec
* Quality presets (Simple and Advanced)
* Encoder speed presets
- Preview stays synchronized with current settings
- Users can now see exactly what command will be generated
This gives professionals comprehensive format options while keeping
the preview accurate and up-to-date.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Made the FFmpeg command preview less intrusive by adding a toggle button
and showing actual file paths instead of placeholders.
Changes:
- Added convertCommandPreviewShow state field to track preview visibility
- Added "Command Preview" toggle button next to "View Queue" button
- Command preview now hidden by default to save screen space
- Preview shows actual input/output file paths instead of INPUT/OUTPUT
- Cover art paths also shown with real file path when present
This makes the interface cleaner while providing more useful information
when the preview is needed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Integrated history sidebar into main menu with toggle button and split
view layout. Added history details dialog with FFmpeg command copy.
Changes:
- internal/ui/mainmenu.go:
* Updated BuildMainMenu() signature to accept sidebar parameters
* Added "☰ History" toggle button to header
* Implemented HSplit layout (20% sidebar, 80% main) when sidebar visible
- main.go:
* Added "sort" import for showHistoryDetails
* Added showHistoryDetails() method to display job details dialog
* Shows timestamps, config, error messages, FFmpeg command
* "Show in Folder" button (only if output file exists)
* "View Log" button (only if log file exists)
* Updated showMainMenu() to build and pass sidebar
* Implemented sidebar toggle that refreshes main menu
The sidebar can be toggled on/off from the main menu, shows history
entries with filtering by status (Completed vs Failed/Cancelled), and
clicking an entry opens a detailed view with all job information and
the ability to copy the FFmpeg command for manual execution.
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added history sidebar UI with tabs for completed and failed jobs.
Created reusable UI components and helpers for displaying history entries.
Changes:
- internal/ui/mainmenu.go:
* Added HistoryEntry type definition
* Added BuildHistorySidebar() for main sidebar UI with tabs
* Added buildHistoryList() and buildHistoryItem() helpers
* Added imports for queue and utils packages
- internal/ui/components.go:
* Moved GetStatusColor() and BuildModuleBadge() here as shared functions
* Added queue and utils imports for shared helpers
- internal/ui/queueview.go:
* Updated to use shared GetStatusColor() and BuildModuleBadge()
* Removed duplicate function definitions
- main.go:
* Updated to use ui.HistoryEntry type throughout
* Updated historyConfig, appState, and all methods to use ui.HistoryEntry
The sidebar displays history entries with:
- Status-colored indicators (green/red/orange)
- Module type badges with colors
- Shortened titles and formatted timestamps
- Separate tabs for "Completed" and "Failed" (includes cancelled)
- Empty state messages when no entries exist
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added conversion history tracking with persistence to disk. Jobs are
automatically added to history when they complete, fail, or are cancelled.
Changes:
- Added HistoryEntry struct to represent completed jobs
- Added historyConfig for JSON persistence
- Added historyConfigPath(), loadHistoryConfig(), saveHistoryConfig() functions
- Added historyEntries and sidebarVisible fields to appState
- Added addToHistory() method to save completed jobs
- Initialize history loading on app startup
- Hook into queue change callback to automatically save finished jobs
- Store FFmpeg command in history for each job
- Limit history to 20 most recent entries
History is saved to ~/.config/VideoTools/history.json and includes job
details, timestamps, error messages, and the FFmpeg command for manual
reproduction.
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>