Add UI for viewing the album info returned by Subsonic getAlbumInfo API
- Adding "Get Info" in album page's "meatball" menu. When the option is clicked a pop up appears with the album information and links to Last.fm and MusicBrainz. Screenshot: Fixes #105
This commit is contained in:
@@ -39,6 +39,8 @@ type MediaProvider interface {
|
||||
|
||||
GetAlbum(albumID string) (*AlbumWithTracks, error)
|
||||
|
||||
GetAlbumInfo(albumID string) (*AlbumInfo, error)
|
||||
|
||||
GetArtist(artistID string) (*ArtistWithAlbums, error)
|
||||
|
||||
GetArtistInfo(artistID string) (*ArtistInfo, error)
|
||||
|
||||
@@ -18,6 +18,12 @@ type AlbumWithTracks struct {
|
||||
Tracks []*Track
|
||||
}
|
||||
|
||||
type AlbumInfo struct {
|
||||
Info string
|
||||
LastFMUrl string
|
||||
MusicBrainzID string
|
||||
}
|
||||
|
||||
type Artist struct {
|
||||
ID string
|
||||
CoverArtID string
|
||||
|
||||
@@ -59,6 +59,19 @@ func (s *subsonicMediaProvider) GetAlbum(albumID string) (*mediaprovider.AlbumWi
|
||||
return album, nil
|
||||
}
|
||||
|
||||
func (s *subsonicMediaProvider) GetAlbumInfo(albumID string) (*mediaprovider.AlbumInfo, error) {
|
||||
al, err := s.client.GetAlbumInfo(albumID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
album := &mediaprovider.AlbumInfo{
|
||||
Info: al.Notes,
|
||||
LastFMUrl: al.LastFmUrl,
|
||||
MusicBrainzID: al.MusicBrainzID,
|
||||
}
|
||||
return album, nil
|
||||
}
|
||||
|
||||
func (s *subsonicMediaProvider) GetArtist(artistID string) (*mediaprovider.ArtistWithAlbums, error) {
|
||||
ar, err := s.client.GetArtist(artistID)
|
||||
if err != nil {
|
||||
|
||||
@@ -203,7 +203,9 @@ func NewAlbumPageHeader(page *AlbumPage) *AlbumPageHeader {
|
||||
}),
|
||||
fyne.NewMenuItem("Download...", func() {
|
||||
a.page.contr.ShowDownloadDialog(a.page.tracks, a.titleLabel.String())
|
||||
|
||||
}),
|
||||
fyne.NewMenuItem("Get Info...", func() {
|
||||
a.page.contr.ShowAlbumInfoDialog(a.albumID, a.titleLabel.String(), a.cover.Image.Image)
|
||||
}))
|
||||
pop = widget.NewPopUpMenu(menu, fyne.CurrentApp().Driver().CanvasForObject(a))
|
||||
}
|
||||
|
||||
@@ -651,3 +651,22 @@ func (c *Controller) sendNotification(title, content string) {
|
||||
Content: content,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Controller) ShowAlbumInfoDialog(albumID, albumName string, albumCover image.Image) {
|
||||
go func() {
|
||||
albumInfo, err := c.App.ServerManager.Server.GetAlbumInfo(albumID)
|
||||
if err != nil {
|
||||
log.Print("Error getting album info: ", err)
|
||||
return
|
||||
}
|
||||
dlg := dialogs.NewAlbumInfoDialog(albumInfo, albumName, albumCover)
|
||||
pop := widget.NewModalPopUp(dlg, c.MainWindow.Canvas())
|
||||
dlg.OnDismiss = func() {
|
||||
pop.Hide()
|
||||
c.doModalClosed()
|
||||
}
|
||||
c.ClosePopUpOnEscape(pop)
|
||||
c.haveModal = true
|
||||
pop.Show()
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package dialogs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||
"github.com/dweymouth/supersonic/ui/layouts"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/container"
|
||||
|
||||
"fyne.io/fyne/v2/layout"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
type AlbumInfoDialog struct {
|
||||
widget.BaseWidget
|
||||
|
||||
OnDismiss func()
|
||||
|
||||
content fyne.CanvasObject
|
||||
}
|
||||
|
||||
func NewAlbumInfoDialog(albumInfo *mediaprovider.AlbumInfo, albumName string, albumCover image.Image) *AlbumInfoDialog {
|
||||
a := &AlbumInfoDialog{}
|
||||
a.ExtendBaseWidget(a)
|
||||
|
||||
a.content = container.NewVBox(
|
||||
a.buildMainContainer(albumInfo, albumName, albumCover),
|
||||
widget.NewSeparator(),
|
||||
container.NewHBox(
|
||||
layout.NewSpacer(),
|
||||
widget.NewButton("Close", func() {
|
||||
if a.OnDismiss != nil {
|
||||
a.OnDismiss()
|
||||
}
|
||||
}),
|
||||
),
|
||||
)
|
||||
a.content.Resize(a.MinSize())
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *AlbumInfoDialog) MinSize() fyne.Size {
|
||||
return fyne.NewSize(550, a.BaseWidget.MinSize().Height)
|
||||
}
|
||||
|
||||
func (a *AlbumInfoDialog) buildMainContainer(albumInfo *mediaprovider.AlbumInfo, albumName string, albumCover image.Image) *fyne.Container {
|
||||
iconImage := canvas.NewImageFromImage(albumCover)
|
||||
iconImage.FillMode = canvas.ImageFillContain
|
||||
iconImage.SetMinSize(fyne.NewSize(100, 100))
|
||||
title := widget.NewRichTextWithText(albumName)
|
||||
title.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = true
|
||||
title.Segments[0].(*widget.TextSegment).Style.SizeName = theme.SizeNameSubHeadingText
|
||||
title.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignCenter
|
||||
|
||||
infoContent := widget.NewLabel("Album info not available")
|
||||
|
||||
if albumInfo.Info != "" {
|
||||
infoContent = a.infoLabel(albumInfo.Info)
|
||||
}
|
||||
|
||||
urlContainer := a.buildUrlContainer(albumInfo.LastFMUrl, albumInfo.MusicBrainzID)
|
||||
|
||||
return container.NewVBox(
|
||||
iconImage,
|
||||
title,
|
||||
infoContent,
|
||||
urlContainer,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
func (a *AlbumInfoDialog) CreateRenderer() fyne.WidgetRenderer {
|
||||
return widget.NewSimpleRenderer(a.content)
|
||||
}
|
||||
|
||||
func (a *AlbumInfoDialog) infoLabel(info string) *widget.Label {
|
||||
last := strings.LastIndex(info, "<a href")
|
||||
infoWithoutLink := strings.TrimSpace(info[:last])
|
||||
lbl := widget.NewLabel(infoWithoutLink)
|
||||
lbl.Wrapping = fyne.TextWrapWord
|
||||
lbl.Alignment = fyne.TextAlignLeading
|
||||
return lbl
|
||||
}
|
||||
|
||||
func (a *AlbumInfoDialog) buildUrlContainer(lastFM, musicBrainzID string) *fyne.Container {
|
||||
urls := make([]*widget.Hyperlink, 0)
|
||||
|
||||
if lastFMUrl, err := url.Parse(lastFM); err == nil {
|
||||
urls = append(urls, widget.NewHyperlink("Last.fm", lastFMUrl))
|
||||
}
|
||||
if musicBrainzUrl, err := url.Parse(fmt.Sprintf("https://musicbrainz.org/release/%s", musicBrainzID)); err == nil {
|
||||
urls = append(urls, widget.NewHyperlink("MusicBrainz", musicBrainzUrl))
|
||||
}
|
||||
|
||||
urlContainer := container.New(&layouts.HboxCustomPadding{DisableThemePad: true, ExtraPad: -10})
|
||||
for index, url := range urls {
|
||||
if index > 0 {
|
||||
urlContainer.Add(widget.NewLabel("·"))
|
||||
}
|
||||
urlContainer.Add(url)
|
||||
}
|
||||
|
||||
return container.NewCenter(urlContainer)
|
||||
}
|
||||
Reference in New Issue
Block a user