diff --git a/backend/albumiterator.go b/backend/albumiterator.go index a801a53..c09128e 100644 --- a/backend/albumiterator.go +++ b/backend/albumiterator.go @@ -51,17 +51,17 @@ var ( func (l *LibraryManager) AlbumsIter(sort AlbumSortOrder) AlbumIterator { switch sort { case AlbumSortRecentlyAdded: - return l.newBaseIter("newest") + return l.newBaseIter("newest", make(map[string]string)) case AlbumSortRecentlyPlayed: - return l.newBaseIter("recent") + return l.newBaseIter("recent", make(map[string]string)) case AlbumSortFrequentlyPlayed: - return l.newBaseIter("frequent") + return l.newBaseIter("frequent", make(map[string]string)) case AlbumSortRandom: return l.newRandomIter() case AlbumSortTitleAZ: - return l.newBaseIter("alphabeticalByName") + return l.newBaseIter("alphabeticalByName", make(map[string]string)) case AlbumSortArtistAZ: - return l.newBaseIter("alphabeticalByArtist") + return l.newBaseIter("alphabeticalByArtist", make(map[string]string)) default: log.Printf("Undefined album sort order: %s", sort) return nil @@ -69,7 +69,11 @@ func (l *LibraryManager) AlbumsIter(sort AlbumSortOrder) AlbumIterator { } func (l *LibraryManager) StarredIter() AlbumIterator { - return l.newBaseIter("starred") + return l.newBaseIter("starred", make(map[string]string)) +} + +func (l *LibraryManager) GenreIter(genre string) AlbumIterator { + return l.newBaseIter("", map[string]string{"genre": genre}) } func (l *LibraryManager) SearchIter(query string) AlbumIterator { @@ -99,16 +103,18 @@ type baseIter struct { pos int l *LibraryManager s *subsonic.Client + opts map[string]string prefetched []*subsonic.AlbumID3 prefetchedPos int done bool } -func (l *LibraryManager) newBaseIter(listType string) *baseIter { +func (l *LibraryManager) newBaseIter(listType string, opts map[string]string) *baseIter { return &baseIter{ listType: listType, l: l, s: l.s.Server, + opts: opts, } } @@ -128,7 +134,8 @@ func (r *baseIter) Next() *subsonic.AlbumID3 { return a } - albums, err := r.s.GetAlbumList2(r.listType, map[string]string{"size": "20", "offset": strconv.Itoa(r.pos)}) + r.opts["offset"] = strconv.Itoa(r.pos) + albums, err := r.s.GetAlbumList2(r.listType, r.opts) if err != nil { log.Println(err) albums = nil diff --git a/ui/browsing/genrepage.go b/ui/browsing/genrepage.go new file mode 100644 index 0000000..ca971b5 --- /dev/null +++ b/ui/browsing/genrepage.go @@ -0,0 +1,104 @@ +package browsing + +import ( + "supersonic/backend" + "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" +) + +// TODO: there is a lot of code duplication between this and albumspage. Refactor? +type GenrePage struct { + widget.BaseWidget + + genre string + im *backend.ImageManager + lm *backend.LibraryManager + nav func(Route) + grid *widgets.AlbumGrid + searchGrid *widgets.AlbumGrid + searcher *widgets.Searcher + searchText string + titleDisp *widget.RichText + + OnPlayAlbum func(string, int) + + container *fyne.Container +} + +func NewGenrePage(genre string, lm *backend.LibraryManager, im *backend.ImageManager, nav func(Route)) *GenrePage { + g := &GenrePage{ + genre: genre, + lm: lm, + im: im, + nav: nav, + } + g.ExtendBaseWidget(g) + + g.titleDisp = widget.NewRichTextWithText(genre) + g.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{ + SizeName: theme.SizeNameHeadingText, + } + g.grid = widgets.NewFixedAlbumGrid(nil, im.GetAlbumThumbnail, false /*showYear*/) + g.grid.OnPlayAlbum = g.onPlayAlbum + g.grid.OnShowArtistPage = g.onShowArtistPage + g.grid.OnShowAlbumPage = g.onShowAlbumPage + g.searcher = widgets.NewSearcher() + g.searcher.OnSearched = g.OnSearched + searchVbox := container.NewVBox(layout.NewSpacer(), g.searcher.Entry, layout.NewSpacer()) + g.container = container.NewBorder( + container.NewHBox(widgets.NewHSpace(9), g.titleDisp, layout.NewSpacer(), searchVbox, widgets.NewHSpace(15)), + nil, + nil, + nil, + g.grid, + ) + return g +} + +func (g *GenrePage) CreateRenderer() fyne.WidgetRenderer { + return widget.NewSimpleRenderer(g.container) +} + +func (a *GenrePage) Route() Route { + return GenreRoute(a.genre) +} + +func (a *GenrePage) SetPlayAlbumCallback(cb func(string, int)) { + a.OnPlayAlbum = cb +} + +func (g *GenrePage) Reload() { + if g.searchText != "" { + g.doSearch(g.searchText) + } else { + g.grid.Reset(nil) + g.grid.Refresh() + } +} + +func (a *GenrePage) onPlayAlbum(albumID string) { + if a.OnPlayAlbum != nil { + a.OnPlayAlbum(albumID, 0) + } +} + +func (a *GenrePage) onShowArtistPage(artistID string) { + a.nav(ArtistRoute(artistID)) +} + +func (a *GenrePage) onShowAlbumPage(albumID string) { + a.nav(AlbumRoute(albumID)) +} + +func (g *GenrePage) OnSearched(query string) { + +} + +func (g *GenrePage) doSearch(query string) { + +} diff --git a/ui/browsing/router.go b/ui/browsing/router.go index b7ba96e..dcc6271 100644 --- a/ui/browsing/router.go +++ b/ui/browsing/router.go @@ -12,6 +12,8 @@ const ( Albums Artist Artists + Genre + Genres Playlist Playlists ) @@ -33,6 +35,10 @@ func AlbumRoute(albumID string) Route { return Route{Page: Album, Arg: albumID} } +func GenreRoute(genre string) Route { + return Route{Page: Genre, Arg: genre} +} + type NavigationHandler interface { SetPage(Page) }