search framework
This commit is contained in:
parent
0e01d77136
commit
1acc255c61
@ -64,6 +64,14 @@ func ArtistAlbums(ctx *gctx.Context, client *spotify.Client, artist spotify.ID,
|
||||
return albums, nil
|
||||
}
|
||||
|
||||
func Search(ctx *gctx.Context, client *spotify.Client, search string, page int) (*spotify.SearchResult, error) {
|
||||
result, err := client.Search(ctx, search, spotify.SearchTypeAlbum|spotify.SearchTypeArtist|spotify.SearchTypeTrack|spotify.SearchTypePlaylist, spotify.Limit(50), spotify.Offset((page-1)*50))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func AlbumTracks(ctx *gctx.Context, client *spotify.Client, album spotify.ID, page int) (*spotify.SimpleTrackPage, error) {
|
||||
tracks, err := client.GetAlbumTracks(ctx, album, spotify.Limit(50), spotify.Offset((page-1)*50), spotify.Market(spotify.CountryUSA))
|
||||
if err != nil {
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/charmbracelet/bubbles/key"
|
||||
"github.com/charmbracelet/bubbles/list"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/zmb3/spotify/v2"
|
||||
@ -36,12 +37,14 @@ 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 string
|
||||
playlist spotify.SimplePlaylist
|
||||
artist spotify.SimpleArtist
|
||||
album spotify.SimpleAlbum
|
||||
search string
|
||||
fromArtist bool
|
||||
}
|
||||
|
||||
@ -70,10 +73,14 @@ func (m *mainModel) Tick() {
|
||||
}
|
||||
|
||||
func (m mainModel) View() string {
|
||||
return DocStyle.Render(m.list.View())
|
||||
if m.input.Focused() {
|
||||
return DocStyle.Render(m.list.View() + "\n" + m.input.View())
|
||||
}
|
||||
return DocStyle.Render(m.list.View() + "\n")
|
||||
}
|
||||
|
||||
func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
search := false
|
||||
m.list.NewStatusMessage(currentlyPlaying)
|
||||
select {
|
||||
case update := <-main_updates:
|
||||
@ -88,7 +95,28 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
if m.input.Focused() {
|
||||
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())
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return m, tea.Quit
|
||||
}
|
||||
m.search = m.input.Value()
|
||||
m.list.SetItems(items)
|
||||
m.list.ResetSelected()
|
||||
m.input.SetValue("")
|
||||
m.input.Blur()
|
||||
search = true
|
||||
}
|
||||
m.input, _ = m.input.Update(msg)
|
||||
}
|
||||
if msg.String() == "s" {
|
||||
m.input.Focus()
|
||||
}
|
||||
if msg.String() == "d" {
|
||||
if !m.input.Focused() {
|
||||
m.mode = "devices"
|
||||
new_items, err := DeviceView(m.ctx, m.client)
|
||||
if err != nil {
|
||||
@ -99,8 +127,22 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.list.ResetSelected()
|
||||
m.list.NewStatusMessage("Setting view to devices")
|
||||
}
|
||||
}
|
||||
if msg.String() == "backspace" || msg.String() == "esc" || msg.String() == "q" {
|
||||
if m.mode == "album" {
|
||||
if m.input.Focused() {
|
||||
if msg.String() == "esc" {
|
||||
m.input.SetValue("")
|
||||
m.input.Blur()
|
||||
m.list.SetShowPagination(true)
|
||||
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)
|
||||
}
|
||||
} else if m.mode == "album" {
|
||||
if m.fromArtist {
|
||||
m.mode = "albums"
|
||||
m.fromArtist = true
|
||||
@ -163,6 +205,51 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
if msg.String() == "enter" || msg.String() == "spacebar" {
|
||||
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 {
|
||||
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 = "searchplaylist"
|
||||
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:
|
||||
@ -296,9 +383,11 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
case tea.WindowSizeMsg:
|
||||
h, v := DocStyle.GetFrameSize()
|
||||
m.list.SetSize(msg.Width-h, msg.Height-v)
|
||||
m.list.SetSize(msg.Width-h, msg.Height-v-1)
|
||||
}
|
||||
if search {
|
||||
m.mode = "search"
|
||||
}
|
||||
|
||||
var cmd tea.Cmd
|
||||
m.list, cmd = m.list.Update(msg)
|
||||
return m, cmd
|
||||
@ -353,5 +442,11 @@ func InitMain(ctx *gctx.Context, client *spotify.Client, mode string) (tea.Model
|
||||
key.NewBinding(key.WithKeys("d"), key.WithHelp("d", "select device")),
|
||||
}
|
||||
}
|
||||
input := textinput.New()
|
||||
input.Prompt = "$ "
|
||||
input.Placeholder = "Search..."
|
||||
input.CharLimit = 250
|
||||
input.Width = 50
|
||||
m.input = input
|
||||
return m, nil
|
||||
}
|
||||
|
@ -63,6 +63,49 @@ func ArtistsView(ctx *gctx.Context, client *spotify.Client) ([]list.Item, error)
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func SearchArtistsView(ctx *gctx.Context, client *spotify.Client, artists *spotify.FullArtistPage) ([]list.Item, error) {
|
||||
items := []list.Item{}
|
||||
for _, artist := range artists.Artists {
|
||||
items = append(items, mainItem{
|
||||
Name: artist.Name,
|
||||
ID: artist.ID,
|
||||
Desc: fmt.Sprintf("%d followers, genres: %s, popularity: %d", artist.Followers.Count, artist.Genres, artist.Popularity),
|
||||
SpotifyItem: artist.SimpleArtist,
|
||||
})
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func SearchView(ctx *gctx.Context, client *spotify.Client, search string) ([]list.Item, error) {
|
||||
items := []list.Item{}
|
||||
|
||||
result, err := commands.Search(ctx, client, search, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, mainItem{
|
||||
Name: "Tracks",
|
||||
Desc: "Search results",
|
||||
SpotifyItem: result.Tracks,
|
||||
})
|
||||
items = append(items, mainItem{
|
||||
Name: "Albums",
|
||||
Desc: "Search results",
|
||||
SpotifyItem: result.Albums,
|
||||
})
|
||||
items = append(items, mainItem{
|
||||
Name: "Artists",
|
||||
Desc: "Search results",
|
||||
SpotifyItem: result.Artists,
|
||||
})
|
||||
items = append(items, mainItem{
|
||||
Name: "Playlists",
|
||||
Desc: "Search results",
|
||||
SpotifyItem: result.Playlists,
|
||||
})
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func AlbumsView(ctx *gctx.Context, client *spotify.Client) ([]list.Item, error) {
|
||||
items := []list.Item{}
|
||||
albums, err := commands.UserAlbums(ctx, client, 1)
|
||||
@ -80,6 +123,31 @@ func AlbumsView(ctx *gctx.Context, client *spotify.Client) ([]list.Item, error)
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func SearchPlaylistsView(ctx *gctx.Context, client *spotify.Client, playlists *spotify.SimplePlaylistPage) ([]list.Item, error) {
|
||||
items := []list.Item{}
|
||||
for _, playlist := range playlists.Playlists {
|
||||
items = append(items, mainItem{
|
||||
Name: playlist.Name,
|
||||
Desc: playlist.Description,
|
||||
SpotifyItem: playlist,
|
||||
})
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func SearchAlbumsView(ctx *gctx.Context, client *spotify.Client, albums *spotify.SimpleAlbumPage) ([]list.Item, error) {
|
||||
items := []list.Item{}
|
||||
for _, album := range albums.Albums {
|
||||
items = append(items, mainItem{
|
||||
Name: album.Name,
|
||||
ID: album.ID,
|
||||
Desc: fmt.Sprintf("%s, %d", album.Artists[0].Name, album.ReleaseDateTime()),
|
||||
SpotifyItem: album,
|
||||
})
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func ArtistAlbumsView(ctx *gctx.Context, album spotify.ID, client *spotify.Client) ([]list.Item, error) {
|
||||
items := []list.Item{}
|
||||
albums, err := commands.ArtistAlbums(ctx, client, album, 1)
|
||||
@ -115,6 +183,20 @@ func AlbumTracksView(ctx *gctx.Context, album spotify.ID, client *spotify.Client
|
||||
return items, err
|
||||
}
|
||||
|
||||
func SearchTracksView(ctx *gctx.Context, client *spotify.Client, tracks *spotify.FullTrackPage) ([]list.Item, error) {
|
||||
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(),
|
||||
})
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func SavedTracksView(ctx *gctx.Context, client *spotify.Client) ([]list.Item, error) {
|
||||
items := []list.Item{}
|
||||
tracks, err := commands.TrackList(ctx, client, 1)
|
||||
|
Loading…
Reference in New Issue
Block a user