diff --git a/src/commands/commands.go b/src/commands/commands.go index e7019b6..383cc0b 100644 --- a/src/commands/commands.go +++ b/src/commands/commands.go @@ -208,7 +208,7 @@ func PlayLikedSongs(ctx *gctx.Context, client *spotify.Client, position int) err func RadioGivenArtist(ctx *gctx.Context, client *spotify.Client, artist_id spotify.ID) error { seed := spotify.Seeds{ - Tracks: []spotify.ID{artist_id}, + Artists: []spotify.ID{artist_id}, } recomendations, err := client.GetRecommendations(ctx, seed, &spotify.TrackAttributes{}, spotify.Limit(100)) if err != nil { diff --git a/src/tui/handlers.go b/src/tui/handlers.go index 213237f..db419e2 100644 --- a/src/tui/handlers.go +++ b/src/tui/handlers.go @@ -9,7 +9,7 @@ import ( "github.com/zmb3/spotify/v2" ) -func HandlePlay(ctx *gctx.Context, client *spotify.Client, uri *spotify.URI, pos int) { +func HandlePlayWithContext(ctx *gctx.Context, client *spotify.Client, uri *spotify.URI, pos int) { var err error err = commands.PlaySongInPlaylist(ctx, client, uri, pos) if err != nil { @@ -31,6 +31,13 @@ func HandleAlbumRadio(ctx *gctx.Context, client *spotify.Client, id spotify.ID) } } +func HandleArtistRadio(ctx *gctx.Context, client *spotify.Client, id spotify.ID) { + err := commands.RadioGivenArtist(ctx, client, id) + if err != nil { + return + } +} + func HandleAlbumArtist(ctx *gctx.Context, client *spotify.Client, id spotify.ID) { err := commands.RadioGivenArtist(ctx, client, id) if err != nil { @@ -41,7 +48,6 @@ func HandleAlbumArtist(ctx *gctx.Context, client *spotify.Client, id spotify.ID) func HandlePlaylistRadio(ctx *gctx.Context, client *spotify.Client, playlist spotify.SimplePlaylist) { err := commands.RadioFromPlaylist(ctx, client, playlist) if err != nil { - fmt.Println("AHHHHHHHHHHHHHHHHHH", err.Error()) return } } @@ -62,8 +68,20 @@ func HandlePlayLikedSong(ctx *gctx.Context, client *spotify.Client, position int } } +func HandlePlayTrack(ctx *gctx.Context, client *spotify.Client, track spotify.ID) { + err := commands.QueueSong(ctx, client, track) + if err != nil { + fmt.Println(err.Error()) + return + } + err = commands.Next(ctx, client) + if err != nil { + fmt.Println(err.Error()) + return + } +} + func HandleSetDevice(ctx *gctx.Context, client *spotify.Client, player spotify.PlayerDevice) { - fmt.Println("WHOA") var err error err = commands.SetDevice(ctx, client, player) if err != nil { diff --git a/src/tui/main.go b/src/tui/main.go index 6cbc22f..730f6b5 100644 --- a/src/tui/main.go +++ b/src/tui/main.go @@ -25,24 +25,25 @@ var ( type Mode string const ( - Album Mode = "album" - ArtistAlbum = "artistalbum" - Artist = "artist" - Artists = "artists" - Tracks = "tracks" - Albums = "albums" - Main = "main" - Playlists = "playlists" - Playlist = "playlist" - Devices = "devices" - Search = "search" - SearchAlbums = "searchalbums" - SearchArtists = "searchartists" - SearchTracks = "searchtracks" - SearchPlaylists = "searchplaylsits" - SearchArtist = "searchartist" - SearchPlaylist = "searchplaylist" - SearchAlbum = "searchalbum" + Album Mode = "album" + ArtistAlbum = "artistalbum" + Artist = "artist" + Artists = "artists" + Tracks = "tracks" + Albums = "albums" + Main = "main" + Playlists = "playlists" + Playlist = "playlist" + Devices = "devices" + Search = "search" + SearchAlbums = "searchalbums" + SearchAlbum = "searchalbum" + SearchArtists = "searchartists" + SearchArtist = "searchartist" + SearchArtistAlbum = "searchartistalbum" + SearchTracks = "searchtracks" + SearchPlaylists = "searchplaylsits" + SearchPlaylist = "searchplaylist" ) type mainItem struct { @@ -54,21 +55,57 @@ type mainItem struct { SpotifyItem any } +type SearchResults struct { + Tracks *spotify.FullTrackPage + Artists *spotify.FullArtistPage + Playlists *spotify.SimplePlaylistPage + Albums *spotify.SimpleAlbumPage +} + func (i mainItem) Title() string { return i.Name } func (i mainItem) Description() string { return i.Desc } func (i mainItem) FilterValue() string { return i.Title() + i.Desc } type mainModel struct { - list list.Model - input textinput.Model - ctx *gctx.Context - client *spotify.Client - mode Mode - playlist spotify.SimplePlaylist - artist spotify.SimpleArtist - album spotify.SimpleAlbum - search string - fromArtist bool + list list.Model + input textinput.Model + ctx *gctx.Context + client *spotify.Client + mode Mode + playlist spotify.SimplePlaylist + artist spotify.SimpleArtist + album spotify.SimpleAlbum + searchResults *SearchResults + search string +} + +func (m *mainModel) PlayRadio() { + currentlyPlaying = m.list.SelectedItem().FilterValue() + m.list.NewStatusMessage("Playing " + currentlyPlaying) + selectedItem := m.list.SelectedItem().(mainItem).SpotifyItem + switch selectedItem.(type) { + case spotify.SimplePlaylist: + go HandlePlaylistRadio(m.ctx, m.client, selectedItem.(spotify.SimplePlaylist)) + return + case spotify.SavedTrackPage: + go HandleLibraryRadio(m.ctx, m.client) + return + case spotify.SimpleAlbum: + go HandleAlbumRadio(m.ctx, m.client, selectedItem.(spotify.SimpleAlbum).ID) + return + case spotify.FullAlbum: + go HandleAlbumRadio(m.ctx, m.client, selectedItem.(spotify.FullAlbum).ID) + return + case spotify.SimpleArtist: + go HandleArtistRadio(m.ctx, m.client, selectedItem.(spotify.SimpleArtist).ID) + return + case spotify.FullArtist: + go HandleArtistRadio(m.ctx, m.client, selectedItem.(spotify.FullArtist).ID) + return + default: + go HandleRadio(m.ctx, m.client, m.list.SelectedItem().(mainItem).ID) + return + } } func (m *mainModel) GoBack() (tea.Cmd, error) { @@ -97,7 +134,6 @@ func (m *mainModel) GoBack() (tea.Cmd, error) { case Artist: m.mode = Artists - m.fromArtist = false m.list.NewStatusMessage("Setting view to artists") new_items, err := ArtistsView(m.ctx, m.client) if err != nil { @@ -108,7 +144,6 @@ func (m *mainModel) GoBack() (tea.Cmd, error) { case ArtistAlbum: m.mode = Artist - m.fromArtist = true m.list.NewStatusMessage("Opening " + m.artist.Name) new_items, err := ArtistAlbumsView(m.ctx, m.artist.ID, m.client) if err != nil { @@ -120,20 +155,45 @@ func (m *mainModel) GoBack() (tea.Cmd, error) { case SearchArtists, SearchTracks, SearchAlbums, SearchPlaylists: m.mode = Search m.list.NewStatusMessage("Setting view to search for " + m.input.Value()) - items, err := SearchView(m.ctx, m.client, m.search) + items, result, err := SearchView(m.ctx, m.client, m.search) if err != nil { return nil, err } + m.searchResults = result m.list.SetItems(items) case SearchArtist: m.mode = SearchArtists - + m.list.NewStatusMessage("Setting view to artists") + new_items, err := SearchArtistsView(m.ctx, m.client, m.searchResults.Artists) + if err != nil { + return nil, err + } + m.list.SetItems(new_items) + case SearchArtistAlbum: + m.mode = SearchArtist + m.list.NewStatusMessage("Opening " + m.artist.Name) + new_items, err := ArtistAlbumsView(m.ctx, m.artist.ID, m.client) + if err != nil { + return nil, err + } + m.list.SetItems(new_items) + m.list.ResetSelected() case SearchAlbum: m.mode = SearchAlbums - + m.list.NewStatusMessage("Setting view to albums") + new_items, err := SearchAlbumsView(m.ctx, m.client, m.searchResults.Albums) + if err != nil { + return nil, err + } + m.list.SetItems(new_items) case SearchPlaylist: m.mode = SearchPlaylists - + m.list.NewStatusMessage("Setting view to playlists") + new_items, err := SearchPlaylistsView(m.ctx, m.client, m.searchResults.Playlists) + if err != nil { + return nil, err + } + m.list.SetItems(new_items) default: m.list.ResetSelected() page = 0 @@ -141,6 +201,192 @@ func (m *mainModel) GoBack() (tea.Cmd, error) { return nil, nil } +func (m *mainModel) SelectItem() error { + switch m.mode { + case Search: + switch m.list.SelectedItem().(mainItem).SpotifyItem.(type) { + case *spotify.FullArtistPage: + m.mode = SearchArtists + m.list.NewStatusMessage("Setting view to artists") + new_items, err := SearchArtistsView(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.FullArtistPage)) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case *spotify.SimpleAlbumPage: + m.mode = SearchAlbums + m.list.NewStatusMessage("Setting view to albums") + new_items, err := SearchAlbumsView(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.SimpleAlbumPage)) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case *spotify.SimplePlaylistPage: + m.mode = SearchPlaylists + playlists := m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.SimplePlaylistPage) + m.list.NewStatusMessage("Setting view to playlist") + new_items, err := SearchPlaylistsView(m.ctx, m.client, playlists) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case *spotify.FullTrackPage: + m.mode = SearchTracks + m.list.NewStatusMessage("Setting view to tracks") + new_items, err := SearchTracksView(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.FullTrackPage)) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + m.list.NewStatusMessage("Setting view to tracks") + } + case SearchArtists: + m.mode = SearchArtist + m.artist = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleArtist) + m.list.NewStatusMessage("Opening " + m.artist.Name) + new_items, err := ArtistAlbumsView(m.ctx, m.artist.ID, m.client) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case SearchArtist: + m.mode = SearchArtistAlbum + m.album = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleAlbum) + m.list.NewStatusMessage("Opening " + m.album.Name) + new_items, err := AlbumTracksView(m.ctx, m.album.ID, m.client) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case SearchAlbums: + m.mode = SearchAlbum + m.album = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleAlbum) + m.list.NewStatusMessage("Opening " + m.album.Name) + new_items, err := AlbumTracksView(m.ctx, m.album.ID, m.client) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case SearchPlaylists: + m.mode = SearchPlaylist + playlist := m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimplePlaylist) + m.playlist = playlist + m.list.NewStatusMessage("Setting view to playlist " + playlist.Name) + new_items, err := PlaylistView(m.ctx, m.client, playlist) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case Main: + switch m.list.SelectedItem().(mainItem).SpotifyItem.(type) { + case *spotify.FullArtistCursorPage: + m.mode = Artists + m.list.NewStatusMessage("Setting view to artists") + new_items, err := ArtistsView(m.ctx, m.client) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case *spotify.SavedAlbumPage: + m.mode = Albums + m.list.NewStatusMessage("Setting view to albums") + new_items, err := AlbumsView(m.ctx, m.client) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case spotify.SimplePlaylist: + m.mode = Playlist + playlist := m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimplePlaylist) + m.playlist = playlist + m.list.NewStatusMessage("Setting view to playlist " + playlist.Name) + new_items, err := PlaylistView(m.ctx, m.client, playlist) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case *spotify.SavedTrackPage: + m.mode = Tracks + m.list.NewStatusMessage("Setting view to saved tracks") + new_items, err := SavedTracksView(m.ctx, m.client) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + m.list.NewStatusMessage("Setting view to tracks") + } + case Albums: + m.mode = Album + m.album = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleAlbum) + m.list.NewStatusMessage("Opening " + m.album.Name) + new_items, err := AlbumTracksView(m.ctx, m.album.ID, m.client) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case Artist: + m.mode = ArtistAlbum + m.album = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleAlbum) + m.list.NewStatusMessage("Opening " + m.album.Name) + new_items, err := AlbumTracksView(m.ctx, m.album.ID, m.client) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case Artists: + m.mode = Artist + m.artist = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleArtist) + m.list.NewStatusMessage("Opening " + m.artist.Name) + new_items, err := ArtistAlbumsView(m.ctx, m.artist.ID, m.client) + if err != nil { + return err + } + m.list.SetItems(new_items) + m.list.ResetSelected() + case Album, ArtistAlbum, SearchArtistAlbum, SearchAlbum: + currentlyPlaying = m.list.SelectedItem().FilterValue() + m.list.NewStatusMessage("Playing " + currentlyPlaying) + go HandlePlayWithContext(m.ctx, m.client, &m.album.URI, m.list.Cursor()+(m.list.Paginator.Page*m.list.Paginator.TotalPages)) + case Playlist, SearchPlaylist: + currentlyPlaying = m.list.SelectedItem().FilterValue() + m.list.NewStatusMessage("Playing " + currentlyPlaying) + go HandlePlayWithContext(m.ctx, m.client, &m.playlist.URI, m.list.Cursor()+(m.list.Paginator.Page*m.list.Paginator.PerPage)) + case Tracks: + currentlyPlaying = m.list.SelectedItem().FilterValue() + m.list.NewStatusMessage("Playing " + currentlyPlaying) + go HandlePlayLikedSong(m.ctx, m.client, m.list.Cursor()+(m.list.Paginator.Page*m.list.Paginator.PerPage)) + case SearchTracks: + currentlyPlaying = m.list.SelectedItem().FilterValue() + m.list.NewStatusMessage("Playing " + currentlyPlaying) + go HandlePlayTrack(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.FullTrack).ID) + case Devices: + go HandleSetDevice(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.PlayerDevice)) + m.list.NewStatusMessage("Setting device to " + m.list.SelectedItem().FilterValue()) + m.mode = "main" + m.list.NewStatusMessage("Setting view to main") + new_items, err := MainView(m.ctx, m.client) + if err != nil { + fmt.Println(err.Error()) + } + m.list.SetItems(new_items) + } + return nil +} + func (m mainModel) Init() tea.Cmd { main_updates = make(chan *mainModel) return nil @@ -175,11 +421,12 @@ func (m mainModel) View() string { func (m *mainModel) Typing(msg tea.KeyMsg) (bool, tea.Cmd) { if msg.String() == "enter" { m.list.NewStatusMessage("Setting view to search for " + m.input.Value()) - items, err := SearchView(m.ctx, m.client, m.input.Value()) + items, result, err := SearchView(m.ctx, m.client, m.input.Value()) if err != nil { fmt.Println(err.Error()) return false, tea.Quit } + m.searchResults = result m.search = m.input.Value() m.list.SetItems(items) m.list.ResetSelected() @@ -197,23 +444,29 @@ func (m *mainModel) Typing(msg tea.KeyMsg) (bool, tea.Cmd) { } func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + // Update Now Playing m.list.NewStatusMessage(currentlyPlaying) + // Update list items from LoadMore select { case update := <-main_updates: m.list.SetItems(update.list.Items()) default: } + // Call for more items if needed if m.list.Paginator.Page == m.list.Paginator.TotalPages-2 && m.list.Cursor() == 0 { // if last request was still full request more if len(m.list.Items())%50 == 0 { go m.LoadMoreItems() } } + // Handle user input switch msg := msg.(type) { case tea.KeyMsg: + // quit if msg.String() == "ctrl+c" { return m, tea.Quit } + // search input if m.input.Focused() { search, cmd := m.Typing(msg) if search { @@ -221,22 +474,23 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } return m, cmd } - if msg.String() == "s" { + // start search + if msg.String() == "s" || msg.String() == "/" { m.input.Focus() } + // enter device selection if msg.String() == "d" { - if !m.input.Focused() { - m.mode = Devices - new_items, err := DeviceView(m.ctx, m.client) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - m.list.NewStatusMessage("Setting view to devices") + m.mode = Devices + new_items, err := DeviceView(m.ctx, m.client) + if err != nil { + fmt.Println(err.Error()) + return m, tea.Quit } + m.list.SetItems(new_items) + m.list.ResetSelected() + m.list.NewStatusMessage("Setting view to devices") } + // go back if msg.String() == "backspace" || msg.String() == "esc" || msg.String() == "q" { msg, err := m.GoBack() if err != nil { @@ -245,212 +499,19 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, msg } + // select item if msg.String() == "enter" || msg.String() == "spacebar" { - switch m.mode { - case SearchArtists: - m.mode = SearchArtist - m.fromArtist = true - m.artist = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleArtist) - m.list.NewStatusMessage("Opening " + m.artist.Name) - new_items, err := ArtistAlbumsView(m.ctx, m.artist.ID, m.client) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case SearchAlbums: - m.mode = SearchAlbum - m.album = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleAlbum) - m.list.NewStatusMessage("Opening " + m.album.Name) - new_items, err := AlbumTracksView(m.ctx, m.album.ID, m.client) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case SearchPlaylists: - m.mode = SearchPlaylist - playlist := m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimplePlaylist) - m.playlist = playlist - m.list.NewStatusMessage("Setting view to playlist " + playlist.Name) - new_items, err := PlaylistView(m.ctx, m.client, playlist) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case Search: - switch m.list.SelectedItem().(mainItem).SpotifyItem.(type) { - case *spotify.FullArtistPage: - m.mode = SearchArtists - m.list.NewStatusMessage("Setting view to artists") - new_items, err := SearchArtistsView(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.FullArtistPage)) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case *spotify.SimpleAlbumPage: - m.mode = SearchAlbums - m.list.NewStatusMessage("Setting view to albums") - new_items, err := SearchAlbumsView(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.SimpleAlbumPage)) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case *spotify.SimplePlaylistPage: - m.mode = SearchPlaylists - playlists := m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.SimplePlaylistPage) - m.list.NewStatusMessage("Setting view to playlist") - new_items, err := SearchPlaylistsView(m.ctx, m.client, playlists) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case *spotify.FullTrackPage: - m.mode = SearchTracks - m.list.NewStatusMessage("Setting view to tracks") - new_items, err := SearchTracksView(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.FullTrackPage)) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - m.list.NewStatusMessage("Setting view to tracks") - } - case "main": - switch m.list.SelectedItem().(mainItem).SpotifyItem.(type) { - case *spotify.FullArtistCursorPage: - m.mode = Artists - m.list.NewStatusMessage("Setting view to artists") - new_items, err := ArtistsView(m.ctx, m.client) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case *spotify.SavedAlbumPage: - m.mode = Albums - m.list.NewStatusMessage("Setting view to albums") - new_items, err := AlbumsView(m.ctx, m.client) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case spotify.SimplePlaylist: - m.mode = Playlist - playlist := m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimplePlaylist) - m.playlist = playlist - m.list.NewStatusMessage("Setting view to playlist " + playlist.Name) - new_items, err := PlaylistView(m.ctx, m.client, playlist) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case *spotify.SavedTrackPage: - m.mode = Tracks - m.list.NewStatusMessage("Setting view to saved tracks") - new_items, err := SavedTracksView(m.ctx, m.client) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - m.list.NewStatusMessage("Setting view to tracks") - } - case Albums: - m.mode = Album - m.album = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleAlbum) - m.list.NewStatusMessage("Opening " + m.album.Name) - new_items, err := AlbumTracksView(m.ctx, m.album.ID, m.client) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case Artist: - m.mode = ArtistAlbum - m.album = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleAlbum) - m.list.NewStatusMessage("Opening " + m.album.Name) - new_items, err := AlbumTracksView(m.ctx, m.album.ID, m.client) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case Artists: - m.mode = Artist - m.fromArtist = true - m.artist = m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleArtist) - m.list.NewStatusMessage("Opening " + m.artist.Name) - new_items, err := ArtistAlbumsView(m.ctx, m.artist.ID, m.client) - if err != nil { - fmt.Println(err.Error()) - return m, tea.Quit - } - m.list.SetItems(new_items) - m.list.ResetSelected() - case Album, ArtistAlbum: - currentlyPlaying = m.list.SelectedItem().FilterValue() - m.list.NewStatusMessage("Playing " + currentlyPlaying) - go HandlePlay(m.ctx, m.client, &m.album.URI, m.list.Cursor()+(m.list.Paginator.Page*m.list.Paginator.TotalPages)) - case Playlist, SearchPlaylist: - currentlyPlaying = m.list.SelectedItem().FilterValue() - m.list.NewStatusMessage("Playing " + currentlyPlaying) - go HandlePlay(m.ctx, m.client, &m.playlist.URI, m.list.Cursor()+(m.list.Paginator.Page*m.list.Paginator.PerPage)) - case Tracks, SearchTracks: - currentlyPlaying = m.list.SelectedItem().FilterValue() - m.list.NewStatusMessage("Playing " + currentlyPlaying) - go HandlePlayLikedSong(m.ctx, m.client, m.list.Cursor()+(m.list.Paginator.Page*m.list.Paginator.PerPage)) - case Devices: - go HandleSetDevice(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.PlayerDevice)) - m.list.NewStatusMessage("Setting device to " + m.list.SelectedItem().FilterValue()) - m.mode = "main" - m.list.NewStatusMessage("Setting view to main") - new_items, err := MainView(m.ctx, m.client) - if err != nil { - fmt.Println(err.Error()) - } - m.list.SetItems(new_items) + err := m.SelectItem() + if err != nil { + return m, tea.Quit } } + // start radio if msg.String() == "ctrl+r" { - switch m.list.SelectedItem().(mainItem).SpotifyItem.(type) { - case spotify.SimplePlaylist: - currentlyPlaying = m.list.SelectedItem().FilterValue() - m.list.NewStatusMessage("Starting radio for " + currentlyPlaying) - go HandlePlaylistRadio(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimplePlaylist)) - case *spotify.SavedTrackPage: - currentlyPlaying = m.list.SelectedItem().FilterValue() - m.list.NewStatusMessage("Starting radio for " + currentlyPlaying) - go HandleLibraryRadio(m.ctx, m.client) - case *spotify.SimpleAlbum, *spotify.FullAlbum: - currentlyPlaying = m.list.SelectedItem().FilterValue() - m.list.NewStatusMessage("Stating radio for" + currentlyPlaying) - go HandleAlbumRadio(m.ctx, m.client, m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimpleAlbum).ID) - default: - currentlyPlaying = m.list.SelectedItem().FilterValue() - m.list.NewStatusMessage("Playing " + currentlyPlaying) - go HandleRadio(m.ctx, m.client, m.list.SelectedItem().(mainItem).ID) - } + m.PlayRadio() } + + // handle mouse case tea.MouseMsg: if msg.Type == 5 { m.list.CursorUp() @@ -458,10 +519,14 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if msg.Type == 6 { m.list.CursorDown() } + + // window size -1 to handle search bar case tea.WindowSizeMsg: h, v := DocStyle.GetFrameSize() m.list.SetSize(msg.Width-h, msg.Height-v-1) } + + // return var cmd tea.Cmd m.list, cmd = m.list.Update(msg) return m, cmd diff --git a/src/tui/views.go b/src/tui/views.go index 2831979..5f7d9e6 100644 --- a/src/tui/views.go +++ b/src/tui/views.go @@ -76,12 +76,12 @@ func SearchArtistsView(ctx *gctx.Context, client *spotify.Client, artists *spoti return items, nil } -func SearchView(ctx *gctx.Context, client *spotify.Client, search string) ([]list.Item, error) { +func SearchView(ctx *gctx.Context, client *spotify.Client, search string) ([]list.Item, *SearchResults, error) { items := []list.Item{} result, err := commands.Search(ctx, client, search, 1) if err != nil { - return nil, err + return nil, nil, err } items = append(items, mainItem{ Name: "Tracks", @@ -103,7 +103,13 @@ func SearchView(ctx *gctx.Context, client *spotify.Client, search string) ([]lis Desc: "Search results", SpotifyItem: result.Playlists, }) - return items, nil + results := &SearchResults{ + Tracks: result.Tracks, + Playlists: result.Playlists, + Albums: result.Albums, + Artists: result.Artists, + } + return items, results, nil } func AlbumsView(ctx *gctx.Context, client *spotify.Client) ([]list.Item, error) { @@ -173,11 +179,12 @@ func AlbumTracksView(ctx *gctx.Context, album spotify.ID, client *spotify.Client } for _, track := range tracks.Tracks { 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(), + 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(), }) } return items, err @@ -187,11 +194,12 @@ func SearchTracksView(ctx *gctx.Context, client *spotify.Client, tracks *spotify items := []list.Item{} for _, track := range tracks.Tracks { 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(), + 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(), }) } return items, nil @@ -205,11 +213,12 @@ func SavedTracksView(ctx *gctx.Context, client *spotify.Client) ([]list.Item, er } for _, track := range tracks.Tracks { 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(), + 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(), }) } return items, err