Fix #421: properly handle reordering and deleting repeat tracks in queue
This commit is contained in:
@@ -341,15 +341,15 @@ func (p *playbackEngine) UpdatePlayQueue(items []mediaprovider.MediaItem) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *playbackEngine) RemoveTracksFromQueue(trackIDs []string) {
|
func (p *playbackEngine) RemoveTracksFromQueue(idxs []int) {
|
||||||
newQueue := make([]mediaprovider.MediaItem, 0, len(p.playQueue)-len(trackIDs))
|
newQueue := make([]mediaprovider.MediaItem, 0, len(p.playQueue)-len(idxs))
|
||||||
idSet := sharedutil.ToSet(trackIDs)
|
idxSet := sharedutil.ToSet(idxs)
|
||||||
isPlayingTrackRemoved := false
|
isPlayingTrackRemoved := false
|
||||||
isNextPlayingTrackremoved := false
|
isNextPlayingTrackremoved := false
|
||||||
nowPlaying := p.NowPlayingIndex()
|
nowPlaying := p.NowPlayingIndex()
|
||||||
newNowPlaying := nowPlaying
|
newNowPlaying := nowPlaying
|
||||||
for i, tr := range p.playQueue {
|
for i, tr := range p.playQueue {
|
||||||
if _, ok := idSet[tr.Metadata().ID]; ok {
|
if _, ok := idxSet[i]; ok {
|
||||||
if i < nowPlaying {
|
if i < nowPlaying {
|
||||||
// if removing a track earlier than the currently playing one (if any),
|
// if removing a track earlier than the currently playing one (if any),
|
||||||
// decrement new now playing index by one to account for new position in queue
|
// decrement new now playing index by one to account for new position in queue
|
||||||
|
|||||||
@@ -267,8 +267,8 @@ func (p *PlaybackManager) OnTrackRatingChanged(id string, rating int) {
|
|||||||
p.engine.OnTrackRatingChanged(id, rating)
|
p.engine.OnTrackRatingChanged(id, rating)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PlaybackManager) RemoveTracksFromQueue(trackIDs []string) {
|
func (p *PlaybackManager) RemoveTracksFromQueue(idxs []int) {
|
||||||
p.engine.RemoveTracksFromQueue(trackIDs)
|
p.engine.RemoveTracksFromQueue(idxs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop playback and clear the play queue.
|
// Stop playback and clear the play queue.
|
||||||
|
|||||||
@@ -144,9 +144,9 @@ func NewNowPlayingPage(
|
|||||||
a.queueList.OnShowArtistPage = func(artistID string) {
|
a.queueList.OnShowArtistPage = func(artistID string) {
|
||||||
a.contr.NavigateTo(controller.ArtistRoute(artistID))
|
a.contr.NavigateTo(controller.ArtistRoute(artistID))
|
||||||
}
|
}
|
||||||
a.queueList.OnRemoveFromQueue = func(trackIDs []string) {
|
a.queueList.OnRemoveFromQueue = func(idxs []int) {
|
||||||
a.queueList.UnselectAll()
|
a.queueList.UnselectAll()
|
||||||
a.pm.RemoveTracksFromQueue(trackIDs)
|
a.pm.RemoveTracksFromQueue(idxs)
|
||||||
}
|
}
|
||||||
a.queueList.OnSetRating = func(trackIDs []string, rating int) {
|
a.queueList.OnSetRating = func(trackIDs []string, rating int) {
|
||||||
contr.SetTrackRatings(trackIDs, rating)
|
contr.SetTrackRatings(trackIDs, rating)
|
||||||
@@ -515,14 +515,7 @@ func (a *NowPlayingPage) Refresh() {
|
|||||||
a.BaseWidget.Refresh()
|
a.BaseWidget.Refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *NowPlayingPage) doSetNewTrackOrder(trackIDs []string, insertPos int) {
|
func (a *NowPlayingPage) doSetNewTrackOrder(idxs []int, insertPos int) {
|
||||||
trackIDSet := sharedutil.ToSet(trackIDs)
|
|
||||||
idxs := make([]int, 0, len(trackIDs))
|
|
||||||
for i, tr := range a.queue {
|
|
||||||
if _, ok := trackIDSet[tr.Metadata().ID]; ok {
|
|
||||||
idxs = append(idxs, i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newTracks := sharedutil.ReorderItems(a.queue, idxs, insertPos)
|
newTracks := sharedutil.ReorderItems(a.queue, idxs, insertPos)
|
||||||
a.pm.UpdatePlayQueue(newTracks)
|
a.pm.UpdatePlayQueue(newTracks)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ func SelectedItemIDs(items []*TrackListModel) []string {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SelectedIndexes(items []*TrackListModel) []int {
|
||||||
|
var selected []int
|
||||||
|
for i, tm := range items {
|
||||||
|
if tm.Selected {
|
||||||
|
selected = append(selected, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selected
|
||||||
|
}
|
||||||
|
|
||||||
func SelectItem(items []*TrackListModel, idx int) {
|
func SelectItem(items []*TrackListModel, idx int) {
|
||||||
if items[idx].Selected {
|
if items[idx].Selected {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ type PlayQueueList struct {
|
|||||||
OnAddToPlaylist func(trackIDs []string)
|
OnAddToPlaylist func(trackIDs []string)
|
||||||
OnSetFavorite func(trackIDs []string, fav bool)
|
OnSetFavorite func(trackIDs []string, fav bool)
|
||||||
OnSetRating func(trackIDs []string, rating int)
|
OnSetRating func(trackIDs []string, rating int)
|
||||||
OnRemoveFromQueue func(itemIDs []string)
|
OnRemoveFromQueue func(idxs []int)
|
||||||
OnDownload func(tracks []*mediaprovider.Track, downloadName string)
|
OnDownload func(tracks []*mediaprovider.Track, downloadName string)
|
||||||
OnShare func(tracks []*mediaprovider.Track)
|
OnShare func(tracks []*mediaprovider.Track)
|
||||||
OnShowArtistPage func(artistID string)
|
OnShowArtistPage func(artistID string)
|
||||||
OnReorderItems func(itemIDs []string, reorderTo int)
|
OnReorderItems func(idxs []int, reorderTo int)
|
||||||
|
|
||||||
useNonQueueMenu bool
|
useNonQueueMenu bool
|
||||||
menu *widget.PopUpMenu // ctx menu for when only tracks are selected
|
menu *widget.PopUpMenu // ctx menu for when only tracks are selected
|
||||||
@@ -111,7 +111,7 @@ func NewPlayQueueList(im *backend.ImageManager, useNonQueueMenu bool) *PlayQueue
|
|||||||
}
|
}
|
||||||
p.list.OnDragEnd = func(dragged, insertPos int) {
|
p.list.OnDragEnd = func(dragged, insertPos int) {
|
||||||
if p.OnReorderItems != nil {
|
if p.OnReorderItems != nil {
|
||||||
p.OnReorderItems(p.selectedItemIDs(), insertPos)
|
p.OnReorderItems(p.selectedIdxs(), insertPos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +309,7 @@ func (p *PlayQueueList) ensureTracksMenu() {
|
|||||||
if !p.useNonQueueMenu {
|
if !p.useNonQueueMenu {
|
||||||
remove := fyne.NewMenuItem("Remove from queue", func() {
|
remove := fyne.NewMenuItem("Remove from queue", func() {
|
||||||
if p.OnRemoveFromQueue != nil {
|
if p.OnRemoveFromQueue != nil {
|
||||||
p.OnRemoveFromQueue(p.selectedItemIDs())
|
p.OnRemoveFromQueue(p.selectedIdxs())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
remove.Icon = theme.ContentRemoveIcon()
|
remove.Icon = theme.ContentRemoveIcon()
|
||||||
@@ -330,7 +330,7 @@ func (p *PlayQueueList) ensureRadiosMenu() {
|
|||||||
}
|
}
|
||||||
remove := fyne.NewMenuItem("Remove from queue", func() {
|
remove := fyne.NewMenuItem("Remove from queue", func() {
|
||||||
if p.OnRemoveFromQueue != nil {
|
if p.OnRemoveFromQueue != nil {
|
||||||
p.OnRemoveFromQueue(p.selectedItemIDs())
|
p.OnRemoveFromQueue(p.selectedIdxs())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
remove.Icon = theme.ContentRemoveIcon()
|
remove.Icon = theme.ContentRemoveIcon()
|
||||||
@@ -386,6 +386,12 @@ func (t *PlayQueueList) selectedItemIDs() []string {
|
|||||||
return util.SelectedItemIDs(t.items)
|
return util.SelectedItemIDs(t.items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *PlayQueueList) selectedIdxs() []int {
|
||||||
|
t.tracksMutex.RLock()
|
||||||
|
defer t.tracksMutex.RUnlock()
|
||||||
|
return util.SelectedIndexes(t.items)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PlayQueueList) CreateRenderer() fyne.WidgetRenderer {
|
func (p *PlayQueueList) CreateRenderer() fyne.WidgetRenderer {
|
||||||
return widget.NewSimpleRenderer(p.list)
|
return widget.NewSimpleRenderer(p.list)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user