Closes #519: Add click-to-seek to lyrics viewer
This commit is contained in:
@@ -39,6 +39,7 @@ type NowPlayingPage struct {
|
||||
// volatile state
|
||||
nowPlaying mediaprovider.MediaItem
|
||||
nowPlayingID string
|
||||
curLyrics *mediaprovider.Lyrics
|
||||
curLyricsID string // id of track currently shown in lyrics
|
||||
curRelatedID string // id of track currrently used to populate related list
|
||||
totalTime float64
|
||||
@@ -177,13 +178,20 @@ func NewNowPlayingPage(
|
||||
a.relatedList.OnShowTrackInfo = func(track *mediaprovider.Track) {
|
||||
a.contr.ShowTrackInfoDialog(track)
|
||||
}
|
||||
a.lyricsViewer = widgets.NewLyricsViewer()
|
||||
a.lyricsViewer = widgets.NewLyricsViewer(a.onSeekToLyricLine)
|
||||
a.statusLabel = widget.NewLabel(lang.L("Stopped"))
|
||||
|
||||
a.Reload()
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *NowPlayingPage) onSeekToLyricLine(lineNum int) {
|
||||
if a.curLyrics != nil && len(a.curLyrics.Lines) > lineNum-1 {
|
||||
time := a.curLyrics.Lines[lineNum-1].Start
|
||||
a.pm.SeekSeconds(time)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *NowPlayingPage) CreateRenderer() fyne.WidgetRenderer {
|
||||
if a.container == nil {
|
||||
initialTab := 0
|
||||
@@ -341,6 +349,7 @@ func (a *NowPlayingPage) updateLyrics() {
|
||||
}
|
||||
if a.nowPlaying == nil || a.nowPlaying.Metadata().Type == mediaprovider.MediaItemTypeRadioStation {
|
||||
a.lyricsViewer.SetLyrics(nil)
|
||||
a.curLyrics = nil
|
||||
a.curLyricsID = ""
|
||||
return
|
||||
}
|
||||
@@ -350,6 +359,7 @@ func (a *NowPlayingPage) updateLyrics() {
|
||||
a.lyricsLoading.Start()
|
||||
// set the widget to an empty (not nil) lyric during fetch
|
||||
// to keep it from showing "Lyrics not available"
|
||||
a.lyricsViewer.DisableTapToSeek()
|
||||
a.lyricsViewer.SetLyrics(&mediaprovider.Lyrics{Synced: true,
|
||||
Lines: []mediaprovider.LyricLine{{Text: ""}}})
|
||||
tr, _ := a.nowPlaying.(*mediaprovider.Track)
|
||||
@@ -376,7 +386,9 @@ func (a *NowPlayingPage) fetchLyrics(ctx context.Context, song *mediaprovider.Tr
|
||||
default:
|
||||
fyne.Do(func() {
|
||||
a.lyricsLoading.Stop()
|
||||
a.lyricsViewer.EnableTapToSeek()
|
||||
a.lyricsViewer.SetLyrics(lyrics)
|
||||
a.curLyrics = lyrics
|
||||
if lyrics != nil {
|
||||
a.lyricsViewer.OnSeeked(a.lastPlayPos)
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/lang"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
fynelyrics "github.com/dweymouth/fyne-lyrics"
|
||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||
"github.com/dweymouth/supersonic/ui/theme"
|
||||
fynelyrics "github.com/supersonic-app/fyne-lyrics"
|
||||
)
|
||||
|
||||
type LyricsViewer struct {
|
||||
@@ -23,21 +23,36 @@ type LyricsViewer struct {
|
||||
// for the current lyrics
|
||||
firstUpdate bool
|
||||
|
||||
onSeekToLine func(int)
|
||||
|
||||
container *fyne.Container
|
||||
isEmpty bool
|
||||
}
|
||||
|
||||
func NewLyricsViewer() *LyricsViewer {
|
||||
func NewLyricsViewer(onSeekToLine func(int)) *LyricsViewer {
|
||||
l := &LyricsViewer{
|
||||
noLyricsMsg: container.NewCenter(NewInfoMessage(
|
||||
lang.L("Lyrics not available"), "")),
|
||||
isEmpty: true,
|
||||
isEmpty: true,
|
||||
onSeekToLine: onSeekToLine,
|
||||
}
|
||||
l.ExtendBaseWidget(l)
|
||||
l.container = container.NewStack(l.noLyricsMsg)
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *LyricsViewer) DisableTapToSeek() {
|
||||
if l.viewer != nil {
|
||||
l.viewer.OnLyricTapped = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LyricsViewer) EnableTapToSeek() {
|
||||
if l.viewer != nil {
|
||||
l.viewer.OnLyricTapped = l.onSeekToLine
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LyricsViewer) SetLyrics(lyrics *mediaprovider.Lyrics) {
|
||||
l.lyrics = lyrics
|
||||
l.nextLyricLine = 0
|
||||
@@ -55,6 +70,7 @@ func (l *LyricsViewer) SetLyrics(lyrics *mediaprovider.Lyrics) {
|
||||
l.viewer = fynelyrics.NewLyricsViewer()
|
||||
l.viewer.ActiveLyricPosition = fynelyrics.ActiveLyricPositionUpperMiddle
|
||||
l.viewer.InactiveLyricColorName = theme.ColorNameInactiveLyric
|
||||
l.viewer.OnLyricTapped = l.onSeekToLine
|
||||
}
|
||||
lines := make([]string, len(lyrics.Lines))
|
||||
for i, line := range lyrics.Lines {
|
||||
|
||||
Reference in New Issue
Block a user