batch-add albums to infinite scroll grid to slightly improve smoothness
This commit is contained in:
+17
-32
@@ -10,7 +10,6 @@ import (
|
|||||||
|
|
||||||
type AlbumIterator interface {
|
type AlbumIterator interface {
|
||||||
Next() *subsonic.AlbumID3
|
Next() *subsonic.AlbumID3
|
||||||
NextN(int, func(*subsonic.AlbumID3))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LibraryManager struct {
|
type LibraryManager struct {
|
||||||
@@ -164,18 +163,6 @@ func (r *baseIter) Next() *subsonic.AlbumID3 {
|
|||||||
return r.prefetched[0]
|
return r.prefetched[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *baseIter) NextN(n int, cb func(*subsonic.AlbumID3)) {
|
|
||||||
go func() {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
a := r.Next()
|
|
||||||
cb(a)
|
|
||||||
if a == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
type searchIter struct {
|
type searchIter struct {
|
||||||
query string
|
query string
|
||||||
artistOffset int
|
artistOffset int
|
||||||
@@ -263,18 +250,6 @@ func (s *searchIter) Next() *subsonic.AlbumID3 {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *searchIter) NextN(n int, cb func(*subsonic.AlbumID3)) {
|
|
||||||
go func() {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
a := s.Next()
|
|
||||||
cb(a)
|
|
||||||
if a == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *searchIter) addNewAlbums(al []*subsonic.AlbumID3) {
|
func (s *searchIter) addNewAlbums(al []*subsonic.AlbumID3) {
|
||||||
for _, album := range al {
|
for _, album := range al {
|
||||||
if _, have := s.albumIDset[album.ID]; have {
|
if _, have := s.albumIDset[album.ID]; have {
|
||||||
@@ -386,14 +361,24 @@ func (r *randomIter) Next() *subsonic.AlbumID3 {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *randomIter) NextN(n int, cb func(*subsonic.AlbumID3)) {
|
type BatchingIterator struct {
|
||||||
go func() {
|
iter AlbumIterator
|
||||||
for i := 0; i < n; i++ {
|
}
|
||||||
a := r.Next()
|
|
||||||
cb(a)
|
func NewBatchingIterator(iter AlbumIterator) *BatchingIterator {
|
||||||
if a == nil {
|
return &BatchingIterator{iter}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BatchingIterator) NextN(n int) []*subsonic.AlbumID3 {
|
||||||
|
results := make([]*subsonic.AlbumID3, 0, n)
|
||||||
|
i := 0
|
||||||
|
for i < n {
|
||||||
|
album := b.iter.Next()
|
||||||
|
if album == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
results = append(results, album)
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
}()
|
return results
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-18
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"image"
|
"image"
|
||||||
"log"
|
"log"
|
||||||
|
"supersonic/backend"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
@@ -15,10 +16,6 @@ type ImageFetcher interface {
|
|||||||
GetAlbumThumbnail(string) (image.Image, error)
|
GetAlbumThumbnail(string) (image.Image, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlbumIterator interface {
|
|
||||||
NextN(int, func(*subsonic.AlbumID3))
|
|
||||||
}
|
|
||||||
|
|
||||||
type AlbumGrid struct {
|
type AlbumGrid struct {
|
||||||
widget.BaseWidget
|
widget.BaseWidget
|
||||||
|
|
||||||
@@ -29,7 +26,7 @@ type AlbumGrid struct {
|
|||||||
|
|
||||||
type AlbumGridState struct {
|
type AlbumGridState struct {
|
||||||
albums []*subsonic.AlbumID3
|
albums []*subsonic.AlbumID3
|
||||||
iter AlbumIterator
|
iter *backend.BatchingIterator
|
||||||
fetching bool
|
fetching bool
|
||||||
done bool
|
done bool
|
||||||
showYear bool
|
showYear bool
|
||||||
@@ -58,10 +55,10 @@ func NewFixedAlbumGrid(albums []*subsonic.AlbumID3, fetch ImageFetcher, showYear
|
|||||||
return ag
|
return ag
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAlbumGrid(iter AlbumIterator, fetch ImageFetcher, showYear bool) *AlbumGrid {
|
func NewAlbumGrid(iter backend.AlbumIterator, fetch ImageFetcher, showYear bool) *AlbumGrid {
|
||||||
ag := &AlbumGrid{
|
ag := &AlbumGrid{
|
||||||
AlbumGridState: AlbumGridState{
|
AlbumGridState: AlbumGridState{
|
||||||
iter: iter,
|
iter: backend.NewBatchingIterator(iter),
|
||||||
imageFetcher: fetch,
|
imageFetcher: fetch,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -94,11 +91,11 @@ func (ag *AlbumGrid) Clear() {
|
|||||||
ag.done = true
|
ag.done = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ag *AlbumGrid) Reset(iter AlbumIterator) {
|
func (ag *AlbumGrid) Reset(iter backend.AlbumIterator) {
|
||||||
ag.albums = nil
|
ag.albums = nil
|
||||||
ag.fetching = false
|
ag.fetching = false
|
||||||
ag.done = false
|
ag.done = false
|
||||||
ag.iter = iter
|
ag.iter = backend.NewBatchingIterator(iter)
|
||||||
ag.fetchMoreAlbums(36)
|
ag.fetchMoreAlbums(36)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,20 +179,18 @@ func (a *AlbumGrid) fetchMoreAlbums(count int) {
|
|||||||
if a.iter == nil {
|
if a.iter == nil {
|
||||||
a.done = true
|
a.done = true
|
||||||
}
|
}
|
||||||
i := 0
|
|
||||||
a.fetching = true
|
a.fetching = true
|
||||||
a.iter.NextN(count, func(al *subsonic.AlbumID3) {
|
go func() {
|
||||||
if al == nil {
|
albums := a.iter.NextN(count)
|
||||||
|
a.albums = append(a.albums, albums...)
|
||||||
|
if len(albums) < count {
|
||||||
a.done = true
|
a.done = true
|
||||||
return
|
|
||||||
}
|
}
|
||||||
a.albums = append(a.albums, al)
|
|
||||||
i++
|
|
||||||
if i == count {
|
|
||||||
a.fetching = false
|
a.fetching = false
|
||||||
}
|
if len(albums) > 0 {
|
||||||
a.Refresh()
|
a.Refresh()
|
||||||
})
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AlbumGrid) CreateRenderer() fyne.WidgetRenderer {
|
func (a *AlbumGrid) CreateRenderer() fyne.WidgetRenderer {
|
||||||
|
|||||||
Reference in New Issue
Block a user