mirror of
https://github.com/aditya-K2/gspt.git
synced 2026-01-07 21:13:50 -05:00
@@ -107,6 +107,7 @@ $ gspt
|
||||
1. `?` Search
|
||||
1. `v` Toggle Visual Mode (Only works in some views)
|
||||
1. `a` Add to Playlist (Only works in some views)
|
||||
1. `q` Queue Songs or Contexts (Only works in some views)
|
||||
1. `ctrl-p` Start playing the entry under the cursor in some views (PlaylistNavigator, Albums, etc.)
|
||||
1. ` ` Toggle Playback (Space)
|
||||
1. `o` Open the Current Track's Album
|
||||
|
||||
@@ -14,9 +14,11 @@ var (
|
||||
"recently_played_view": {
|
||||
"normal": {
|
||||
{R: 'a'}: "add_to_playlist",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
"visual": {
|
||||
{R: 'a'}: "add_to_playlist",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
},
|
||||
"search_view": {
|
||||
@@ -54,27 +56,33 @@ var (
|
||||
"playlist_nav": {
|
||||
"normal": {
|
||||
{K: tcell.KeyCtrlP}: "play_entry",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
},
|
||||
"playlist_view": {
|
||||
"normal": {
|
||||
{R: 'a'}: "add_to_playlist",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
"visual": {
|
||||
{R: 'a'}: "add_to_playlist",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
},
|
||||
"top_tracks_view": {
|
||||
"normal": {
|
||||
{K: tcell.KeyCtrlP}: "play_entry",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
},
|
||||
"liked_songs_view": {
|
||||
"normal": {
|
||||
{R: 'a'}: "add_to_playlist",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
"visual": {
|
||||
{R: 'a'}: "add_to_playlist",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
},
|
||||
"artists_view": {
|
||||
@@ -96,9 +104,11 @@ var (
|
||||
"album_view": {
|
||||
"normal": {
|
||||
{R: 'a'}: "add_to_playlist",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
"visual": {
|
||||
{R: 'a'}: "add_to_playlist",
|
||||
{R: 'q'}: "queue_entry",
|
||||
},
|
||||
},
|
||||
"nav_menu": {},
|
||||
|
||||
39
spt/add.go
39
spt/add.go
@@ -8,15 +8,15 @@ import (
|
||||
)
|
||||
|
||||
func AddTracksToPlaylist(playlistId spotify.ID, t ...spotify.ID) error {
|
||||
_, err := Client.AddTracksToPlaylist(ctx(), playlistId, t...)
|
||||
_, err := Client.AddTracksToPlaylist(ctx, playlistId, t...)
|
||||
return err
|
||||
}
|
||||
|
||||
func QueueTracks(ids ...spotify.SimpleTrack) error {
|
||||
func QueueTracks(ids ...spotify.ID) error {
|
||||
count := 0
|
||||
_ctx := ctx()
|
||||
for _, v := range ids {
|
||||
if err := Client.QueueSong(_ctx, v.ID); err != nil {
|
||||
_ctx := ctx
|
||||
for _, id := range ids {
|
||||
if err := Client.QueueSong(_ctx, id); err != nil {
|
||||
return errors.New(fmt.Sprintf("%s | Tracks Queued: %d", err.Error(), count))
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,34 @@ func QueueAlbum(id spotify.ID) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := QueueTracks(*album.Tracks...); err != nil {
|
||||
|
||||
ids := []spotify.ID{}
|
||||
for _, v := range *album.Tracks {
|
||||
ids = append(ids, v.ID)
|
||||
}
|
||||
|
||||
if err := QueueTracks(ids...); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func QueuePlaylist(id spotify.ID) error {
|
||||
playlist, c := GetPlaylist(id)
|
||||
if c == nil {
|
||||
return (errors.New("hi!"))
|
||||
}
|
||||
err := <-c
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ids := []spotify.ID{}
|
||||
for _, v := range *playlist.Tracks {
|
||||
ids = append(ids, v.Track.ID)
|
||||
}
|
||||
|
||||
if err := QueueTracks(ids...); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
50
spt/get.go
50
spt/get.go
@@ -39,7 +39,7 @@ type Playable interface {
|
||||
}
|
||||
|
||||
var (
|
||||
ctx = func() context.Context { return context.Background() }
|
||||
ctx = context.Background()
|
||||
Client *spotify.Client
|
||||
playlistCache map[spotify.ID]*Playlist = make(map[spotify.ID]*Playlist)
|
||||
albumCache map[spotify.ID]*Album = make(map[spotify.ID]*Album)
|
||||
@@ -48,7 +48,7 @@ var (
|
||||
|
||||
func GetPlaylist(playlistId spotify.ID) (*Playlist, chan error) {
|
||||
c := make(chan error)
|
||||
if fp, err := Client.GetPlaylist(ctx(), playlistId); err != nil {
|
||||
if fp, err := Client.GetPlaylist(ctx, playlistId); err != nil {
|
||||
go func() { c <- err }()
|
||||
return nil, c
|
||||
} else {
|
||||
@@ -60,7 +60,7 @@ func GetPlaylist(playlistId spotify.ID) (*Playlist, chan error) {
|
||||
addTracks()
|
||||
go func() {
|
||||
for page := 1; ; page++ {
|
||||
if perr := Client.NextPage(ctx(), &fp.Tracks); perr == spotify.ErrNoMorePages {
|
||||
if perr := Client.NextPage(ctx, &fp.Tracks); perr == spotify.ErrNoMorePages {
|
||||
c <- nil
|
||||
break
|
||||
} else if perr != nil {
|
||||
@@ -86,7 +86,7 @@ func GetPlaylist(playlistId spotify.ID) (*Playlist, chan error) {
|
||||
func GetAlbum(albumID spotify.ID) (*Album, chan error) {
|
||||
c := make(chan error)
|
||||
if _, ok := albumCache[albumID]; !ok {
|
||||
fa, err := Client.GetAlbum(ctx(), albumID)
|
||||
fa, err := Client.GetAlbum(ctx, albumID)
|
||||
if err != nil {
|
||||
go func() { c <- err }()
|
||||
return nil, c
|
||||
@@ -98,7 +98,7 @@ func GetAlbum(albumID spotify.ID) (*Album, chan error) {
|
||||
addTracks()
|
||||
go func() {
|
||||
for page := 1; ; page++ {
|
||||
if perr := Client.NextPage(ctx(), &fa.Tracks); perr == spotify.ErrNoMorePages {
|
||||
if perr := Client.NextPage(ctx, &fa.Tracks); perr == spotify.ErrNoMorePages {
|
||||
c <- nil
|
||||
break
|
||||
} else if perr != nil {
|
||||
@@ -125,7 +125,7 @@ func CurrentUserSavedAlbums() (*SavedAlbums, chan error) {
|
||||
c := make(chan error)
|
||||
_a := make(SavedAlbums, 0)
|
||||
albums := &_a
|
||||
if sp, err := Client.CurrentUsersAlbums(ctx()); err != nil {
|
||||
if sp, err := Client.CurrentUsersAlbums(ctx); err != nil {
|
||||
go func() { c <- err }()
|
||||
return nil, c
|
||||
} else {
|
||||
@@ -135,7 +135,7 @@ func CurrentUserSavedAlbums() (*SavedAlbums, chan error) {
|
||||
addAlbums()
|
||||
go func() {
|
||||
for page := 1; ; page++ {
|
||||
if perr := Client.NextPage(ctx(), sp); perr == spotify.ErrNoMorePages {
|
||||
if perr := Client.NextPage(ctx, sp); perr == spotify.ErrNoMorePages {
|
||||
c <- nil
|
||||
break
|
||||
} else if perr != nil {
|
||||
@@ -153,7 +153,7 @@ func CurrentUserPlaylists() (*UserPlaylists, chan error) {
|
||||
c := make(chan error)
|
||||
_p := make(UserPlaylists, 0)
|
||||
playlists := &_p
|
||||
if spp, err := Client.CurrentUsersPlaylists(ctx()); err != nil {
|
||||
if spp, err := Client.CurrentUsersPlaylists(ctx); err != nil {
|
||||
go func() { c <- err }()
|
||||
return nil, c
|
||||
} else {
|
||||
@@ -163,7 +163,7 @@ func CurrentUserPlaylists() (*UserPlaylists, chan error) {
|
||||
addPlaylists()
|
||||
go func() {
|
||||
for page := 1; ; page++ {
|
||||
if perr := Client.NextPage(ctx(), spp); perr == spotify.ErrNoMorePages {
|
||||
if perr := Client.NextPage(ctx, spp); perr == spotify.ErrNoMorePages {
|
||||
c <- nil
|
||||
break
|
||||
} else if perr != nil {
|
||||
@@ -181,7 +181,7 @@ func CurrentUserSavedTracks() (*LikedSongs, chan error) {
|
||||
c := make(chan error)
|
||||
_p := make(LikedSongs, 0)
|
||||
playlists := &_p
|
||||
if ls, err := Client.CurrentUsersTracks(ctx()); err != nil {
|
||||
if ls, err := Client.CurrentUsersTracks(ctx); err != nil {
|
||||
go func() { c <- err }()
|
||||
return nil, c
|
||||
} else {
|
||||
@@ -191,7 +191,7 @@ func CurrentUserSavedTracks() (*LikedSongs, chan error) {
|
||||
addTracks()
|
||||
go func() {
|
||||
for page := 1; ; page++ {
|
||||
if perr := Client.NextPage(ctx(), ls); perr == spotify.ErrNoMorePages {
|
||||
if perr := Client.NextPage(ctx, ls); perr == spotify.ErrNoMorePages {
|
||||
c <- nil
|
||||
break
|
||||
} else if perr != nil {
|
||||
@@ -210,7 +210,7 @@ func CurrentUserFollowedArtists() (*FollowedArtists, chan error) {
|
||||
// TODO: Check if this is the proper implementation
|
||||
_a := make(FollowedArtists, 0)
|
||||
artists := &_a
|
||||
if ar, err := Client.CurrentUsersFollowedArtists(ctx()); err != nil {
|
||||
if ar, err := Client.CurrentUsersFollowedArtists(ctx); err != nil {
|
||||
go func() { c <- err }()
|
||||
return nil, c
|
||||
} else {
|
||||
@@ -225,7 +225,7 @@ func CurrentUserFollowedArtists() (*FollowedArtists, chan error) {
|
||||
if len(ar.Artists) == 0 {
|
||||
c <- nil
|
||||
}
|
||||
if ar, err = Client.CurrentUsersFollowedArtists(ctx(), spotify.After(string(ap))); err != nil {
|
||||
if ar, err = Client.CurrentUsersFollowedArtists(ctx, spotify.After(string(ap))); err != nil {
|
||||
if err == spotify.ErrNoMorePages {
|
||||
c <- nil
|
||||
break
|
||||
@@ -243,15 +243,15 @@ func CurrentUserFollowedArtists() (*FollowedArtists, chan error) {
|
||||
}
|
||||
|
||||
func RecentlyPlayed() ([]spotify.RecentlyPlayedItem, error) {
|
||||
return Client.PlayerRecentlyPlayedOpt(ctx(), &spotify.RecentlyPlayedOptions{Limit: 50})
|
||||
return Client.PlayerRecentlyPlayedOpt(ctx, &spotify.RecentlyPlayedOptions{Limit: 50})
|
||||
}
|
||||
|
||||
func GetPlayerState() (*spotify.PlayerState, error) {
|
||||
return Client.PlayerState(ctx())
|
||||
return Client.PlayerState(ctx)
|
||||
}
|
||||
|
||||
func GetTopTracks() ([]spotify.FullTrack, error) {
|
||||
c, err := Client.CurrentUsersTopTracks(ctx(), spotify.Limit(topTracksLimit))
|
||||
c, err := Client.CurrentUsersTopTracks(ctx, spotify.Limit(topTracksLimit))
|
||||
if c != nil {
|
||||
return c.Tracks, err
|
||||
} else {
|
||||
@@ -260,7 +260,7 @@ func GetTopTracks() ([]spotify.FullTrack, error) {
|
||||
}
|
||||
|
||||
func GetTopArtists() ([]spotify.FullArtist, error) {
|
||||
c, err := Client.CurrentUsersTopArtists(ctx(), spotify.Limit(topTracksLimit))
|
||||
c, err := Client.CurrentUsersTopArtists(ctx, spotify.Limit(topTracksLimit))
|
||||
if c != nil {
|
||||
return c.Artists, err
|
||||
} else {
|
||||
@@ -269,15 +269,15 @@ func GetTopArtists() ([]spotify.FullArtist, error) {
|
||||
}
|
||||
|
||||
func GetArtistTopTracks(artistID spotify.ID) ([]spotify.FullTrack, error) {
|
||||
c, err := Client.CurrentUser(ctx())
|
||||
c, err := Client.CurrentUser(ctx)
|
||||
if err != nil {
|
||||
return []spotify.FullTrack{}, err
|
||||
}
|
||||
return Client.GetArtistsTopTracks(ctx(), artistID, c.Country)
|
||||
return Client.GetArtistsTopTracks(ctx, artistID, c.Country)
|
||||
}
|
||||
|
||||
func GetArtistAlbums(artistID spotify.ID) ([]spotify.SimpleAlbum, error) {
|
||||
c, err := Client.GetArtistAlbums(ctx(), artistID, albumtypes)
|
||||
c, err := Client.GetArtistAlbums(ctx, artistID, albumtypes)
|
||||
if err != nil {
|
||||
return []spotify.SimpleAlbum{}, err
|
||||
}
|
||||
@@ -285,7 +285,7 @@ func GetArtistAlbums(artistID spotify.ID) ([]spotify.SimpleAlbum, error) {
|
||||
}
|
||||
|
||||
func Search(s string) (*spotify.SearchResult, error) {
|
||||
return Client.Search(ctx(), s,
|
||||
return Client.Search(ctx, s,
|
||||
spotify.SearchTypePlaylist|
|
||||
spotify.SearchTypeAlbum|
|
||||
spotify.SearchTypeTrack|
|
||||
@@ -293,7 +293,7 @@ func Search(s string) (*spotify.SearchResult, error) {
|
||||
}
|
||||
|
||||
func UserDevices() ([]spotify.PlayerDevice, error) {
|
||||
return Client.PlayerDevices(ctx())
|
||||
return Client.PlayerDevices(ctx)
|
||||
}
|
||||
|
||||
func TransferPlayback(deviceId spotify.ID) error {
|
||||
@@ -301,10 +301,10 @@ func TransferPlayback(deviceId spotify.ID) error {
|
||||
if err != nil {
|
||||
return errors.New("Unable to get Current Player State!")
|
||||
}
|
||||
err = Client.PauseOpt(ctx(), &spotify.PlayOptions{DeviceID: &s.Device.ID})
|
||||
return Client.TransferPlayback(ctx(), deviceId, true)
|
||||
err = Client.PauseOpt(ctx, &spotify.PlayOptions{DeviceID: &s.Device.ID})
|
||||
return Client.TransferPlayback(ctx, deviceId, true)
|
||||
}
|
||||
|
||||
func GetFullPlaylist(id spotify.ID) (*spotify.FullPlaylist, error) {
|
||||
return Client.GetPlaylist(ctx(), id)
|
||||
return Client.GetPlaylist(ctx, id)
|
||||
}
|
||||
|
||||
16
spt/play.go
16
spt/play.go
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func play(options *spotify.PlayOptions) error {
|
||||
return Client.PlayOpt(ctx(), options)
|
||||
return Client.PlayOpt(ctx, options)
|
||||
}
|
||||
|
||||
func PlaySong(uri spotify.URI) error {
|
||||
@@ -38,16 +38,16 @@ func PlayContext(context spotify.URI) error {
|
||||
}
|
||||
|
||||
func TogglePlayback() error {
|
||||
p, err := Client.PlayerCurrentlyPlaying(ctx())
|
||||
p, err := Client.PlayerCurrentlyPlaying(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p.Playing {
|
||||
if err := Client.Pause(ctx()); err != nil {
|
||||
if err := Client.Pause(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := Client.Play(ctx()); err != nil {
|
||||
if err := Client.Play(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -63,11 +63,11 @@ func UriToID(uri spotify.URI) (spotify.ID, error) {
|
||||
}
|
||||
|
||||
func Next() error {
|
||||
return Client.Next(ctx())
|
||||
return Client.Next(ctx)
|
||||
}
|
||||
|
||||
func Previous() error {
|
||||
return Client.Previous(ctx())
|
||||
return Client.Previous(ctx)
|
||||
}
|
||||
|
||||
func Shuffle() error {
|
||||
@@ -77,7 +77,7 @@ func Shuffle() error {
|
||||
return err
|
||||
}
|
||||
|
||||
return Client.Shuffle(ctx(), !s.ShuffleState)
|
||||
return Client.Shuffle(ctx, !s.ShuffleState)
|
||||
}
|
||||
|
||||
func Repeat() error {
|
||||
@@ -92,5 +92,5 @@ func Repeat() error {
|
||||
return err
|
||||
}
|
||||
|
||||
return Client.Repeat(ctx(), next[s.RepeatState])
|
||||
return Client.Repeat(ctx, next[s.RepeatState])
|
||||
}
|
||||
|
||||
31
ui/app.go
31
ui/app.go
@@ -286,6 +286,7 @@ func NewApplication() *tview.Application {
|
||||
App.SetFocus(Main)
|
||||
return nil
|
||||
}, nil),
|
||||
"queue_entry": NewAction(playlistNav.QueueEntry, nil),
|
||||
}))
|
||||
navMenu.SetActions(utils.MergeMaps(globalActions, map[string]*Action{
|
||||
"open_entry": NewAction(navMenu.OpenEntry,
|
||||
@@ -296,24 +297,40 @@ func NewApplication() *tview.Application {
|
||||
playlistView.AddToPlaylist()
|
||||
return nil
|
||||
}, nil),
|
||||
"queue_entry": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
playlistView.QueueEntry()
|
||||
return nil
|
||||
}, nil),
|
||||
}))
|
||||
recentlyPlayedView.SetActions(utils.MergeMaps(globalActions, map[string]*Action{
|
||||
"add_to_playlist": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
recentlyPlayedView.AddToPlaylist()
|
||||
return nil
|
||||
}, nil),
|
||||
"queue_entry": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
recentlyPlayedView.QueueEntry()
|
||||
return nil
|
||||
}, nil),
|
||||
}))
|
||||
topTracksView.SetActions(utils.MergeMaps(globalActions, map[string]*Action{
|
||||
"play_entry": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
topTracksView.PlaySelectedEntry()
|
||||
topTracksView.PlayEntry()
|
||||
return nil
|
||||
}, progressBar),
|
||||
"queue_entry": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
topTracksView.QueueEntry()
|
||||
return nil
|
||||
}, nil),
|
||||
}))
|
||||
likedSongsView.SetActions(utils.MergeMaps(globalActions, map[string]*Action{
|
||||
"add_to_playlist": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
likedSongsView.AddToPlaylist()
|
||||
return nil
|
||||
}, nil),
|
||||
"queue_entry": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
likedSongsView.QueueEntry()
|
||||
return nil
|
||||
}, nil),
|
||||
}))
|
||||
searchView.SetActions(utils.MergeMaps(globalActions, map[string]*Action{
|
||||
"play_entry": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
@@ -339,29 +356,37 @@ func NewApplication() *tview.Application {
|
||||
return nil
|
||||
}, progressBar),
|
||||
"queue_entry": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
albumsView.QueueSelectEntry()
|
||||
albumsView.QueueEntry()
|
||||
return nil
|
||||
}, progressBar),
|
||||
}, nil),
|
||||
}))
|
||||
albumView.SetActions(utils.MergeMaps(globalActions, map[string]*Action{
|
||||
"add_to_playlist": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
albumView.AddToPlaylist()
|
||||
return nil
|
||||
}, nil),
|
||||
"queue_entry": NewAction(func(e *tcell.EventKey) *tcell.EventKey {
|
||||
albumView.QueueEntry()
|
||||
return nil
|
||||
}, nil),
|
||||
}))
|
||||
|
||||
// Visual Actions
|
||||
albumView.SetVisualActions(map[string]func(start, end int, e *tcell.EventKey) *tcell.EventKey{
|
||||
"add_to_playlist": albumView.AddToPlaylistVisual,
|
||||
"queue_entry": albumView.QueueSongsVisual,
|
||||
})
|
||||
recentlyPlayedView.SetVisualActions(map[string]func(start, end int, e *tcell.EventKey) *tcell.EventKey{
|
||||
"add_to_playlist": recentlyPlayedView.AddToPlaylistVisual,
|
||||
"queue_entry": recentlyPlayedView.QueueSongsVisual,
|
||||
})
|
||||
playlistView.SetVisualActions(map[string]func(start, end int, e *tcell.EventKey) *tcell.EventKey{
|
||||
"add_to_playlist": playlistView.AddToPlaylistVisual,
|
||||
"queue_entry": playlistView.QueueSongsVisual,
|
||||
})
|
||||
likedSongsView.SetVisualActions(map[string]func(start, end int, e *tcell.EventKey) *tcell.EventKey{
|
||||
"add_to_playlist": likedSongsView.AddToPlaylistVisual,
|
||||
"queue_entry": likedSongsView.QueueSongsVisual,
|
||||
})
|
||||
|
||||
mappings := config.GenerateMappings()
|
||||
|
||||
15
ui/nav.go
15
ui/nav.go
@@ -83,6 +83,21 @@ func (v *PlaylistNav) PlayEntry(e *tcell.EventKey) *tcell.EventKey {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *PlaylistNav) QueueEntry(e *tcell.EventKey) *tcell.EventKey {
|
||||
r, _ := v.Table.GetSelection()
|
||||
playlist := (*v.Playlists)[r]
|
||||
msg := SendNotificationWithChan("Queueing %s...", playlist.Name)
|
||||
go func() {
|
||||
if err := spt.QueuePlaylist(playlist.ID); err != nil {
|
||||
msg <- err.Error()
|
||||
return
|
||||
}
|
||||
msg <- playlist.Name + " Queued Succesfully!"
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *PlaylistNav) RefreshState() {
|
||||
p, ch := spt.CurrentUserPlaylists()
|
||||
go func() {
|
||||
|
||||
18
ui/utils.go
18
ui/utils.go
@@ -71,6 +71,17 @@ func addToPlaylist(tracks []spotify.ID) {
|
||||
})
|
||||
}
|
||||
|
||||
func queueSongs(tracks []spotify.ID) {
|
||||
msg := SendNotificationWithChan(fmt.Sprintf("Queueing %d tracks...", len(tracks)))
|
||||
go func() {
|
||||
err := spt.QueueTracks(tracks...)
|
||||
if err != nil {
|
||||
msg <- err.Error()
|
||||
}
|
||||
msg <- fmt.Sprintf("Queued %d tracks!", len(tracks))
|
||||
}()
|
||||
}
|
||||
|
||||
func fileName(a spotify.SimpleAlbum) string {
|
||||
return fmt.Sprintf(filepath.Join(cfg.CacheDir, "%s.jpg"), a.ID)
|
||||
}
|
||||
@@ -131,3 +142,10 @@ func artistName(s []spotify.SimpleArtist) string {
|
||||
func wrap(args ...interface{}) []interface{} {
|
||||
return args
|
||||
}
|
||||
|
||||
func Map[K any, V any](a []K, f func(K) V) (res []V) {
|
||||
for _, v := range a {
|
||||
res = append(res, f(v))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aditya-K2/gspt/spt"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/zmb3/spotify/v2"
|
||||
@@ -33,14 +35,14 @@ func (a *AlbumView) Content() func() [][]Content {
|
||||
|
||||
if a.currentAlbumID != nil {
|
||||
if a.currentFullAlbum == nil {
|
||||
msg := SendNotificationWithChan("Loading %s....", a.currentAlbumName)
|
||||
msg := SendNotificationWithChan("Fetching %s....", a.currentAlbumName)
|
||||
al, ch := spt.GetAlbum(*a.currentAlbumID)
|
||||
go func() {
|
||||
err := <-ch
|
||||
if err != nil {
|
||||
msg <- err.Error()
|
||||
} else {
|
||||
msg <- "Album Loaded Succesfully!"
|
||||
msg <- "Album Fetched Succesfully!"
|
||||
}
|
||||
}()
|
||||
a.currentFullAlbum = al
|
||||
@@ -64,13 +66,30 @@ func (a *AlbumView) AddToPlaylist() {
|
||||
addToPlaylist([]spotify.ID{track.ID})
|
||||
}
|
||||
|
||||
func (a *AlbumView) AddToPlaylistVisual(start, end int, e *tcell.EventKey) *tcell.EventKey {
|
||||
tracks := make([]spotify.ID, 0)
|
||||
sTracks := (*(*a.currentFullAlbum).Tracks)
|
||||
for k := start; k <= end; k++ {
|
||||
tracks = append(tracks, sTracks[k].ID)
|
||||
func (a *AlbumView) QueueEntry() {
|
||||
r, _ := Main.GetSelection()
|
||||
track := (*(*a.currentFullAlbum).Tracks)[r]
|
||||
msg := fmt.Sprintf("%s queued succesfully!", track.Name)
|
||||
if err := spt.QueueTracks(track.ID); err != nil {
|
||||
msg = err.Error()
|
||||
}
|
||||
addToPlaylist(tracks)
|
||||
SendNotification(msg)
|
||||
}
|
||||
|
||||
func (a *AlbumView) AddToPlaylistVisual(start, end int, e *tcell.EventKey) *tcell.EventKey {
|
||||
addToPlaylist(Map((*(*a.currentFullAlbum).Tracks)[start:end+1],
|
||||
func(s spotify.SimpleTrack) spotify.ID {
|
||||
return s.ID
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AlbumView) QueueSongsVisual(start, end int, e *tcell.EventKey) *tcell.EventKey {
|
||||
tracks := (*(*a.currentFullAlbum).Tracks)[start : end+1]
|
||||
queueSongs(Map(tracks,
|
||||
func(s spotify.SimpleTrack) spotify.ID {
|
||||
return s.ID
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ func (a *AlbumsView) Content() func() [][]Content {
|
||||
return func() [][]Content {
|
||||
c := make([][]Content, 0)
|
||||
if a.savedAlbums == nil {
|
||||
msg := SendNotificationWithChan("Loading Albums from your Library...")
|
||||
msg := SendNotificationWithChan("Fetching Albums from your Library...")
|
||||
sa, ch := spt.CurrentUserSavedAlbums()
|
||||
go func() {
|
||||
err := <-ch
|
||||
@@ -59,16 +59,16 @@ func (a *AlbumsView) PlayEntry() {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlbumsView) QueueSelectEntry() {
|
||||
func (a *AlbumsView) QueueEntry() {
|
||||
r, _ := Main.GetSelection()
|
||||
alb := (*a.savedAlbums)[r]
|
||||
msg := SendNotificationWithChan("Queueing " + alb.Name + "...")
|
||||
go func() {
|
||||
if err := spt.QueueAlbum(alb.ID); err != nil {
|
||||
msg <- err.Error()
|
||||
} else {
|
||||
msg <- (alb.Name) + " queued succesfully!"
|
||||
return
|
||||
}
|
||||
msg <- (alb.Name) + " queued succesfully!"
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ func (a *ArtistView) SetArtist(id *spotify.ID) {
|
||||
}
|
||||
|
||||
func (a *ArtistView) RefreshState() {
|
||||
msg := SendNotificationWithChan("Loading Artist!")
|
||||
msg := SendNotificationWithChan("Fetching Artist....")
|
||||
topTracks, err := spt.GetArtistTopTracks(*a.artistID)
|
||||
if err != nil {
|
||||
msg <- ("Error retrieving Artist Top Tracks: " + err.Error())
|
||||
@@ -45,7 +45,7 @@ func (a *ArtistView) RefreshState() {
|
||||
return
|
||||
}
|
||||
a.albums = albums
|
||||
msg <- "Artist Loaded Succesfully!"
|
||||
msg <- "Artist Fetched Succesfully!"
|
||||
}
|
||||
|
||||
func (a *ArtistView) Content() func() [][]Content {
|
||||
@@ -71,29 +71,37 @@ func (a *ArtistView) Content() func() [][]Content {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ArtistView) PlayEntry() {
|
||||
r, _ := Main.GetSelection()
|
||||
if r > 0 {
|
||||
if r < (len(a.albums) + 1) {
|
||||
if err := spt.PlayContext(a.albums[r-1].URI); err != nil {
|
||||
SendNotification(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ArtistView) OpenEntry() {
|
||||
func (a *ArtistView) handle(albumHandler func(int), trackHandler func(int)) {
|
||||
r, _ := Main.GetSelection()
|
||||
if r > 0 {
|
||||
if r < (len(a.albums)+1) && len(a.albums) > 0 {
|
||||
albumView.SetAlbum(a.albums[r-1].Name, &a.albums[r-1].ID)
|
||||
SetCurrentView(albumView)
|
||||
albumHandler(r - 1)
|
||||
} else if r != len(a.albums)+1 && len(a.topTracks) > 0 {
|
||||
if err := spt.PlaySong(a.topTracks[r-2-len(a.albums)].URI); err != nil {
|
||||
SendNotification(err.Error())
|
||||
}
|
||||
trackHandler(r - 2 - len(a.albums))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ArtistView) PlayEntry() {
|
||||
a.handle(func(r int) {
|
||||
if err := spt.PlayContext(a.albums[r].URI); err != nil {
|
||||
SendNotification(err.Error())
|
||||
}
|
||||
}, func(int) {})
|
||||
}
|
||||
|
||||
func (a *ArtistView) OpenEntry() {
|
||||
a.handle(func(r int) {
|
||||
albumView.SetAlbum(a.albums[r].Name, &a.albums[r].ID)
|
||||
SetCurrentView(albumView)
|
||||
}, func(r int) {
|
||||
if err := spt.PlaySong(a.topTracks[r].URI); err != nil {
|
||||
SendNotification(err.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (a *ArtistsView) QueueEntry() {
|
||||
}
|
||||
|
||||
func (a *ArtistView) Name() string { return "AlbumsView" }
|
||||
|
||||
@@ -21,7 +21,7 @@ func (a *ArtistsView) Content() func() [][]Content {
|
||||
return func() [][]Content {
|
||||
c := make([][]Content, 0)
|
||||
if a.followedArtists == nil {
|
||||
msg := SendNotificationWithChan("Loading Artists from your Library...")
|
||||
msg := SendNotificationWithChan("Fetching Artists from your Library...")
|
||||
fa, ch := spt.CurrentUserFollowedArtists()
|
||||
go func() {
|
||||
err := <-ch
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aditya-K2/gspt/spt"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/zmb3/spotify/v2"
|
||||
@@ -23,13 +25,13 @@ func (p *LikedSongsView) Content() func() [][]Content {
|
||||
return func() [][]Content {
|
||||
c := make([][]Content, 0)
|
||||
if p.likedSongs == nil {
|
||||
msg := SendNotificationWithChan("Loading Liked Songs...")
|
||||
msg := SendNotificationWithChan("Fetching Liked Songs...")
|
||||
p.refreshState(func(err error) {
|
||||
if err != nil {
|
||||
msg <- err.Error()
|
||||
return
|
||||
}
|
||||
msg <- "Liked Songs Loaded Succesfully!"
|
||||
msg <- "Liked Songs Fetched Succesfully!"
|
||||
})
|
||||
}
|
||||
if p.likedSongs != nil {
|
||||
@@ -51,11 +53,19 @@ func (l *LikedSongsView) AddToPlaylist() {
|
||||
}
|
||||
|
||||
func (l *LikedSongsView) AddToPlaylistVisual(start, end int, e *tcell.EventKey) *tcell.EventKey {
|
||||
tracks := make([]spotify.ID, 0)
|
||||
for k := start; k <= end; k++ {
|
||||
tracks = append(tracks, (*l.likedSongs)[k].ID)
|
||||
}
|
||||
addToPlaylist(tracks)
|
||||
addToPlaylist(Map((*l.likedSongs)[start:end+1],
|
||||
func(s spotify.SavedTrack) spotify.ID {
|
||||
return s.ID
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *LikedSongsView) QueueSongsVisual(start, end int, e *tcell.EventKey) *tcell.EventKey {
|
||||
tracks := (*l.likedSongs)[start : end+1]
|
||||
queueSongs(Map(tracks,
|
||||
func(s spotify.SavedTrack) spotify.ID {
|
||||
return s.ID
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -66,6 +76,16 @@ func (l *LikedSongsView) OpenEntry() {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LikedSongsView) QueueEntry() {
|
||||
r, _ := Main.GetSelection()
|
||||
track := (*l.likedSongs)[r]
|
||||
msg := fmt.Sprintf("%s Queued Succesfully!", track.Name)
|
||||
if err := spt.QueueTracks(track.ID); err != nil {
|
||||
msg = err.Error()
|
||||
}
|
||||
SendNotification(msg)
|
||||
}
|
||||
|
||||
func (l *LikedSongsView) Name() string { return "LikedSongsView" }
|
||||
|
||||
func (p *LikedSongsView) refreshState(errHandler func(error)) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aditya-K2/gspt/spt"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/zmb3/spotify/v2"
|
||||
@@ -31,14 +33,14 @@ func (p *PlaylistView) Content() func() [][]Content {
|
||||
c := make([][]Content, 0)
|
||||
if p.currentPlaylist != nil {
|
||||
if p.currentUserFullPlaylist == nil {
|
||||
msg := SendNotificationWithChan("Loading %s....", p.currentPlaylist.Name)
|
||||
msg := SendNotificationWithChan("Fetching %s....", p.currentPlaylist.Name)
|
||||
pf, ch := spt.GetPlaylist(p.currentPlaylist.ID)
|
||||
go func() {
|
||||
err := <-ch
|
||||
if err != nil {
|
||||
msg <- err.Error()
|
||||
} else {
|
||||
msg <- "Playlist Loaded Succesfully!"
|
||||
msg <- "Playlist Fetched Succesfully!"
|
||||
}
|
||||
}()
|
||||
p.currentUserFullPlaylist = pf
|
||||
@@ -63,12 +65,19 @@ func (p *PlaylistView) AddToPlaylist() {
|
||||
}
|
||||
|
||||
func (p *PlaylistView) AddToPlaylistVisual(start, end int, e *tcell.EventKey) *tcell.EventKey {
|
||||
tracks := make([]spotify.ID, 0)
|
||||
sTracks := (*(*p.currentUserFullPlaylist).Tracks)
|
||||
for k := start; k <= end; k++ {
|
||||
tracks = append(tracks, sTracks[k].Track.ID)
|
||||
}
|
||||
addToPlaylist(tracks)
|
||||
addToPlaylist(Map((*(*p.currentUserFullPlaylist).Tracks)[start:end+1],
|
||||
func(s spotify.PlaylistTrack) spotify.ID {
|
||||
return s.Track.ID
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PlaylistView) QueueSongsVisual(start, end int, e *tcell.EventKey) *tcell.EventKey {
|
||||
tracks := (*(*p.currentUserFullPlaylist).Tracks)[start : end+1]
|
||||
queueSongs(Map(tracks,
|
||||
func(s spotify.PlaylistTrack) spotify.ID {
|
||||
return s.Track.ID
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -79,4 +88,14 @@ func (p *PlaylistView) OpenEntry() {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PlaylistView) QueueEntry() {
|
||||
r, _ := Main.GetSelection()
|
||||
track := (*(*p.currentUserFullPlaylist).Tracks)[r].Track
|
||||
msg := fmt.Sprintf("%s Queued Succesfully!", track.Name)
|
||||
if err := spt.QueueTracks(track.ID); err != nil {
|
||||
msg = err.Error()
|
||||
}
|
||||
SendNotification(msg)
|
||||
}
|
||||
|
||||
func (p *PlaylistView) Name() string { return "PlaylistView" }
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aditya-K2/gspt/spt"
|
||||
"github.com/aditya-K2/utils"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
@@ -40,11 +42,19 @@ func (r *RecentlyPlayedView) AddToPlaylist() {
|
||||
}
|
||||
|
||||
func (r *RecentlyPlayedView) AddToPlaylistVisual(start, end int, e *tcell.EventKey) *tcell.EventKey {
|
||||
tracks := make([]spotify.ID, 0)
|
||||
for k := start; k <= end; k++ {
|
||||
tracks = append(tracks, r.recentlyPlayed[k].Track.ID)
|
||||
}
|
||||
addToPlaylist(tracks)
|
||||
addToPlaylist(Map(r.recentlyPlayed[start:end+1],
|
||||
func(r spotify.RecentlyPlayedItem) spotify.ID {
|
||||
return r.Track.ID
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *RecentlyPlayedView) QueueSongsVisual(start, end int, e *tcell.EventKey) *tcell.EventKey {
|
||||
tracks := r.recentlyPlayed[start : end+1]
|
||||
queueSongs(Map(tracks,
|
||||
func(s spotify.RecentlyPlayedItem) spotify.ID {
|
||||
return s.Track.ID
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -73,3 +83,13 @@ func (re *RecentlyPlayedView) OpenEntry() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (re *RecentlyPlayedView) QueueEntry() {
|
||||
r, _ := Main.GetSelection()
|
||||
track := re.recentlyPlayed[r].Track
|
||||
msg := fmt.Sprintf("%s Queued Succesfully!", track.Name)
|
||||
if err := spt.QueueTracks(track.ID); err != nil {
|
||||
msg = err.Error()
|
||||
}
|
||||
SendNotification(msg)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aditya-K2/gspt/spt"
|
||||
"github.com/zmb3/spotify/v2"
|
||||
)
|
||||
@@ -57,30 +59,52 @@ func (a *TopTracksView) Content() func() [][]Content {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *TopTracksView) PlaySelectedEntry() {
|
||||
func (a *TopTracksView) handle(trackHandler, artistHandler func(r int)) {
|
||||
r, _ := Main.GetSelection()
|
||||
if r > 0 {
|
||||
if r < (len(a.topArtists) + 1) {
|
||||
if err := spt.PlayContext(a.topArtists[r-1].URI); err != nil {
|
||||
SendNotification(err.Error())
|
||||
if artistHandler != nil {
|
||||
artistHandler(r - 1)
|
||||
}
|
||||
} else if r != len(a.topArtists)+1 {
|
||||
if trackHandler != nil {
|
||||
trackHandler(r - 2 - len(a.topArtists))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *TopTracksView) PlayEntry() {
|
||||
a.handle(nil, func(r int) {
|
||||
if err := spt.PlayContext(a.topArtists[r].URI); err != nil {
|
||||
SendNotification(err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (a *TopTracksView) OpenEntry() {
|
||||
r, _ := Main.GetSelection()
|
||||
if r > 0 {
|
||||
if r < (len(a.topArtists) + 1) {
|
||||
artistView.SetArtist(&(a.topArtists)[r-1].ID)
|
||||
SetCurrentView(artistView)
|
||||
} else if r != len(a.topArtists)+1 {
|
||||
if err := spt.PlaySong(a.topTracks[r-2-len(a.topArtists)].URI); err != nil {
|
||||
SendNotification(err.Error())
|
||||
}
|
||||
artistHandler := func(r int) {
|
||||
artistView.SetArtist(&(a.topArtists)[r].ID)
|
||||
SetCurrentView(artistView)
|
||||
}
|
||||
trackHandler := func(r int) {
|
||||
if err := spt.PlaySong(a.topTracks[r].URI); err != nil {
|
||||
SendNotification(err.Error())
|
||||
}
|
||||
}
|
||||
a.handle(trackHandler, artistHandler)
|
||||
}
|
||||
|
||||
func (a *TopTracksView) QueueEntry() {
|
||||
a.handle(func(r int) {
|
||||
msg := fmt.Sprintf("%s Queued Succesfully!", a.topTracks[r].Name)
|
||||
if err := spt.QueueTracks(a.topTracks[r].ID); err != nil {
|
||||
msg = err.Error()
|
||||
}
|
||||
SendNotification(msg)
|
||||
}, func(int) { SendNotification("Artists can not be queued!") })
|
||||
|
||||
}
|
||||
|
||||
func (a *TopTracksView) Name() string { return "TopTracksView" }
|
||||
|
||||
Reference in New Issue
Block a user