From bf97cdb52680d45155eb7026a757113db48f1ffe Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Thu, 18 Jul 2024 17:33:42 -0700 Subject: [PATCH] add more to track info dialog --- backend/mediaprovider/helpers/other.go | 6 ++- backend/mediaprovider/model.go | 5 ++- .../subsonic/subsonicmediaprovider.go | 13 ++++++- backend/mpris.go | 8 ++-- ui/controller/controller.go | 15 +++++++ ui/dialogs/trackinfodialog.go | 39 ++++++++++++++++++- 6 files changed, 76 insertions(+), 10 deletions(-) diff --git a/backend/mediaprovider/helpers/other.go b/backend/mediaprovider/helpers/other.go index dd70978b..41d9682c 100644 --- a/backend/mediaprovider/helpers/other.go +++ b/backend/mediaprovider/helpers/other.go @@ -14,7 +14,11 @@ func GetSimilarSongsFallback(mp mediaprovider.MediaProvider, track *mediaprovide tracks, _ = mp.GetSimilarTracks(track.ArtistIDs[0], count) } if len(tracks) == 0 { - tracks, _ = mp.GetRandomTracks(track.Genre, count) + genre := "" + if len(track.Genres) > 0 { + genre = track.Genres[0] + } + tracks, _ = mp.GetRandomTracks(genre, count) } // make sure to exclude the song itself from the similar list diff --git a/backend/mediaprovider/model.go b/backend/mediaprovider/model.go index 9d80a74d..2516dc1a 100644 --- a/backend/mediaprovider/model.go +++ b/backend/mediaprovider/model.go @@ -1,5 +1,7 @@ package mediaprovider +import "time" + // Bit field flag for the ReleaseTypes property type ReleaseType = int32 @@ -90,7 +92,7 @@ type Track struct { Duration int TrackNumber int DiscNumber int - Genre string + Genres []string ArtistIDs []string ArtistNames []string Album string @@ -100,6 +102,7 @@ type Track struct { Favorite bool Size int64 PlayCount int + LastPlayed time.Time FilePath string BitRate int ContentType string diff --git a/backend/mediaprovider/subsonic/subsonicmediaprovider.go b/backend/mediaprovider/subsonic/subsonicmediaprovider.go index d38f7bb9..cd3c681a 100644 --- a/backend/mediaprovider/subsonic/subsonicmediaprovider.go +++ b/backend/mediaprovider/subsonic/subsonicmediaprovider.go @@ -500,6 +500,15 @@ func toTrack(ch *subsonic.Child) *mediaprovider.Track { rGain.AlbumPeak = rg.AlbumPeak rGain.TrackPeak = rg.TrackPeak } + var genres []string + if len(ch.Genres) > 0 { + genres = sharedutil.MapSlice(ch.Genres, func(idName subsonic.IDName) string { + return idName.Name + }) + } else if ch.Genre != "" { + genres = []string{ch.Genre} + } + return &mediaprovider.Track{ ID: ch.ID, CoverArtID: ch.CoverArt, @@ -508,7 +517,7 @@ func toTrack(ch *subsonic.Child) *mediaprovider.Track { Duration: ch.Duration, TrackNumber: ch.Track, DiscNumber: ch.DiscNumber, - Genre: ch.Genre, + Genres: genres, ArtistIDs: artistIDs, ArtistNames: artistNames, Album: ch.Album, @@ -517,12 +526,14 @@ func toTrack(ch *subsonic.Child) *mediaprovider.Track { Rating: ch.UserRating, Favorite: !ch.Starred.IsZero(), PlayCount: int(ch.PlayCount), + LastPlayed: ch.Played, FilePath: ch.Path, Size: ch.Size, BitRate: ch.BitRate, ContentType: ch.ContentType, Comment: ch.Comment, BPM: ch.BPM, + ReplayGain: rGain, } } diff --git a/backend/mpris.go b/backend/mpris.go index 7be7121a..d0716c34 100644 --- a/backend/mpris.go +++ b/backend/mpris.go @@ -254,7 +254,7 @@ func (m *MPRISHandler) Metadata() (types.Metadata, error) { var meta mediaprovider.MediaItemMetadata // metadata that can come only from tracks var discNumber, trackNumber, userRating, playCount, year int - var genre string + var genres []string if np := m.pm.NowPlaying(); np != nil && status.State != player.Stopped { meta = np.Metadata() @@ -264,7 +264,7 @@ func (m *MPRISHandler) Metadata() (types.Metadata, error) { userRating = track.Rating playCount = track.PlayCount year = track.Year - genre = track.Genre + genres = track.Genres } } var artURL string @@ -284,9 +284,7 @@ func (m *MPRISHandler) Metadata() (types.Metadata, error) { UserRating: float64(userRating) / 5, UseCount: playCount, ArtUrl: artURL, - } - if genre != "" { - mprisMeta.Genre = []string{genre} + Genre: genres, } if year != 0 { mprisMeta.ContentCreated = strconv.Itoa(year) diff --git a/ui/controller/controller.go b/ui/controller/controller.go index 41affdca..65dd5099 100644 --- a/ui/controller/controller.go +++ b/ui/controller/controller.go @@ -866,6 +866,21 @@ func (c *Controller) ShowTrackInfoDialog(track *mediaprovider.Track) { pop.Hide() c.doModalClosed() } + info.OnNavigateToAlbum = func(albumID string) { + info.OnDismiss() + c.NavigateTo(AlbumRoute(albumID)) + } + info.OnNavigateToArtist = func(artistID string) { + info.OnDismiss() + c.NavigateTo(ArtistRoute(artistID)) + } + info.OnNavigateToGenre = func(genre string) { + info.OnDismiss() + c.NavigateTo(GenreRoute(genre)) + } + info.OnCopyFilePath = func() { + c.MainWindow.Clipboard().SetContent(track.FilePath) + } c.ClosePopUpOnEscape(pop) winSize := c.MainWindow.Canvas().Size() popMin := pop.MinSize() diff --git a/ui/dialogs/trackinfodialog.go b/ui/dialogs/trackinfodialog.go index 4553ad9e..7981bbbc 100644 --- a/ui/dialogs/trackinfodialog.go +++ b/ui/dialogs/trackinfodialog.go @@ -3,10 +3,12 @@ package dialogs import ( "fmt" "strconv" + "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/layout" + "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" "github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/ui/util" @@ -19,6 +21,8 @@ type TrackInfoDialog struct { OnDismiss func() OnNavigateToArtist func(artistID string) OnNavigateToAlbum func(albumID string) + OnNavigateToGenre func(genre string) + OnCopyFilePath func() track *mediaprovider.Track } @@ -53,8 +57,31 @@ func (t *TrackInfoDialog) CreateRenderer() fyne.WidgetRenderer { } c.Add(album) + if len(t.track.Genres) > 0 { + c.Add(newFormText("Genres", true)) + genres := widgets.NewMultiHyperlink() + genres.BuildSegments(t.track.Genres, t.track.Genres) + genres.OnTapped = func(g string) { + if t.OnNavigateToGenre != nil { + t.OnNavigateToGenre(g) + } + } + c.Add(genres) + } + addFormRow(c, "Duration", util.SecondsToTimeString(float64(t.track.Duration))) - addFormRow(c, "File path", t.track.FilePath) + + copyBtn := widgets.NewIconButton(theme.ContentCopyIcon(), func() { + if t.OnCopyFilePath != nil { + t.OnCopyFilePath() + } + }) + copyBtn.IconSize = widgets.IconButtonSizeSmaller + btnCtr := container.New(layout.NewCustomPaddedLayout(8, 0, 10, 0), + container.NewVBox(copyBtn, layout.NewSpacer())) + c.Add(container.NewHBox(btnCtr, newFormText("File path", true))) + c.Add(newFormText(t.track.FilePath, false)) + addFormRow(c, "Comment", t.track.Comment) addFormRow(c, "Year", strconv.Itoa(t.track.Year)) addFormRow(c, "Track number", strconv.Itoa(t.track.TrackNumber)) @@ -69,6 +96,10 @@ func (t *TrackInfoDialog) CreateRenderer() fyne.WidgetRenderer { addFormRow(c, "File size", util.BytesToSizeString(t.track.Size)) addFormRow(c, "Play count", strconv.Itoa(t.track.PlayCount)) + if !t.track.LastPlayed.IsZero() { + addFormRow(c, "Last played", t.track.LastPlayed.Format(time.RFC1123)) + } + if t.track.ReplayGain.TrackPeak > 0 { addFormRow(c, "Track gain", fmt.Sprintf("%0.2f dB", t.track.ReplayGain.TrackGain)) addFormRow(c, "Track peak", fmt.Sprintf("%0.6f", t.track.ReplayGain.TrackPeak)) @@ -94,12 +125,16 @@ func (t *TrackInfoDialog) CreateRenderer() fyne.WidgetRenderer { container.NewHBox(layout.NewSpacer(), dismissBtn), ), /*left/right*/ nil, nil, - /*center*/ container.NewScroll(c), + /*center*/ container.New(layout.NewCustomPaddedLayout(10, 10, 15, 15), + container.NewScroll(c)), ), ) } func addFormRow(c *fyne.Container, left, right string) { + if right == "" { + return + } c.Add(newFormText(left, true)) c.Add(newFormText(right, false)) }