From 16140e2e1297218d1d2dabadc2e5a80f1a8c6852 Mon Sep 17 00:00:00 2001 From: Stu Leak Date: Tue, 23 Dec 2025 20:27:59 -0500 Subject: [PATCH] Add batch queue feature to Convert module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert Module: - Add "Add All to Queue" button when multiple videos loaded - Batch-add all loaded videos to queue with one click - Remove confirmation dialogs for faster workflow - Queue button updates immediately to show new count - Button only visible when 2+ videos are loaded Workflow improvements: - No more clicking through videos one by one to queue - No "OK" confirmation clicks required - Queue count updates instantly in View Queue button - Auto-starts queue after adding jobs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- main.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index d103e77..9332ef8 100644 --- a/main.go +++ b/main.go @@ -1820,9 +1820,11 @@ func (s *appState) addConvertToQueue() error { return fmt.Errorf("no video loaded") } - src := s.source + return s.addConvertToQueueForSource(s.source) +} + +func (s *appState) addConvertToQueueForSource(src *videoSource) error { outputBase := s.resolveOutputBase(src, true) - s.convert.OutputBase = outputBase cfg := s.convert cfg.OutputBase = outputBase @@ -1844,7 +1846,6 @@ func (s *appState) addConvertToQueue() error { (strings.EqualFold(adjustedCodec, "H.264") && friendly == "H.265") || (strings.EqualFold(adjustedCodec, "H.265") && friendly == "H.264") { adjustedCodec = friendly - s.convert.VideoCodec = friendly } } } @@ -1912,6 +1913,22 @@ func (s *appState) addConvertToQueue() error { return nil } +func (s *appState) addAllConvertToQueue() (int, error) { + if len(s.loadedVideos) == 0 { + return 0, fmt.Errorf("no videos loaded") + } + + count := 0 + for _, src := range s.loadedVideos { + if err := s.addConvertToQueueForSource(src); err != nil { + return count, fmt.Errorf("failed to add %s: %w", filepath.Base(src.Path), err) + } + count++ + } + + return count, nil +} + func (s *appState) showBenchmark() { s.stopPreview() s.stopPlayer() @@ -5609,7 +5626,8 @@ func (s *appState) executeAddToQueue() { if err := s.addConvertToQueue(); err != nil { dialog.ShowError(err, s.window) } else { - dialog.ShowInformation("Queue", "Job added to queue!", s.window) + // Update queue button to show new count + s.updateQueueButtonLabel() // Auto-start queue if not already running if s.jobQueue != nil && !s.jobQueue.IsRunning() && !s.convertBusy { s.jobQueue.Start() @@ -5618,6 +5636,22 @@ func (s *appState) executeAddToQueue() { } } +func (s *appState) executeAddAllToQueue() { + count, err := s.addAllConvertToQueue() + if err != nil { + dialog.ShowError(err, s.window) + } else { + // Update queue button to show new count + s.updateQueueButtonLabel() + logging.Debug(logging.CatUI, "Added %d jobs to queue", count) + // Auto-start queue if not already running + if s.jobQueue != nil && !s.jobQueue.IsRunning() && !s.convertBusy { + s.jobQueue.Start() + logging.Debug(logging.CatUI, "queue auto-started after adding %d jobs", count) + } + } +} + func (s *appState) executeConversion() { // Add job to queue and start immediately if err := s.addConvertToQueue(); err != nil { @@ -7831,6 +7865,16 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { addQueueBtn.Disable() } + // Add All to Queue button (only shown when multiple videos are loaded) + addAllQueueBtn := widget.NewButton("Add All to Queue", func() { + state.persistConvertConfig() + state.executeAddAllToQueue() + }) + addAllQueueBtn.Importance = widget.MediumImportance + if len(state.loadedVideos) <= 1 { + addAllQueueBtn.Hide() + } + convertBtn = widget.NewButton("CONVERT NOW", func() { state.persistConvertConfig() state.executeConversion() @@ -7856,6 +7900,9 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { convertBtn.Disable() cancelBtn.Enable() addQueueBtn.Enable() + if len(state.loadedVideos) > 1 { + addAllQueueBtn.Enable() + } if state.convertActiveLog != "" { viewLogBtn.Enable() } @@ -7864,6 +7911,9 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { if state.jobQueue != nil && state.jobQueue.IsRunning() { convertBtn.Disable() addQueueBtn.Enable() + if len(state.loadedVideos) > 1 { + addAllQueueBtn.Enable() + } } // Keyboard shortcut: Ctrl+Enter (Cmd+Enter on macOS maps to Super) -> Convert Now @@ -8004,7 +8054,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject { buildCommandPreview() leftControls := container.NewHBox(resetBtn, loadCfgBtn, saveCfgBtn, autoCompareCheck) - rightControls := container.NewHBox(cancelBtn, cancelQueueBtn, viewLogBtn, addQueueBtn, convertBtn) + rightControls := container.NewHBox(cancelBtn, cancelQueueBtn, viewLogBtn, addAllQueueBtn, addQueueBtn, convertBtn) actionBar := container.NewHBox(leftControls, layout.NewSpacer(), rightControls) // Start a UI refresh ticker to update widgets from state while conversion is active