feat(qt): kiosk profile release hardening

Integrate the Kiosk profile hardening round: 12 dedicated Kiosk views plus
22 shared opt-in hosts, shared navigation history with Back/Forward, Albums
as the default library tab, native paged Local Library (artists/tracks),
lightweight MyQBZ grid and detail, Ephemeral lifecycle, bounded lists and
artwork sized to the physical frame, static skeletons, 64px transport bar,
Settings touch reflow and a persistent Immersive exit.

Desktop keeps its prior behavior: every shared component defaults to the
desktop path and only opts into Kiosk behavior through explicit properties
(origin-relative ScrollMemory, viewport-bounded artwork requests).

Regression coverage: kiosk navigation and artwork Node tests added to the
runtime gate, scroll-origin fixtures for fixed and grouped rows, i18n
strings for all eight locales.

Verified by 750 release tests, six QML audits, Kiosk smokes at 800x480 and
1280x800 and a Desktop A/B with seven pixel-identical captures.

cc
This commit is contained in:
vicrodh committed 2026-09-07 08:23:11 -06:00
1 parent c1c463dc94
commit b1dba198c9
139 files changed
+9590 -4973

No files matched your search

+8 -4
View File
@@ -74,6 +74,8 @@ import "../shell"
import "../theme"
Rectangle {
property bool kioskHost: false
id: root
property var item: ({})
@@ -450,7 +452,7 @@ Rectangle {
? theme.alphaTier(10) : (theme.isDark ? "#1affffff" : "#1a000000")
width: parent ? parent.width : 0
height: 50
height: kioskHost ? (showReorder ? 88 : 64) : 50
radius: 8
// Hover fill is OFF on a dead row (views/purchases/PurchaseListRow.qml
// does the same on its unavailable rows): a row that lights up under the
@@ -523,7 +525,7 @@ Rectangle {
// these rows lines up with them by construction. The title column's
// arithmetic lives there too (`titleWidth`) — the header asks the same
// function the same question and gets the same answer.
TrackCols { id: cols }
TrackCols { id: cols; kioskHost: root.kioskHost }
/// One chevron of the reorder gutter. Declared at the file's top level
/// (an inline component must be — the same rule TrackListHeader's
@@ -626,6 +628,7 @@ Rectangle {
spacing: 0
ReorderChevron {
id: chevUp
height: root.kioskHost ? 44 : 18
width: cols.colReorder
glyph: "chevron-up"
armed: root.canMoveUp
@@ -633,6 +636,7 @@ Rectangle {
}
ReorderChevron {
id: chevDown
height: root.kioskHost ? 44 : 18
width: cols.colReorder
glyph: "chevron-down"
armed: root.canMoveDown
@@ -894,7 +898,7 @@ Rectangle {
// to stop reading as live content.
color: (root.pulledDead || root.playBlocked)
? theme.textMuted : theme.textPrimary
font.pixelSize: 14
font.pixelSize: root.kioskHost ? 16 : 14
font.weight: theme.weightMedium
elide: Text.ElideRight
width: Math.min(implicitWidth, parent.parent.width
@@ -1192,7 +1196,7 @@ Rectangle {
Loader {
id: rowMenuLoader
active: false
sourceComponent: CardMenu {
sourceComponent: CardMenu { kioskHost: root.kioskHost;
menuWidth: 224
entries: root.menuModel()
onPicked: function (a) { root.menuAction(a) }