Fix #161: ensure gridview doesn't have concurrent fetch tasks on reset
This commit is contained in:
+28
-15
@@ -82,7 +82,7 @@ type GridViewState struct {
|
|||||||
iter GridViewIterator
|
iter GridViewIterator
|
||||||
imageFetcher ImageFetcher
|
imageFetcher ImageFetcher
|
||||||
highestShown int
|
highestShown int
|
||||||
fetching bool
|
fetchCancel context.CancelFunc
|
||||||
done bool
|
done bool
|
||||||
|
|
||||||
OnPlay func(id string, shuffle bool)
|
OnPlay func(id string, shuffle bool)
|
||||||
@@ -148,9 +148,12 @@ func (g *GridView) Clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GridView) Reset(iter GridViewIterator) {
|
func (g *GridView) Reset(iter GridViewIterator) {
|
||||||
|
if g.fetchCancel != nil {
|
||||||
|
g.fetchCancel()
|
||||||
|
g.fetchCancel = nil
|
||||||
|
}
|
||||||
g.itemsMutex.Lock()
|
g.itemsMutex.Lock()
|
||||||
g.items = nil
|
g.items = nil
|
||||||
g.fetching = false
|
|
||||||
g.done = false
|
g.done = false
|
||||||
g.highestShown = 0
|
g.highestShown = 0
|
||||||
g.iter = iter
|
g.iter = iter
|
||||||
@@ -159,10 +162,13 @@ func (g *GridView) Reset(iter GridViewIterator) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GridView) ResetFixed(items []GridViewItemModel) {
|
func (g *GridView) ResetFixed(items []GridViewItemModel) {
|
||||||
|
if g.fetchCancel != nil {
|
||||||
|
g.fetchCancel()
|
||||||
|
g.fetchCancel = nil
|
||||||
|
}
|
||||||
g.itemsMutex.Lock()
|
g.itemsMutex.Lock()
|
||||||
g.items = items
|
g.items = items
|
||||||
g.itemsMutex.Unlock()
|
g.itemsMutex.Unlock()
|
||||||
g.fetching = false
|
|
||||||
g.done = true
|
g.done = true
|
||||||
g.highestShown = 0
|
g.highestShown = 0
|
||||||
g.iter = nil
|
g.iter = nil
|
||||||
@@ -262,7 +268,7 @@ func (g *GridView) doUpdateItemCard(itemIdx int, card *GridViewItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if user has scrolled near the bottom, fetch more
|
// if user has scrolled near the bottom, fetch more
|
||||||
if !g.done && !g.fetching && itemIdx > g.lenItems()-10 {
|
if !g.done && g.fetchCancel == nil && itemIdx > g.lenItems()-10 {
|
||||||
g.fetchMoreItems(20)
|
g.fetchMoreItems(20)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,8 +283,10 @@ func (g *GridView) lenItems() int {
|
|||||||
func (g *GridView) fetchMoreItems(count int) {
|
func (g *GridView) fetchMoreItems(count int) {
|
||||||
if g.iter == nil {
|
if g.iter == nil {
|
||||||
g.done = true
|
g.done = true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
g.fetching = true
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
g.fetchCancel = cancel
|
||||||
go func() {
|
go func() {
|
||||||
// keep repeating the fetch task as long as the user
|
// keep repeating the fetch task as long as the user
|
||||||
// has scrolled near the bottom
|
// has scrolled near the bottom
|
||||||
@@ -286,19 +294,24 @@ func (g *GridView) fetchMoreItems(count int) {
|
|||||||
n := 0
|
n := 0
|
||||||
for !g.done && n < count {
|
for !g.done && n < count {
|
||||||
items := g.iter.NextN(batchFetchSize)
|
items := g.iter.NextN(batchFetchSize)
|
||||||
g.itemsMutex.Lock()
|
select {
|
||||||
g.items = append(g.items, items...)
|
case <-ctx.Done():
|
||||||
g.itemsMutex.Unlock()
|
return
|
||||||
if len(items) < batchFetchSize {
|
default:
|
||||||
g.done = true
|
g.itemsMutex.Lock()
|
||||||
}
|
g.items = append(g.items, items...)
|
||||||
n += len(items)
|
g.itemsMutex.Unlock()
|
||||||
if len(items) > 0 {
|
if len(items) < batchFetchSize {
|
||||||
g.Refresh()
|
g.done = true
|
||||||
|
}
|
||||||
|
n += len(items)
|
||||||
|
if len(items) > 0 {
|
||||||
|
g.Refresh()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.fetching = false
|
g.fetchCancel = nil
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user