Fix #115: add search to artists, genres, and playlists pages
This commit is contained in:
@@ -3,13 +3,16 @@ package browsing
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"supersonic/backend"
|
||||
"supersonic/sharedutil"
|
||||
"supersonic/ui/controller"
|
||||
"supersonic/ui/layouts"
|
||||
"supersonic/ui/widgets"
|
||||
|
||||
"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/subsonic"
|
||||
@@ -20,12 +23,19 @@ type PlaylistsPage struct {
|
||||
|
||||
contr *controller.Controller
|
||||
sm *backend.ServerManager
|
||||
playlists []*subsonic.Playlist
|
||||
|
||||
searcher *widgets.Searcher
|
||||
titleDisp *widget.RichText
|
||||
container *fyne.Container
|
||||
list *PlaylistList
|
||||
}
|
||||
|
||||
func NewPlaylistsPage(contr *controller.Controller, sm *backend.ServerManager) *PlaylistsPage {
|
||||
return newPlaylistsPage(contr, sm, "")
|
||||
}
|
||||
|
||||
func newPlaylistsPage(contr *controller.Controller, sm *backend.ServerManager, searchText string) *PlaylistsPage {
|
||||
a := &PlaylistsPage{
|
||||
sm: sm,
|
||||
contr: contr,
|
||||
@@ -37,17 +47,42 @@ func NewPlaylistsPage(contr *controller.Controller, sm *backend.ServerManager) *
|
||||
a.list.OnNavTo = func(id string) {
|
||||
a.contr.NavigateTo(controller.PlaylistRoute(id))
|
||||
}
|
||||
a.searcher = widgets.NewSearcher()
|
||||
a.searcher.OnSearched = a.onSearched
|
||||
a.searcher.Entry.Text = searchText
|
||||
a.buildContainer()
|
||||
go a.loadAsync()
|
||||
go a.load(searchText != "")
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *PlaylistsPage) loadAsync() {
|
||||
func (a *PlaylistsPage) load(searchOnLoad bool) {
|
||||
playlists, err := a.sm.Server.GetPlaylists(nil)
|
||||
if err != nil {
|
||||
log.Printf("error loading playlists: %v", err.Error())
|
||||
}
|
||||
a.list.Playlists = playlists
|
||||
a.playlists = playlists
|
||||
if searchOnLoad {
|
||||
a.onSearched(a.searcher.Entry.Text)
|
||||
} else {
|
||||
a.list.Playlists = playlists
|
||||
a.list.Refresh()
|
||||
}
|
||||
}
|
||||
|
||||
func (a *PlaylistsPage) onSearched(query string) {
|
||||
// since the playlist list is returned in full non-paginated, we will do our own
|
||||
// simple search based on the name, description, and owner, rather than calling a server API
|
||||
if query == "" {
|
||||
a.list.Playlists = a.playlists
|
||||
} else {
|
||||
result := sharedutil.FilterSlice(a.playlists, func(p *subsonic.Playlist) bool {
|
||||
qLower := strings.ToLower(query)
|
||||
return strings.Contains(strings.ToLower(p.Name), qLower) ||
|
||||
strings.Contains(strings.ToLower(p.Comment), qLower) ||
|
||||
strings.Contains(strings.ToLower(p.Owner), qLower)
|
||||
})
|
||||
a.list.Playlists = result
|
||||
}
|
||||
a.list.Refresh()
|
||||
}
|
||||
|
||||
@@ -56,28 +91,33 @@ func (a *PlaylistsPage) Route() controller.Route {
|
||||
}
|
||||
|
||||
func (a *PlaylistsPage) Reload() {
|
||||
go a.loadAsync()
|
||||
go a.load(false)
|
||||
}
|
||||
|
||||
func (a *PlaylistsPage) Save() SavedPage {
|
||||
return &savedPlaylistsPage{
|
||||
contr: a.contr,
|
||||
sm: a.sm,
|
||||
contr: a.contr,
|
||||
sm: a.sm,
|
||||
searchText: a.searcher.Entry.Text,
|
||||
}
|
||||
}
|
||||
|
||||
type savedPlaylistsPage struct {
|
||||
contr *controller.Controller
|
||||
sm *backend.ServerManager
|
||||
contr *controller.Controller
|
||||
sm *backend.ServerManager
|
||||
searchText string
|
||||
}
|
||||
|
||||
func (s *savedPlaylistsPage) Restore() Page {
|
||||
return NewPlaylistsPage(s.contr, s.sm)
|
||||
return newPlaylistsPage(s.contr, s.sm, s.searchText)
|
||||
}
|
||||
|
||||
func (a *PlaylistsPage) buildContainer() {
|
||||
searchVbox := container.NewVBox(layout.NewSpacer(), a.searcher.Entry, layout.NewSpacer())
|
||||
a.container = container.New(&layouts.MaxPadLayout{PadLeft: 15, PadRight: 15, PadTop: 5, PadBottom: 15},
|
||||
container.NewBorder(a.titleDisp, nil, nil, nil, a.list))
|
||||
container.NewBorder(
|
||||
container.NewHBox(a.titleDisp, layout.NewSpacer(), searchVbox),
|
||||
nil, nil, nil, a.list))
|
||||
}
|
||||
|
||||
func (a *PlaylistsPage) CreateRenderer() fyne.WidgetRenderer {
|
||||
|
||||
Reference in New Issue
Block a user