From f9479c6aafa7f413ecaa9b4074c58119a83676f9 Mon Sep 17 00:00:00 2001 From: Stu Leak Date: Sat, 3 Jan 2026 23:49:25 -0500 Subject: [PATCH] Add lightweight queue elapsed updates --- internal/ui/queueview.go | 26 ++++++++++++++++++++++ main.go | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/internal/ui/queueview.go b/internal/ui/queueview.go index 7d6385e..981ae60 100644 --- a/internal/ui/queueview.go +++ b/internal/ui/queueview.go @@ -548,6 +548,32 @@ func (v *QueueView) UpdateJobs(jobs []*queue.Job) { v.jobList.Refresh() } +// UpdateRunningStatus updates elapsed/progress text for running jobs without rebuilding the list. +func (v *QueueView) UpdateRunningStatus(jobs []*queue.Job) { + if len(jobs) == 0 { + return + } + queuePositions := make(map[string]int) + position := 1 + for _, job := range jobs { + if job.Status == queue.JobStatusPending || job.Status == queue.JobStatusPaused { + queuePositions[job.ID] = position + position++ + } + } + + for _, job := range jobs { + if job.Status != queue.JobStatusRunning { + continue + } + item := v.items[job.ID] + if item == nil { + continue + } + updateJobItem(item, job, queuePositions, v.callbacks) + } +} + // getStatusText returns a human-readable status string func getStatusText(job *queue.Job, queuePositions map[string]int) string { switch job.Status { diff --git a/main.go b/main.go index 715591d..a2c2c25 100644 --- a/main.go +++ b/main.go @@ -1022,6 +1022,8 @@ type appState struct { queueAutoRefreshStop chan struct{} queueAutoRefreshRunning bool queueView *ui.QueueView + queueElapsedStop chan struct{} + queueElapsedRunning bool // Main menu refresh throttling mainMenuLastRefresh time.Time @@ -1662,6 +1664,7 @@ func (s *appState) showMainMenu() { s.stopPreview() s.stopPlayer() s.stopQueueAutoRefresh() + s.stopQueueElapsedTicker() if s.queueView != nil { s.queueView.StopAnimations() } @@ -1817,6 +1820,7 @@ func (s *appState) showQueue() { s.setContent(s.queueView.Root) } s.startQueueAutoRefresh() + s.startQueueElapsedTicker() } // clearCompletedJobs removes all completed and failed jobs from the queue @@ -2067,6 +2071,49 @@ func (s *appState) stopQueueAutoRefresh() { } } +func (s *appState) startQueueElapsedTicker() { + if s.queueElapsedRunning { + return + } + stop := make(chan struct{}) + s.queueElapsedStop = stop + s.queueElapsedRunning = true + go func() { + ticker := time.NewTicker(500 * time.Millisecond) + defer ticker.Stop() + for { + select { + case <-stop: + return + case <-ticker.C: + if s.active != "queue" || s.queueView == nil { + return + } + app := fyne.CurrentApp() + if app == nil || app.Driver() == nil { + continue + } + app.Driver().DoFromGoroutine(func() { + if s.active == "queue" && s.queueView != nil { + s.queueView.UpdateRunningStatus(s.jobQueue.List()) + } + }, false) + } + } + }() +} + +func (s *appState) stopQueueElapsedTicker() { + if !s.queueElapsedRunning { + return + } + if s.queueElapsedStop != nil { + close(s.queueElapsedStop) + } + s.queueElapsedStop = nil + s.queueElapsedRunning = false +} + // addConvertToQueue adds a conversion job to the queue func (s *appState) addConvertToQueue(addToTop bool) error { if s.source == nil { @@ -2738,6 +2785,7 @@ func (s *appState) showMissingDependenciesDialog(moduleID string) { func (s *appState) showModule(id string) { if id != "queue" { s.stopQueueAutoRefresh() + s.stopQueueElapsedTicker() if s.queueView != nil { s.queueView.StopAnimations() }