perf(slint): virtualize playlist track list + lighter artwork

Large playlists (2000+ tracks) were sluggish. Addressed the root
causes; this strategy is reusable for the library / mixtapes / tracks
views.

  - Virtualization: the track list is now a ListView (only visible
    rows are instantiated) instead of a Flickable with a for over all
    rows. The header + column header are pinned above it.
  - Smaller images: track rows use ImageSet::smallest() (new) instead
    of best() — they are 40px thumbnails, so best() was downloading
    mega/large covers.
  - Per-target decode size: row thumbnails decode to 96px instead of
    the 264px card size, so a 2000-row model holds ~75MB of pixels
    rather than ~550MB.
  - Track-number column widened to fit 4-digit positions.
  - Back-to-top button: appears once scrolled past one viewport
    (bottom-right), scrolls the list home. A shared rule for big lists.
  - Custom-artwork buttons only show on cover hover.

cc
This commit is contained in:
vicrodh committed 2026-05-22 09:27:45 -06:00
1 parent 4fe034d86b
commit 85223b03ff
6 files changed
+110 -30

No files matched your search

+11
View File
@@ -182,6 +182,17 @@ impl ImageSet {
.or(self.thumbnail.as_ref())
.or(self.small.as_ref())
}
/// The smallest available variant — for list-row thumbnails, where
/// `best()` (mega/large) would needlessly download huge images.
pub fn smallest(&self) -> Option<&String> {
self.small
.as_ref()
.or(self.thumbnail.as_ref())
.or(self.large.as_ref())
.or(self.extralarge.as_ref())
.or(self.mega.as_ref())
}
}
// ============ Core Media Types ============