refactored many events to use wails bindings, reducing boilerplate

This commit is contained in:
2026-02-25 18:51:07 -05:00
parent baa4644ece
commit cf144bf0dd
20 changed files with 1044 additions and 716 deletions
-429
View File
@@ -1,11 +1,5 @@
package queue
import (
"github.com/wailsapp/wails/v2/pkg/runtime"
"yellowjacket/backend/events"
)
// OnPlaybackFinished is called when a track finishes playing naturally.
// This drives the auto-advance behavior.
func (q *Queue) OnPlaybackFinished() {
@@ -36,426 +30,3 @@ func (q *Queue) OnPlaybackFinished() {
q.playCurrentTrack()
q.emitIndexChanged()
}
// registerEventHandlers sets up Wails event listeners for queue commands.
func (q *Queue) registerEventHandlers() {
if q.ctx == nil {
q.logger.Error("Context is nil, cannot register event handlers")
return
}
runtime.EventsOn(q.ctx, events.RequestPlay, func(_ ...any) {
q.logger.Info("Received RequestPlay")
q.Play()
})
runtime.EventsOn(q.ctx, events.RequestNext, func(_ ...any) {
q.logger.Info("Received RequestNext")
q.Next()
})
runtime.EventsOn(q.ctx, events.RequestPrevious, func(_ ...any) {
q.logger.Info("Received RequestPrevious")
q.Previous()
})
runtime.EventsOn(q.ctx, events.RequestSetQueue, func(data ...any) {
q.logger.Info("Received RequestSetQueue")
q.handleSetQueue(data...)
})
runtime.EventsOn(q.ctx, events.RequestAddToQueue, func(data ...any) {
q.logger.Info("Received RequestAddToQueue")
q.handleAddToQueue(data...)
})
runtime.EventsOn(q.ctx, events.RequestPlayNext, func(data ...any) {
q.logger.Info("Received RequestPlayNext")
q.handlePlayNext(data...)
})
runtime.EventsOn(
q.ctx,
events.RequestRemoveFromQueue,
func(data ...any) {
q.logger.Info("Received RequestRemoveFromQueue")
q.handleRemoveFromQueue(data...)
},
)
runtime.EventsOn(
q.ctx,
events.RequestToggleShuffle,
func(_ ...any) {
q.logger.Info("Received RequestToggleShuffle")
q.ToggleShuffle()
},
)
runtime.EventsOn(
q.ctx,
events.RequestCycleRepeat,
func(_ ...any) {
q.logger.Info("Received RequestCycleRepeat")
q.CycleRepeat()
},
)
runtime.EventsOn(
q.ctx,
events.RequestAddTracksToQueue,
func(data ...any) {
q.logger.Info("Received RequestAddTracksToQueue")
q.handleAddTracksToQueue(data...)
},
)
runtime.EventsOn(
q.ctx,
events.RequestPlayTracksNext,
func(data ...any) {
q.logger.Info("Received RequestPlayTracksNext")
q.handlePlayTracksNext(data...)
},
)
runtime.EventsOn(
q.ctx,
events.RequestPlayQueueIndex,
func(data ...any) {
q.logger.Info("Received RequestPlayQueueIndex")
q.handlePlayQueueIndex(data...)
},
)
runtime.EventsOn(
q.ctx,
events.RequestRemoveTracksFromQueue,
func(data ...any) {
q.logger.Info(
"Received RequestRemoveTracksFromQueue",
)
q.handleRemoveTracksFromQueue(data...)
},
)
runtime.EventsOn(
q.ctx,
events.RequestInsertTracksAtIndex,
func(data ...any) {
q.logger.Info(
"Received RequestInsertTracksAtIndex",
)
q.handleInsertTracksAtIndex(data...)
},
)
runtime.EventsOn(
q.ctx,
events.RequestMoveQueueTracks,
func(data ...any) {
q.logger.Info(
"Received RequestMoveQueueTracks",
)
q.handleMoveQueueTracks(data...)
},
)
runtime.EventsOn(
q.ctx,
events.RequestClearQueue,
func(_ ...any) {
q.logger.Info("Received RequestClearQueue")
q.Clear()
},
)
}
// toStringSlice extracts strings from a Wails event argument.
func toStringSlice(raw []interface{}) []string {
result := make([]string, 0, len(raw))
for _, v := range raw {
if s, ok := v.(string); ok {
result = append(result, s)
}
}
return result
}
// toIntSlice extracts ints (from float64) from a Wails event argument.
func toIntSlice(raw []interface{}) []int {
result := make([]int, 0, len(raw))
for _, v := range raw {
if f, ok := v.(float64); ok {
result = append(result, int(f))
}
}
return result
}
// handleSetQueue processes the RequestSetQueue event payload.
// Expects data[0] = []interface{} of file path strings,
// data[1] = float64 start index, data[2] = bool shuffleStart (optional).
func (q *Queue) handleSetQueue(data ...any) {
if len(data) < 2 {
q.logger.Error("RequestSetQueue: missing data")
return
}
filePathsRaw, ok := data[0].([]interface{})
if !ok {
q.logger.Error("RequestSetQueue: invalid filePaths type")
return
}
filePaths := toStringSlice(filePathsRaw)
startIndex := 0
if si, ok := data[1].(float64); ok {
startIndex = int(si)
}
shuffleStart := false
if len(data) > 2 {
if ss, ok := data[2].(bool); ok {
shuffleStart = ss
}
}
q.SetQueue(filePaths, startIndex, shuffleStart)
}
// handleAddToQueue processes the RequestAddToQueue event payload.
// Expects data[0] = string file path.
func (q *Queue) handleAddToQueue(data ...any) {
if len(data) < 1 {
q.logger.Error("RequestAddToQueue: missing data")
return
}
filePath, ok := data[0].(string)
if !ok {
q.logger.Error(
"RequestAddToQueue: invalid filePath type",
"got", data[0],
)
return
}
q.AddTrack(filePath)
}
// handlePlayNext processes the RequestPlayNext event payload.
// Expects data[0] = string file path.
func (q *Queue) handlePlayNext(data ...any) {
if len(data) < 1 {
q.logger.Error("RequestPlayNext: missing data")
return
}
filePath, ok := data[0].(string)
if !ok {
q.logger.Error(
"RequestPlayNext: invalid filePath type",
"got", data[0],
)
return
}
q.InsertNext(filePath)
}
// handleRemoveFromQueue processes the RequestRemoveFromQueue event payload.
// Expects data[0] = float64 position.
func (q *Queue) handleRemoveFromQueue(data ...any) {
if len(data) < 1 {
q.logger.Error("RequestRemoveFromQueue: missing data")
return
}
position, ok := data[0].(float64)
if !ok {
q.logger.Error(
"RequestRemoveFromQueue: invalid position type",
"got", data[0],
)
return
}
q.RemoveTrack(int(position))
}
// handleRemoveTracksFromQueue processes the RequestRemoveTracksFromQueue
// event payload. Expects data[0] = []interface{} of float64 positions.
func (q *Queue) handleRemoveTracksFromQueue(data ...any) {
if len(data) < 1 {
q.logger.Error(
"RequestRemoveTracksFromQueue: missing data",
)
return
}
positionsRaw, ok := data[0].([]interface{})
if !ok {
q.logger.Error(
"RequestRemoveTracksFromQueue: invalid positions type",
"got", data[0],
)
return
}
q.RemoveTracks(toIntSlice(positionsRaw))
}
// handleAddTracksToQueue processes the RequestAddTracksToQueue event payload.
// Expects data[0] = []interface{} of file path strings.
func (q *Queue) handleAddTracksToQueue(data ...any) {
if len(data) < 1 {
q.logger.Error("RequestAddTracksToQueue: missing data")
return
}
filePathsRaw, ok := data[0].([]interface{})
if !ok {
q.logger.Error(
"RequestAddTracksToQueue: invalid filePaths type",
"got", data[0],
)
return
}
q.AddTracks(toStringSlice(filePathsRaw))
}
// handleInsertTracksAtIndex processes the RequestInsertTracksAtIndex event
// payload. Expects data[0] = []interface{} of file path strings,
// data[1] = float64 target index.
func (q *Queue) handleInsertTracksAtIndex(data ...any) {
if len(data) < 2 {
q.logger.Error(
"RequestInsertTracksAtIndex: missing data",
)
return
}
filePathsRaw, ok := data[0].([]interface{})
if !ok {
q.logger.Error(
"RequestInsertTracksAtIndex: invalid filePaths type",
"got", data[0],
)
return
}
idx, ok := data[1].(float64)
if !ok {
q.logger.Error(
"RequestInsertTracksAtIndex: invalid index type",
"got", data[1],
)
return
}
q.InsertTracksAt(toStringSlice(filePathsRaw), int(idx))
}
// handleMoveQueueTracks processes the RequestMoveQueueTracks event payload.
// Expects data[0] = []interface{} of float64 source indices,
// data[1] = float64 target index.
func (q *Queue) handleMoveQueueTracks(data ...any) {
if len(data) < 2 {
q.logger.Error(
"RequestMoveQueueTracks: missing data",
)
return
}
indicesRaw, ok := data[0].([]interface{})
if !ok {
q.logger.Error(
"RequestMoveQueueTracks: invalid indices type",
"got", data[0],
)
return
}
toIdx, ok := data[1].(float64)
if !ok {
q.logger.Error(
"RequestMoveQueueTracks: invalid toIndex type",
"got", data[1],
)
return
}
q.MoveQueueTracks(toIntSlice(indicesRaw), int(toIdx))
}
// handlePlayQueueIndex processes the RequestPlayQueueIndex event payload.
// Expects data[0] = float64 index.
func (q *Queue) handlePlayQueueIndex(data ...any) {
if len(data) < 1 {
q.logger.Error("RequestPlayQueueIndex: missing data")
return
}
index, ok := data[0].(float64)
if !ok {
q.logger.Error(
"RequestPlayQueueIndex: invalid index type",
"got", data[0],
)
return
}
q.PlayIndex(int(index))
}
// handlePlayTracksNext processes the RequestPlayTracksNext event payload.
// Expects data[0] = []interface{} of file path strings.
func (q *Queue) handlePlayTracksNext(data ...any) {
if len(data) < 1 {
q.logger.Error("RequestPlayTracksNext: missing data")
return
}
filePathsRaw, ok := data[0].([]interface{})
if !ok {
q.logger.Error(
"RequestPlayTracksNext: invalid filePaths type",
"got", data[0],
)
return
}
q.InsertNextTracks(toStringSlice(filePathsRaw))
}
+1 -2
View File
@@ -130,10 +130,9 @@ func NewQueue(logger *slog.Logger, db *database.DB) *Queue {
}
}
// SetContext sets the Wails runtime context and registers event handlers.
// SetContext sets the Wails runtime context for event emission.
func (q *Queue) SetContext(ctx context.Context) {
q.ctx = ctx
q.registerEventHandlers()
}
// SetPlayer provides the queue with a reference to the player for auto-advance.