perf(ui): sort History once per redraw, drop duplicate jobs refreshes
Stage 4 of the GUI layout plan (F11, F12). History: the cell callback copied and sorted the whole event list on every call, and a full-window Refresh issues one call per visible cell — 126 sorts of a 300-element slice per redraw, measured. The sorted snapshot now lives in `rows`, refilled by `resort()` at build time, on a sort toggle, and from `refresh()`. The length callback moves to `len(rows)` with it: cells and the row count have to read the same slice, which was only incidentally true while each cell re-derived the order for itself. The column captions become a package-level array instead of a slice reallocated per header update, and the per-cell `TextStyle`/`Refresh()` pair goes — the template already carries the zero style and `SetText` refreshes. Jobs: `refreshView()` already re-reads the service snapshot and refreshes the list, so the six `list.Refresh()` calls that preceded it, and the duplicate `syncFromService()` in the pause handler, were redundant. The folder filter's early-return path never reaches `refreshView()`, so its `list.Refresh()` moves into that branch rather than being deleted. Both changes carry regression tests, each verified to fail against the behaviour it guards: `TestHistorySortToggleKeepsRowsInSync` for the cache-versus-length hazard, `TestToolbarButtonRedrawsRowAndDetails` for the handlers that now rely on `refreshView` alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+3
-8
@@ -166,12 +166,14 @@ func newJobsView(w fyne.Window, svc *app.Service) (fyne.CanvasObject, func()) {
|
||||
}
|
||||
selectedFolder = value
|
||||
filteredJobs = filteredJobIndexes(jobs, selectedFolder)
|
||||
list.Refresh()
|
||||
if len(filteredJobs) == 0 {
|
||||
// The "No folder" filter is intentionally allowed to be empty. It is a
|
||||
// real filter choice, not an error state, so the selection is cleared.
|
||||
// This path returns without reaching refreshView(), so it is the one
|
||||
// place the list has to be redrawn by hand.
|
||||
selected = -1
|
||||
updateDetails(-1)
|
||||
list.Refresh()
|
||||
return
|
||||
}
|
||||
selected = filteredJobs[0]
|
||||
@@ -223,7 +225,6 @@ func newJobsView(w fyne.Window, svc *app.Service) (fyne.CanvasObject, func()) {
|
||||
}
|
||||
selected = indexOfID(jobs, created.ID)
|
||||
filteredJobs = filteredJobIndexes(jobs, selectedFolder)
|
||||
list.Refresh()
|
||||
list.Select(app.DisplayIndex(filteredJobs, selected))
|
||||
refreshView()
|
||||
})
|
||||
@@ -241,7 +242,6 @@ func newJobsView(w fyne.Window, svc *app.Service) (fyne.CanvasObject, func()) {
|
||||
syncFromService()
|
||||
folderSelect.Options = folderOptions(jobs)
|
||||
folderSelect.Refresh()
|
||||
list.Refresh()
|
||||
refreshView()
|
||||
})
|
||||
})
|
||||
@@ -255,7 +255,6 @@ func newJobsView(w fyne.Window, svc *app.Service) (fyne.CanvasObject, func()) {
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
list.Refresh()
|
||||
refreshView()
|
||||
})
|
||||
|
||||
@@ -287,7 +286,6 @@ func newJobsView(w fyne.Window, svc *app.Service) (fyne.CanvasObject, func()) {
|
||||
stopAllButton.SetText("Disable auto")
|
||||
stopAllButton.SetIcon(theme.MediaPauseIcon())
|
||||
}
|
||||
list.Refresh()
|
||||
refreshView()
|
||||
}
|
||||
pauseButton := widget.NewButtonWithIcon("Pause", theme.MediaPauseIcon(), func() {
|
||||
@@ -299,8 +297,6 @@ func newJobsView(w fyne.Window, svc *app.Service) (fyne.CanvasObject, func()) {
|
||||
dialog.ShowError(err, w)
|
||||
return
|
||||
}
|
||||
syncFromService()
|
||||
list.Refresh()
|
||||
refreshView()
|
||||
})
|
||||
deleteButton := widget.NewButtonWithIcon("Delete", theme.DeleteIcon(), func() {
|
||||
@@ -332,7 +328,6 @@ func newJobsView(w fyne.Window, svc *app.Service) (fyne.CanvasObject, func()) {
|
||||
} else {
|
||||
selected = filteredJobs[0]
|
||||
}
|
||||
list.Refresh()
|
||||
if selected >= 0 {
|
||||
list.Select(app.DisplayIndex(filteredJobs, selected))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user