fix race condition with async image fetches

This commit is contained in:
Drew Weymouth
2022-12-17 18:12:37 -08:00
parent a85d377a82
commit 78050f8b43
3 changed files with 35 additions and 9 deletions
+8 -1
View File
@@ -1,6 +1,7 @@
package ui
import (
"context"
"image"
"log"
@@ -39,9 +40,15 @@ type AlbumCard struct {
albumID string
title *widget.Label
artist *widget.Label
Cover *TappableImage
container *fyne.Container
// updated by AlbumGrid
Cover *TappableImage
// these fields are used by AlbumGrid to track async update tasks
PrevAlbumID string
ImgLoadCancel context.CancelFunc
OnTapped func()
}
+23 -4
View File
@@ -1,6 +1,7 @@
package ui
import (
"context"
"gomuse/backend"
"fyne.io/fyne/v2"
@@ -41,15 +42,33 @@ func NewAlbumGrid(iter backend.AlbumIterator, pm *backend.PlaybackManager, im *b
// update func
func(itemID int, obj fyne.CanvasObject) {
ac := obj.(*AlbumCard)
ac.Update(ag.albums[itemID])
album := ag.albums[itemID]
if ac.PrevAlbumID == album.ID {
// nothing to do
return
}
ac.Update(album)
ac.PrevAlbumID = album.ID
// TODO: set image to a placeholder before spinning off async fetch
go func() {
i, err := im.GetAlbumThumbnail(ag.albums[itemID].ID)
// cancel any previous image fetch
if ac.ImgLoadCancel != nil {
ac.ImgLoadCancel()
ac.ImgLoadCancel = nil
}
ctx, cancel := context.WithCancel(context.Background())
go func(ctx context.Context) {
i, err := im.GetAlbumThumbnail(album.ID)
select {
case <-ctx.Done():
return
default:
if err == nil {
ac.Cover.SetImage(i)
ac.Refresh()
}
}()
}
}(ctx)
ac.ImgLoadCancel = cancel
// TODO: remove magic number 10
if !ag.done && !ag.fetching && itemID > len(ag.albums)-10 {
+1 -1
View File
@@ -37,7 +37,7 @@ func NewNowPlayingCard() *NowPlayingCard {
n.cover.SetMinSize(fyne.NewSize(100, 100))
n.cover.FillMode = canvas.ImageFillContain
n.c = container.NewBorder(nil, nil, n.cover, nil, container.New(&layout.VboxCustomPadding{-10}, n.trackName, n.artistName, n.albumName))
n.c = container.NewBorder(nil, nil, n.cover, nil, container.New(&layout.VboxCustomPadding{ExtraPad: -10}, n.trackName, n.artistName, n.albumName))
return n
}