diff --git a/backend/app.go b/backend/app.go index 483585b..3a00e80 100644 --- a/backend/app.go +++ b/backend/app.go @@ -21,6 +21,7 @@ import ( "github.com/dweymouth/supersonic/backend/player/mpv" "github.com/dweymouth/supersonic/backend/util" "github.com/dweymouth/supersonic/backend/windows" + "github.com/dweymouth/supersonic/sharedutil" "github.com/google/uuid" "github.com/20after4/configdir" @@ -32,6 +33,7 @@ const ( portableDir = "supersonic_portable" savedQueueFile = "saved_queue.json" savedUnshuffledQueueFile = "saved_unshuffled_queue.json" + savedShuffledQueueFile = "saved_shuffled_queue.json" themesDir = "themes" audioCacheSubdir = "audio" ) @@ -552,8 +554,13 @@ func (a *App) SavePlayQueueIfEnabled() { } SavePlayQueue(a.ServerManager.ServerID.String(), a.PlaybackManager.GetActivePlayQueue(), a.PlaybackManager, path.Join(a.configDir, savedQueueFile), queueServer) if a.Config.Playback.Shuffle { - // if shuffle, also save the unshuffeled queue to enable unshuffling on restarting supersonic - SavePlayQueue(a.ServerManager.ServerID.String(), a.PlaybackManager.GetPlayQueue(), a.PlaybackManager, path.Join(a.configDir, savedUnshuffledQueueFile), queueServer) + // if shuffle + // save the unshuffeled queue to enable unshuffling on restarting supersonic + // save the shuffled queue again to enable checking if the playQueue was changed server side on start up + + // both files are just saved locally + SavePlayQueue(a.ServerManager.ServerID.String(), a.PlaybackManager.GetPlayQueue(), a.PlaybackManager, path.Join(a.configDir, savedUnshuffledQueueFile), nil) + SavePlayQueue(a.ServerManager.ServerID.String(), a.PlaybackManager.GetShuffledPlayQueue(), a.PlaybackManager, path.Join(a.configDir, savedShuffledQueueFile), nil) } } @@ -561,10 +568,20 @@ func (a *App) LoadSavedPlayQueue() error { queueFilePath := path.Join(a.configDir, savedQueueFile) playQueue, err := LoadPlayQueue(queueFilePath, a.ServerManager, a.Config.Application.SaveQueueToServer) var unshuffledPlayQueue *SavedPlayQueue + var shuffledPlayQueue *SavedPlayQueue - if a.Config.Playback.Shuffle { + isShuffe := a.Config.Playback.Shuffle + + if isShuffe { unshuffledQueueFilePath := path.Join(a.configDir, savedUnshuffledQueueFile) - unshuffledPlayQueue, err = LoadPlayQueue(unshuffledQueueFilePath, a.ServerManager, a.Config.Application.SaveQueueToServer) //unshuffledPlayQueue is only stored locally + unshuffledPlayQueue, err = LoadPlayQueue(unshuffledQueueFilePath, a.ServerManager, false) + + if err != nil { + return err + } + + shuffledQueueFilePath := path.Join(a.configDir, savedUnshuffledQueueFile) + shuffledPlayQueue, err = LoadPlayQueue(shuffledQueueFilePath, a.ServerManager, false) if err != nil { return err @@ -581,7 +598,7 @@ func (a *App) LoadSavedPlayQueue() error { return nil } - a.PlaybackManager.LoadTracks(playQueue.Tracks, Replace, false) + a.PlaybackManager.LoadTracks(playQueue.Tracks, Replace, Both, false) if playQueue.TrackIndex >= 0 && playQueue.TrackIndex < len(playQueue.Tracks) { // TODO: This isn't ideal but doesn't seem to cause an audible play-for-a-split-second artifact a.PlaybackManager.PlayTrackAt(playQueue.TrackIndex) @@ -590,20 +607,22 @@ func (a *App) LoadSavedPlayQueue() error { a.PlaybackManager.SeekSeconds(playQueue.TimePos) } - if a.Config.Playback.Shuffle { + if isShuffe { // check if queue was changed server side - // if playQueue.items same as unshuffledPlayQueue.items - // set shuffle to false, only load normal playqueue if len(playQueue.Tracks) != len(unshuffledPlayQueue.Tracks) { // queue was changed server side, no need to compare elements a.PlaybackManager.SetShuffle(false) } else { - //TODO_SHUFFLE: implement + serverStatePlayQueue := sharedutil.CopyTrackSliceToMediaItemSlice(playQueue.Tracks) + clientStatePlayQueue := sharedutil.CopyTrackSliceToMediaItemSlice(shuffledPlayQueue.Tracks) - //shuffled := sharedutil.CopyTrackSliceToMediaItemSlice(playQueue.Tracks) - //unshuffled := sharedutil.CopyTrackSliceToMediaItemSlice(unshuffledPlayQueue.Tracks) - - //a.PlaybackManager.engine.setPlayQueue(unshuffled) + if slices.Equal(serverStatePlayQueue, clientStatePlayQueue) { + fmt.Println("Loading unshuffled items into playQueue") + a.PlaybackManager.SetShuffle(true) + a.PlaybackManager.LoadTracks(unshuffledPlayQueue.Tracks, Replace, PlayQueue, false) + } else { + a.PlaybackManager.SetShuffle(false) + } } } return nil diff --git a/backend/playbackcommands.go b/backend/playbackcommands.go index 2632fef..3a79b70 100644 --- a/backend/playbackcommands.go +++ b/backend/playbackcommands.go @@ -35,6 +35,7 @@ type playbackCommand struct { Arg any Arg2 any Arg3 any + Arg4 any OnDone func() } @@ -148,13 +149,14 @@ func (c *playbackCommandQueue) LoadRadioStation(radio *mediaprovider.RadioStatio c.cmdAvailable.Signal() } -func (c *playbackCommandQueue) LoadItems(items []mediaprovider.MediaItem, insertQueueMode InsertQueueMode, shuffle bool) { +func (c *playbackCommandQueue) LoadItems(items []mediaprovider.MediaItem, insertQueueMode InsertQueueMode, queueType QueueType, shuffle bool) { c.mutex.Lock() c.queue = append(c.queue, playbackCommand{ Type: cmdLoadItems, Arg: items, Arg2: insertQueueMode, - Arg3: shuffle, + Arg3: queueType, + Arg4: shuffle, }) c.mutex.Unlock() c.cmdAvailable.Signal() diff --git a/backend/playbackengine.go b/backend/playbackengine.go index 9081751..cca4291 100644 --- a/backend/playbackengine.go +++ b/backend/playbackengine.go @@ -7,6 +7,7 @@ import ( "log" "math/rand" "slices" + "strconv" "time" "github.com/dweymouth/supersonic/backend/mediaprovider" @@ -33,6 +34,14 @@ const ( Append ) +type QueueType int + +const ( + PlayQueue QueueType = iota + ShuffledPlayQueue + Both +) + // The playback loop mode (LoopNone, LoopAll, LoopOne). type LoopMode int @@ -239,7 +248,7 @@ func (p *playbackEngine) getPlayQueueLength() int { func (p *playbackEngine) clearPlayQueue() { p.playQueue = nil - p.SetShuffle(false) + p.shuffledPlayQueue = nil } func (p *playbackEngine) setPlayQueue(items []mediaprovider.MediaItem) { @@ -254,9 +263,17 @@ func (p *playbackEngine) getPlayQueueItemAt(idx int) mediaprovider.MediaItem { return p.getPlayQueue()[idx] } -func (p *playbackEngine) insertItemsIntoPlayQueueAt(items []mediaprovider.MediaItem, idx int) { - p.playQueue = append(p.playQueue[:idx], append(items, p.playQueue[idx:]...)...) - p.shuffledPlayQueue = append(p.shuffledPlayQueue[:idx], append(items, p.shuffledPlayQueue[idx:]...)...) +func (p *playbackEngine) insertItemsIntoPlayQueueAt(items []mediaprovider.MediaItem, idx int, queueType QueueType) { + switch queueType { + case Both: + p.playQueue = append(p.playQueue[:idx], append(items, p.playQueue[idx:]...)...) + p.shuffledPlayQueue = append(p.shuffledPlayQueue[:idx], append(items, p.shuffledPlayQueue[idx:]...)...) + case PlayQueue: + fmt.Println("Inserting into playQueue at: " + strconv.Itoa(idx)) + p.playQueue = append(p.playQueue[:idx], append(items, p.playQueue[idx:]...)...) + case ShuffledPlayQueue: + p.shuffledPlayQueue = append(p.shuffledPlayQueue[:idx], append(items, p.shuffledPlayQueue[idx:]...)...) + } } func (p *playbackEngine) GetPlayQueueDeepCopy() []mediaprovider.MediaItem { @@ -320,7 +337,7 @@ func (p *playbackEngine) GetLoopMode() LoopMode { func (p *playbackEngine) GetNowPlayingIdxFrom(items []mediaprovider.MediaItem) int { newNowPlayingIdx := -1 - if p.nowPlayingIdx >= 0 { + if p.nowPlayingIdx >= 0 && len(items) > p.nowPlayingIdx { nowPlayingID := p.getPlayQueueItemAt(p.nowPlayingIdx).Metadata().ID for i, tr := range items { if tr.Metadata().ID == nowPlayingID { @@ -455,19 +472,19 @@ func (p *playbackEngine) Continue() error { // Load items into the play queue. // If replacing the current queue (!appendToQueue), playback will be stopped. -func (p *playbackEngine) LoadItems(items []mediaprovider.MediaItem, insertQueueMode InsertQueueMode, shuffle bool) error { +func (p *playbackEngine) LoadItems(items []mediaprovider.MediaItem, insertQueueMode InsertQueueMode, queueType QueueType, shuffle bool) error { newItems := deepCopyMediaItemSlice(items) - return p.doLoaditems(newItems, insertQueueMode, shuffle) + return p.doLoaditems(newItems, insertQueueMode, queueType, shuffle) } // 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 { +func (p *playbackEngine) LoadTracks(tracks []*mediaprovider.Track, insertQueueMode InsertQueueMode, queueType QueueType, shuffle bool) error { newTracks := sharedutil.CopyTrackSliceToMediaItemSlice(tracks) - return p.doLoaditems(newTracks, insertQueueMode, shuffle) + return p.doLoaditems(newTracks, insertQueueMode, queueType, shuffle) } -func (p *playbackEngine) doLoaditems(items []mediaprovider.MediaItem, insertQueueMode InsertQueueMode, shuffle bool) error { +func (p *playbackEngine) doLoaditems(items []mediaprovider.MediaItem, insertQueueMode InsertQueueMode, queueType QueueType, shuffle bool) error { if insertQueueMode == Replace { p.player.Stop(false) p.nowPlayingIdx = -1 @@ -477,7 +494,7 @@ func (p *playbackEngine) doLoaditems(items []mediaprovider.MediaItem, insertQueu defer p.handleNextTrackUpdated() } - if shuffle { + if shuffle || p.shuffle { rand.Shuffle(len(items), func(i, j int) { items[i], items[j] = items[j], items[i] }) } @@ -486,7 +503,7 @@ func (p *playbackEngine) doLoaditems(items []mediaprovider.MediaItem, insertQueu insertIdx = p.nowPlayingIdx + 1 } - p.insertItemsIntoPlayQueueAt(items, insertIdx) + p.insertItemsIntoPlayQueueAt(items, insertIdx, queueType) p.invokeNoArgCallbacks(p.onQueueChange) return nil } @@ -504,7 +521,7 @@ func (p *playbackEngine) LoadRadioStation(radio *mediaprovider.RadioStation, ins if insertMode == InsertNext { insertIdx = p.nowPlayingIdx + 1 } - p.insertItemsIntoPlayQueueAt([]mediaprovider.MediaItem{radio}, insertIdx) + p.insertItemsIntoPlayQueueAt([]mediaprovider.MediaItem{radio}, insertIdx, Both) p.invokeNoArgCallbacks(p.onQueueChange) } diff --git a/backend/playbackmanager.go b/backend/playbackmanager.go index 9999d4c..a9e3b91 100644 --- a/backend/playbackmanager.go +++ b/backend/playbackmanager.go @@ -364,7 +364,7 @@ func (p *PlaybackManager) LoadAlbum(albumID string, insertQueueMode InsertQueueM if err != nil { return err } - p.LoadTracks(album.Tracks, insertQueueMode, shuffle) + p.LoadTracks(album.Tracks, insertQueueMode, Both, shuffle) return nil } @@ -378,21 +378,21 @@ func (p *PlaybackManager) LoadPlaylist(playlistID string, insertQueueMode Insert if err != nil { return err } - p.LoadTracks(playlist.Tracks, insertQueueMode, shuffle) + p.LoadTracks(playlist.Tracks, insertQueueMode, Both, shuffle) return nil } // Load tracks into the play queue. // If replacing the current queue (!appendToQueue), playback will be stopped. -func (p *PlaybackManager) LoadTracks(tracks []*mediaprovider.Track, insertQueueMode InsertQueueMode, shuffle bool) { +func (p *PlaybackManager) LoadTracks(tracks []*mediaprovider.Track, insertQueueMode InsertQueueMode, queueType QueueType, shuffle bool) { items := sharedutil.CopyTrackSliceToMediaItemSlice(tracks) - p.cmdQueue.LoadItems(items, insertQueueMode, shuffle) + p.cmdQueue.LoadItems(items, insertQueueMode, queueType, shuffle) } -// Load items into the play queue. +// Load items into the currently active queue. (shuffledPlayQueue/playQueue) // If replacing the current queue (!appendToQueue), playback will be stopped. -func (p *PlaybackManager) LoadItems(items []mediaprovider.MediaItem, insertQueueMode InsertQueueMode, shuffle bool) { - p.cmdQueue.LoadItems(items, insertQueueMode, shuffle) +func (p *PlaybackManager) LoadItems(items []mediaprovider.MediaItem, insertQueueMode InsertQueueMode, queueType QueueType, shuffle bool) { + p.cmdQueue.LoadItems(items, insertQueueMode, queueType, shuffle) } // Replaces the play queue with the given set of tracks. @@ -429,7 +429,7 @@ func (p *PlaybackManager) PlayTrack(trackID string) error { if err != nil { return err } - p.LoadTracks([]*mediaprovider.Track{tr}, Replace, false) + p.LoadTracks([]*mediaprovider.Track{tr}, Replace, Both, false) if p.engine.replayGainCfg.Mode == ReplayGainAuto { p.SetReplayGainMode(player.ReplayGainTrack) } @@ -467,7 +467,7 @@ func (p *PlaybackManager) PlayArtistDiscography(artistID string, shuffleTracks b log.Printf("failed to get artist tracks: %v\n", err) return } - p.LoadTracks(tr, Replace, shuffleTracks) + p.LoadTracks(tr, Replace, Both, shuffleTracks) if p.engine.replayGainCfg.Mode == ReplayGainAuto { if shuffleTracks { p.SetReplayGainMode(player.ReplayGainTrack) @@ -532,7 +532,7 @@ func (p *PlaybackManager) PlayRandomAlbums(genreName string) error { break } if al, err := mp.GetAlbum(al.ID); err == nil { - p.LoadTracks(al.Tracks, insertMode, false) + p.LoadTracks(al.Tracks, insertMode, Both, false) if i == 0 { p.PlayFromBeginning() insertMode = Append @@ -556,7 +556,7 @@ func (p *PlaybackManager) fetchAndPlayTracks(fetchFn func() ([]*mediaprovider.Tr if songs, err := fetchFn(); err != nil { return err } else { - p.LoadTracks(songs, Replace, false) + p.LoadTracks(songs, Replace, Both, false) if p.engine.replayGainCfg.Mode == ReplayGainAuto { p.SetReplayGainMode(player.ReplayGainTrack) } @@ -806,7 +806,7 @@ func (p *PlaybackManager) enqueueAutoplayTracks() { } if len(tracks) > 0 { - p.LoadTracks(tracks, Append, false /*no need to shuffle, already random*/) + p.LoadTracks(tracks, Append, Both, false /*no need to shuffle, already random*/) } }() } @@ -850,7 +850,8 @@ func (p *PlaybackManager) runCmdQueue(ctx context.Context) { err := p.engine.LoadItems( c.Arg.([]mediaprovider.MediaItem), c.Arg2.(InsertQueueMode), - c.Arg3.(bool), + c.Arg3.(QueueType), + c.Arg4.(bool), ) logIfErr("LoadItems", err) case cmdLoadRadioStation: diff --git a/ui/browsing/albumpage.go b/ui/browsing/albumpage.go index 830a8a2..0221df2 100644 --- a/ui/browsing/albumpage.go +++ b/ui/browsing/albumpage.go @@ -260,7 +260,7 @@ func NewAlbumPageHeader(page *AlbumPage) *AlbumPageHeader { go a.page.pm.PlayAlbum(a.page.albumID, 0, false) }) shuffleBtn := widget.NewButtonWithIcon(lang.L("Shuffle"), myTheme.ShuffleIcon, func() { - a.page.pm.LoadTracks(a.page.tracklist.GetTracks(), backend.Replace, true) + a.page.pm.LoadTracks(a.page.tracklist.GetTracks(), backend.Replace, backend.Both, true) a.page.pm.PlayFromBeginning() }) var pop *widget.PopUpMenu diff --git a/ui/browsing/favoritespage.go b/ui/browsing/favoritespage.go index 4ef3000..1708113 100644 --- a/ui/browsing/favoritespage.go +++ b/ui/browsing/favoritespage.go @@ -98,7 +98,7 @@ func (a *FavoritesPage) createHeader(activeBtnIdx int) { widget.NewButtonWithIcon("", myTheme.TracksIcon, a.onShowFavoriteSongs)) a.shuffleBtn = widget.NewButtonWithIcon(lang.L("Shuffle"), myTheme.ShuffleIcon, func() { if tr := a.tracklistOrNil(); tr != nil { - a.pm.LoadTracks(tr.GetTracks(), backend.Replace, true /*shuffle*/) + a.pm.LoadTracks(tr.GetTracks(), backend.Replace, backend.Both, true /*shuffle*/) a.pm.PlayFromBeginning() } }) diff --git a/ui/browsing/nowplayingpage.go b/ui/browsing/nowplayingpage.go index 97716b9..241958c 100644 --- a/ui/browsing/nowplayingpage.go +++ b/ui/browsing/nowplayingpage.go @@ -159,18 +159,18 @@ func NewNowPlayingPage( a.relatedList.OnSetRating = a.queueList.OnSetRating a.relatedList.OnSetFavorite = a.queueList.OnSetFavorite a.relatedList.OnPlayItemAt = func(idx int) { - a.pm.LoadTracks(a.related, backend.Replace, false) + a.pm.LoadTracks(a.related, backend.Replace, backend.Both, false) a.pm.PlayTrackAt(idx) } a.relatedList.OnAddToQueue = func(items []mediaprovider.MediaItem) { - a.pm.LoadItems(items, backend.Append, false) + a.pm.LoadItems(items, backend.Append, backend.Both, false) } a.relatedList.OnPlaySelection = func(items []mediaprovider.MediaItem, shuffle bool) { - a.pm.LoadItems(items, backend.Replace, shuffle) + a.pm.LoadItems(items, backend.Replace, backend.Both, shuffle) a.pm.PlayFromBeginning() } a.relatedList.OnPlaySelectionNext = func(items []mediaprovider.MediaItem) { - a.pm.LoadItems(items, backend.InsertNext, false) + a.pm.LoadItems(items, backend.InsertNext, backend.Both, false) } a.relatedList.OnPlaySongRadio = func(track *mediaprovider.Track) { go func() { diff --git a/ui/browsing/playlistpage.go b/ui/browsing/playlistpage.go index 31374e1..e4aff18 100644 --- a/ui/browsing/playlistpage.go +++ b/ui/browsing/playlistpage.go @@ -348,11 +348,11 @@ func NewPlaylistPageHeader(page *PlaylistPage) *PlaylistPageHeader { }) a.editButton.Hidden = true playButton := widget.NewButtonWithIcon(lang.L("Play"), theme.MediaPlayIcon(), func() { - a.page.pm.LoadTracks(a.page.tracks, backend.Replace, false) + a.page.pm.LoadTracks(a.page.tracks, backend.Replace, backend.Both, false) a.page.pm.PlayFromBeginning() }) shuffleBtn := widget.NewButtonWithIcon(lang.L("Shuffle"), myTheme.ShuffleIcon, func() { - a.page.pm.LoadTracks(a.page.tracks, backend.Replace, true) + a.page.pm.LoadTracks(a.page.tracks, backend.Replace, backend.Both, true) a.page.pm.PlayFromBeginning() }) diff --git a/ui/controller/connectactions.go b/ui/controller/connectactions.go index 1f051e5..cc617c4 100644 --- a/ui/controller/connectactions.go +++ b/ui/controller/connectactions.go @@ -25,20 +25,20 @@ func (m *Controller) ConnectTracklistActions(tracklist *widgets.Tracklist) { func (m *Controller) connectTracklistActionsWithReplayGainMode(tracklist *widgets.Tracklist, mode player.ReplayGainMode) { tracklist.OnAddToPlaylist = m.DoAddTracksToPlaylistWorkflow tracklist.OnPlaySelectionNext = func(tracks []*mediaprovider.Track) { - m.App.PlaybackManager.LoadTracks(tracks, backend.InsertNext, false) + m.App.PlaybackManager.LoadTracks(tracks, backend.InsertNext, backend.Both, false) } tracklist.OnAddToQueue = func(tracks []*mediaprovider.Track) { - m.App.PlaybackManager.LoadTracks(tracks, backend.Append, false) + m.App.PlaybackManager.LoadTracks(tracks, backend.Append, backend.Both, false) } tracklist.OnPlayTrackAt = func(idx int) { - m.App.PlaybackManager.LoadTracks(tracklist.GetTracks(), backend.Replace, false) + m.App.PlaybackManager.LoadTracks(tracklist.GetTracks(), backend.Replace, backend.Both, false) 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) + m.App.PlaybackManager.LoadTracks(tracks, backend.Replace, backend.Both, shuffle) if m.App.Config.ReplayGain.Mode == backend.ReplayGainAuto { m.App.PlaybackManager.SetReplayGainMode(mode) } @@ -70,7 +70,7 @@ func (m *Controller) connectTracklistActionsWithReplayGainMode(tracklist *widget log.Println("Error getting song radio: ", err) return } - m.App.PlaybackManager.LoadTracks(tracks, backend.Replace, false) + m.App.PlaybackManager.LoadTracks(tracks, backend.Replace, backend.Both, false) if m.App.Config.ReplayGain.Mode == backend.ReplayGainAuto { m.App.PlaybackManager.SetReplayGainMode(mode) } @@ -164,11 +164,11 @@ func (m *Controller) onDownloadAlbum(albumID string) { func (m *Controller) ConnectArtistGridActions(grid *widgets.GridView) { grid.OnShowItemPage = func(id string) { m.NavigateTo(ArtistRoute(id)) } grid.OnPlayNext = func(artistID string) { - go m.App.PlaybackManager.LoadTracks(m.GetArtistTracks(artistID), backend.InsertNext, false) + go m.App.PlaybackManager.LoadTracks(m.GetArtistTracks(artistID), backend.InsertNext, backend.Both, false) } grid.OnPlay = func(artistID string, shuffle bool) { go m.App.PlaybackManager.PlayArtistDiscography(artistID, shuffle) } grid.OnAddToQueue = func(artistID string) { - go m.App.PlaybackManager.LoadTracks(m.GetArtistTracks(artistID), backend.Append, false) + go m.App.PlaybackManager.LoadTracks(m.GetArtistTracks(artistID), backend.Append, backend.Both, false) } grid.OnAddToPlaylist = func(artistID string) { m.DoAddTracksToPlaylistWorkflow( diff --git a/ui/controller/searchdialog.go b/ui/controller/searchdialog.go index b7c44d3..3c4ab65 100644 --- a/ui/controller/searchdialog.go +++ b/ui/controller/searchdialog.go @@ -46,7 +46,7 @@ func (c *Controller) ShowQuickSearch() { case mediaprovider.ContentTypeTrack: c.App.PlaybackManager.LoadTracks( []*mediaprovider.Track{item.(*mediaprovider.Track)}, - backend.Replace, false /*shuffle*/) + backend.Replace, backend.Both, false /*shuffle*/) c.App.PlaybackManager.PlayFromBeginning() case mediaprovider.ContentTypeAlbum: go c.App.PlaybackManager.PlayAlbum(id, 0, shuffle) @@ -69,7 +69,7 @@ func (c *Controller) ShowQuickSearch() { go func() { tracks, err := c.GetSongRadioTracks(track) if err != nil { - c.App.PlaybackManager.LoadTracks(tracks, backend.Replace, false) + c.App.PlaybackManager.LoadTracks(tracks, backend.Replace, backend.Both, false) c.App.PlaybackManager.PlayFromBeginning() } }() @@ -99,6 +99,7 @@ func (c *Controller) ShowQuickSearch() { func (c *Controller) handleSearchDialogOnAddToQueue(t mediaprovider.ContentType, id string, item any, next bool) { insertMode := backend.Append + queueType := backend.Both if next { insertMode = backend.InsertNext } @@ -106,13 +107,13 @@ func (c *Controller) handleSearchDialogOnAddToQueue(t mediaprovider.ContentType, case mediaprovider.ContentTypeTrack: c.App.PlaybackManager.LoadTracks( []*mediaprovider.Track{item.(*mediaprovider.Track)}, - insertMode, false /*shuffle*/) + insertMode, queueType, false /*shuffle*/) case mediaprovider.ContentTypeAlbum: go c.App.PlaybackManager.LoadAlbum(id, insertMode, false) case mediaprovider.ContentTypeArtist: go func() { tracks := c.GetArtistTracks(id) - c.App.PlaybackManager.LoadTracks(tracks, insertMode, false) + c.App.PlaybackManager.LoadTracks(tracks, insertMode, queueType, false) }() case mediaprovider.ContentTypePlaylist: go c.App.PlaybackManager.LoadPlaylist(id, insertMode, false) @@ -120,7 +121,7 @@ func (c *Controller) handleSearchDialogOnAddToQueue(t mediaprovider.ContentType, go func() { tr, err := c.App.ServerManager.Server.GetRandomTracks(id /*genre name*/, c.App.Config.Application.EnqueueBatchSize) if err != nil { - c.App.PlaybackManager.LoadTracks(tr, insertMode, false /*shuffle*/) + c.App.PlaybackManager.LoadTracks(tr, insertMode, queueType, false /*shuffle*/) } }() case mediaprovider.ContentTypeRadioStation: