only update lyrics when visible

This commit is contained in:
Drew Weymouth
2024-05-25 10:17:47 -07:00
parent 20fedf67ae
commit 4ba358ad23
+78 -24
View File
@@ -7,6 +7,7 @@ import (
"log" "log"
"slices" "slices"
"strings" "strings"
"sync"
"github.com/dweymouth/supersonic/backend" "github.com/dweymouth/supersonic/backend"
"github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/backend/mediaprovider"
@@ -31,16 +32,21 @@ type NowPlayingPage struct {
nowPlayingPageState nowPlayingPageState
queue []*mediaprovider.Track nowPlaying *mediaprovider.Track
queueList *widgets.PlayQueueList nowPlayingID string
lyricsViewer *widgets.LyricsViewer curLyricsID string
imageLoadCancel context.CancelFunc queue []*mediaprovider.Track
card *widgets.LargeNowPlayingCard queueList *widgets.PlayQueueList
statusLabel *widget.Label lyricLock sync.Mutex
totalTime float64 lyricsViewer *widgets.LyricsViewer
nowPlayingID string lyricFetchCancel context.CancelFunc
albumID string imageLoadCancel context.CancelFunc
container *fyne.Container card *widgets.LargeNowPlayingCard
statusLabel *widget.Label
tabs *container.AppTabs
totalTime float64
lastPlayPos float64
container *fyne.Container
} }
type nowPlayingPageState struct { type nowPlayingPageState struct {
@@ -76,7 +82,7 @@ func NewNowPlayingPage(
a.card = widgets.NewLargeNowPlayingCard() a.card = widgets.NewLargeNowPlayingCard()
a.card.DisableRating = !canRate a.card.DisableRating = !canRate
a.card.OnAlbumNameTapped = func() { a.card.OnAlbumNameTapped = func() {
contr.NavigateTo(controller.AlbumRoute(a.albumID)) contr.NavigateTo(controller.AlbumRoute(sharedutil.AlbumIDOrEmptyStr(a.nowPlaying)))
} }
a.card.OnArtistNameTapped = func(artistID string) { a.card.OnArtistNameTapped = func(artistID string) {
contr.NavigateTo(controller.ArtistRoute(artistID)) contr.NavigateTo(controller.ArtistRoute(artistID))
@@ -140,19 +146,26 @@ func (a *NowPlayingPage) CreateRenderer() fyne.WidgetRenderer {
LeftRightObjectPercent: .8, LeftRightObjectPercent: .8,
TopBottomObjectPercent: .8, TopBottomObjectPercent: .8,
} }
tabs := container.NewAppTabs( a.tabs = container.NewAppTabs(
container.NewTabItem("Play Queue", container.NewTabItem("Play Queue",
container.NewBorder(layout.NewSpacer(), nil, nil, nil, a.queueList)), container.NewBorder(layout.NewSpacer(), nil, nil, nil, a.queueList)),
container.NewTabItem("Lyrics", a.lyricsViewer), container.NewTabItem("Lyrics", a.lyricsViewer),
) )
tabs.SelectIndex(initialTab) a.tabs.SelectIndex(initialTab)
tabs.OnSelected = func(*container.TabItem) { a.tabs.OnSelected = func(*container.TabItem) {
a.saveSelectedTab(tabs.SelectedIndex()) idx := a.tabs.SelectedIndex()
a.saveSelectedTab(idx)
if idx == 1 /*lyrics*/ {
a.updateLyrics()
}
}
if initialTab == 1 /*lyrics*/ {
a.updateLyrics()
} }
mainContent := container.NewGridWithColumns(2, mainContent := container.NewGridWithColumns(2,
container.New(paddedLayout, a.card), container.New(paddedLayout, a.card),
container.New(paddedLayout, container.New(paddedLayout,
util.AddHeaderBackground(tabs))) util.AddHeaderBackground(a.tabs)))
a.container = container.NewStack( a.container = container.NewStack(
mainContent, mainContent,
container.NewVBox( container.NewVBox(
@@ -181,14 +194,14 @@ func (a *NowPlayingPage) Route() controller.Route {
var _ CanShowNowPlaying = (*NowPlayingPage)(nil) var _ CanShowNowPlaying = (*NowPlayingPage)(nil)
func (a *NowPlayingPage) OnSongChange(song, lastScrobbledIfAny *mediaprovider.Track) { func (a *NowPlayingPage) OnSongChange(song, _ *mediaprovider.Track) {
a.nowPlaying = song
if a.imageLoadCancel != nil { if a.imageLoadCancel != nil {
a.imageLoadCancel() a.imageLoadCancel()
} }
a.nowPlayingID = sharedutil.TrackIDOrEmptyStr(song) a.nowPlayingID = sharedutil.TrackIDOrEmptyStr(song)
a.queueList.SetNowPlaying(a.nowPlayingID) a.queueList.SetNowPlaying(a.nowPlayingID)
a.albumID = sharedutil.AlbumIDOrEmptyStr(song)
a.card.Update(song) a.card.Update(song)
if song == nil { if song == nil {
a.card.SetCoverImage(nil) a.card.SetCoverImage(nil)
@@ -203,15 +216,50 @@ func (a *NowPlayingPage) OnSongChange(song, lastScrobbledIfAny *mediaprovider.Tr
} }
}) })
if a.tabs != nil && a.tabs.SelectedIndex() == 1 /*lyrics*/ {
a.updateLyrics()
}
}
func (a *NowPlayingPage) updateLyrics() {
a.lyricLock.Lock()
defer a.lyricLock.Unlock()
if a.lyricFetchCancel != nil {
a.lyricFetchCancel()
}
if a.nowPlayingID == a.curLyricsID {
if a.nowPlayingID != "" {
// just need to sync the current time
a.lyricsViewer.OnSeeked(a.lastPlayPos)
}
}
if a.nowPlaying == nil {
a.lyricsViewer.SetLyrics(nil)
a.curLyricsID = ""
return
}
a.curLyricsID = a.nowPlayingID
if lp, ok := a.sm.Server.(mediaprovider.LyricsProvider); ok { if lp, ok := a.sm.Server.(mediaprovider.LyricsProvider); ok {
go func() { ctx, cancel := context.WithCancel(context.Background())
if lyrics, err := lp.GetLyrics(song); err == nil { a.lyricFetchCancel = cancel
a.lyricsViewer.SetLyrics(lyrics) go func(ctx context.Context) {
} else { var lyrics *mediaprovider.Lyrics
var err error
if lyrics, err = lp.GetLyrics(a.nowPlaying); err != nil {
log.Printf("Error fetching lyrics: %v", err) log.Printf("Error fetching lyrics: %v", err)
a.lyricsViewer.SetLyrics(nil)
} }
}() select {
case <-ctx.Done():
return
default:
a.lyricLock.Lock()
a.lyricsViewer.SetLyrics(lyrics)
a.lyricsViewer.OnSeeked(a.lastPlayPos)
a.lyricLock.Unlock()
}
}(ctx)
} else { } else {
a.lyricsViewer.SetLyrics(nil) a.lyricsViewer.SetLyrics(nil)
} }
@@ -242,7 +290,13 @@ func (s *nowPlayingPageState) Restore() Page {
var _ CanShowPlayTime = (*NowPlayingPage)(nil) var _ CanShowPlayTime = (*NowPlayingPage)(nil)
func (a *NowPlayingPage) OnPlayTimeUpdate(curTime, _ float64, seeked bool) { func (a *NowPlayingPage) OnPlayTimeUpdate(curTime, _ float64, seeked bool) {
a.lastPlayPos = curTime
a.formatStatusLine() a.formatStatusLine()
if a.tabs == nil || a.tabs.SelectedIndex() != 1 /*lyrics*/ {
return
}
a.lyricLock.Lock()
defer a.lyricLock.Unlock()
if seeked { if seeked {
a.lyricsViewer.OnSeeked(curTime) a.lyricsViewer.OnSeeked(curTime)
} else { } else {