now playing page can remove tracks from play queue
This commit is contained in:
@@ -64,6 +64,7 @@ func NewPlaybackManager(ctx context.Context, s *ServerManager, p *player.Player)
|
||||
pm.checkScrobble(pm.playTimeStopwatch.Elapsed())
|
||||
pm.playTimeStopwatch.Reset()
|
||||
pm.stopPollTimePos()
|
||||
pm.doUpdateTimePos()
|
||||
for _, cb := range pm.onSongChange {
|
||||
cb(nil)
|
||||
}
|
||||
@@ -171,14 +172,43 @@ func (p *PlaybackManager) GetPlayQueue() []*subsonic.Child {
|
||||
return pq
|
||||
}
|
||||
|
||||
// trackIdxs must be sorted
|
||||
func (p *PlaybackManager) RemoveTracksFromQueue(trackIdxs []int) {
|
||||
// TODO
|
||||
newQueue := make([]*subsonic.Child, 0, len(p.playQueue)-len(trackIdxs))
|
||||
rmCount := 0
|
||||
rmIdx := 0
|
||||
for i, tr := range p.playQueue {
|
||||
if rmIdx < len(trackIdxs) && trackIdxs[rmIdx] == i {
|
||||
// removing this track
|
||||
rmIdx++
|
||||
if err := p.player.RemoveTrackAt(i - rmCount); err == nil {
|
||||
rmCount++
|
||||
} else {
|
||||
log.Printf("error removing track: %v", err.Error())
|
||||
// did not remove this track
|
||||
newQueue = append(newQueue, tr)
|
||||
}
|
||||
} else {
|
||||
// not removing this track
|
||||
newQueue = append(newQueue, tr)
|
||||
}
|
||||
}
|
||||
p.playQueue = newQueue
|
||||
p.nowPlayingIdx = p.player.GetStatus().PlaylistPos
|
||||
// fire on song change callbacks in case the playing track was removed
|
||||
// TODO: only call this if the playing track actually was removed
|
||||
for _, cb := range p.onSongChange {
|
||||
cb(p.NowPlaying())
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PlaybackManager) checkScrobble(playDur time.Duration) {
|
||||
if playDur.Seconds() < 0.1 || p.curTrackTime < 0.1 {
|
||||
if len(p.playQueue) == 0 || p.nowPlayingIdx < 0 {
|
||||
return
|
||||
}
|
||||
if playDur.Seconds() < 0.1 || p.curTrackTime < 0.1 {
|
||||
return // ignore spurious onTrackChange callbacks
|
||||
}
|
||||
song := p.playQueue[p.nowPlayingIdx]
|
||||
if playDur.Seconds()/p.curTrackTime > ScrobbleThreshold {
|
||||
log.Printf("Scrobbling %q", song.Title)
|
||||
|
||||
@@ -131,6 +131,14 @@ func (p *Player) PlayFile(url string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Removes the item at the given index from the internal playqueue.
|
||||
func (p *Player) RemoveTrackAt(idx int) error {
|
||||
if p.mpv == nil {
|
||||
return ErrUnitialized
|
||||
}
|
||||
return p.mpv.Command([]string{"playlist-remove", strconv.Itoa(idx)})
|
||||
}
|
||||
|
||||
// Stops playback and clears the play queue.
|
||||
func (p *Player) Stop() error {
|
||||
if p.mpv == nil {
|
||||
|
||||
@@ -43,6 +43,9 @@ func NewNowPlayingPage(
|
||||
a.tracklist.DisablePlaybackMenu = true
|
||||
a.tracklist.OnPlayTrackAt = a.onPlayTrackAt
|
||||
a.tracklist.OnAddToPlaylist = a.contr.DoAddTracksToPlaylistWorkflow
|
||||
a.tracklist.AuxiliaryMenuItems = []*fyne.MenuItem{
|
||||
fyne.NewMenuItem("Remove from queue", a.onRemoveSelectedFromQueue),
|
||||
}
|
||||
a.title = widget.NewRichTextWithText("Now Playing")
|
||||
a.title.Segments[0].(*widget.TextSegment).Style.SizeName = widget.RichTextStyleHeading.SizeName
|
||||
a.container = container.New(&layouts.MaxPadLayout{PadLeft: 15, PadRight: 15, PadTop: 5, PadBottom: 15},
|
||||
@@ -89,6 +92,12 @@ func (a *NowPlayingPage) onPlayTrackAt(tracknum int) {
|
||||
_ = a.pm.PlayTrackAt(tracknum)
|
||||
}
|
||||
|
||||
func (a *NowPlayingPage) onRemoveSelectedFromQueue() {
|
||||
a.pm.RemoveTracksFromQueue(a.tracklist.SelectedTrackIndexes())
|
||||
a.tracklist.UnselectAll()
|
||||
go a.Reload()
|
||||
}
|
||||
|
||||
func (a *NowPlayingPage) loadAsync() {
|
||||
go func() {
|
||||
queue := a.pm.GetPlayQueue()
|
||||
|
||||
Reference in New Issue
Block a user