mirror of
https://github.com/aditya-K2/gspt.git
synced 2026-01-09 22:08:04 -05:00
Liked Songs Implementation
This commit is contained in:
32
spt/get.go
32
spt/get.go
@@ -20,6 +20,7 @@ type Album struct {
|
||||
|
||||
type SavedAlbums []spotify.SavedAlbum
|
||||
type UserPlaylists []spotify.SimplePlaylist
|
||||
type LikedSongs []spotify.SavedTrack
|
||||
|
||||
type Playable interface {
|
||||
Type() string
|
||||
@@ -180,3 +181,34 @@ func CurrentUserPlaylists(done func(status bool, err error)) (*UserPlaylists, er
|
||||
return playlists, nil
|
||||
}
|
||||
}
|
||||
|
||||
// CurrentUserSavedTracks returns the LikedSongs of the current user in a
|
||||
// specific manner. It returns the first page and then starts a go routine in
|
||||
// the background and keeps updating the LikedSongs and calls the done
|
||||
// function with a status of true and nil error if successful else calls the
|
||||
// done function with a status of false and the corresponding error.
|
||||
func CurrentUserSavedTracks(done func(status bool, err error)) (*LikedSongs, error) {
|
||||
_p := make(LikedSongs, 0)
|
||||
playlists := &_p
|
||||
if ls, err := Client.CurrentUsersTracks(ctx()); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
addTracks := func() {
|
||||
_p = append(_p, ls.Tracks...)
|
||||
}
|
||||
addTracks()
|
||||
go func() {
|
||||
for page := 1; ; page++ {
|
||||
if perr := Client.NextPage(ctx(), ls); perr == spotify.ErrNoMorePages {
|
||||
done(true, nil)
|
||||
break
|
||||
} else if perr != nil {
|
||||
done(false, perr)
|
||||
return
|
||||
}
|
||||
addTracks()
|
||||
}
|
||||
}()
|
||||
return playlists, nil
|
||||
}
|
||||
}
|
||||
|
||||
10
ui/app.go
10
ui/app.go
@@ -38,7 +38,12 @@ func NewApplication() *Application {
|
||||
NavMenu := newNavMenu([]navItem{
|
||||
{"Albums", NewAction(func(e *tcell.EventKey) *tcell.EventKey { SetCurrentView(albumsView); return nil }, nil)},
|
||||
{"Artists", NewAction(func(e *tcell.EventKey) *tcell.EventKey { fmt.Println("Artists"); return nil }, nil)},
|
||||
{"Liked Songs", NewAction(func(e *tcell.EventKey) *tcell.EventKey { fmt.Println("Liked Songs"); return nil }, nil)},
|
||||
{"Liked Songs", NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
likedSongsView.RefreshState()
|
||||
SetCurrentView(likedSongsView)
|
||||
App.SetFocus(Main.Table)
|
||||
return nil
|
||||
}, nil)},
|
||||
{"Recently Played", NewAction(func(e *tcell.EventKey) *tcell.EventKey { fmt.Println("Recently Played"); return nil }, nil)},
|
||||
})
|
||||
imagePreviewer := tview.NewBox()
|
||||
@@ -61,13 +66,14 @@ func NewApplication() *Application {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Root.AfterContextClose(func() { App.SetFocus(Main.Table) })
|
||||
playlistNav.Table.SetBackgroundColor(tcell.ColorDefault)
|
||||
PlaylistActions = map[string]*Action{
|
||||
"playEntry": NewAction(playlistNav.PlaySelectEntry, nil),
|
||||
"openEntry": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
Root.AfterContextClose(func() { App.SetFocus(Main.Table) })
|
||||
r, _ := playlistNav.Table.GetSelection()
|
||||
playlistView.SetPlaylist(&(*playlistNav.Playlists)[r])
|
||||
SetCurrentView(playlistView)
|
||||
App.SetFocus(Main.Table)
|
||||
return nil
|
||||
}, nil),
|
||||
|
||||
@@ -22,7 +22,7 @@ func newNavMenu(m []navItem) *NavMenu {
|
||||
T.SetDrawFunc(func(tcell.Screen, int, int, int, int) (int, int, int, int) {
|
||||
for k := range n.m {
|
||||
T.SetCell(k, 0,
|
||||
GetCell(n.m[k].name, tcell.StyleDefault.Foreground(tcell.ColorRed)))
|
||||
GetCell(n.m[k].name, tcell.StyleDefault.Foreground(tcell.Color64)))
|
||||
}
|
||||
return T.GetInnerRect()
|
||||
})
|
||||
@@ -70,7 +70,7 @@ func NewPlaylistNav(done func(s bool, e error)) (*PlaylistNav, error) {
|
||||
func (v *PlaylistNav) Draw() {
|
||||
for k, p := range *v.Playlists {
|
||||
v.Table.SetCell(k, 0,
|
||||
GetCell(p.Name, tcell.StyleDefault.Foreground(tcell.ColorRed)))
|
||||
GetCell(p.Name, tcell.StyleDefault.Foreground(tcell.ColorTeal)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,11 @@ package ui
|
||||
import "github.com/gdamore/tcell/v2"
|
||||
|
||||
var (
|
||||
CurrentView View
|
||||
playlistView = &PlaylistView{}
|
||||
albumView = &AlbumView{}
|
||||
albumsView = &AlbumsView{}
|
||||
CurrentView View
|
||||
playlistView = &PlaylistView{}
|
||||
albumView = &AlbumView{}
|
||||
albumsView = &AlbumsView{}
|
||||
likedSongsView = &LikedSongsView{}
|
||||
)
|
||||
|
||||
type View interface {
|
||||
|
||||
95
ui/view_liked.go
Normal file
95
ui/view_liked.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aditya-K2/gspt/spt"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/zmb3/spotify/v2"
|
||||
)
|
||||
|
||||
type LikedSongsView struct {
|
||||
*PlaylistView
|
||||
likedSongs *spt.LikedSongs
|
||||
}
|
||||
|
||||
func (p *LikedSongsView) Content() func() [][]Content {
|
||||
return func() [][]Content {
|
||||
c := make([][]Content, 0)
|
||||
if p.likedSongs == nil {
|
||||
msg := SendNotificationWithChan("Loading Liked Songs...")
|
||||
if err := p.refreshState(func(s bool, e error) {
|
||||
go func() {
|
||||
if !s {
|
||||
msg <- e.Error()
|
||||
} else {
|
||||
msg <- "Done"
|
||||
}
|
||||
}()
|
||||
}); err != nil {
|
||||
SendNotification(err.Error())
|
||||
return c
|
||||
}
|
||||
}
|
||||
for _, v := range *p.likedSongs {
|
||||
c = append(c, []Content{
|
||||
{Content: v.Name, Style: Defaultstyle.Foreground(tcell.ColorBlue)},
|
||||
{Content: v.Artists[0].Name, Style: Defaultstyle.Foreground(tcell.ColorPink)},
|
||||
{Content: v.Album.Name, Style: Defaultstyle.Foreground(tcell.ColorGreen)},
|
||||
})
|
||||
}
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LikedSongsView) ContextHandler() func(start, end, sel int) {
|
||||
return func(start, end, sel int) {
|
||||
// Assuming that there are no external effects on the user's playlists
|
||||
// (i.e Any Creation or Deletion of Playlists while the context Menu is
|
||||
// open
|
||||
userPlaylists, err := spt.CurrentUserPlaylists(func(s bool, err error) {})
|
||||
if err != nil {
|
||||
SendNotification("Error Retrieving User Playlists")
|
||||
return
|
||||
}
|
||||
tracks := make([]spotify.ID, 0)
|
||||
for k := start; k <= end; k++ {
|
||||
tracks = append(tracks, (*l.likedSongs)[k].ID)
|
||||
}
|
||||
aerr := spt.AddTracksToPlaylist((*userPlaylists)[sel].ID, tracks...)
|
||||
if aerr != nil {
|
||||
SendNotification(aerr.Error())
|
||||
return
|
||||
} else {
|
||||
SendNotification(fmt.Sprintf("Added %d tracks to %s", len(tracks), (*userPlaylists)[sel].Name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LikedSongsView) ExternalInputCapture() func(e *tcell.EventKey) *tcell.EventKey {
|
||||
return func(e *tcell.EventKey) *tcell.EventKey {
|
||||
if e.Key() == tcell.KeyEnter {
|
||||
r, _ := Ui.Main.Table.GetSelection()
|
||||
if err := spt.PlaySong((*l.likedSongs)[r].URI); err != nil {
|
||||
SendNotification(err.Error())
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LikedSongsView) refreshState(f func(bool, error)) error {
|
||||
pf, err := spt.CurrentUserSavedTracks(f)
|
||||
if err == nil {
|
||||
l.likedSongs = pf
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *LikedSongsView) Name() string { return "LikedSongsView" }
|
||||
|
||||
func (l *LikedSongsView) RefreshState() {
|
||||
if err := l.refreshState(func(bool, error) {}); err != nil {
|
||||
SendNotification(err.Error())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user