diff --git a/go.mod b/go.mod index 698bfdd..8f5d4c7 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/zmb3/spotify/v2 v2.3.1 golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 + golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 google.golang.org/api v0.30.0 modernc.org/sqlite v1.20.4 tuxpa.in/a/zlog v1.60.0 diff --git a/go.sum b/go.sum index 530afa1..5247a64 100644 --- a/go.sum +++ b/go.sum @@ -297,6 +297,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/src/commands/commands.go b/src/commands/commands.go index f02e26b..23549d5 100644 --- a/src/commands/commands.go +++ b/src/commands/commands.go @@ -172,11 +172,11 @@ func (c *Commands) AlbumTracks(ctx *gctx.Context, album spotify.ID, page int) (* } func (c *Commands) UserAlbums(ctx *gctx.Context, page int) (*spotify.SavedAlbumPage, error) { - albums, err := c.Client().CurrentUsersAlbums(ctx, spotify.Limit(50), spotify.Offset((page-1)*50)) - if err != nil { - return nil, err - } - return albums, nil + return c.Client().CurrentUsersAlbums(ctx, spotify.Limit(50), spotify.Offset((page-1)*50)) +} + +func (c *Commands) UserQueue(ctx *gctx.Context) (*spotify.Queue, error) { + return c.Client().GetQueue(ctx) } func (c *Commands) PlayUrl(ctx *gctx.Context, args []string) error { @@ -990,10 +990,6 @@ func (c *Commands) TrackList(ctx *gctx.Context, page int) (*spotify.SavedTrackPa return c.Client().CurrentUsersTracks(ctx, spotify.Limit(50), spotify.Offset((page-1)*50)) } -func (c *Commands) GetQueue(ctx *gctx.Context) (*spotify.Queue, error) { - return c.Client().GetQueue(ctx) -} - func (c *Commands) Playlists(ctx *gctx.Context, page int) (*spotify.SimplePlaylistPage, error) { return c.Client().CurrentUsersPlaylists(ctx, spotify.Limit(50), spotify.Offset((page-1)*50)) } diff --git a/src/tui/handlers.go b/src/tui/handlers.go index 1a393b4..85ad868 100644 --- a/src/tui/handlers.go +++ b/src/tui/handlers.go @@ -92,6 +92,13 @@ func HandlePlayTrack(ctx *gctx.Context, commands *commands.Commands, track spoti } } +func HandleSkipWithinContext(ctx *gctx.Context, commands *commands.Commands, amt int) { + err := commands.Next(ctx, amt) + if err != nil { + return + } +} + func HandleSetDevice(ctx *gctx.Context, commands *commands.Commands, player spotify.PlayerDevice) { err := commands.SetDevice(ctx, player) if err != nil { diff --git a/src/tui/main.go b/src/tui/main.go index ce4a947..e9baaa3 100644 --- a/src/tui/main.go +++ b/src/tui/main.go @@ -35,6 +35,7 @@ const ( ArtistAlbum Mode = "artistalbum" Artist Mode = "artist" Artists Mode = "artists" + Queue Mode = "queue" Tracks Mode = "tracks" Albums Mode = "albums" Main Mode = "main" @@ -130,7 +131,7 @@ func (m *mainModel) GoBack() (tea.Cmd, error) { switch m.mode { case Main: return tea.Quit, nil - case Albums, Artists, Tracks, Playlist, Devices, Search: + case Albums, Artists, Tracks, Playlist, Devices, Search, Queue: m.mode = Main new_items, err := MainView(m.ctx, m.commands) if err != nil { @@ -243,6 +244,17 @@ func (m *mainModel) CopyToClipboard() error { func (m *mainModel) SelectItem() error { switch m.mode { + case Queue: + page = 1 + go func() { + HandleSkipWithinContext(m.ctx, m.commands, m.list.Index()) + new_items, err := QueueView(m.ctx, m.commands) + if err != nil { + return + } + m.list.SetItems(new_items) + m.list.ResetSelected() + }() case Search: page = 1 switch item := m.list.SelectedItem().(mainItem).SpotifyItem.(type) { @@ -323,6 +335,14 @@ func (m *mainModel) SelectItem() error { case Main: page = 1 switch item := m.list.SelectedItem().(mainItem).SpotifyItem.(type) { + case spotify.Queue: + m.mode = Queue + new_items, err := QueueView(m.ctx, m.commands) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() case *spotify.FullArtistCursorPage: m.mode = Artists new_items, err := ArtistsView(m.ctx, m.commands) @@ -527,6 +547,17 @@ func (m *mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { cmd := m.progress.SetPercent(float64(playing.Progress) / float64(playing.Item.Duration)) m.playing = playing m.playbackContext = playbackContext + if m.mode == Queue { + if m.list.Items()[0].(mainItem).SpotifyItem.(spotify.FullTrack).Name != playing.Item.Name { + go func() { + new_items, err := QueueView(m.ctx, m.commands) + if err != nil { + return + } + m.list.SetItems(new_items) + }() + } + } return m, tea.Batch(Tick(), cmd) } return m, Tick() diff --git a/src/tui/views.go b/src/tui/views.go index ea70a70..ee55b23 100644 --- a/src/tui/views.go +++ b/src/tui/views.go @@ -3,11 +3,11 @@ package tui import ( "fmt" "regexp" - "sync" "time" "git.asdf.cafe/abs3nt/gospt/src/commands" "git.asdf.cafe/abs3nt/gospt/src/gctx" + "golang.org/x/sync/errgroup" "github.com/charmbracelet/bubbles/list" "github.com/zmb3/spotify/v2" @@ -31,6 +31,33 @@ func DeviceView(ctx *gctx.Context, commands *commands.Commands) ([]list.Item, er return items, nil } +func QueueView(ctx *gctx.Context, commands *commands.Commands) ([]list.Item, error) { + items := []list.Item{} + tracks, err := commands.UserQueue(ctx) + if err != nil { + return nil, err + } + items = append(items, mainItem{ + Name: tracks.CurrentlyPlaying.Name, + Artist: tracks.CurrentlyPlaying.Artists[0], + Duration: tracks.CurrentlyPlaying.TimeDuration().Round(time.Second).String(), + ID: tracks.CurrentlyPlaying.ID, + Desc: tracks.CurrentlyPlaying.Artists[0].Name + " - " + tracks.CurrentlyPlaying.TimeDuration().Round(time.Second).String(), + SpotifyItem: tracks.CurrentlyPlaying, + }) + for _, track := range tracks.Items { + items = append(items, mainItem{ + Name: track.Name, + Artist: track.Artists[0], + Duration: track.TimeDuration().Round(time.Second).String(), + ID: track.ID, + Desc: track.Artists[0].Name + " - " + track.TimeDuration().Round(time.Second).String(), + SpotifyItem: track, + }) + } + return items, nil +} + func PlaylistView(ctx *gctx.Context, commands *commands.Commands, playlist spotify.SimplePlaylist) ([]list.Item, error) { items := []list.Item{} tracks, err := commands.PlaylistTracks(ctx, playlist.ID, 1) @@ -216,57 +243,36 @@ func SavedTracksView(ctx *gctx.Context, commands *commands.Commands) ([]list.Ite } func MainView(ctx *gctx.Context, commands *commands.Commands) ([]list.Item, error) { - var wg sync.WaitGroup + wg := errgroup.Group{} var saved_items *spotify.SavedTrackPage var playlists *spotify.SimplePlaylistPage var artists *spotify.FullArtistCursorPage var albums *spotify.SavedAlbumPage - wg.Add(1) - go func() { - defer wg.Done() - var err error + wg.Go(func() (err error) { saved_items, err = commands.TrackList(ctx, 1) - if err != nil { - fmt.Println(err.Error()) - return - } - }() + return + }) - wg.Add(1) - go func() { - defer wg.Done() - var err error + wg.Go(func() (err error) { playlists, err = commands.Playlists(ctx, 1) - if err != nil { - fmt.Println(err.Error()) - return - } - }() + return + }) - wg.Add(1) - go func() { - defer wg.Done() - var err error + wg.Go(func() (err error) { artists, err = commands.UserArtists(ctx, 1) - if err != nil { - fmt.Println(err.Error()) - return - } - }() + return + }) - wg.Add(1) - go func() { - defer wg.Done() - var err error + wg.Go(func() (err error) { albums, err = commands.UserAlbums(ctx, 1) - if err != nil { - fmt.Println(err.Error()) - return - } - }() + return + }) - wg.Wait() + err := wg.Wait() + if err != nil { + return nil, err + } items := []list.Item{} if saved_items != nil && saved_items.Total != 0 { @@ -290,6 +296,11 @@ func MainView(ctx *gctx.Context, commands *commands.Commands) ([]list.Item, erro SpotifyItem: artists, }) } + items = append(items, mainItem{ + Name: "Queue", + Desc: "Your Current Queue", + SpotifyItem: spotify.Queue{}, + }) if playlists != nil && playlists.Total != 0 { for _, playlist := range playlists.Playlists { items = append(items, mainItem{