Files
yellowjacket/backend/queue/emit.go
T
yonluandClaude Opus 5 bf4f352117 fix(queue): stop claiming a queue came from somewhere it no longer does
`q.source` was written by SetQueue and cleared in exactly one place,
Clear, so no append path touched it: adding a track to a queue built
from an album left the page still offering "Playing from <that album>",
and since the source is persisted alongside the queue state the wrong
label outlived the session that earned it.

Every add and insert path drops it now. Removing and reordering
deliberately do not — a queue with a track taken out of it is still
that album, and the link still goes somewhere true. Only the arrival of
a track from elsewhere makes the claim false.

The delta event carries the source for the same reason it carries the
current index: an append emits nothing else, so the frontend would keep
the label it was last given until something forced a full state.

Closes #14

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 08:05:43 -04:00

88 lines
1.8 KiB
Go

package queue
import (
"yellowjacket/backend/events"
)
// emitQueueChanged emits the full queue state to the frontend.
func (q *Queue) emitQueueChanged() {
state := State{
Tracks: q.tracks,
CurrentIndex: q.currentIndex,
ShuffleMode: q.shuffleMode,
RepeatMode: q.repeatMode,
Source: q.source,
}
// Ensure tracks is never nil in JSON.
if state.Tracks == nil {
state.Tracks = []Track{}
}
events.Emit(q.ctx, events.QueueChanged, state)
}
// emitIndexChanged emits only the current index to the frontend.
func (q *Queue) emitIndexChanged() {
events.Emit(
q.ctx,
events.QueueIndexChanged,
IndexChanged{CurrentIndex: q.currentIndex},
)
}
// emitModeChanged emits only the shuffle/repeat mode to the frontend.
func (q *Queue) emitModeChanged() {
events.Emit(
q.ctx,
events.QueueModeChanged,
ModeChanged{
ShuffleMode: q.shuffleMode,
RepeatMode: q.repeatMode,
},
)
}
// emitPlaybackFailed tells the frontend that a track could not be
// played. Before this existed the failure was logged, the index was
// reverted and nothing reached the user: a moved file was a button
// that did nothing, twice, forever (errors.C1).
func (q *Queue) emitPlaybackFailed(track Track, reason error) {
msg := ""
if reason != nil {
msg = reason.Error()
}
events.Emit(
q.ctx,
events.PlaybackFailed,
PlaybackFailure{
FilePath: track.FilePath,
Title: track.Title,
Artist: track.Artist,
Reason: msg,
},
)
}
// emitTracksModified emits a delta update for track list changes.
func (q *Queue) emitTracksModified(
action string,
tracks []Track,
index int,
positions []int,
) {
events.Emit(
q.ctx,
events.QueueTracksModified,
TracksModified{
Action: action,
Tracks: tracks,
Index: index,
Positions: positions,
CurrentIndex: q.currentIndex,
Source: q.source,
},
)
}