From b365c339e954c16749c1d0108087115037491da5 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Thu, 26 Jan 2023 17:47:05 -0800 Subject: [PATCH] add search + iterative loading to favorites page --- ui/browsing/favoritespage.go | 127 ++++++++++++++++++++++++++--------- ui/browsing/router.go | 2 +- 2 files changed, 96 insertions(+), 33 deletions(-) diff --git a/ui/browsing/favoritespage.go b/ui/browsing/favoritespage.go index 6e8ec2e..72eed3d 100644 --- a/ui/browsing/favoritespage.go +++ b/ui/browsing/favoritespage.go @@ -1,44 +1,86 @@ package browsing import ( - "log" "supersonic/backend" "supersonic/ui/widgets" + "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" + "github.com/dweymouth/go-subsonic" ) type FavoritesPage struct { widget.BaseWidget - im *backend.ImageManager - sm *backend.ServerManager - nav func(Route) - grid *widgets.AlbumGrid - titleDisp *widget.RichText - container *fyne.Container + im *backend.ImageManager + sm *backend.ServerManager + lm *backend.LibraryManager + nav func(Route) + grid *widgets.AlbumGrid + searchGrid *widgets.AlbumGrid + searcher *widgets.Searcher + searchText string + titleDisp *widget.RichText + container *fyne.Container OnPlayAlbum func(string, int) } -func NewFavoritesPage(sm *backend.ServerManager, im *backend.ImageManager, nav func(Route)) *FavoritesPage { +func NewFavoritesPage(sm *backend.ServerManager, lm *backend.LibraryManager, im *backend.ImageManager, nav func(Route)) *FavoritesPage { a := &FavoritesPage{ + lm: lm, sm: sm, im: im, nav: nav, } a.ExtendBaseWidget(a) + a.createTitle() + iter := lm.StarredIter() + a.grid = widgets.NewAlbumGrid(iter, im, false) + a.grid.OnPlayAlbum = a.onPlayAlbum + a.grid.OnShowAlbumPage = a.onShowAlbumPage + a.grid.OnShowArtistPage = a.onShowArtistPage + a.searcher = widgets.NewSearcher() + a.searcher.OnSearched = a.OnSearched + a.createContainer() + return a +} + +func (a *FavoritesPage) createTitle() { a.titleDisp = widget.NewRichTextWithText("Favorites") a.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{ SizeName: theme.SizeNameHeadingText, } +} + +func (a *FavoritesPage) createContainer() { + searchVbox := container.NewVBox(layout.NewSpacer(), a.searcher.Entry, layout.NewSpacer()) a.container = container.NewBorder( - container.NewHBox(widgets.NewHSpace(9), a.titleDisp), nil, nil, nil, layout.NewSpacer()) - a.loadAsync() + container.NewHBox(widgets.NewHSpace(9), a.titleDisp, layout.NewSpacer(), searchVbox, widgets.NewHSpace(15)), + nil, nil, nil, a.grid) +} + +func restoreFavoritesPage(saved *savedFavoritesPage) *FavoritesPage { + a := &FavoritesPage{ + lm: saved.lm, + sm: saved.sm, + im: saved.im, + nav: saved.nav, + } + a.ExtendBaseWidget(a) + a.createTitle() + a.grid = widgets.NewAlbumGridFromState(saved.gridState) + a.grid.OnPlayAlbum = a.onPlayAlbum + a.grid.OnShowAlbumPage = a.onShowAlbumPage + a.grid.OnShowArtistPage = a.onShowArtistPage + a.searcher = widgets.NewSearcher() + a.searcher.OnSearched = a.OnSearched + a.createContainer() + return a } @@ -51,17 +93,48 @@ func (a *FavoritesPage) SetPlayAlbumCallback(cb func(string, int)) { } func (a *FavoritesPage) Reload() { - a.loadAsync() + a.grid.Reset(a.lm.StarredIter()) } func (a *FavoritesPage) Save() SavedPage { return &savedFavoritesPage{ - sm: a.sm, - im: a.im, - nav: a.nav, + sm: a.sm, + im: a.im, + lm: a.lm, + nav: a.nav, + gridState: a.grid.SaveToState(), } } +func (a *FavoritesPage) OnSearched(query string) { + a.searchText = query + if query == "" { + a.container.Objects[0] = a.grid + if a.searchGrid != nil { + a.searchGrid.Clear() + } + a.Refresh() + return + } + a.doSearch(query) +} + +func (a *FavoritesPage) doSearch(query string) { + iter := a.lm.SearchIterWithFilter(query, func(al *subsonic.AlbumID3) bool { + return al.Starred.After(time.Time{}) + }) + if a.searchGrid == nil { + a.searchGrid = widgets.NewAlbumGrid(iter, a.im, false /*showYear*/) + a.searchGrid.OnPlayAlbum = a.onPlayAlbum + a.searchGrid.OnShowAlbumPage = a.onShowAlbumPage + a.searchGrid.OnShowArtistPage = a.onShowArtistPage + } else { + a.searchGrid.Reset(iter) + } + a.container.Objects[0] = a.searchGrid + a.Refresh() +} + func (a *FavoritesPage) onPlayAlbum(albumID string) { if a.OnPlayAlbum != nil { a.OnPlayAlbum(albumID, 0) @@ -72,19 +145,8 @@ func (a *FavoritesPage) onShowAlbumPage(albumID string) { a.nav(AlbumRoute(albumID)) } -func (a *FavoritesPage) loadAsync() { - go func() { - starred, err := a.sm.Server.GetStarred2(nil) - if err != nil { - log.Printf("Failed to get favorites: %s", err.Error()) - return - } - ag := widgets.NewFixedAlbumGrid(starred.Album, a.im, false /*showYear*/) - ag.OnPlayAlbum = a.onPlayAlbum - ag.OnShowAlbumPage = a.onShowAlbumPage - a.container.Objects[0] = ag - a.container.Refresh() - }() +func (a *FavoritesPage) onShowArtistPage(artistID string) { + a.nav(ArtistRoute(artistID)) } func (a *FavoritesPage) CreateRenderer() fyne.WidgetRenderer { @@ -93,12 +155,13 @@ func (a *FavoritesPage) CreateRenderer() fyne.WidgetRenderer { } type savedFavoritesPage struct { - artistID string - sm *backend.ServerManager - im *backend.ImageManager - nav func(Route) + sm *backend.ServerManager + im *backend.ImageManager + lm *backend.LibraryManager + gridState widgets.AlbumGridState + nav func(Route) } func (s *savedFavoritesPage) Restore() Page { - return NewFavoritesPage(s.sm, s.im, s.nav) + return restoreFavoritesPage(s) } diff --git a/ui/browsing/router.go b/ui/browsing/router.go index 9d4cb03..8eab236 100644 --- a/ui/browsing/router.go +++ b/ui/browsing/router.go @@ -107,7 +107,7 @@ func (r Router) CreatePage(rte Route) Page { case Artists: return NewArtistsGenresPage(false, r.App.ServerManager, r.OpenRoute) case Favorites: - return NewFavoritesPage(r.App.ServerManager, r.App.ImageManager, r.OpenRoute) + return NewFavoritesPage(r.App.ServerManager, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute) case Genre: return NewGenrePage(rte.Arg, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute) case Genres: