From 0bdabaf1eadeb1b4d305ca646560e31a7b39c43c Mon Sep 17 00:00:00 2001 From: aditya-K2 Date: Wed, 12 Apr 2023 04:39:06 +0530 Subject: [PATCH] Implement RecentlyPlayedView --- spt/get.go | 4 +++ ui/app.go | 7 +++- ui/view.go | 11 +++--- ui/view_recent.go | 88 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 ui/view_recent.go diff --git a/spt/get.go b/spt/get.go index 9701e5f..fcaa1e9 100644 --- a/spt/get.go +++ b/spt/get.go @@ -212,3 +212,7 @@ func CurrentUserSavedTracks(done func(status bool, err error)) (*LikedSongs, err return playlists, nil } } + +func RecentlyPlayed() ([]spotify.RecentlyPlayedItem, error) { + return Client.PlayerRecentlyPlayed(ctx()) +} diff --git a/ui/app.go b/ui/app.go index 33b5cc5..d6b114b 100644 --- a/ui/app.go +++ b/ui/app.go @@ -54,7 +54,12 @@ func NewApplication() *Application { App.SetFocus(Main.Table) return nil }, nil)}, - {"Recently Played", NewAction(func(e *tcell.EventKey) *tcell.EventKey { fmt.Println("Recently Played"); return nil }, nil)}, + {"Recently Played", NewAction(func(e *tcell.EventKey) *tcell.EventKey { + recentlyPlayedView.RefreshState() + SetCurrentView(recentlyPlayedView) + App.SetFocus(Main.Table) + return nil + }, nil)}, }) imagePreviewer := tview.NewBox() diff --git a/ui/view.go b/ui/view.go index 58f06b4..ef8a37e 100644 --- a/ui/view.go +++ b/ui/view.go @@ -3,11 +3,12 @@ package ui import "github.com/gdamore/tcell/v2" var ( - CurrentView View - playlistView = &PlaylistView{} - albumView = &AlbumView{} - albumsView = &AlbumsView{} - likedSongsView = &LikedSongsView{} + CurrentView View + playlistView = &PlaylistView{} + albumView = &AlbumView{} + albumsView = &AlbumsView{} + likedSongsView = &LikedSongsView{} + recentlyPlayedView = &RecentlyPlayedView{} ) type View interface { diff --git a/ui/view_recent.go b/ui/view_recent.go new file mode 100644 index 0000000..f4e92a0 --- /dev/null +++ b/ui/view_recent.go @@ -0,0 +1,88 @@ +package ui + +import ( + "fmt" + "time" + + "github.com/aditya-K2/gspt/spt" + "github.com/gdamore/tcell/v2" + "github.com/zmb3/spotify/v2" +) + +type RecentlyPlayedView struct { + *PlaylistView + recentlyPlayed []spotify.RecentlyPlayedItem +} + +func format(t time.Duration) string { + z := time.Unix(0, 0).UTC() + return z.Add(t).Format("04:05") +} + +func (r *RecentlyPlayedView) Content() func() [][]Content { + return func() [][]Content { + c := make([][]Content, 0) + for _, v := range r.recentlyPlayed { + c = append(c, []Content{ + {Content: v.Track.Name, Style: TrackStyle}, + {Content: v.Track.Artists[0].Name, Style: ArtistStyle}, + {Content: format(time.Duration(v.Track.Duration)), Style: TimeStyle}, + }) + } + return c + } +} + +func (r *RecentlyPlayedView) 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, r.recentlyPlayed[k].Track.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 (re *RecentlyPlayedView) ExternalInputCapture() func(e *tcell.EventKey) *tcell.EventKey { + return func(e *tcell.EventKey) *tcell.EventKey { + if e.Key() == tcell.KeyEnter { + r, _ := Ui.Main.Table.GetSelection() + contextUri := re.recentlyPlayed[r].PlaybackContext.URI + if string(contextUri) != "" { + if err := spt.PlaySongWithContext(&re.recentlyPlayed[r].PlaybackContext.URI, r); err != nil { + SendNotification(err.Error()) + } + } else { + if err := spt.PlaySong(re.recentlyPlayed[r].Track.URI); err != nil { + SendNotification(err.Error()) + } + } + } + return e + } +} + +func (r *RecentlyPlayedView) Name() string { return "RecentlyPlayedView" } + +func (r *RecentlyPlayedView) RefreshState() { + _r, err := spt.RecentlyPlayed() + if err != nil { + SendNotification(err.Error()) + return + } + r.recentlyPlayed = _r +}