perf(kiosk): window the album grid so only visible cards mount

cc
This commit is contained in:
vicrodh committed 2026-07-12 12:43:56 -06:00
1 parent 26f9e3e1a2
commit 8cdf26cd34
1 file changed
+24 -11
+24 -11
View File
@@ -1,9 +1,13 @@
// KioskAlbumGrid — a lightweight wrapping grid of KioskCards for the kiosk
// Search/Library album tabs (2.0.2 frente #3). Absolute-positioned cells
// (Math.mod/Math.floor columns, the same idiom the desktop grids use) inside a
// vertical Flickable; card width derives from the grid width so it reflows.
// Binds `[AlbumCardItem]` directly so the artwork pipeline's in-place pushes
// land on the cards.
// KioskAlbumGrid — lightweight wrapping grid of KioskCards for the kiosk
// Search/Library album tabs (2.0.2 frente #3). Absolute-positioned cells inside
// a vertical Flickable; card width derives from the grid width so it reflows.
//
// WINDOWED (in-window pattern, mirrors the desktop Carousel): the `for` creates
// only cheap empty positioned slots for every album, but the heavy KioskCard
// (Image + text) mounts ONLY for slots whose band intersects the viewport. A
// plain full grid mounted every card at once and spiked CPU on entry — a Pi
// can't afford that. Binds `[AlbumCardItem]` so artwork pushes land on the cards.
import { Theme } from "../foundation/semantic-colors.slint";
import { AlbumCardItem } from "../state.slint";
import { KioskCard } from "KioskCard.slint";
@@ -22,13 +26,22 @@ export component KioskAlbumGrid inherits Flickable {
viewport-height: root.rows * (root.card-h + root.gap) + root.pad;
Rectangle {
for album[i] in root.albums: KioskCard {
for album[i] in root.albums: slot := Rectangle {
x: root.pad + Math.mod(i, root.columns) * (root.card-w + root.gap);
y: root.pad + Math.floor(i / root.columns) * (root.card-h + root.gap);
art-size: root.card-w;
album: album;
clicked(id) => {
root.open(id);
width: root.card-w;
height: root.card-h;
// Visible band (content coords) is [-viewport-y, -viewport-y+height];
// 240px margin keeps a card mounted just off-screen for smooth scroll.
property <bool> in-window: (self.y + self.height >= -root.viewport-y - 240px)
&& (self.y <= -root.viewport-y + root.height + 240px);
if slot.in-window: KioskCard {
width: root.card-w;
art-size: root.card-w;
album: album;
clicked(id) => {
root.open(id);
}
}
}
}