add cover art to playlist page

This commit is contained in:
Drew Weymouth
2023-02-05 10:44:12 -08:00
parent 3b3dc780af
commit 56715c5598
4 changed files with 88 additions and 49 deletions
+7 -39
View File
@@ -3,7 +3,6 @@ package browsing
import (
"bytes"
"image"
"image/color"
"log"
"strings"
"supersonic/backend"
@@ -13,7 +12,6 @@ import (
"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"
@@ -46,7 +44,9 @@ func NewArtistPage(artistID string, sm *backend.ServerManager, im *backend.Image
}
a.ExtendBaseWidget(a)
a.header = NewArtistPageHeader(nav)
a.container = container.NewBorder(a.header, nil, nil, nil, layout.NewSpacer())
a.container = container.NewBorder(
container.New(&layouts.MaxPadLayout{PadLeft: 15, PadRight: 15, PadTop: 15, PadBottom: 10}, a.header),
nil, nil, nil, layout.NewSpacer())
a.loadAsync()
return a
}
@@ -124,7 +124,7 @@ type ArtistPageHeader struct {
nav func(Route)
artistID string
artistImageCtr *fyne.Container
artistImage *widgets.ImagePlaceholder
titleDisp *widget.RichText
biographyDisp *widget.RichText
similarArtists *fyne.Container
@@ -141,8 +141,7 @@ func NewArtistPageHeader(nav func(Route)) *ArtistPageHeader {
a.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{
SizeName: theme.SizeNameHeadingText,
}
a.artistImageCtr = container.New(&layouts.CenterPadLayout{PadLeftRight: 10, PadTopBottom: 10},
NewMissingArtistImage())
a.artistImage = widgets.NewImagePlaceholder(res.ResPeopleInvertPng, 225)
a.biographyDisp.Wrapping = fyne.TextWrapWord
a.ExtendBaseWidget(a)
a.createContainer()
@@ -193,47 +192,16 @@ func (a *ArtistPageHeader) UpdateInfo(info *subsonic.ArtistInfo2) {
if err != nil {
return
}
img := canvas.NewImageFromImage(im)
img.FillMode = canvas.ImageFillContain
img.SetMinSize(fyne.NewSize(225, 225))
a.artistImageCtr.RemoveAll()
a.artistImageCtr.Add(img)
a.artistImageCtr.Refresh()
a.artistImage.SetImage(im)
}
}
}
func (a *ArtistPageHeader) createContainer() {
a.container = container.NewBorder(nil, nil, a.artistImageCtr, nil,
a.container = container.NewBorder(nil, nil, a.artistImage, nil,
container.NewBorder(a.titleDisp, nil, nil, nil, container.NewVBox(a.biographyDisp, a.similarArtists)))
}
func (a *ArtistPageHeader) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(a.container)
}
type MissingArtistImage struct {
widget.BaseWidget
container *fyne.Container
}
func NewMissingArtistImage() *MissingArtistImage {
m := &MissingArtistImage{}
m.ExtendBaseWidget(m)
img := canvas.NewImageFromResource(res.ResPeopleInvertPng)
img.FillMode = canvas.ImageFillContain
img.SetMinSize(fyne.NewSize(64, 64))
rect := canvas.NewRectangle(theme.BackgroundColor())
rect.StrokeColor = color.Black
rect.StrokeWidth = 3
rect.SetMinSize(fyne.NewSize(225, 225))
m.container = container.NewMax(
rect,
container.NewCenter(img),
)
return m
}
func (m *MissingArtistImage) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(m.container)
}
+32 -9
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"log"
"supersonic/backend"
"supersonic/res"
"supersonic/ui/layouts"
"supersonic/ui/util"
"supersonic/ui/widgets"
@@ -21,6 +22,7 @@ type PlaylistPage struct {
playlistID string
sm *backend.ServerManager
pm *backend.PlaybackManager
im *backend.ImageManager
nav func(Route)
header *PlaylistPageHeader
tracklist *widgets.Tracklist
@@ -33,9 +35,10 @@ func NewPlaylistPage(
playlistID string,
sm *backend.ServerManager,
pm *backend.PlaybackManager,
im *backend.ImageManager,
nav func(Route),
) *PlaylistPage {
a := &PlaylistPage{playlistID: playlistID, sm: sm, pm: pm}
a := &PlaylistPage{playlistID: playlistID, sm: sm, pm: pm, im: im}
a.ExtendBaseWidget(a)
a.header = NewPlaylistPageHeader(a)
a.tracklist = widgets.NewTracklist(nil)
@@ -57,6 +60,7 @@ func (a *PlaylistPage) Save() SavedPage {
playlistID: a.playlistID,
sm: a.sm,
pm: a.pm,
im: a.im,
nav: a.nav,
}
}
@@ -89,9 +93,10 @@ func (a *PlaylistPage) loadAsync() {
log.Printf("Failed to get playlist: %s", err.Error())
return
}
a.header.Update(playlist)
a.tracklist.Tracks = playlist.Entry
a.tracklist.SetNowPlaying(a.nowPlayingID)
a.tracklist.Refresh()
a.header.Update(playlist)
}()
}
@@ -100,6 +105,8 @@ type PlaylistPageHeader struct {
page *PlaylistPage
image *widgets.ImagePlaceholder
titleLabel *widget.RichText
descriptionLabel *widget.Label
createdAtLabel *widget.Label
@@ -115,6 +122,7 @@ func NewPlaylistPageHeader(page *PlaylistPage) *PlaylistPageHeader {
a := &PlaylistPageHeader{page: page}
a.ExtendBaseWidget(a)
a.image = widgets.NewImagePlaceholder(res.ResPlaylistInvertPng, 225)
a.titleLabel = widget.NewRichTextWithText("")
a.titleLabel.Wrapping = fyne.TextTruncate
a.titleLabel.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{
@@ -128,12 +136,13 @@ func NewPlaylistPageHeader(page *PlaylistPage) *PlaylistPageHeader {
page.onPlayTrackAt(0)
})
a.container = container.NewVBox(a.titleLabel, container.New(&layouts.VboxCustomPadding{ExtraPad: -10},
a.descriptionLabel,
a.ownerLabel,
a.trackTimeLabel),
container.NewHBox(a.playButton),
)
a.container = container.NewBorder(nil, nil, a.image, nil,
container.NewVBox(a.titleLabel, container.New(&layouts.VboxCustomPadding{ExtraPad: -10},
a.descriptionLabel,
a.ownerLabel,
a.trackTimeLabel),
container.NewHBox(a.playButton),
))
return a
}
@@ -147,6 +156,19 @@ func (a *PlaylistPageHeader) Update(playlist *subsonic.Playlist) {
a.ownerLabel.SetText(a.formatPlaylistOwnerStr(playlist))
a.trackTimeLabel.SetText(a.formatPlaylistTrackTimeStr(playlist))
a.createdAtLabel.SetText("created at TODO")
var haveCover bool
if playlist.CoverArt != "" {
if im, err := a.page.im.GetAlbumThumbnail(playlist.CoverArt); err == nil && im != nil {
a.image.SetImage(im)
haveCover = true
}
}
if !haveCover {
if im, err := a.page.im.GetAlbumThumbnail(playlist.ID); err == nil && im != nil {
a.image.SetImage(im)
}
}
a.Refresh()
}
@@ -166,9 +188,10 @@ type savedPlaylistPage struct {
playlistID string
sm *backend.ServerManager
pm *backend.PlaybackManager
im *backend.ImageManager
nav func(Route)
}
func (s *savedPlaylistPage) Restore() Page {
return NewPlaylistPage(s.playlistID, s.sm, s.pm, s.nav)
return NewPlaylistPage(s.playlistID, s.sm, s.pm, s.im, s.nav)
}
+1 -1
View File
@@ -113,7 +113,7 @@ func (r Router) CreatePage(rte Route) Page {
case Genres:
return NewArtistsGenresPage(true, r.App.ServerManager, r.OpenRoute)
case Playlist:
return NewPlaylistPage(rte.Arg, r.App.ServerManager, r.App.PlaybackManager, r.OpenRoute)
return NewPlaylistPage(rte.Arg, r.App.ServerManager, r.App.PlaybackManager, r.App.ImageManager, r.OpenRoute)
case Playlists:
return NewPlaylistsPage(r.App.ServerManager, r.OpenRoute)
}
+48
View File
@@ -0,0 +1,48 @@
package widgets
import (
"image"
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
type ImagePlaceholder struct {
widget.BaseWidget
container *fyne.Container
minSize float32
}
func NewImagePlaceholder(centerIcon fyne.Resource, minSize float32) *ImagePlaceholder {
m := &ImagePlaceholder{minSize: minSize}
m.ExtendBaseWidget(m)
img := canvas.NewImageFromResource(centerIcon)
img.FillMode = canvas.ImageFillContain
img.SetMinSize(fyne.NewSize(minSize/4, minSize/4))
rect := canvas.NewRectangle(theme.BackgroundColor())
rect.StrokeColor = color.Black
rect.StrokeWidth = 3
rect.SetMinSize(fyne.NewSize(minSize, minSize))
m.container = container.NewMax(
rect,
container.NewCenter(img),
)
return m
}
func (i *ImagePlaceholder) SetImage(img image.Image) {
cImg := canvas.NewImageFromImage(img)
cImg.FillMode = canvas.ImageFillContain
cImg.SetMinSize(fyne.NewSize(i.minSize, i.minSize))
i.container.RemoveAll()
i.container.Add(cImg)
i.container.Refresh()
}
func (i *ImagePlaceholder) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(i.container)
}