2023-01-13 06:19:43 +00:00
|
|
|
package tui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-04-16 06:21:48 +00:00
|
|
|
"regexp"
|
2023-01-13 06:19:43 +00:00
|
|
|
"time"
|
|
|
|
|
2023-03-10 07:48:02 +00:00
|
|
|
"git.asdf.cafe/abs3nt/gospt/src/commands"
|
|
|
|
"git.asdf.cafe/abs3nt/gospt/src/gctx"
|
2023-04-16 07:05:23 +00:00
|
|
|
"golang.org/x/sync/errgroup"
|
2023-01-13 06:19:43 +00:00
|
|
|
|
|
|
|
"github.com/charmbracelet/bubbles/list"
|
|
|
|
"github.com/zmb3/spotify/v2"
|
|
|
|
)
|
|
|
|
|
2023-04-16 06:21:48 +00:00
|
|
|
const regex = `<.*?>`
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func DeviceView(ctx *gctx.Context, commands *commands.Commands) ([]list.Item, error) {
|
2023-01-13 06:19:43 +00:00
|
|
|
items := []list.Item{}
|
2023-02-17 22:08:25 +00:00
|
|
|
devices, err := commands.Client().PlayerDevices(ctx)
|
2023-01-13 06:19:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, device := range devices {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: device.Name,
|
|
|
|
Desc: fmt.Sprintf("%s - active: %t", device.ID, device.Active),
|
|
|
|
SpotifyItem: device,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, nil
|
|
|
|
}
|
|
|
|
|
2023-04-16 07:05:23 +00:00
|
|
|
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
|
|
|
|
}
|
2023-04-16 07:12:50 +00:00
|
|
|
if tracks.CurrentlyPlaying.Name != "" {
|
|
|
|
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,
|
|
|
|
})
|
|
|
|
}
|
2023-04-16 07:05:23 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func PlaylistView(ctx *gctx.Context, commands *commands.Commands, playlist spotify.SimplePlaylist) ([]list.Item, error) {
|
2023-01-13 06:19:43 +00:00
|
|
|
items := []list.Item{}
|
2023-02-17 22:08:25 +00:00
|
|
|
tracks, err := commands.PlaylistTracks(ctx, playlist.ID, 1)
|
2023-01-13 06:19:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, track := range tracks.Tracks {
|
|
|
|
items = append(items, mainItem{
|
2023-01-27 06:28:57 +00:00
|
|
|
Name: track.Track.Name,
|
|
|
|
Artist: track.Track.Artists[0],
|
|
|
|
Duration: track.Track.TimeDuration().Round(time.Second).String(),
|
|
|
|
ID: track.Track.ID,
|
|
|
|
Desc: track.Track.Artists[0].Name + " - " + track.Track.TimeDuration().Round(time.Second).String(),
|
|
|
|
SpotifyItem: track,
|
2023-01-13 06:19:43 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, nil
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func ArtistsView(ctx *gctx.Context, commands *commands.Commands) ([]list.Item, error) {
|
2023-01-13 06:19:43 +00:00
|
|
|
items := []list.Item{}
|
2023-02-17 22:08:25 +00:00
|
|
|
artists, err := commands.UserArtists(ctx, 1)
|
2023-01-13 06:19:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, artist := range artists.Artists {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: artist.Name,
|
|
|
|
ID: artist.ID,
|
2023-04-16 06:04:18 +00:00
|
|
|
Desc: fmt.Sprintf("%d followers", artist.Followers.Count),
|
2023-01-13 06:19:43 +00:00
|
|
|
SpotifyItem: artist.SimpleArtist,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, nil
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func SearchArtistsView(ctx *gctx.Context, commands *commands.Commands, artists *spotify.FullArtistPage) ([]list.Item, error) {
|
2023-01-13 09:12:31 +00:00
|
|
|
items := []list.Item{}
|
|
|
|
for _, artist := range artists.Artists {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: artist.Name,
|
|
|
|
ID: artist.ID,
|
2023-04-16 06:04:18 +00:00
|
|
|
Desc: fmt.Sprintf("%d followers", artist.Followers.Count),
|
2023-01-13 09:12:31 +00:00
|
|
|
SpotifyItem: artist.SimpleArtist,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, nil
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func SearchView(ctx *gctx.Context, commands *commands.Commands, search string) ([]list.Item, *SearchResults, error) {
|
2023-01-13 09:12:31 +00:00
|
|
|
items := []list.Item{}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
result, err := commands.Search(ctx, search, 1)
|
2023-01-13 09:12:31 +00:00
|
|
|
if err != nil {
|
2023-01-14 20:20:41 +00:00
|
|
|
return nil, nil, err
|
2023-01-13 09:12:31 +00:00
|
|
|
}
|
2023-04-07 01:11:06 +00:00
|
|
|
items = append(
|
|
|
|
items,
|
|
|
|
mainItem{Name: "Tracks", Desc: "Search results", SpotifyItem: result.Tracks},
|
|
|
|
mainItem{Name: "Albums", Desc: "Search results", SpotifyItem: result.Albums},
|
|
|
|
mainItem{Name: "Artists", Desc: "Search results", SpotifyItem: result.Artists},
|
|
|
|
mainItem{Name: "Playlists", Desc: "Search results", SpotifyItem: result.Playlists},
|
|
|
|
)
|
2023-01-14 20:20:41 +00:00
|
|
|
results := &SearchResults{
|
|
|
|
Tracks: result.Tracks,
|
|
|
|
Playlists: result.Playlists,
|
|
|
|
Albums: result.Albums,
|
|
|
|
Artists: result.Artists,
|
|
|
|
}
|
|
|
|
return items, results, nil
|
2023-01-13 09:12:31 +00:00
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func AlbumsView(ctx *gctx.Context, commands *commands.Commands) ([]list.Item, error) {
|
2023-01-13 06:19:43 +00:00
|
|
|
items := []list.Item{}
|
2023-02-17 22:08:25 +00:00
|
|
|
albums, err := commands.UserAlbums(ctx, 1)
|
2023-01-13 06:19:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, album := range albums.Albums {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: album.Name,
|
|
|
|
ID: album.ID,
|
2023-04-16 06:04:18 +00:00
|
|
|
Desc: fmt.Sprintf("%s by %s, %d tracks, released %d", album.AlbumType, album.Artists[0].Name, album.Tracks.Total, album.ReleaseDateTime().Year()),
|
2023-01-13 06:19:43 +00:00
|
|
|
SpotifyItem: album.SimpleAlbum,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, nil
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func SearchPlaylistsView(ctx *gctx.Context, commands *commands.Commands, playlists *spotify.SimplePlaylistPage) ([]list.Item, error) {
|
2023-01-13 09:12:31 +00:00
|
|
|
items := []list.Item{}
|
|
|
|
for _, playlist := range playlists.Playlists {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: playlist.Name,
|
2023-04-16 06:21:48 +00:00
|
|
|
Desc: stripHtmlRegex(playlist.Description),
|
2023-01-13 09:12:31 +00:00
|
|
|
SpotifyItem: playlist,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, nil
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func SearchAlbumsView(ctx *gctx.Context, commands *commands.Commands, albums *spotify.SimpleAlbumPage) ([]list.Item, error) {
|
2023-01-13 09:12:31 +00:00
|
|
|
items := []list.Item{}
|
|
|
|
for _, album := range albums.Albums {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: album.Name,
|
|
|
|
ID: album.ID,
|
2023-04-16 06:04:18 +00:00
|
|
|
Desc: fmt.Sprintf("%s by %s, released %d", album.AlbumType, album.Artists[0].Name, album.ReleaseDateTime().Year()),
|
2023-01-13 09:12:31 +00:00
|
|
|
SpotifyItem: album,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, nil
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func ArtistAlbumsView(ctx *gctx.Context, album spotify.ID, commands *commands.Commands) ([]list.Item, error) {
|
2023-01-13 06:19:43 +00:00
|
|
|
items := []list.Item{}
|
2023-02-17 22:08:25 +00:00
|
|
|
albums, err := commands.ArtistAlbums(ctx, album, 1)
|
2023-01-13 06:19:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, album := range albums.Albums {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: album.Name,
|
|
|
|
ID: album.ID,
|
|
|
|
Desc: fmt.Sprintf("%s by %s", album.AlbumType, album.Artists[0].Name),
|
|
|
|
SpotifyItem: album,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, err
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func AlbumTracksView(ctx *gctx.Context, album spotify.ID, commands *commands.Commands) ([]list.Item, error) {
|
2023-01-13 06:19:43 +00:00
|
|
|
items := []list.Item{}
|
2023-02-17 22:08:25 +00:00
|
|
|
tracks, err := commands.AlbumTracks(ctx, album, 1)
|
2023-01-13 06:19:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, track := range tracks.Tracks {
|
|
|
|
items = append(items, mainItem{
|
2023-01-14 20:20:41 +00:00
|
|
|
Name: track.Name,
|
|
|
|
Artist: track.Artists[0],
|
|
|
|
Duration: track.TimeDuration().Round(time.Second).String(),
|
|
|
|
ID: track.ID,
|
|
|
|
SpotifyItem: track,
|
|
|
|
Desc: track.Artists[0].Name + " - " + track.TimeDuration().Round(time.Second).String(),
|
2023-01-13 06:19:43 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, err
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func SearchTracksView(ctx *gctx.Context, commands *commands.Commands, tracks *spotify.FullTrackPage) ([]list.Item, error) {
|
2023-01-13 09:12:31 +00:00
|
|
|
items := []list.Item{}
|
|
|
|
for _, track := range tracks.Tracks {
|
|
|
|
items = append(items, mainItem{
|
2023-01-14 20:20:41 +00:00
|
|
|
Name: track.Name,
|
|
|
|
Artist: track.Artists[0],
|
|
|
|
Duration: track.TimeDuration().Round(time.Second).String(),
|
|
|
|
ID: track.ID,
|
|
|
|
SpotifyItem: track,
|
|
|
|
Desc: track.Artists[0].Name + " - " + track.TimeDuration().Round(time.Second).String(),
|
2023-01-13 09:12:31 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, nil
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func SavedTracksView(ctx *gctx.Context, commands *commands.Commands) ([]list.Item, error) {
|
2023-01-13 06:19:43 +00:00
|
|
|
items := []list.Item{}
|
2023-02-17 22:08:25 +00:00
|
|
|
tracks, err := commands.TrackList(ctx, 1)
|
2023-01-13 06:19:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, track := range tracks.Tracks {
|
|
|
|
items = append(items, mainItem{
|
2023-01-14 20:20:41 +00:00
|
|
|
Name: track.Name,
|
|
|
|
Artist: track.Artists[0],
|
|
|
|
Duration: track.TimeDuration().Round(time.Second).String(),
|
|
|
|
ID: track.ID,
|
|
|
|
SpotifyItem: track,
|
|
|
|
Desc: track.Artists[0].Name + " - " + track.TimeDuration().Round(time.Second).String(),
|
2023-01-13 06:19:43 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
return items, err
|
|
|
|
}
|
|
|
|
|
2023-02-17 22:08:25 +00:00
|
|
|
func MainView(ctx *gctx.Context, commands *commands.Commands) ([]list.Item, error) {
|
2023-04-16 07:05:23 +00:00
|
|
|
wg := errgroup.Group{}
|
2023-01-13 06:19:43 +00:00
|
|
|
var saved_items *spotify.SavedTrackPage
|
|
|
|
var playlists *spotify.SimplePlaylistPage
|
|
|
|
var artists *spotify.FullArtistCursorPage
|
|
|
|
var albums *spotify.SavedAlbumPage
|
|
|
|
|
2023-04-16 07:05:23 +00:00
|
|
|
wg.Go(func() (err error) {
|
2023-02-17 22:08:25 +00:00
|
|
|
saved_items, err = commands.TrackList(ctx, 1)
|
2023-04-16 07:05:23 +00:00
|
|
|
return
|
|
|
|
})
|
2023-01-13 06:19:43 +00:00
|
|
|
|
2023-04-16 07:05:23 +00:00
|
|
|
wg.Go(func() (err error) {
|
2023-02-17 22:08:25 +00:00
|
|
|
playlists, err = commands.Playlists(ctx, 1)
|
2023-04-16 07:05:23 +00:00
|
|
|
return
|
|
|
|
})
|
2023-01-13 06:19:43 +00:00
|
|
|
|
2023-04-16 07:05:23 +00:00
|
|
|
wg.Go(func() (err error) {
|
2023-02-17 22:08:25 +00:00
|
|
|
artists, err = commands.UserArtists(ctx, 1)
|
2023-04-16 07:05:23 +00:00
|
|
|
return
|
|
|
|
})
|
2023-01-13 06:19:43 +00:00
|
|
|
|
2023-04-16 07:05:23 +00:00
|
|
|
wg.Go(func() (err error) {
|
2023-02-17 22:08:25 +00:00
|
|
|
albums, err = commands.UserAlbums(ctx, 1)
|
2023-04-16 07:05:23 +00:00
|
|
|
return
|
|
|
|
})
|
2023-01-13 06:19:43 +00:00
|
|
|
|
2023-04-16 07:05:23 +00:00
|
|
|
err := wg.Wait()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-01-13 06:19:43 +00:00
|
|
|
|
|
|
|
items := []list.Item{}
|
2023-01-16 18:14:01 +00:00
|
|
|
if saved_items != nil && saved_items.Total != 0 {
|
2023-01-13 06:19:43 +00:00
|
|
|
items = append(items, mainItem{
|
2023-01-16 18:14:01 +00:00
|
|
|
Name: "Saved Tracks",
|
|
|
|
Desc: fmt.Sprintf("%d saved songs", saved_items.Total),
|
|
|
|
SpotifyItem: saved_items,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if albums != nil && albums.Total != 0 {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: "Albums",
|
|
|
|
Desc: fmt.Sprintf("%d albums", albums.Total),
|
|
|
|
SpotifyItem: albums,
|
2023-01-13 06:19:43 +00:00
|
|
|
})
|
|
|
|
}
|
2023-01-16 18:14:01 +00:00
|
|
|
if artists != nil && artists.Total != 0 {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: "Artists",
|
|
|
|
Desc: fmt.Sprintf("%d artists", artists.Total),
|
|
|
|
SpotifyItem: artists,
|
|
|
|
})
|
|
|
|
}
|
2023-04-16 07:05:23 +00:00
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: "Queue",
|
|
|
|
Desc: "Your Current Queue",
|
|
|
|
SpotifyItem: spotify.Queue{},
|
|
|
|
})
|
2023-01-16 18:14:01 +00:00
|
|
|
if playlists != nil && playlists.Total != 0 {
|
|
|
|
for _, playlist := range playlists.Playlists {
|
|
|
|
items = append(items, mainItem{
|
|
|
|
Name: playlist.Name,
|
2023-04-16 06:21:48 +00:00
|
|
|
Desc: stripHtmlRegex(playlist.Description),
|
2023-01-16 18:14:01 +00:00
|
|
|
SpotifyItem: playlist,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2023-01-13 06:19:43 +00:00
|
|
|
return items, nil
|
|
|
|
}
|
2023-04-16 06:21:48 +00:00
|
|
|
|
|
|
|
func stripHtmlRegex(s string) string {
|
|
|
|
r := regexp.MustCompile(regex)
|
|
|
|
return r.ReplaceAllString(s, "")
|
|
|
|
}
|