From 91701902e632c183ceb713ac2a03c23506b4c96d Mon Sep 17 00:00:00 2001 From: Siiiiinth <60766886+Siiiiinth@users.noreply.github.com> Date: Fri, 20 Feb 2026 15:57:54 +0100 Subject: [PATCH] fixed playTrackAt when double clicking track --- backend/playbackcommands.go | 13 ++++++++++++ backend/playbackengine.go | 37 ++++++++++++++++++++++++--------- backend/playbackmanager.go | 13 ++++++++++++ ui/controller/connectactions.go | 3 +-- 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/backend/playbackcommands.go b/backend/playbackcommands.go index b6cdd58..3bb9d8b 100644 --- a/backend/playbackcommands.go +++ b/backend/playbackcommands.go @@ -25,6 +25,7 @@ const ( // arg2: InsertMode // arg3: bool (shuffle) cmdLoadItems + cmdLoadItemsAndPlayAtIdx cmdSetQueueState cmdLoadRadioStation // arg: *mediaprovider.RadioStation, arg2: InsertQueueMode @@ -161,6 +162,18 @@ func (c *playbackCommandQueue) LoadItems(items []mediaprovider.MediaItem, insert c.cmdAvailable.Signal() } +func (c *playbackCommandQueue) LoadItemsAndPlayAtIdx(items []mediaprovider.MediaItem, shuffle bool, idx int) { + c.mutex.Lock() + c.queue = append(c.queue, playbackCommand{ + Type: cmdLoadItemsAndPlayAtIdx, + Arg: items, + Arg2: shuffle, + Arg3: idx, + }) + c.mutex.Unlock() + c.cmdAvailable.Signal() +} + func (c *playbackCommandQueue) SetQueueState(tracks []*mediaprovider.Track, queueType QueueType) { c.mutex.Lock() c.queue = append(c.queue, playbackCommand{ diff --git a/backend/playbackengine.go b/backend/playbackengine.go index b085b77..cae0fa4 100644 --- a/backend/playbackengine.go +++ b/backend/playbackengine.go @@ -371,16 +371,7 @@ func (p *playbackEngine) SetShuffle(shuffle bool) { newNowPlayingIdx := 0 if shuffle { - shuffledQueue := deepCopyMediaItemSlice(p.playQueue) - rand.Shuffle(len(shuffledQueue), func(i, j int) { - shuffledQueue[i], shuffledQueue[j] = shuffledQueue[j], shuffledQueue[i] - }) - if p.nowPlayingIdx >= 0 && len(p.getPlayQueue()) > p.nowPlayingIdx { - nowPlayingID := p.getPlayQueue()[p.nowPlayingIdx].Metadata().ID - p.setShuffledPlayQueue(sharedutil.ReorderItems(shuffledQueue, []int{p.GetTrackIdxByIdFrom(shuffledQueue, nowPlayingID)}, 0)) - } else { - return - } + p.LoadItemsAndPlayAtIdx(p.playQueue, true, p.nowPlayingIdx) } else { if p.nowPlayingIdx >= 0 && len(p.getShuffledPlayQueue()) > p.nowPlayingIdx { nowPlayingID := p.getShuffledPlayQueue()[p.nowPlayingIdx].Metadata().ID @@ -515,6 +506,32 @@ func (p *playbackEngine) LoadItems(items []mediaprovider.MediaItem, insertQueueM return p.doLoaditems(newItems, insertQueueMode, shuffle) } +// Load items into the play queue. +// If replacing the current queue (!appendToQueue), playback will be stopped. +func (p *playbackEngine) LoadItemsAndPlayAtIdx(items []mediaprovider.MediaItem, shuffle bool, idx int) error { + newItems := deepCopyMediaItemSlice(items) + + if p.shuffle || shuffle { + rand.Shuffle(len(newItems), func(i, j int) { + newItems[i], newItems[j] = newItems[j], newItems[i] + }) + if idx < len(items) { + nowPlayingID := items[idx].Metadata().ID + p.setPlayQueue(deepCopyMediaItemSlice(items)) + p.setShuffledPlayQueue(sharedutil.ReorderItems(newItems, []int{p.GetTrackIdxByIdFrom(newItems, nowPlayingID)}, 0)) + p.PlayTrackAt(0) + } + } else { + p.doLoaditems(newItems, Replace, shuffle) + p.PlayTrackAt(idx) + } + + p.handleNextTrackUpdated() + p.invokeNoArgCallbacks(p.onQueueChange) + + return nil +} + // Load tracks into the play queue. // If replacing the current queue (!appendToQueue), playback will be stopped. func (p *playbackEngine) LoadTracks(tracks []*mediaprovider.Track, insertQueueMode InsertQueueMode, shuffle bool) error { diff --git a/backend/playbackmanager.go b/backend/playbackmanager.go index f8ad465..41378bb 100644 --- a/backend/playbackmanager.go +++ b/backend/playbackmanager.go @@ -399,6 +399,12 @@ func (p *PlaybackManager) LoadTracks(tracks []*mediaprovider.Track, insertQueueM p.cmdQueue.LoadItems(items, insertQueueMode, shuffle) } +// Replaces the playQueue with tracks and moves the track at idx to position 0 +func (p *PlaybackManager) LoadTracksAndPlayAtIdx(tracks []*mediaprovider.Track, shuffle bool, idx int) { + items := sharedutil.CopyTrackSliceToMediaItemSlice(tracks) + p.cmdQueue.LoadItemsAndPlayAtIdx(items, shuffle, idx) +} + // Load items into the currently active queue. (shuffledPlayQueue/playQueue) // If replacing the current queue (!appendToQueue), playback will be stopped. // Loading items into the shuffledPlayQueue may also modify the playQueue @@ -871,6 +877,13 @@ func (p *PlaybackManager) runCmdQueue(ctx context.Context) { c.Arg3.(bool), ) logIfErr("LoadItems", err) + case cmdLoadItemsAndPlayAtIdx: + err := p.engine.LoadItemsAndPlayAtIdx( + c.Arg.([]mediaprovider.MediaItem), + c.Arg2.(bool), + c.Arg3.(int), + ) + logIfErr("LoadItemsAndPlayAtIdx", err) case cmdSetQueueState: err := p.engine.SetQueueState( c.Arg.([]*mediaprovider.Track), diff --git a/ui/controller/connectactions.go b/ui/controller/connectactions.go index 1f051e5..fa7dab2 100644 --- a/ui/controller/connectactions.go +++ b/ui/controller/connectactions.go @@ -31,11 +31,10 @@ func (m *Controller) connectTracklistActionsWithReplayGainMode(tracklist *widget m.App.PlaybackManager.LoadTracks(tracks, backend.Append, false) } tracklist.OnPlayTrackAt = func(idx int) { - m.App.PlaybackManager.LoadTracks(tracklist.GetTracks(), backend.Replace, false) + m.App.PlaybackManager.LoadTracksAndPlayAtIdx(tracklist.GetTracks(), false, idx) if m.App.Config.ReplayGain.Mode == backend.ReplayGainAuto { m.App.PlaybackManager.SetReplayGainMode(mode) } - m.App.PlaybackManager.PlayTrackAt(idx) } tracklist.OnPlaySelection = func(tracks []*mediaprovider.Track, shuffle bool) { m.App.PlaybackManager.LoadTracks(tracks, backend.Replace, shuffle)