Add batch queue feature to Convert module
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
This commit is contained in:
parent
1294c7f156
commit
df83bc334a
60
main.go
60
main.go
|
|
@ -1820,9 +1820,11 @@ func (s *appState) addConvertToQueue() error {
|
||||||
return fmt.Errorf("no video loaded")
|
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)
|
outputBase := s.resolveOutputBase(src, true)
|
||||||
s.convert.OutputBase = outputBase
|
|
||||||
cfg := s.convert
|
cfg := s.convert
|
||||||
cfg.OutputBase = outputBase
|
cfg.OutputBase = outputBase
|
||||||
|
|
||||||
|
|
@ -1844,7 +1846,6 @@ func (s *appState) addConvertToQueue() error {
|
||||||
(strings.EqualFold(adjustedCodec, "H.264") && friendly == "H.265") ||
|
(strings.EqualFold(adjustedCodec, "H.264") && friendly == "H.265") ||
|
||||||
(strings.EqualFold(adjustedCodec, "H.265") && friendly == "H.264") {
|
(strings.EqualFold(adjustedCodec, "H.265") && friendly == "H.264") {
|
||||||
adjustedCodec = friendly
|
adjustedCodec = friendly
|
||||||
s.convert.VideoCodec = friendly
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1912,6 +1913,22 @@ func (s *appState) addConvertToQueue() error {
|
||||||
return nil
|
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() {
|
func (s *appState) showBenchmark() {
|
||||||
s.stopPreview()
|
s.stopPreview()
|
||||||
s.stopPlayer()
|
s.stopPlayer()
|
||||||
|
|
@ -5609,7 +5626,8 @@ func (s *appState) executeAddToQueue() {
|
||||||
if err := s.addConvertToQueue(); err != nil {
|
if err := s.addConvertToQueue(); err != nil {
|
||||||
dialog.ShowError(err, s.window)
|
dialog.ShowError(err, s.window)
|
||||||
} else {
|
} 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
|
// Auto-start queue if not already running
|
||||||
if s.jobQueue != nil && !s.jobQueue.IsRunning() && !s.convertBusy {
|
if s.jobQueue != nil && !s.jobQueue.IsRunning() && !s.convertBusy {
|
||||||
s.jobQueue.Start()
|
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() {
|
func (s *appState) executeConversion() {
|
||||||
// Add job to queue and start immediately
|
// Add job to queue and start immediately
|
||||||
if err := s.addConvertToQueue(); err != nil {
|
if err := s.addConvertToQueue(); err != nil {
|
||||||
|
|
@ -7831,6 +7865,16 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
||||||
addQueueBtn.Disable()
|
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() {
|
convertBtn = widget.NewButton("CONVERT NOW", func() {
|
||||||
state.persistConvertConfig()
|
state.persistConvertConfig()
|
||||||
state.executeConversion()
|
state.executeConversion()
|
||||||
|
|
@ -7856,6 +7900,9 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
||||||
convertBtn.Disable()
|
convertBtn.Disable()
|
||||||
cancelBtn.Enable()
|
cancelBtn.Enable()
|
||||||
addQueueBtn.Enable()
|
addQueueBtn.Enable()
|
||||||
|
if len(state.loadedVideos) > 1 {
|
||||||
|
addAllQueueBtn.Enable()
|
||||||
|
}
|
||||||
if state.convertActiveLog != "" {
|
if state.convertActiveLog != "" {
|
||||||
viewLogBtn.Enable()
|
viewLogBtn.Enable()
|
||||||
}
|
}
|
||||||
|
|
@ -7864,6 +7911,9 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
||||||
if state.jobQueue != nil && state.jobQueue.IsRunning() {
|
if state.jobQueue != nil && state.jobQueue.IsRunning() {
|
||||||
convertBtn.Disable()
|
convertBtn.Disable()
|
||||||
addQueueBtn.Enable()
|
addQueueBtn.Enable()
|
||||||
|
if len(state.loadedVideos) > 1 {
|
||||||
|
addAllQueueBtn.Enable()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keyboard shortcut: Ctrl+Enter (Cmd+Enter on macOS maps to Super) -> Convert Now
|
// 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()
|
buildCommandPreview()
|
||||||
|
|
||||||
leftControls := container.NewHBox(resetBtn, loadCfgBtn, saveCfgBtn, autoCompareCheck)
|
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)
|
actionBar := container.NewHBox(leftControls, layout.NewSpacer(), rightControls)
|
||||||
|
|
||||||
// Start a UI refresh ticker to update widgets from state while conversion is active
|
// Start a UI refresh ticker to update widgets from state while conversion is active
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user