diff --git a/ui/albumpage.go b/ui/albumpage.go index 6931ada..b707406 100644 --- a/ui/albumpage.go +++ b/ui/albumpage.go @@ -1,15 +1,19 @@ package ui import ( + "fmt" "log" "supersonic/backend" + "supersonic/ui/util" "supersonic/ui/widgets" "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" + "github.com/dweymouth/go-subsonic" ) type AlbumPage struct { @@ -18,21 +22,19 @@ type AlbumPage struct { albumID string im *backend.ImageManager lm *backend.LibraryManager - titleDisp *widget.RichText + nav func(Route) + header *AlbumPageHeader tracklist *widgets.Tracklist container *fyne.Container OnPlayAlbum func(string, int) } -func NewAlbumPage(albumID string, lm *backend.LibraryManager) *AlbumPage { - a := &AlbumPage{albumID: albumID, lm: lm} +func NewAlbumPage(albumID string, lm *backend.LibraryManager, im *backend.ImageManager, nav func(Route)) *AlbumPage { + a := &AlbumPage{albumID: albumID, lm: lm, im: im, nav: nav} a.ExtendBaseWidget(a) - a.titleDisp = widget.NewRichTextWithText("Artist") - a.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{ - SizeName: theme.SizeNameHeadingText, - } - a.container = container.NewBorder(a.titleDisp, nil, nil, nil, layout.NewSpacer()) + a.header = NewAlbumPageHeader(nav) + a.container = container.NewBorder(a.header, nil, nil, nil, layout.NewSpacer()) a.loadAsync() return a } @@ -62,11 +64,74 @@ func (a *AlbumPage) loadAsync() { log.Printf("Failed to get album: %s", err.Error()) return } - a.titleDisp.Segments[0].(*widget.TextSegment).Text = album.Name - a.titleDisp.Refresh() + a.header.Update(album, a.im) tl := widgets.NewTracklist(album.Song) tl.OnPlayTrackAt = a.onPlayTrackAt a.container.Objects[0] = tl a.container.Refresh() }() } + +type AlbumPageHeader struct { + widget.BaseWidget + + albumID string + artistID string + + cover *canvas.Image + titleLabel *widget.RichText + artistLabel *widgets.CustomHyperlink + genreLabel *widget.Label // later custom hyperlink + miscLabel *widget.Label + + container *fyne.Container +} + +func NewAlbumPageHeader(nav func(Route)) *AlbumPageHeader { + a := &AlbumPageHeader{} + a.ExtendBaseWidget(a) + a.cover = &canvas.Image{FillMode: canvas.ImageFillContain} + a.cover.SetMinSize(fyne.NewSize(225, 225)) + a.titleLabel = widget.NewRichTextWithText("Album Title") + a.titleLabel.Wrapping = fyne.TextTruncate + a.titleLabel.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{ + SizeName: theme.SizeNameHeadingText, + } + a.artistLabel = widgets.NewCustomHyperlink() + a.artistLabel.OnTapped = func() { + nav(ArtistRoute(a.artistID)) + } + a.genreLabel = widget.NewLabel("") + a.miscLabel = widget.NewLabel("") + + a.container = container.NewBorder(nil, nil, a.cover, nil, + container.NewVBox(a.titleLabel, a.artistLabel, a.genreLabel, a.miscLabel), + ) + return a +} + +func (a *AlbumPageHeader) CreateRenderer() fyne.WidgetRenderer { + return widget.NewSimpleRenderer(a.container) +} + +func (a *AlbumPageHeader) Update(album *subsonic.AlbumID3, im *backend.ImageManager) { + a.albumID = album.ID + a.artistID = album.ArtistID + a.titleLabel.Segments[0].(*widget.TextSegment).Text = album.Name + a.artistLabel.SetText(album.Artist) + a.genreLabel.SetText(album.Genre) + a.miscLabel.SetText(formatMiscLabelStr(album)) + a.Refresh() + go func() { + if cover, err := im.GetAlbumThumbnail(album.ID); err == nil { + a.cover.Image = cover + a.cover.Refresh() + } else { + log.Printf("error fetching cover: %v", err) + } + }() +} + +func formatMiscLabelStr(a *subsonic.AlbumID3) string { + return fmt.Sprintf("%d · %d tracks · %s", a.Year, a.SongCount, util.SecondsToTimeString(float64(a.Duration))) +} diff --git a/ui/layout/centerpadlayout.go b/ui/layouts/centerpadlayout.go similarity index 98% rename from ui/layout/centerpadlayout.go rename to ui/layouts/centerpadlayout.go index b0f4dba..71caafd 100644 --- a/ui/layout/centerpadlayout.go +++ b/ui/layouts/centerpadlayout.go @@ -1,4 +1,4 @@ -package layout +package layouts import ( "fyne.io/fyne/v2" diff --git a/ui/layout/columnslayout.go b/ui/layouts/columnslayout.go similarity index 98% rename from ui/layout/columnslayout.go rename to ui/layouts/columnslayout.go index fdb715b..bc40147 100644 --- a/ui/layout/columnslayout.go +++ b/ui/layouts/columnslayout.go @@ -1,4 +1,4 @@ -package layout +package layouts import "fyne.io/fyne/v2" diff --git a/ui/layout/vboxcustompadding.go b/ui/layouts/vboxcustompadding.go similarity index 98% rename from ui/layout/vboxcustompadding.go rename to ui/layouts/vboxcustompadding.go index 3f69c7f..ab8c8fb 100644 --- a/ui/layout/vboxcustompadding.go +++ b/ui/layouts/vboxcustompadding.go @@ -1,4 +1,4 @@ -package layout +package layouts import ( "fyne.io/fyne/v2" diff --git a/ui/router.go b/ui/router.go index 587f1b0..b3c38b9 100644 --- a/ui/router.go +++ b/ui/router.go @@ -50,7 +50,7 @@ func NewRouter(app *backend.App, nav NavigationHandler) Router { func (r Router) CreatePage(rte Route) Page { switch rte.Page { case Album: - return NewAlbumPage(rte.Arg, r.App.LibraryManager) + return NewAlbumPage(rte.Arg, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute) case Albums: return NewAlbumsPage("Albums", rte.Arg, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute) case Artist: diff --git a/ui/widgets/albumcard.go b/ui/widgets/albumcard.go index cd687de..7f2c684 100644 --- a/ui/widgets/albumcard.go +++ b/ui/widgets/albumcard.go @@ -5,7 +5,7 @@ import ( "image" "strconv" - "supersonic/ui/layout" + "supersonic/ui/layouts" "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" @@ -123,9 +123,9 @@ func (a *AlbumCard) createContainer() { if a.showYear { secondLabel = a.year } - info := container.New(&layout.VboxCustomPadding{ExtraPad: -16}, a.title, secondLabel) - c := container.New(&layout.VboxCustomPadding{ExtraPad: -5}, a.Cover, info) - pad := &layout.CenterPadLayout{PadLeftRight: 20, PadTopBottom: 10} + info := container.New(&layouts.VboxCustomPadding{ExtraPad: -16}, a.title, secondLabel) + c := container.New(&layouts.VboxCustomPadding{ExtraPad: -5}, a.Cover, info) + pad := &layouts.CenterPadLayout{PadLeftRight: 20, PadTopBottom: 10} a.container = container.New(pad, c) } diff --git a/ui/widgets/nowplayingcard.go b/ui/widgets/nowplayingcard.go index ca741ad..a69c314 100644 --- a/ui/widgets/nowplayingcard.go +++ b/ui/widgets/nowplayingcard.go @@ -2,8 +2,7 @@ package widgets import ( "image" - - "supersonic/ui/layout" + "supersonic/ui/layouts" "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" @@ -35,7 +34,7 @@ func NewNowPlayingCard() *NowPlayingCard { n.cover.SetMinSize(fyne.NewSize(100, 100)) n.cover.FillMode = canvas.ImageFillContain - n.c = container.NewBorder(nil, nil, n.cover, nil, container.New(&layout.VboxCustomPadding{ExtraPad: -10}, n.trackName, n.artistName, n.albumName)) + n.c = container.NewBorder(nil, nil, n.cover, nil, container.New(&layouts.VboxCustomPadding{ExtraPad: -10}, n.trackName, n.artistName, n.albumName)) return n } diff --git a/ui/widgets/tracklist.go b/ui/widgets/tracklist.go index d0a0b1f..e59d90d 100644 --- a/ui/widgets/tracklist.go +++ b/ui/widgets/tracklist.go @@ -2,7 +2,7 @@ package widgets import ( "strconv" - "supersonic/ui/layout" + "supersonic/ui/layouts" "supersonic/ui/util" "fyne.io/fyne/v2" @@ -39,7 +39,7 @@ func NewTrackRow() *TrackRow { t.artist.Wrapping = fyne.TextTruncate t.dur = widget.NewRichTextWithText("") - t.container = container.New(layout.NewColumnsLayout([]float32{30, -1, -1, 55}), + t.container = container.New(layouts.NewColumnsLayout([]float32{30, -1, -1, 55}), t.num, t.name, t.artist, t.dur) return t }