From 6445320cb519418087e6e42f5305e3ca9af0141d Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Wed, 22 Nov 2023 12:28:18 -0600 Subject: [PATCH] #283: Prevent artist bio from overflowing header space --- ui/browsing/artistpage.go | 18 ++++++------------ ui/util/util.go | 9 ++++----- ui/widgets/maxrowslabel.go | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 ui/widgets/maxrowslabel.go diff --git a/ui/browsing/artistpage.go b/ui/browsing/artistpage.go index e3a329a..8f5c4d0 100644 --- a/ui/browsing/artistpage.go +++ b/ui/browsing/artistpage.go @@ -3,7 +3,6 @@ package browsing import ( "log" "strconv" - "strings" "github.com/dweymouth/supersonic/backend" "github.com/dweymouth/supersonic/backend/mediaprovider" @@ -280,7 +279,7 @@ type ArtistPageHeader struct { artistPage *ArtistPage artistImage *widgets.ImagePlaceholder titleDisp *widget.RichText - biographyDisp *widget.RichText + biographyDisp *widgets.MaxRowsLabel similarArtists *fyne.Container favoriteBtn *widgets.FavoriteButton playBtn *widget.Button @@ -294,7 +293,7 @@ func NewArtistPageHeader(page *ArtistPage) *ArtistPageHeader { a := &ArtistPageHeader{ artistPage: page, titleDisp: widget.NewRichTextWithText(""), - biographyDisp: widget.NewRichTextWithText(artistBioNotAvailableStr), + biographyDisp: widgets.NewMaxRowsLabel(5, artistBioNotAvailableStr), similarArtists: container.NewHBox(), } a.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{ @@ -312,6 +311,7 @@ func NewArtistPageHeader(page *ArtistPage) *ArtistPageHeader { }) a.playRadioBtn = widget.NewButtonWithIcon(" Play Artist Radio", myTheme.ShuffleIcon, a.artistPage.playArtistRadio) a.biographyDisp.Wrapping = fyne.TextWrapWord + a.biographyDisp.Truncation = fyne.TextTruncateEllipsis a.ExtendBaseWidget(a) a.createContainer() return a @@ -321,7 +321,7 @@ func (a *ArtistPageHeader) Clear() { a.artistID = "" a.favoriteBtn.IsFavorited = false a.titleDisp.Segments[0].(*widget.TextSegment).Text = "" - a.biographyDisp.Segments[0].(*widget.TextSegment).Text = artistBioNotAvailableStr + a.biographyDisp.Text = artistBioNotAvailableStr for _, obj := range a.similarArtists.Objects { obj.Hide() } @@ -352,14 +352,8 @@ func (a *ArtistPageHeader) UpdateInfo(info *mediaprovider.ArtistInfo) { return } - if info.Biography != "" { - segs := util.RichTextSegsFromHTMLString(info.Biography) - if len(segs) > 0 { - if ts, ok := segs[0].(*widget.TextSegment); ok && strings.TrimSpace(ts.Text) != "" { - a.biographyDisp.Segments = segs - a.biographyDisp.Refresh() - } - } + if text := util.PlaintextFromHTMLString(info.Biography); text != "" { + a.biographyDisp.SetText(text) } if len(a.similarArtists.Objects) == 0 { diff --git a/ui/util/util.go b/ui/util/util.go index 6f8b106..35c3510 100644 --- a/ui/util/util.go +++ b/ui/util/util.go @@ -82,10 +82,10 @@ func NewDebouncer(dur time.Duration, callOnDone func()) func() { } } -func RichTextSegsFromHTMLString(s string) []widget.RichTextSegment { +func PlaintextFromHTMLString(s string) string { tokr := html.NewTokenizer(strings.NewReader(s)) - var segs []widget.RichTextSegment + var text string var isLink bool var done bool for !done { @@ -102,12 +102,11 @@ func RichTextSegsFromHTMLString(s string) []widget.RichTextSegment { t := tokr.Token() // for now, skip displaying Navidrome's "Read more on Last.FM" link if !isLink { - segs = append(segs, &widget.TextSegment{Text: t.Data}) + text = text + t.Data } } } - - return segs + return text } func NewRatingSubmenu(onSetRating func(int)) *fyne.MenuItem { diff --git a/ui/widgets/maxrowslabel.go b/ui/widgets/maxrowslabel.go new file mode 100644 index 0000000..81e90b4 --- /dev/null +++ b/ui/widgets/maxrowslabel.go @@ -0,0 +1,36 @@ +package widgets + +import ( + "strings" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/widget" +) + +type MaxRowsLabel struct { + widget.Label + + maxHeight float32 +} + +func NewMaxRowsLabel(maxRows int, text string) *MaxRowsLabel { + if maxRows < 1 { + maxRows = 1 + } + m := &MaxRowsLabel{ + Label: widget.Label{ + Text: text, + }, + } + m.ExtendBaseWidget(m) + + maxHeightText := strings.Repeat("W\n", maxRows) + maxHeightText = maxHeightText[:len(maxHeightText)-1] + m.maxHeight = widget.NewLabel(maxHeightText).MinSize().Height + + return m +} + +func (m *MaxRowsLabel) MinSize() fyne.Size { + return fyne.NewSize(m.Label.MinSize().Width, m.maxHeight) +}