add Now Playing page to show play queue

This commit is contained in:
Drew Weymouth
2023-02-11 12:00:33 -08:00
parent 1cb273e086
commit 7d5677057c
5 changed files with 145 additions and 17 deletions
+102
View File
@@ -0,0 +1,102 @@
package browsing
import (
"supersonic/backend"
"supersonic/ui/controller"
"supersonic/ui/layouts"
"supersonic/ui/widgets"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
"github.com/dweymouth/go-subsonic/subsonic"
)
type NowPlayingPage struct {
widget.BaseWidget
nowPlayingPageState
title *widget.RichText
tracklist *widgets.Tracklist
nowPlayingID string
container *fyne.Container
}
type nowPlayingPageState struct {
contr controller.Controller
sm *backend.ServerManager
pm *backend.PlaybackManager
nav func(Route)
}
func NewNowPlayingPage(
contr controller.Controller,
sm *backend.ServerManager,
pm *backend.PlaybackManager,
nav func(Route),
) *NowPlayingPage {
a := &NowPlayingPage{nowPlayingPageState: nowPlayingPageState{contr: contr, sm: sm, pm: pm, nav: nav}}
a.ExtendBaseWidget(a)
a.tracklist = widgets.NewTracklist(nil)
a.tracklist.AutoNumber = true
a.tracklist.DisablePlaybackMenu = true
a.tracklist.OnPlayTrackAt = a.onPlayTrackAt
a.tracklist.OnAddToPlaylist = a.contr.DoAddTracksToPlaylistWorkflow
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},
container.NewBorder(a.title, nil, nil, nil, a.tracklist))
a.loadAsync()
return a
}
func (a *NowPlayingPage) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(a.container)
}
func (a *NowPlayingPage) Save() SavedPage {
nps := a.nowPlayingPageState
return &nps
}
func (a *NowPlayingPage) Route() Route {
return NowPlayingRoute()
}
func (a *NowPlayingPage) Tapped(*fyne.PointEvent) {
a.tracklist.UnselectAll()
}
func (a *NowPlayingPage) SelectAll() {
a.tracklist.SelectAll()
}
func (a *NowPlayingPage) OnSongChange(song *subsonic.Child) {
if song == nil {
a.nowPlayingID = ""
} else {
a.nowPlayingID = song.ID
}
a.tracklist.SetNowPlaying(a.nowPlayingID)
}
func (a *NowPlayingPage) Reload() {
a.loadAsync()
}
func (a *NowPlayingPage) onPlayTrackAt(tracknum int) {
_ = a.pm.PlayTrackAt(tracknum)
}
func (a *NowPlayingPage) loadAsync() {
go func() {
queue := a.pm.GetPlayQueue()
a.tracklist.Tracks = queue
a.tracklist.SetNowPlaying(a.nowPlayingID)
}()
}
func (s *nowPlayingPageState) Restore() Page {
return NewNowPlayingPage(s.contr, s.sm, s.pm, s.nav)
}
+7 -3
View File
@@ -3,7 +3,6 @@ package browsing
import (
"supersonic/backend"
"supersonic/ui/controller"
"supersonic/ui/util"
)
type PageName int
@@ -17,6 +16,7 @@ const (
Genre
Genres
Favorites
NowPlaying
Playlist
Playlists
)
@@ -61,6 +61,10 @@ func ArtistsRoute() Route {
return Route{Page: Artists}
}
func NowPlayingRoute() Route {
return Route{Page: NowPlaying}
}
type NavigationHandler interface {
SetPage(Page)
}
@@ -69,8 +73,6 @@ type Router struct {
App *backend.App
Controller controller.Controller
Nav NavigationHandler
pop util.PopUpProvider
}
func NewRouter(app *backend.App, controller controller.Controller, nav NavigationHandler) Router {
@@ -98,6 +100,8 @@ func (r Router) CreatePage(rte Route) Page {
return NewGenrePage(rte.Arg, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute)
case Genres:
return NewArtistsGenresPage(true, r.App.ServerManager, r.OpenRoute)
case NowPlaying:
return NewNowPlayingPage(r.Controller, r.App.ServerManager, r.App.PlaybackManager, r.OpenRoute)
case Playlist:
return NewPlaylistPage(rte.Arg, r.Controller, r.App.ServerManager, r.App.PlaybackManager, r.App.ImageManager, r.OpenRoute)
case Playlists:
+3
View File
@@ -82,6 +82,9 @@ func (m *MainWindow) PromptForFirstServer(cb func(string, string, string, string
}
func (m *MainWindow) addNavigationButtons() {
m.BrowsingPane.AddNavigationButton(res.ResHeadphonesInvertPng, func() {
m.Router.OpenRoute(browsing.NowPlayingRoute())
})
m.BrowsingPane.AddNavigationButton(res.ResHeartFilledInvertPng, func() {
m.Router.OpenRoute(browsing.FavoritesRoute())
})
+19 -14
View File
@@ -119,7 +119,8 @@ type Tracklist struct {
Tracks []*subsonic.Child
AutoNumber bool
// must be set before the context menu is shown for the first time
AuxiliaryMenuItems []*fyne.MenuItem
AuxiliaryMenuItems []*fyne.MenuItem
DisablePlaybackMenu bool
// user action callbacks
OnPlayTrackAt func(int)
@@ -216,23 +217,27 @@ func (t *Tracklist) onShowContextMenu(e *fyne.PointEvent, trackIdx int) {
t.selectionMgr.Select(trackIdx)
t.Refresh()
if t.ctxMenu == nil {
t.ctxMenu = fyne.NewMenu("",
fyne.NewMenuItem("Play", func() {
if t.OnPlaySelection != nil {
t.OnPlaySelection(t.selectedTracks())
}
}),
fyne.NewMenuItem("Add to queue", func() {
if t.OnPlaySelection != nil {
t.OnAddToQueue(t.selectedTracks())
}
}),
t.ctxMenu = fyne.NewMenu("")
if !t.DisablePlaybackMenu {
t.ctxMenu.Items = append(t.ctxMenu.Items,
fyne.NewMenuItem("Play", func() {
if t.OnPlaySelection != nil {
t.OnPlaySelection(t.selectedTracks())
}
}))
t.ctxMenu.Items = append(t.ctxMenu.Items,
fyne.NewMenuItem("Add to queue", func() {
if t.OnPlaySelection != nil {
t.OnAddToQueue(t.selectedTracks())
}
}))
}
t.ctxMenu.Items = append(t.ctxMenu.Items,
fyne.NewMenuItem("Add to playlist...", func() {
if t.OnAddToPlaylist != nil {
t.OnAddToPlaylist(t.selectedTrackIDs())
}
}),
)
}))
if len(t.AuxiliaryMenuItems) > 0 {
t.ctxMenu.Items = append(t.ctxMenu.Items, fyne.NewMenuItemSeparator())
t.ctxMenu.Items = append(t.ctxMenu.Items, t.AuxiliaryMenuItems...)