Simplify threading solution and add Clear All button
Simplified the approach by removing complex callback logic and using a
simple 500ms timer-based update for the stats bar instead. This eliminates
threading errors completely while keeping the code straightforward.
Changes:
1. Removed queue change callback entirely
2. Added background timer that updates stats bar every 500ms
3. Removed initComplete flag (no longer needed)
4. Simplified setContent() to direct calls
5. Added onClearAll parameter to BuildQueueView()
6. Added ClearAll() method to Queue (removes all jobs)
7. Added Clear All button with DangerImportance styling in queue view
8. Clear Completed button now has LowImportance styling
This approach is much simpler: the UI just polls the queue state
periodically instead of trying to handle callbacks from goroutines.
No more threading errors, less code, easier to understand.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
b80b81198f
commit
fa4f4119b5
|
|
@ -378,6 +378,15 @@ func (q *Queue) Clear() {
|
|||
q.notifyChange()
|
||||
}
|
||||
|
||||
// ClearAll removes all jobs from the queue
|
||||
func (q *Queue) ClearAll() {
|
||||
q.mu.Lock()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
q.jobs = make([]*Job, 0)
|
||||
q.notifyChange()
|
||||
}
|
||||
|
||||
// generateID generates a unique ID for a job
|
||||
func generateID() string {
|
||||
return fmt.Sprintf("job-%d", time.Now().UnixNano())
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ func BuildQueueView(
|
|||
onCancel func(string),
|
||||
onRemove func(string),
|
||||
onClear func(),
|
||||
onClearAll func(),
|
||||
titleColor, bgColor, textColor color.Color,
|
||||
) fyne.CanvasObject {
|
||||
// Header
|
||||
|
|
@ -29,12 +30,18 @@ func BuildQueueView(
|
|||
title.TextSize = 24
|
||||
|
||||
backBtn := widget.NewButton("← Back", onBack)
|
||||
backBtn.Importance = widget.LowImportance
|
||||
|
||||
clearBtn := widget.NewButton("Clear Completed", onClear)
|
||||
clearBtn.Importance = widget.LowImportance
|
||||
|
||||
clearAllBtn := widget.NewButton("Clear All", onClearAll)
|
||||
clearAllBtn.Importance = widget.DangerImportance
|
||||
|
||||
header := container.NewBorder(
|
||||
nil, nil,
|
||||
backBtn,
|
||||
clearBtn,
|
||||
container.NewHBox(clearBtn, clearAllBtn),
|
||||
container.NewCenter(title),
|
||||
)
|
||||
|
||||
|
|
|
|||
95
main.go
95
main.go
|
|
@ -151,31 +151,30 @@ func (c convertConfig) CoverLabel() string {
|
|||
}
|
||||
|
||||
type appState struct {
|
||||
window fyne.Window
|
||||
active string
|
||||
initComplete bool // True after initial UI setup completes
|
||||
source *videoSource
|
||||
loadedVideos []*videoSource // Multiple loaded videos for navigation
|
||||
currentIndex int // Current video index in loadedVideos
|
||||
anim *previewAnimator
|
||||
convert convertConfig
|
||||
currentFrame string
|
||||
player player.Controller
|
||||
playerReady bool
|
||||
playerVolume float64
|
||||
playerMuted bool
|
||||
lastVolume float64
|
||||
playerPaused bool
|
||||
playerPos float64
|
||||
playerLast time.Time
|
||||
progressQuit chan struct{}
|
||||
convertCancel context.CancelFunc
|
||||
playerSurf *playerSurface
|
||||
convertBusy bool
|
||||
convertStatus string
|
||||
playSess *playSession
|
||||
jobQueue *queue.Queue
|
||||
statsBar *ui.ConversionStatsBar
|
||||
window fyne.Window
|
||||
active string
|
||||
source *videoSource
|
||||
loadedVideos []*videoSource // Multiple loaded videos for navigation
|
||||
currentIndex int // Current video index in loadedVideos
|
||||
anim *previewAnimator
|
||||
convert convertConfig
|
||||
currentFrame string
|
||||
player player.Controller
|
||||
playerReady bool
|
||||
playerVolume float64
|
||||
playerMuted bool
|
||||
lastVolume float64
|
||||
playerPaused bool
|
||||
playerPos float64
|
||||
playerLast time.Time
|
||||
progressQuit chan struct{}
|
||||
convertCancel context.CancelFunc
|
||||
playerSurf *playerSurface
|
||||
convertBusy bool
|
||||
convertStatus string
|
||||
playSess *playSession
|
||||
jobQueue *queue.Queue
|
||||
statsBar *ui.ConversionStatsBar
|
||||
}
|
||||
|
||||
func (s *appState) stopPreview() {
|
||||
|
|
@ -425,6 +424,10 @@ func (s *appState) showQueue() {
|
|||
s.jobQueue.Clear()
|
||||
s.showQueue() // Refresh
|
||||
},
|
||||
func() { // onClearAll
|
||||
s.jobQueue.ClearAll()
|
||||
s.showQueue() // Refresh
|
||||
},
|
||||
utils.MustHex("#4CE870"), // titleColor
|
||||
gridColor, // bgColor
|
||||
textColor, // textColor
|
||||
|
|
@ -1082,39 +1085,27 @@ func runGUI() {
|
|||
// Start queue processing (but paused by default)
|
||||
state.jobQueue.Start()
|
||||
|
||||
// Set callback - queue changes are triggered by job processor goroutine
|
||||
state.jobQueue.SetChangeCallback(func() {
|
||||
// Skip updates during initialization
|
||||
if !state.initComplete {
|
||||
return
|
||||
}
|
||||
|
||||
// Marshal UI updates to main thread
|
||||
app := fyne.CurrentApp()
|
||||
if app == nil || app.Driver() == nil {
|
||||
return
|
||||
}
|
||||
|
||||
app.Driver().DoFromGoroutine(func() {
|
||||
// Update stats bar
|
||||
state.updateStatsBar()
|
||||
|
||||
// Refresh UI when queue changes and we're on main menu
|
||||
if state.active == "" {
|
||||
state.showMainMenu()
|
||||
}
|
||||
}, false)
|
||||
})
|
||||
|
||||
// Mark initialization as complete
|
||||
state.initComplete = true
|
||||
|
||||
defer state.shutdown()
|
||||
w.SetOnDropped(func(pos fyne.Position, items []fyne.URI) {
|
||||
state.handleDrop(pos, items)
|
||||
})
|
||||
state.showMainMenu()
|
||||
logging.Debug(logging.CatUI, "main menu rendered with %d modules", len(modulesList))
|
||||
|
||||
// Start stats bar update loop on a timer
|
||||
go func() {
|
||||
ticker := time.NewTicker(500 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
app := fyne.CurrentApp()
|
||||
if app != nil && app.Driver() != nil {
|
||||
app.Driver().DoFromGoroutine(func() {
|
||||
state.updateStatsBar()
|
||||
}, false)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
w.ShowAndRun()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user