diff --git a/openpilot/starpilot/galaxy/tests/test_onroad_layout.mjs b/openpilot/starpilot/galaxy/tests/test_onroad_layout.mjs index 3139b0720d..9037d0529c 100644 --- a/openpilot/starpilot/galaxy/tests/test_onroad_layout.mjs +++ b/openpilot/starpilot/galaxy/tests/test_onroad_layout.mjs @@ -489,6 +489,15 @@ assert.match(OnroadLayoutPage.template, /state\.profile === 'compact'" class="gx // One scene dropdown, grouped, with every scene exactly once. assert.deepEqual(vm.sceneGroups.map(group => group.label), ["Driving", "Conditional experimental", "Speed limit"]) assert.deepEqual(vm.sceneGroups.flatMap(group => group.scenes.map(scene => scene.id)).sort(), vm.scenes.map(scene => scene.id).sort()) +// The Small screen only offers scenes that look different there; a hidden pick falls back to Engaged. +vm.state.scene = "slc_display" +vm.selectProfile("compact") +assert.equal(vm.state.scene, "engaged") +const smallScenes = vm.sceneGroups.flatMap(group => group.scenes.map(scene => scene.id)) +for (const id of ["slc_pedal", "slc_retained", "slc_display"]) assert.ok(!smallScenes.includes(id), id) +assert.ok(smallScenes.includes("slc_unavailable") && smallScenes.includes("slc_disengaged")) +vm.selectProfile("large") +assert.equal(vm.sceneGroups.flatMap(group => group.scenes).length, vm.scenes.length) assert.match(OnroadLayoutPage.template, / id) diff --git a/openpilot/starpilot/galaxy/web/js/onroad-layout.js b/openpilot/starpilot/galaxy/web/js/onroad-layout.js index c963aba85e..f4287ebcd7 100644 --- a/openpilot/starpilot/galaxy/web/js/onroad-layout.js +++ b/openpilot/starpilot/galaxy/web/js/onroad-layout.js @@ -375,9 +375,14 @@ export const OnroadLayoutPage = { const grow = this.state.draft.speedSourcesCard === true ? cruise.sourcesExtent.card : cruise.sourcesExtent.inline return { ...profile, widgets: { ...profile.widgets, cruise_limits: { ...cruise, height: cruise.height + grow } } } }, + // Only the scenes that look different on this screen. + availableScenes() { + const screen = this.projection ? "projection" : this.state.profile + return this.scenes.filter(scene => !scene.hiddenOn?.includes(screen)) + }, sceneGroups() { return [["Driving", scene => !/^(cem|slc)_/.test(scene.id)], ["Conditional experimental", scene => scene.id.startsWith("cem_")], - ["Speed limit", scene => scene.id.startsWith("slc_")]].map(([label, test]) => ({ label, scenes: this.scenes.filter(test) })) + ["Speed limit", scene => scene.id.startsWith("slc_")]].map(([label, test]) => ({ label, scenes: this.availableScenes.filter(test) })) }, layout() { return this.state.draft?.layouts[this.state.profile] }, projectionHasPipWidget() { @@ -723,6 +728,7 @@ export const OnroadLayoutPage = { this.state.profile = profile this.state.selected = Object.keys(this.profile.widgets)[0] || null this.state.placementError = "" + if (!this.availableScenes.some(scene => scene.id === this.state.scene)) this.state.scene = "engaged" }, changePosition(id, x, y) { if (!this.editable) return