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.checkScrobble(pm.playTimeStopwatch.Elapsed())
|
||||||
pm.playTimeStopwatch.Reset()
|
pm.playTimeStopwatch.Reset()
|
||||||
pm.stopPollTimePos()
|
pm.stopPollTimePos()
|
||||||
|
pm.doUpdateTimePos()
|
||||||
for _, cb := range pm.onSongChange {
|
for _, cb := range pm.onSongChange {
|
||||||
cb(nil)
|
cb(nil)
|
||||||
}
|
}
|
||||||
@@ -171,14 +172,43 @@ func (p *PlaybackManager) GetPlayQueue() []*subsonic.Child {
|
|||||||
return pq
|
return pq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trackIdxs must be sorted
|
||||||
func (p *PlaybackManager) RemoveTracksFromQueue(trackIdxs []int) {
|
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) {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
if playDur.Seconds() < 0.1 || p.curTrackTime < 0.1 {
|
||||||
|
return // ignore spurious onTrackChange callbacks
|
||||||
|
}
|
||||||
song := p.playQueue[p.nowPlayingIdx]
|
song := p.playQueue[p.nowPlayingIdx]
|
||||||
if playDur.Seconds()/p.curTrackTime > ScrobbleThreshold {
|
if playDur.Seconds()/p.curTrackTime > ScrobbleThreshold {
|
||||||
log.Printf("Scrobbling %q", song.Title)
|
log.Printf("Scrobbling %q", song.Title)
|
||||||
|
|||||||
@@ -131,6 +131,14 @@ func (p *Player) PlayFile(url string) error {
|
|||||||
return err
|
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.
|
// Stops playback and clears the play queue.
|
||||||
func (p *Player) Stop() error {
|
func (p *Player) Stop() error {
|
||||||
if p.mpv == nil {
|
if p.mpv == nil {
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ func NewNowPlayingPage(
|
|||||||
a.tracklist.DisablePlaybackMenu = true
|
a.tracklist.DisablePlaybackMenu = true
|
||||||
a.tracklist.OnPlayTrackAt = a.onPlayTrackAt
|
a.tracklist.OnPlayTrackAt = a.onPlayTrackAt
|
||||||
a.tracklist.OnAddToPlaylist = a.contr.DoAddTracksToPlaylistWorkflow
|
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 = widget.NewRichTextWithText("Now Playing")
|
||||||
a.title.Segments[0].(*widget.TextSegment).Style.SizeName = widget.RichTextStyleHeading.SizeName
|
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},
|
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)
|
_ = a.pm.PlayTrackAt(tracknum)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *NowPlayingPage) onRemoveSelectedFromQueue() {
|
||||||
|
a.pm.RemoveTracksFromQueue(a.tracklist.SelectedTrackIndexes())
|
||||||
|
a.tracklist.UnselectAll()
|
||||||
|
go a.Reload()
|
||||||
|
}
|
||||||
|
|
||||||
func (a *NowPlayingPage) loadAsync() {
|
func (a *NowPlayingPage) loadAsync() {
|
||||||
go func() {
|
go func() {
|
||||||
queue := a.pm.GetPlayQueue()
|
queue := a.pm.GetPlayQueue()
|
||||||
|
|||||||
Reference in New Issue
Block a user