163 lines
4.7 KiB
Go
163 lines
4.7 KiB
Go
package browsing
|
|
|
|
import (
|
|
"github.com/dweymouth/supersonic/backend"
|
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
|
"github.com/dweymouth/supersonic/sharedutil"
|
|
"github.com/dweymouth/supersonic/ui/controller"
|
|
"github.com/dweymouth/supersonic/ui/layouts"
|
|
"github.com/dweymouth/supersonic/ui/theme"
|
|
"github.com/dweymouth/supersonic/ui/widgets"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/container"
|
|
"fyne.io/fyne/v2/layout"
|
|
"fyne.io/fyne/v2/widget"
|
|
)
|
|
|
|
type TracksPage struct {
|
|
widget.BaseWidget
|
|
|
|
tracksPageState
|
|
|
|
nowPlayingID string
|
|
|
|
title *widget.RichText
|
|
searcher *widgets.SearchEntry
|
|
tracklist *widgets.Tracklist
|
|
loader widgets.TracklistLoader
|
|
searchTracklist *widgets.Tracklist
|
|
searchLoader widgets.TracklistLoader
|
|
playRandom *widget.Button
|
|
container *fyne.Container
|
|
}
|
|
|
|
type tracksPageState struct {
|
|
searchText string
|
|
contr *controller.Controller
|
|
conf *backend.TracksPageConfig
|
|
mp mediaprovider.MediaProvider
|
|
}
|
|
|
|
func NewTracksPage(contr *controller.Controller, conf *backend.TracksPageConfig, mp mediaprovider.MediaProvider) *TracksPage {
|
|
t := &TracksPage{tracksPageState: tracksPageState{contr: contr, conf: conf, mp: mp}}
|
|
t.ExtendBaseWidget(t)
|
|
|
|
t.tracklist = widgets.NewTracklist(nil)
|
|
t.tracklist.Options = widgets.TracklistOptions{
|
|
DisableSorting: true,
|
|
AutoNumber: true,
|
|
}
|
|
t.tracklist.SetVisibleColumns(conf.TracklistColumns)
|
|
t.tracklist.OnVisibleColumnsChanged = func(cols []string) {
|
|
t.conf.TracklistColumns = cols
|
|
if t.searchTracklist != nil {
|
|
t.searchTracklist.SetVisibleColumns(cols)
|
|
}
|
|
}
|
|
contr.ConnectTracklistActions(t.tracklist)
|
|
|
|
t.title = widget.NewRichTextWithText("All Tracks")
|
|
t.title.Segments[0].(*widget.TextSegment).Style.SizeName = widget.RichTextStyleHeading.SizeName
|
|
t.playRandom = widget.NewButtonWithIcon("Play random", theme.ShuffleIcon, t.playRandomSongs)
|
|
t.searcher = widgets.NewSearchEntry()
|
|
t.searcher.OnSearched = t.OnSearched
|
|
t.createContainer()
|
|
t.Reload()
|
|
return t
|
|
}
|
|
|
|
func (t *TracksPage) createContainer() {
|
|
playRandomVbox := container.NewVBox(layout.NewSpacer(), t.playRandom, layout.NewSpacer())
|
|
searchVbox := container.NewVBox(layout.NewSpacer(), t.searcher, layout.NewSpacer())
|
|
topRow := container.NewHBox(t.title, playRandomVbox, layout.NewSpacer(), searchVbox)
|
|
t.container = container.New(&layouts.MaxPadLayout{PadLeft: 15, PadRight: 15, PadTop: 5, PadBottom: 15},
|
|
container.NewBorder(topRow, nil, nil, nil, t.tracklist))
|
|
}
|
|
|
|
func (t *TracksPage) Route() controller.Route {
|
|
return controller.TracksRoute()
|
|
}
|
|
|
|
func (t *TracksPage) Reload() {
|
|
t.tracklist.Clear()
|
|
iter := t.mp.IterateTracks("")
|
|
// loads asynchronously
|
|
t.loader = widgets.NewTracklistLoader(t.tracklist, iter)
|
|
}
|
|
|
|
func (t *TracksPage) OnSongChange(track, lastScrobbledIfAny *mediaprovider.Track) {
|
|
t.nowPlayingID = sharedutil.TrackIDOrEmptyStr(track)
|
|
t.tracklist.SetNowPlaying(t.nowPlayingID)
|
|
if t.searchTracklist != nil {
|
|
t.searchTracklist.SetNowPlaying(t.nowPlayingID)
|
|
}
|
|
playedID := sharedutil.TrackIDOrEmptyStr(lastScrobbledIfAny)
|
|
t.tracklist.IncrementPlayCount(playedID)
|
|
if t.searchTracklist != nil {
|
|
t.searchTracklist.IncrementPlayCount(playedID)
|
|
}
|
|
}
|
|
|
|
var _ Searchable = (*TracksPage)(nil)
|
|
|
|
func (t *TracksPage) SearchWidget() fyne.Focusable {
|
|
return t.searcher
|
|
}
|
|
|
|
func (t *TracksPage) OnSearched(query string) {
|
|
t.searchText = query
|
|
if query == "" {
|
|
t.container.Objects[0].(*fyne.Container).Objects[0] = t.tracklist
|
|
if t.searchTracklist != nil {
|
|
t.searchTracklist.Clear()
|
|
}
|
|
t.Refresh()
|
|
return
|
|
}
|
|
t.doSearch(query)
|
|
}
|
|
|
|
func (t *TracksPage) doSearch(query string) {
|
|
if t.searchTracklist == nil {
|
|
t.searchTracklist = widgets.NewTracklist(nil)
|
|
t.searchTracklist.Options = widgets.TracklistOptions{AutoNumber: true}
|
|
t.searchTracklist.SetVisibleColumns(t.conf.TracklistColumns)
|
|
t.searchTracklist.SetNowPlaying(t.nowPlayingID)
|
|
t.searchTracklist.OnVisibleColumnsChanged = func(cols []string) {
|
|
t.conf.TracklistColumns = cols
|
|
t.tracklist.SetVisibleColumns(cols)
|
|
}
|
|
t.contr.ConnectTracklistActions(t.searchTracklist)
|
|
} else {
|
|
t.searchTracklist.Clear()
|
|
}
|
|
iter := t.mp.IterateTracks(query)
|
|
t.searchLoader = widgets.NewTracklistLoader(t.searchTracklist, iter)
|
|
t.container.Objects[0].(*fyne.Container).Objects[0] = t.searchTracklist
|
|
t.Refresh()
|
|
}
|
|
|
|
func (t *TracksPage) CreateRenderer() fyne.WidgetRenderer {
|
|
return widget.NewSimpleRenderer(t.container)
|
|
}
|
|
|
|
func (t *TracksPage) Save() SavedPage {
|
|
state := t.tracksPageState
|
|
return &state
|
|
}
|
|
|
|
func (s *tracksPageState) Restore() Page {
|
|
t := NewTracksPage(s.contr, s.conf, s.mp)
|
|
t.searchText = s.searchText
|
|
if t.searchText != "" {
|
|
t.searcher.Entry.Text = t.searchText
|
|
t.doSearch(t.searchText)
|
|
}
|
|
return t
|
|
}
|
|
|
|
func (t *TracksPage) playRandomSongs() {
|
|
t.contr.App.PlaybackManager.PlayRandomSongs("")
|
|
}
|