Skip to content

Commit

Permalink
Merge pull request #46 from xxxserxxx/feature_25_song_info
Browse files Browse the repository at this point in the history
Implements #25, display song info.
  • Loading branch information
spezifisch authored Oct 11, 2024
2 parents d7c625f + e4e84b8 commit e4bc7c9
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 21 deletions.
48 changes: 42 additions & 6 deletions gui_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,26 +142,62 @@ func (ui *Ui) addRandomSongsToQueue(Id string, randomType string) {
func (ui *Ui) addSongToQueue(entity *subsonic.SubsonicEntity) {
uri := ui.connection.GetPlayUrl(entity)

response, err := ui.connection.GetAlbum(entity.Parent)
album := ""
if err != nil {
ui.logger.PrintError("addSongToQueue", err)
} else {
switch {
case response.Album.Name != "":
album = response.Album.Name
case response.Album.Title != "":
album = response.Album.Title
case response.Album.Album != "":
album = response.Album.Album
}
}

queueItem := &mpvplayer.QueueItem{
Id: entity.Id,
Uri: uri,
Title: entity.GetSongTitle(),
Artist: entity.Artist,
Duration: entity.Duration,
Id: entity.Id,
Uri: uri,
Title: entity.GetSongTitle(),
Artist: entity.Artist,
Duration: entity.Duration,
Album: album,
TrackNumber: entity.Track,
DiscNumber: entity.DiscNumber,
}
ui.player.AddToQueue(queueItem)
}

func makeSongHandler(entity *subsonic.SubsonicEntity, ui *Ui, fallbackArtist string) func() {
// make copy of values so this function can be used inside a loop iterating over entities
id := entity.Id
// TODO: Why aren't we doing all of this _inside_ the returned func?
uri := ui.connection.GetPlayUrl(entity)
title := entity.Title
artist := stringOr(entity.Artist, fallbackArtist)
duration := entity.Duration
track := entity.Track
disc := entity.DiscNumber

response, err := ui.connection.GetAlbum(entity.Parent)
album := ""
if err != nil {
ui.logger.PrintError("makeSongHandler", err)
} else {
switch {
case response.Album.Name != "":
album = response.Album.Name
case response.Album.Title != "":
album = response.Album.Title
case response.Album.Album != "":
album = response.Album.Album
}
}

return func() {
if err := ui.player.PlayUri(id, uri, title, artist, duration); err != nil {
if err := ui.player.PlayUri(id, uri, title, artist, album, duration, track, disc); err != nil {
ui.logger.PrintError("SongHandler Play", err)
return
}
Expand Down
4 changes: 2 additions & 2 deletions mpvplayer/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ func (p *Player) PlayNextTrack() error {
return nil
}

func (p *Player) PlayUri(id string, uri string, title string, artist string, duration int) error {
p.queue = []QueueItem{{id, uri, title, artist, duration}}
func (p *Player) PlayUri(id, uri, title, artist, album string, duration, track, disc int) error {
p.queue = []QueueItem{{id, uri, title, artist, duration, album, track, disc}}
p.replaceInProgress = true
if ip, e := p.IsPaused(); ip && e == nil {
if err := p.Pause(); err != nil {
Expand Down
21 changes: 14 additions & 7 deletions mpvplayer/queue_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ package mpvplayer
import "github.com/spezifisch/stmps/remote"

type QueueItem struct {
Id string
Uri string
Title string
Artist string
Duration int
Id string
Uri string
Title string
Artist string
Duration int
Album string
TrackNumber int
DiscNumber int
}

var _ remote.TrackInterface = (*QueueItem)(nil)
Expand Down Expand Up @@ -44,9 +47,13 @@ func (q QueueItem) GetUri() string {
}

func (q QueueItem) GetAlbum() string {
return ""
return q.Album
}

func (q QueueItem) GetTrackNumber() int {
return 0
return q.TrackNumber
}

func (q QueueItem) GetDiscNumber() int {
return q.DiscNumber
}
50 changes: 46 additions & 4 deletions page_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package main
import (
"errors"
"fmt"
"text/template"
"time"

"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
Expand Down Expand Up @@ -35,15 +37,29 @@ type QueuePage struct {
queueList *tview.Table
queueData queueData

songInfo *tview.TextView

// external refs
ui *Ui
logger logger.LoggerInterface

songInfoTemplate *template.Template
}

func (ui *Ui) createQueuePage() *QueuePage {
tmpl := template.New("song info").Funcs(template.FuncMap{
"formatTime": func(i int) string {
return (time.Duration(i) * time.Second).String()
},
})
songInfoTemplate, err := tmpl.Parse(songInfoTemplateString)
if err != nil {
ui.logger.PrintError("createQueuePage", err)
}
queuePage := QueuePage{
ui: ui,
logger: ui.logger,
ui: ui,
logger: ui.logger,
songInfoTemplate: songInfoTemplate,
}

// main table
Expand Down Expand Up @@ -75,9 +91,16 @@ func (ui *Ui) createQueuePage() *QueuePage {
return nil
})

// Song info
queuePage.songInfo = tview.NewTextView()
queuePage.songInfo.SetDynamicColors(true).SetScrollable(true).SetBorder(true).SetTitle("Song Info")

queuePage.queueList.SetSelectionChangedFunc(queuePage.changeSelection)

// flex wrapper
queuePage.Root = tview.NewFlex().SetDirection(tview.FlexRow).
AddItem(queuePage.queueList, 0, 1, true)
queuePage.Root = tview.NewFlex().SetDirection(tview.FlexColumn).
AddItem(queuePage.queueList, 0, 2, true).
AddItem(queuePage.songInfo, 0, 1, false)

// private data
queuePage.queueData = queueData{
Expand All @@ -87,6 +110,15 @@ func (ui *Ui) createQueuePage() *QueuePage {
return &queuePage
}

func (q *QueuePage) changeSelection(row, column int) {
q.songInfo.Clear()
if row >= len(q.queueData.playerQueue) || row < 0 || column < 0 {
return
}
currentSong := q.queueData.playerQueue[row]
_ = q.songInfoTemplate.Execute(q.songInfo, currentSong)
}

func (q *QueuePage) UpdateQueue() {
q.updateQueue()
}
Expand Down Expand Up @@ -158,6 +190,9 @@ func (q *QueuePage) updateQueue() {
if queueWasEmpty {
q.queueList.ScrollToBeginning()
}

r, c := q.queueList.GetSelection()
q.changeSelection(r, c)
}

// moveSongUp moves the currently selected song up in the queue
Expand Down Expand Up @@ -291,3 +326,10 @@ func (q *queueData) GetRowCount() int {
func (q *queueData) GetColumnCount() int {
return queueDataColumns
}

var songInfoTemplateString = `[blue::b]Title:[-:-:-:-] [green::i]{{.Title}}[-:-:-:-]
[blue::b]Artist:[-:-:-:-] [::i]{{.Artist}}[-:-:-:-]
[blue::b]Album:[-:-:-:-] [::i]{{.GetAlbum}}[-:-:-:-]
[blue::b]Disc:[-:-:-:-] [::i]{{.GetDiscNumber}}[-:-:-:-]
[blue::b]Track:[-:-:-:-] [::i]{{.GetTrackNumber}}[-:-:-:-]
[blue::b]Duration:[-:-:-:-] [::i]{{formatTime .Duration}}[-:-:-:-] `
1 change: 1 addition & 0 deletions remote/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type TrackInterface interface {
GetAlbumArtist() string
GetAlbum() string
GetTrackNumber() int
GetDiscNumber() int

// something like ID != ""
IsValid() bool
Expand Down
7 changes: 5 additions & 2 deletions subsonic/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ type SubsonicEntity struct {
Artists []Artist `json:"artists"`
Duration int `json:"duration"`
Track int `json:"track"`
DiskNumber int `json:"diskNumber"`
DiscNumber int `json:"discNumber"`
Path string `json:"path"`
}

Expand Down Expand Up @@ -304,7 +304,10 @@ func (connection *SubsonicConnection) GetArtist(id string) (*SubsonicResponse, e

func (connection *SubsonicConnection) GetAlbum(id string) (*SubsonicResponse, error) {
if cachedResponse, present := connection.directoryCache[id]; present {
return &cachedResponse, nil
// This is because Albums that were fetched as Directories aren't populated correctly
if cachedResponse.Album.Name != "" {
return &cachedResponse, nil
}
}

query := defaultQuery(connection)
Expand Down

0 comments on commit e4bc7c9

Please sign in to comment.