From 1d0525fe41be36c52e74c0d64aaa2d80225820b4 Mon Sep 17 00:00:00 2001
From: dirwin31 <83434411+dirwin31@users.noreply.github.com>
Date: Sun, 1 Nov 2026 17:23:04 -0800
Subject: [PATCH] Keep the guided card open after choosing how the car connects
Choosing a USB cable or a tablet app switches the connection at once, which
counts as setup done, so the card closed under the person's finger and left
no way to change the choice. A choice made in the card now holds it open
until Done. In the guided setup the home card's button reads Change how your
car connects, so the way back is visible.
---
.../galaxy/tests/test_starport_guided.mjs | 24 +++++++++++++++++++
openpilot/starpilot/galaxy/web/js/starport.js | 10 ++++----
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/openpilot/starpilot/galaxy/tests/test_starport_guided.mjs b/openpilot/starpilot/galaxy/tests/test_starport_guided.mjs
index 14de96aff0..77240d19c1 100644
--- a/openpilot/starpilot/galaxy/tests/test_starport_guided.mjs
+++ b/openpilot/starpilot/galaxy/tests/test_starport_guided.mjs
@@ -213,3 +213,27 @@ console.log("StarPort guided setup: Bluetooth-first hint passed")
assert.match(StarPortGuidedSetup.template, //)
}
console.log("StarPort guided setup: steps, adapter and app choices, reopening and classic-only dropdowns passed")
+
+// Choosing a cable or an app finishes the setup at once; a choice made in the card must not close the card.
+{
+ const calls = []
+ const vm = { showSteps: false, carTypeLabels: { app: "App", usb: "Wired AA" },
+ saveCarType: (index, label) => calls.push(["type", label]), saveAdapter: (index, label) => calls.push(["adapter", label]),
+ saveApp: (index, label) => calls.push(["app", label]) }
+ StarPortPage.methods.chooseType.call(vm, "app")
+ assert.equal(vm.showSteps, true)
+ vm.showSteps = false
+ StarPortPage.methods.chooseApp.call(vm, "headunitpad")
+ assert.equal(vm.showSteps, true)
+ vm.showSteps = false
+ StarPortPage.methods.chooseAdapter.call(vm, "aawireless")
+ assert.equal(vm.showSteps, true)
+ assert.deepEqual(calls, [["type", "App"], ["app", "HeadunitPad"], ["adapter", "AAWireless"]])
+ // With the card held open by a choice, the finished setup is shown for editing with its Done button, not hidden.
+ const held = guidedState({ setup, runtime: { running: false, state: "idle", connection: "headunitpad" }, setupDone: true, editing: true, carType: "app", appModels, app: "HeadunitPad" })
+ assert.equal(held.show, true)
+ assert.equal(held.editing, true)
+ assert.equal(held.choices.find((choice) => choice.selected).key, "app")
+ assert.equal(held.apps.options.find((option) => option.selected).key, "headunitpad")
+}
+console.log("StarPort guided setup: a choice keeps the card open passed")
diff --git a/openpilot/starpilot/galaxy/web/js/starport.js b/openpilot/starpilot/galaxy/web/js/starport.js
index 86c368ff77..ca5cdd9667 100644
--- a/openpilot/starpilot/galaxy/web/js/starport.js
+++ b/openpilot/starpilot/galaxy/web/js/starport.js
@@ -772,9 +772,11 @@ export const StarPortPage = {
return stopping ? stopping.then((stopped) => stopped && next()) : next()
},
useCar(address) { return this.afterWaiting(() => this.control("select_receiver", { address })) },
- chooseType(key) { return this.saveCarType(0, this.carTypeLabels[key]) },
- chooseAdapter(key) { return this.saveAdapter(0, ADAPTER_MODELS[key]) },
- chooseApp(key) { return this.saveApp(0, HEAD_UNIT_APPS[key]) },
+ // Choosing a cable or an app makes the setup count as done at once, which would close the card under the person's finger.
+ // A choice made in the card keeps it open (its Done button closes it), so the choice can still be changed.
+ chooseType(key) { this.showSteps = true; return this.saveCarType(0, this.carTypeLabels[key]) },
+ chooseAdapter(key) { this.showSteps = true; return this.saveAdapter(0, ADAPTER_MODELS[key]) },
+ chooseApp(key) { this.showSteps = true; return this.saveApp(0, HEAD_UNIT_APPS[key]) },
useClassic() { return this.feed.setNewSetup(false) },
useGuided() { return this.feed.setNewSetup(true) },
saveCarType(index, value) {
@@ -1046,7 +1048,7 @@ export const StarPortPage = {
Customize Layout
+ {{ showSteps ? 'Hide Setup' : newSetup ? 'Change how your car connects' : 'Setup and Pairing' }}