This commit is contained in:
parent
55f9c73966
commit
2fbeb6d21a
87
.golangci.yml
Normal file
87
.golangci.yml
Normal file
@ -0,0 +1,87 @@
|
||||
run:
|
||||
deadline: 10m
|
||||
skip-dirs:
|
||||
- hack
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- gofmt
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- gocritic
|
||||
- bodyclose
|
||||
- gosec
|
||||
- prealloc
|
||||
- unconvert
|
||||
- unused
|
||||
|
||||
linters-settings:
|
||||
gocritic:
|
||||
# Which checks should be enabled; can't be combined with 'disabled-checks';
|
||||
# See https://go-critic.github.io/overview#checks-overview
|
||||
# To check which checks are enabled run `GL_DEBUG=gocritic ./build/bin/golangci-lint run`
|
||||
# By default list of stable checks is used.
|
||||
enabled-checks:
|
||||
- ruleguard
|
||||
- truncateCmp
|
||||
|
||||
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
|
||||
disabled-checks:
|
||||
- captLocal
|
||||
- assignOp
|
||||
- paramTypeCombine
|
||||
- importShadow
|
||||
- commentFormatting
|
||||
- rangeValCopy
|
||||
|
||||
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
|
||||
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
||||
enabled-tags:
|
||||
- performance
|
||||
- diagnostic
|
||||
- opinionated
|
||||
disabled-tags:
|
||||
- experimental
|
||||
settings:
|
||||
hugeParam:
|
||||
# size in bytes that makes the warning trigger (default 80)
|
||||
sizeThreshold: 1000
|
||||
rangeExprCopy:
|
||||
# size in bytes that makes the warning trigger (default 512)
|
||||
sizeThreshold: 512
|
||||
# whether to check test functions (default true)
|
||||
skipTestFuncs: true
|
||||
truncateCmp:
|
||||
# whether to skip int/uint/uintptr types (default true)
|
||||
skipArchDependent: true
|
||||
underef:
|
||||
# whether to skip (*x).method() calls where x is a pointer receiver (default true)
|
||||
skipRecvDeref: true
|
||||
|
||||
govet:
|
||||
disable:
|
||||
- deepequalerrors
|
||||
- fieldalignment
|
||||
- shadow
|
||||
- unsafeptr
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 2
|
||||
gofmt:
|
||||
auto-fix: false
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- linters:
|
||||
- golint
|
||||
text: "should be"
|
||||
- linters:
|
||||
- errcheck
|
||||
text: "not checked"
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: "SA(1019|1029|5011)"
|
@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"tuxpa.in/a/zlog/log"
|
||||
|
||||
@ -91,7 +92,7 @@ func GetClient(ctx *gctx.Context) (*spotify.Client, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = os.WriteFile(authFilePath, out, 0o644)
|
||||
err = os.WriteFile(authFilePath, out, 0o600)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to save auth")
|
||||
}
|
||||
@ -102,8 +103,12 @@ func GetClient(ctx *gctx.Context) (*spotify.Client, error) {
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("Got request for:", r.URL.String())
|
||||
})
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf(":%s", config.Values.Port),
|
||||
ReadHeaderTimeout: 5 * time.Second,
|
||||
}
|
||||
go func() {
|
||||
err := http.ListenAndServe(fmt.Sprintf(":%s", config.Values.Port), nil)
|
||||
err := server.ListenAndServe()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -115,6 +120,7 @@ func GetClient(ctx *gctx.Context) (*spotify.Client, error) {
|
||||
// wait for auth to complete
|
||||
client := <-ch
|
||||
|
||||
server.Shutdown(ctx)
|
||||
// use the client to make calls that require authorization
|
||||
user, err := client.CurrentUser(ctx)
|
||||
if err != nil {
|
||||
@ -137,7 +143,7 @@ func completeAuth(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
err = os.WriteFile(filepath.Join(configDir, "gospt/auth.json"), out, 0o644)
|
||||
err = os.WriteFile(filepath.Join(configDir, "gospt/auth.json"), out, 0o600)
|
||||
if err != nil {
|
||||
panic("FAILED TO SAVE AUTH")
|
||||
}
|
||||
|
2
src/cache/cache.go
vendored
2
src/cache/cache.go
vendored
@ -42,7 +42,7 @@ func (c *Cache) save(m map[string]CacheEntry) error {
|
||||
return err
|
||||
}
|
||||
log.Trace().Str("tosave", string(payload)).Msg("saving cache")
|
||||
err = os.WriteFile(c.Root, payload, 0640)
|
||||
err = os.WriteFile(c.Root, payload, 0o600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -21,11 +21,10 @@ import (
|
||||
|
||||
var (
|
||||
// Used for flags.
|
||||
ctx *gctx.Context
|
||||
commands *cmds.Commands
|
||||
cfgFile string
|
||||
userLicense string
|
||||
verbose bool
|
||||
ctx *gctx.Context
|
||||
commands *cmds.Commands
|
||||
cfgFile string
|
||||
verbose bool
|
||||
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "gospt",
|
||||
@ -90,7 +89,12 @@ func initConfig() {
|
||||
}
|
||||
if config.Values.ClientSecretCmd != "" {
|
||||
args := strings.Fields(config.Values.ClientSecretCmd)
|
||||
secret, err := exec.Command(args[0], args[1:]...).Output()
|
||||
cmd := args[0]
|
||||
secret_command := exec.Command(cmd)
|
||||
if len(args) > 1 {
|
||||
secret_command.Args = args
|
||||
}
|
||||
secret, err := secret_command.Output()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -531,7 +531,7 @@ func (c *Commands) RadioGivenSong(ctx *gctx.Context, song spotify.SimpleTrack, p
|
||||
func (c *Commands) SongExists(db *sql.DB, song spotify.ID) (bool, error) {
|
||||
song_id := string(song)
|
||||
sqlStmt := `SELECT id FROM radio WHERE id = ?`
|
||||
err := db.QueryRow(sqlStmt, string(song_id)).Scan(&song_id)
|
||||
err := db.QueryRow(sqlStmt, song_id).Scan(&song_id)
|
||||
if err != nil {
|
||||
if err != sql.ErrNoRows {
|
||||
return false, err
|
||||
@ -563,15 +563,12 @@ func (c *Commands) Radio(ctx *gctx.Context) error {
|
||||
return err
|
||||
}
|
||||
seed_song = tracks.Tracks[frand.Intn(len(tracks.Tracks))].SimpleTrack
|
||||
} else {
|
||||
if !current_song.Playing {
|
||||
|
||||
tracks, err := c.Client().CurrentUsersTracks(ctx, spotify.Limit(10))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
seed_song = tracks.Tracks[frand.Intn(len(tracks.Tracks))].SimpleTrack
|
||||
} else if !current_song.Playing {
|
||||
tracks, err := c.Client().CurrentUsersTracks(ctx, spotify.Limit(10))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
seed_song = tracks.Tracks[frand.Intn(len(tracks.Tracks))].SimpleTrack
|
||||
}
|
||||
return c.RadioGivenSong(ctx, seed_song, current_song.Progress)
|
||||
}
|
||||
@ -587,6 +584,7 @@ func (c *Commands) RefillRadio(ctx *gctx.Context) error {
|
||||
to_remove := []spotify.ID{}
|
||||
radioPlaylist, db, err := c.GetRadioPlaylist(ctx, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if status.PlaybackContext.URI != radioPlaylist.URI {
|
||||
@ -598,20 +596,17 @@ func (c *Commands) RefillRadio(ctx *gctx.Context) error {
|
||||
return fmt.Errorf("orig playlist items: %w", err)
|
||||
}
|
||||
|
||||
found := false
|
||||
page := 0
|
||||
for !found {
|
||||
for {
|
||||
tracks, err := c.Client().GetPlaylistItems(ctx, radioPlaylist.ID, spotify.Limit(50), spotify.Offset(page*50))
|
||||
if err != nil {
|
||||
return fmt.Errorf("tracks: %w", err)
|
||||
}
|
||||
if len(tracks.Items) == 0 {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
for _, track := range tracks.Items {
|
||||
if track.Track.Track.ID == status.Item.ID {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
to_remove = append(to_remove, track.Track.Track.ID)
|
||||
@ -630,7 +625,7 @@ func (c *Commands) RefillRadio(ctx *gctx.Context) error {
|
||||
return fmt.Errorf("error clearing playlist: %w", err)
|
||||
}
|
||||
}
|
||||
_, err = c.Client().RemoveTracksFromPlaylist(ctx, radioPlaylist.ID, trackGroups...)
|
||||
c.Client().RemoveTracksFromPlaylist(ctx, radioPlaylist.ID, trackGroups...)
|
||||
}
|
||||
|
||||
to_add := 500 - (playlistItems.Total - len(to_remove))
|
||||
@ -642,7 +637,7 @@ func (c *Commands) RefillRadio(ctx *gctx.Context) error {
|
||||
pages := int(math.Ceil(float64(total) / 50))
|
||||
randomPage := 1
|
||||
if pages > 1 {
|
||||
randomPage = frand.Intn(int(pages-1)) + 1
|
||||
randomPage = frand.Intn(pages-1) + 1
|
||||
}
|
||||
playlistPage, err := c.Client().GetPlaylistItems(ctx, radioPlaylist.ID, spotify.Limit(50), spotify.Offset((randomPage-1)*50))
|
||||
if err != nil {
|
||||
@ -684,6 +679,9 @@ func (c *Commands) RefillRadio(ctx *gctx.Context) error {
|
||||
break
|
||||
}
|
||||
_, err = db.QueryContext(ctx, fmt.Sprintf("INSERT INTO radio (id) VALUES('%s')", rec.String()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queue = append(queue, rec)
|
||||
}
|
||||
to_add -= len(queue)
|
||||
@ -825,8 +823,8 @@ func (c *Commands) Next(ctx *gctx.Context, amt int) error {
|
||||
case "playlist":
|
||||
found := false
|
||||
currentTrackIndex := 0
|
||||
page := 1
|
||||
for !found {
|
||||
page := 1
|
||||
playlist, err := c.Client().GetPlaylistItems(ctx, spotify.ID(strings.Split(string(current.PlaybackContext.URI), ":")[2]), spotify.Limit(50), spotify.Offset((page-1)*50))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -850,8 +848,8 @@ func (c *Commands) Next(ctx *gctx.Context, amt int) error {
|
||||
case "album":
|
||||
found := false
|
||||
currentTrackIndex := 0
|
||||
page := 1
|
||||
for !found {
|
||||
page := 1
|
||||
playlist, err := c.Client().GetAlbumTracks(ctx, spotify.ID(strings.Split(string(current.PlaybackContext.URI), ":")[2]), spotify.Limit(50), spotify.Offset((page-1)*50))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -903,9 +901,6 @@ func (c *Commands) Status(ctx *gctx.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(state)
|
||||
return nil
|
||||
}
|
||||
@ -923,7 +918,7 @@ func (c *Commands) LinkContext(ctx *gctx.Context) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(state.PlaybackContext.ExternalURLs["spotify"]), nil
|
||||
return state.PlaybackContext.ExternalURLs["spotify"], nil
|
||||
}
|
||||
|
||||
func (c *Commands) NowPlaying(ctx *gctx.Context) error {
|
||||
@ -953,7 +948,7 @@ func FormatSong(current *spotify.CurrentlyPlaying) string {
|
||||
func (c *Commands) Shuffle(ctx *gctx.Context) error {
|
||||
state, err := c.Client().PlayerState(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to get current playstate")
|
||||
return fmt.Errorf("failed to get current playstate")
|
||||
}
|
||||
err = c.Client().Shuffle(ctx, !state.ShuffleState)
|
||||
if err != nil {
|
||||
@ -966,7 +961,7 @@ func (c *Commands) Shuffle(ctx *gctx.Context) error {
|
||||
func (c *Commands) Repeat(ctx *gctx.Context) error {
|
||||
state, err := c.Client().PlayerState(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to get current playstate")
|
||||
return fmt.Errorf("failed to get current playstate")
|
||||
}
|
||||
newState := "off"
|
||||
if state.RepeatState == "off" {
|
||||
@ -1012,7 +1007,7 @@ func (c *Commands) PrintPlaying(current *spotify.CurrentlyPlaying) error {
|
||||
if !current.Playing {
|
||||
icon = "⏸"
|
||||
}
|
||||
fmt.Println(fmt.Sprintf("%s %s - %s", icon, current.Item.Name, current.Item.Artists[0].Name))
|
||||
fmt.Printf("%s %s - %s\n", icon, current.Item.Name, current.Item.Artists[0].Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1031,7 +1026,7 @@ func (c *Commands) SetDevice(ctx *gctx.Context, device spotify.PlayerDevice) err
|
||||
return err
|
||||
}
|
||||
configDir, _ := os.UserConfigDir()
|
||||
err = os.WriteFile(filepath.Join(configDir, "gospt/device.json"), out, 0o644)
|
||||
err = os.WriteFile(filepath.Join(configDir, "gospt/device.json"), out, 0o600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1049,12 +1044,12 @@ func isNoActiveError(err error) bool {
|
||||
func (c *Commands) RadioFromPlaylist(ctx *gctx.Context, playlist spotify.SimplePlaylist) error {
|
||||
total := playlist.Tracks.Total
|
||||
if total == 0 {
|
||||
return fmt.Errorf("This playlist is empty")
|
||||
return fmt.Errorf("this playlist is empty")
|
||||
}
|
||||
pages := int(math.Ceil(float64(total) / 50))
|
||||
randomPage := 1
|
||||
if pages > 1 {
|
||||
randomPage = frand.Intn(int(pages-1)) + 1
|
||||
randomPage = frand.Intn(pages-1) + 1
|
||||
}
|
||||
playlistPage, err := c.Client().GetPlaylistItems(ctx, playlist.ID, spotify.Limit(50), spotify.Offset((randomPage-1)*50))
|
||||
if err != nil {
|
||||
@ -1083,12 +1078,12 @@ func (c *Commands) RadioFromAlbum(ctx *gctx.Context, album spotify.SimpleAlbum)
|
||||
}
|
||||
total := tracks.Total
|
||||
if total == 0 {
|
||||
return fmt.Errorf("This playlist is empty")
|
||||
return fmt.Errorf("this playlist is empty")
|
||||
}
|
||||
pages := int(math.Ceil(float64(total) / 50))
|
||||
randomPage := 1
|
||||
if pages > 1 {
|
||||
randomPage = frand.Intn(int(pages-1)) + 1
|
||||
randomPage = frand.Intn(pages-1) + 1
|
||||
}
|
||||
albumTrackPage, err := c.AlbumTracks(ctx, album.ID, randomPage)
|
||||
if err != nil {
|
||||
@ -1116,12 +1111,12 @@ func (c *Commands) RadioFromSavedTracks(ctx *gctx.Context) error {
|
||||
return err
|
||||
}
|
||||
if savedSongs.Total == 0 {
|
||||
return fmt.Errorf("You have no saved songs")
|
||||
return fmt.Errorf("you have no saved songs")
|
||||
}
|
||||
pages := int(math.Ceil(float64(savedSongs.Total) / 50))
|
||||
randomPage := 1
|
||||
if pages > 1 {
|
||||
randomPage = frand.Intn(int(pages-1)) + 1
|
||||
randomPage = frand.Intn(pages-1) + 1
|
||||
}
|
||||
trackPage, err := c.Client().CurrentUsersTracks(ctx, spotify.Limit(50), spotify.Offset(randomPage*50))
|
||||
if err != nil {
|
||||
@ -1261,29 +1256,6 @@ func (c *Commands) activateDevice(ctx *gctx.Context) (spotify.ID, error) {
|
||||
return device.ID, nil
|
||||
}
|
||||
|
||||
func (c *Commands) getDefaultDevice(ctx *gctx.Context) (spotify.ID, error) {
|
||||
configDir, _ := os.UserConfigDir()
|
||||
if _, err := os.Stat(filepath.Join(configDir, "gospt/device.json")); err == nil {
|
||||
deviceFile, err := os.Open(filepath.Join(configDir, "gospt/device.json"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer deviceFile.Close()
|
||||
deviceValue, err := io.ReadAll(deviceFile)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var device *spotify.PlayerDevice
|
||||
err = json.Unmarshal(deviceValue, &device)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return device.ID, nil
|
||||
} else {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Commands) GetRadioPlaylist(ctx *gctx.Context, name string) (*spotify.FullPlaylist, *sql.DB, error) {
|
||||
configDir, _ := os.UserConfigDir()
|
||||
playlistFile, err := os.ReadFile(filepath.Join(configDir, "gospt/radio.json"))
|
||||
@ -1299,6 +1271,9 @@ func (c *Commands) GetRadioPlaylist(ctx *gctx.Context, name string) (*spotify.Fu
|
||||
return nil, nil, err
|
||||
}
|
||||
db, err := sql.Open("sqlite", filepath.Join(configDir, "gospt/radio.db"))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return playlist, db, nil
|
||||
}
|
||||
|
||||
@ -1313,11 +1288,14 @@ func (c *Commands) CreateRadioPlaylist(ctx *gctx.Context, name string) (*spotify
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
err = os.WriteFile(filepath.Join(configDir, "gospt/radio.json"), raw, 0o644)
|
||||
err = os.WriteFile(filepath.Join(configDir, "gospt/radio.json"), raw, 0o600)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
db, err := sql.Open("sqlite", filepath.Join(configDir, "gospt/radio.db"))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
db.QueryContext(ctx, "DROP TABLE IF EXISTS radio")
|
||||
db.QueryContext(ctx, "CREATE TABLE IF NOT EXISTS radio (id string PRIMARY KEY)")
|
||||
return playlist, db, nil
|
||||
|
@ -8,8 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func HandlePlayWithContext(ctx *gctx.Context, commands *commands.Commands, uri *spotify.URI, pos int) {
|
||||
var err error
|
||||
err = commands.PlaySongInPlaylist(ctx, uri, pos)
|
||||
err := commands.PlaySongInPlaylist(ctx, uri, pos)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -94,8 +93,7 @@ func HandlePlayTrack(ctx *gctx.Context, commands *commands.Commands, track spoti
|
||||
}
|
||||
|
||||
func HandleSetDevice(ctx *gctx.Context, commands *commands.Commands, player spotify.PlayerDevice) {
|
||||
var err error
|
||||
err = commands.SetDevice(ctx, player)
|
||||
err := commands.SetDevice(ctx, player)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
105
src/tui/main.go
105
src/tui/main.go
@ -31,24 +31,24 @@ 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"
|
||||
SearchAlbum = "searchalbum"
|
||||
SearchArtists = "searchartists"
|
||||
SearchArtist = "searchartist"
|
||||
SearchArtistAlbum = "searchartistalbum"
|
||||
SearchTracks = "searchtracks"
|
||||
SearchPlaylists = "searchplaylsits"
|
||||
SearchPlaylist = "searchplaylist"
|
||||
ArtistAlbum Mode = "artistalbum"
|
||||
Artist Mode = "artist"
|
||||
Artists Mode = "artists"
|
||||
Tracks Mode = "tracks"
|
||||
Albums Mode = "albums"
|
||||
Main Mode = "main"
|
||||
Playlists Mode = "playlists"
|
||||
Playlist Mode = "playlist"
|
||||
Devices Mode = "devices"
|
||||
Search Mode = "search"
|
||||
SearchAlbums Mode = "searchalbums"
|
||||
SearchAlbum Mode = "searchalbum"
|
||||
SearchArtists Mode = "searchartists"
|
||||
SearchArtist Mode = "searchartist"
|
||||
SearchArtistAlbum Mode = "searchartistalbum"
|
||||
SearchTracks Mode = "searchtracks"
|
||||
SearchPlaylists Mode = "searchplaylsits"
|
||||
SearchPlaylist Mode = "searchplaylist"
|
||||
)
|
||||
|
||||
type mainItem struct {
|
||||
@ -90,36 +90,36 @@ type mainModel struct {
|
||||
func (m *mainModel) PlayRadio() {
|
||||
m.list.NewStatusMessage("Starting radio for " + m.list.SelectedItem().(mainItem).Title())
|
||||
selectedItem := m.list.SelectedItem().(mainItem).SpotifyItem
|
||||
switch selectedItem.(type) {
|
||||
switch item := selectedItem.(type) {
|
||||
case spotify.SimplePlaylist:
|
||||
go HandlePlaylistRadio(m.ctx, m.commands, selectedItem.(spotify.SimplePlaylist))
|
||||
go HandlePlaylistRadio(m.ctx, m.commands, item)
|
||||
return
|
||||
case *spotify.SavedTrackPage:
|
||||
go HandleLibraryRadio(m.ctx, m.commands)
|
||||
return
|
||||
case spotify.SimpleAlbum:
|
||||
go HandleAlbumRadio(m.ctx, m.commands, selectedItem.(spotify.SimpleAlbum))
|
||||
go HandleAlbumRadio(m.ctx, m.commands, item)
|
||||
return
|
||||
case spotify.FullAlbum:
|
||||
go HandleAlbumRadio(m.ctx, m.commands, selectedItem.(spotify.FullAlbum).SimpleAlbum)
|
||||
go HandleAlbumRadio(m.ctx, m.commands, item.SimpleAlbum)
|
||||
return
|
||||
case spotify.SimpleArtist:
|
||||
go HandleArtistRadio(m.ctx, m.commands, selectedItem.(spotify.SimpleArtist))
|
||||
go HandleArtistRadio(m.ctx, m.commands, item)
|
||||
return
|
||||
case spotify.FullArtist:
|
||||
go HandleArtistRadio(m.ctx, m.commands, selectedItem.(spotify.FullArtist).SimpleArtist)
|
||||
go HandleArtistRadio(m.ctx, m.commands, item.SimpleArtist)
|
||||
return
|
||||
case spotify.SimpleTrack:
|
||||
go HandleRadio(m.ctx, m.commands, selectedItem.(spotify.SimpleTrack))
|
||||
go HandleRadio(m.ctx, m.commands, item)
|
||||
return
|
||||
case spotify.FullTrack:
|
||||
go HandleRadio(m.ctx, m.commands, selectedItem.(spotify.FullTrack).SimpleTrack)
|
||||
go HandleRadio(m.ctx, m.commands, item.SimpleTrack)
|
||||
return
|
||||
case spotify.PlaylistTrack:
|
||||
go HandleRadio(m.ctx, m.commands, selectedItem.(spotify.PlaylistTrack).Track.SimpleTrack)
|
||||
go HandleRadio(m.ctx, m.commands, item.Track.SimpleTrack)
|
||||
return
|
||||
case spotify.SavedTrack:
|
||||
go HandleRadio(m.ctx, m.commands, selectedItem.(spotify.SavedTrack).SimpleTrack)
|
||||
go HandleRadio(m.ctx, m.commands, item.SimpleTrack)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -132,6 +132,7 @@ func (m *mainModel) GoBack() (tea.Cmd, error) {
|
||||
m.mode = Main
|
||||
new_items, err := MainView(m.ctx, m.commands)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.list.SetItems(new_items)
|
||||
case Album:
|
||||
@ -203,36 +204,36 @@ type SpotifyUrl struct {
|
||||
|
||||
func (m *mainModel) CopyToClipboard() error {
|
||||
item := m.list.SelectedItem().(mainItem).SpotifyItem
|
||||
switch item.(type) {
|
||||
switch converted := item.(type) {
|
||||
case spotify.SimplePlaylist:
|
||||
clipboard.WriteAll(item.(spotify.SimplePlaylist).ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
case *spotify.FullPlaylist:
|
||||
clipboard.WriteAll(item.(*spotify.FullPlaylist).ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
case spotify.SimpleAlbum:
|
||||
clipboard.WriteAll(item.(spotify.SimpleAlbum).ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
case *spotify.FullAlbum:
|
||||
clipboard.WriteAll(item.(*spotify.FullAlbum).ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
case spotify.SimpleArtist:
|
||||
clipboard.WriteAll(item.(spotify.SimpleArtist).ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
case *spotify.FullArtist:
|
||||
clipboard.WriteAll(item.(*spotify.FullArtist).ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
case spotify.SimpleTrack:
|
||||
clipboard.WriteAll(item.(spotify.SimpleTrack).ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
case spotify.PlaylistTrack:
|
||||
clipboard.WriteAll(item.(spotify.PlaylistTrack).Track.ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.Track.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
case spotify.SavedTrack:
|
||||
clipboard.WriteAll(item.(spotify.SavedTrack).ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
case spotify.FullTrack:
|
||||
clipboard.WriteAll(item.(spotify.FullTrack).ExternalURLs["spotify"])
|
||||
clipboard.WriteAll(converted.ExternalURLs["spotify"])
|
||||
m.list.NewStatusMessage("Copying link to " + m.list.SelectedItem().(mainItem).Title())
|
||||
}
|
||||
return nil
|
||||
@ -241,10 +242,10 @@ func (m *mainModel) CopyToClipboard() error {
|
||||
func (m *mainModel) SelectItem() error {
|
||||
switch m.mode {
|
||||
case Search:
|
||||
switch m.list.SelectedItem().(mainItem).SpotifyItem.(type) {
|
||||
switch item := m.list.SelectedItem().(mainItem).SpotifyItem.(type) {
|
||||
case *spotify.FullArtistPage:
|
||||
m.mode = SearchArtists
|
||||
new_items, err := SearchArtistsView(m.ctx, m.commands, m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.FullArtistPage))
|
||||
new_items, err := SearchArtistsView(m.ctx, m.commands, item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -252,7 +253,7 @@ func (m *mainModel) SelectItem() error {
|
||||
m.list.ResetSelected()
|
||||
case *spotify.SimpleAlbumPage:
|
||||
m.mode = SearchAlbums
|
||||
new_items, err := SearchAlbumsView(m.ctx, m.commands, m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.SimpleAlbumPage))
|
||||
new_items, err := SearchAlbumsView(m.ctx, m.commands, item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -260,8 +261,7 @@ func (m *mainModel) SelectItem() error {
|
||||
m.list.ResetSelected()
|
||||
case *spotify.SimplePlaylistPage:
|
||||
m.mode = SearchPlaylists
|
||||
playlists := m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.SimplePlaylistPage)
|
||||
new_items, err := SearchPlaylistsView(m.ctx, m.commands, playlists)
|
||||
new_items, err := SearchPlaylistsView(m.ctx, m.commands, item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -269,7 +269,7 @@ func (m *mainModel) SelectItem() error {
|
||||
m.list.ResetSelected()
|
||||
case *spotify.FullTrackPage:
|
||||
m.mode = SearchTracks
|
||||
new_items, err := SearchTracksView(m.ctx, m.commands, m.list.SelectedItem().(mainItem).SpotifyItem.(*spotify.FullTrackPage))
|
||||
new_items, err := SearchTracksView(m.ctx, m.commands, item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -314,7 +314,7 @@ func (m *mainModel) SelectItem() error {
|
||||
m.list.SetItems(new_items)
|
||||
m.list.ResetSelected()
|
||||
case Main:
|
||||
switch m.list.SelectedItem().(mainItem).SpotifyItem.(type) {
|
||||
switch item := m.list.SelectedItem().(mainItem).SpotifyItem.(type) {
|
||||
case *spotify.FullArtistCursorPage:
|
||||
m.mode = Artists
|
||||
new_items, err := ArtistsView(m.ctx, m.commands)
|
||||
@ -333,9 +333,8 @@ func (m *mainModel) SelectItem() error {
|
||||
m.list.ResetSelected()
|
||||
case spotify.SimplePlaylist:
|
||||
m.mode = Playlist
|
||||
playlist := m.list.SelectedItem().(mainItem).SpotifyItem.(spotify.SimplePlaylist)
|
||||
m.playlist = playlist
|
||||
new_items, err := PlaylistView(m.ctx, m.commands, playlist)
|
||||
m.playlist = item
|
||||
new_items, err := PlaylistView(m.ctx, m.commands, item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -399,7 +398,7 @@ func (m *mainModel) SelectItem() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m mainModel) Init() tea.Cmd {
|
||||
func (m *mainModel) Init() tea.Cmd {
|
||||
main_updates = make(chan *mainModel)
|
||||
return Tick()
|
||||
}
|
||||
@ -437,7 +436,7 @@ func (m *mainModel) TickPlayback() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (m mainModel) View() string {
|
||||
func (m *mainModel) View() string {
|
||||
if m.input.Focused() {
|
||||
return DocStyle.Render(m.list.View() + "\n" + m.input.View())
|
||||
}
|
||||
@ -497,7 +496,7 @@ func (m *mainModel) getContext(playing *spotify.CurrentlyPlaying) (string, error
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
func (m *mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
// Update list items from LoadMore
|
||||
select {
|
||||
case update := <-main_updates:
|
||||
@ -647,7 +646,7 @@ func InitMain(ctx *gctx.Context, c *commands.Commands, mode Mode) (tea.Model, er
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
m := mainModel{
|
||||
m := &mainModel{
|
||||
list: list.New(items, list.NewDefaultDelegate(), 0, 0),
|
||||
ctx: ctx,
|
||||
commands: c,
|
||||
|
@ -84,27 +84,13 @@ func SearchView(ctx *gctx.Context, commands *commands.Commands, search string) (
|
||||
if err != nil {
|
||||
return nil, 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,
|
||||
})
|
||||
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},
|
||||
)
|
||||
results := &SearchResults{
|
||||
Tracks: result.Tracks,
|
||||
Playlists: result.Playlists,
|
||||
@ -149,7 +135,7 @@ func SearchAlbumsView(ctx *gctx.Context, commands *commands.Commands, albums *sp
|
||||
items = append(items, mainItem{
|
||||
Name: album.Name,
|
||||
ID: album.ID,
|
||||
Desc: fmt.Sprintf("%s, %d", album.Artists[0].Name, album.ReleaseDateTime()),
|
||||
Desc: fmt.Sprintf("%s, %s", album.Artists[0].Name, album.ReleaseDateTime().String()),
|
||||
SpotifyItem: album,
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user