From 9d1d1a02fde0a1561ad6a61e551a144bbeadc45b Mon Sep 17 00:00:00 2001 From: Simon Garrelou Date: Fri, 9 Dec 2022 15:21:04 +0100 Subject: Add play queue page --- music/playqueue.go | 17 +++++++++++++++++ src/app.go | 16 ++++++++++++++-- src/footer.go | 2 ++ src/header.go | 4 +++- src/keybinds.go | 22 ++++++++++++++++++++++ src/page_artists.go | 13 +------------ src/page_queue.go | 38 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 97 insertions(+), 15 deletions(-) create mode 100644 src/keybinds.go create mode 100644 src/page_queue.go diff --git a/music/playqueue.go b/music/playqueue.go index 76d14df..fe82c4e 100644 --- a/music/playqueue.go +++ b/music/playqueue.go @@ -142,6 +142,23 @@ func (q *Queue) TogglePause() { } } +func (q *Queue) SkipTo(s *subsonic.Child) { + i := -1 + for n, s2 := range q.GetSongs() { + if s.ID == s2.ID { + i = n + break + } + } + + if i == -1 { + return + } + + q.songs = q.songs[i:] + q.Play() +} + func (p *Queue) setupSpeaker(s beep.Streamer, format beep.Format) (beep.Streamer, error) { if !p.speakerInitialized { err := speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10)) diff --git a/src/app.go b/src/app.go index 029644c..3a02dbe 100644 --- a/src/app.go +++ b/src/app.go @@ -19,10 +19,13 @@ type app struct { footer *tview.TextView cfg *Config - // Artists panel + // Artists page artistsTree *tview.TreeView songsList *tview.List + // Play queue page + playQueueList *tview.List + // Subsonic variables sub *subsonic.Client playQueue *music.Queue @@ -42,6 +45,7 @@ func Run(cfg *Config) { a.pages.SetBorder(true) a.pages.AddPage("config", a.configPage(), true, false) a.pages.AddPage("artists", a.artistsPage(), true, false) + a.pages.AddPage("playqueue", a.queuePage(), true, false) mainLayout := tview.NewFlex(). SetDirection(tview.FlexRow). @@ -69,9 +73,12 @@ func Run(cfg *Config) { a.switchToPage("artists") return nil case tcell.KeyF2: - a.switchToPage("playlists") + a.switchToPage("playqueue") return nil case tcell.KeyF3: + a.switchToPage("playlists") + return nil + case tcell.KeyF4: a.switchToPage("config") return nil } @@ -97,6 +104,11 @@ func (a *app) switchToPage(name string) { a.headerSections.Highlight("artists") a.tv.SetFocus(a.artistsTree) a.pages.SetBorder(false) + case "playqueue": + a.pages.SwitchToPage("playqueue") + a.headerSections.Highlight("playqueue") + a.tv.SetFocus(a.playQueueList) + a.pages.SetBorder(true) case "playlists": a.pages.SwitchToPage("playlists") a.headerSections.Highlight("playlists") diff --git a/src/footer.go b/src/footer.go index 2695a61..7240b0f 100644 --- a/src/footer.go +++ b/src/footer.go @@ -4,6 +4,8 @@ func (a *app) updateFooter() { switch a.headerSections.GetHighlights()[0] { case "artists": a.footer.SetText("[blue]l:[yellow] Next song [blue]k:[yellow] Toggle pause") + case "playqueue": + a.footer.SetText("[blue]l:[yellow] Next song [blue]k:[yellow] Toggle pause") case "playlists": a.footer.SetText("Come back later!") case "config": diff --git a/src/header.go b/src/header.go index e7b7eea..961e5b0 100644 --- a/src/header.go +++ b/src/header.go @@ -24,7 +24,7 @@ func (a *app) buildHeader() tview.Primitive { a.switchToPage(hl) } }) - fmt.Fprintf(a.headerSections, `["artists"]F1: Artists[""] | ["playlists"]F2: Playlists[""] | ["config"]F3: Configuration[""]`) + fmt.Fprintf(a.headerSections, `["artists"]F1: Artists[""] | ["playqueue"]F2: Queue[""] | ["playlists"]F3: Playlists[""] | ["config"]F4: Configuration[""]`) a.headerNowPlaying = tview.NewTextView().SetTextAlign(tview.AlignRight) @@ -42,6 +42,8 @@ func (a *app) buildHeader() tview.Primitive { a.headerNowPlaying.SetText("Not playing") } + a.updatePageQueue() + // Fix "Now Playing" not always updating go a.tv.Draw() }) diff --git a/src/keybinds.go b/src/keybinds.go new file mode 100644 index 0000000..d69be0b --- /dev/null +++ b/src/keybinds.go @@ -0,0 +1,22 @@ +package src + +import ( + "github.com/gdamore/tcell/v2" + "github.com/rivo/tview" +) + +func (a *app) setupMusicControlKeys(p *tview.Box) { + // Add 'k' and 'l' key bindings + p.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + if event.Rune() == 'l' { + a.playQueue.Next() + return nil + } + + if event.Rune() == 'k' { + a.playQueue.TogglePause() + return nil + } + return event + }) +} diff --git a/src/page_artists.go b/src/page_artists.go index 4361767..104fdc7 100644 --- a/src/page_artists.go +++ b/src/page_artists.go @@ -61,18 +61,7 @@ func (a *app) artistsPage() tview.Primitive { return event }) - grid.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { - if event.Rune() == 'l' { - a.playQueue.Next() - return nil - } - - if event.Rune() == 'k' { - a.playQueue.TogglePause() - return nil - } - return event - }) + a.setupMusicControlKeys(grid.Box) grid.AddItem(a.artistsTree, 0, 1, true) grid.AddItem(a.songsList, 0, 1, false) diff --git a/src/page_queue.go b/src/page_queue.go new file mode 100644 index 0000000..fe8910f --- /dev/null +++ b/src/page_queue.go @@ -0,0 +1,38 @@ +package src + +import ( + "fmt" + + "github.com/rivo/tview" +) + +func (a *app) queuePage() tview.Primitive { + a.playQueueList = tview.NewList(). + ShowSecondaryText(false). + SetHighlightFullLine(true) + + a.setupMusicControlKeys(a.playQueueList.Box) + + a.updatePageQueue() + + return a.playQueueList +} + +func (a *app) updatePageQueue() { + sel := a.playQueueList.GetCurrentItem() + a.playQueueList.Clear() + + for _, song := range a.playQueue.GetSongs() { + ownSong := *song + a.playQueueList.AddItem(fmt.Sprintf("* %s - %s", song.Title, song.Artist), "", 0, func() { + a.playQueue.SkipTo(&ownSong) + a.playQueueList.SetCurrentItem(0) + }) + } + + if sel < a.playQueueList.GetItemCount() { + a.playQueueList.SetCurrentItem(sel) + } else { + a.playQueueList.SetCurrentItem(a.playQueueList.GetItemCount() - 1) + } +} -- cgit v1.2.3