debounce tracklist row rendering when fast scrolling

This commit is contained in:
Drew Weymouth
2025-02-08 08:34:40 -03:00
parent c60727f92a
commit 89012a8fe8
2 changed files with 88 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
package util
import (
"time"
)
type EventCounter struct {
buf []time.Time
ptr int
}
func NewEventCounter(maxN int) *EventCounter {
buffer := make([]time.Time, maxN)
return &EventCounter{
buf: buffer,
}
}
func (e *EventCounter) Add() {
e.buf[e.ptr] = time.Now()
e.ptr = (e.ptr + 1) % len(e.buf)
}
func (e *EventCounter) NumEventsSince(t time.Time) int {
i := e.ptr - 1
count := 0
for {
if i < 0 {
i = len(e.buf) - 1
}
if !e.buf[i].IsZero() && e.buf[i].After(t) {
count++
} else {
break
}
if count == len(e.buf) {
break
}
i--
}
return count
}
+45
View File
@@ -5,6 +5,7 @@ import (
"image"
"strconv"
"sync"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
@@ -15,10 +16,31 @@ import (
"fyne.io/fyne/v2/widget"
ttwidget "github.com/dweymouth/fyne-tooltip/widget"
"github.com/dweymouth/supersonic/backend"
"github.com/dweymouth/supersonic/backend/mediaprovider"
myTheme "github.com/dweymouth/supersonic/ui/theme"
"github.com/dweymouth/supersonic/ui/util"
)
var (
tracklistUpdateCounter = util.NewEventCounter(30)
emptyTrack = util.TrackListModel{
Item: &mediaprovider.Track{
ID: "dummy",
Title: "—",
ArtistIDs: []string{"—"},
ArtistNames: []string{"—"},
Album: "—",
Genres: []string{"—"},
ComposerNames: []string{"—"},
ComposerIDs: []string{"—"},
Comment: "—",
FilePath: "—",
ContentType: "—",
},
}
)
const tracklistThumbnailSize = 48
type TracklistColumn struct {
@@ -151,6 +173,9 @@ type tracklistRowBase struct {
isFavorite bool
playCount int
nextUpdateModel *util.TrackListModel
nextUpdateRowNum int
num *widget.Label
name *ttwidget.RichText
artist *MultiHyperlink
@@ -318,6 +343,25 @@ func (t *tracklistRowBase) TrackID() string {
}
func (t *tracklistRowBase) Update(tm *util.TrackListModel, rowNum int) {
if tracklistUpdateCounter.NumEventsSince(time.Now().Add(-150*time.Millisecond)) > 20 {
t.doUpdate(&emptyTrack, 1)
if t.nextUpdateModel == nil {
go fyne.Do(func() {
if t.nextUpdateModel != nil {
t.doUpdate(t.nextUpdateModel, t.nextUpdateRowNum)
}
t.nextUpdateModel = nil
})
}
t.nextUpdateModel = tm
t.nextUpdateRowNum = rowNum
} else {
t.nextUpdateModel = nil
t.doUpdate(tm, rowNum)
}
}
func (t *tracklistRowBase) doUpdate(tm *util.TrackListModel, rowNum int) {
changed := false
if tm.Selected != t.Selected {
t.Selected = tm.Selected
@@ -415,6 +459,7 @@ func (t *tracklistRowBase) Update(tm *util.TrackListModel, rowNum int) {
}
if changed {
tracklistUpdateCounter.Add()
t.Refresh()
}
}