diff --git a/openpilot/starpilot/galaxy/developer_settings.py b/openpilot/starpilot/galaxy/developer_settings.py index a04fa617db..b53004c5d4 100644 --- a/openpilot/starpilot/galaxy/developer_settings.py +++ b/openpilot/starpilot/galaxy/developer_settings.py @@ -55,15 +55,15 @@ class DeveloperSettingsOwner: new_setup_on = new_setup.enabled() held = "Park the vehicle to change this setting." rows = [FeatureRow(STARPORT_HEADING_KEY, "StarPort", "", available=False), - FeatureRow(STARPORT_NEW_SETUP_KEY, "StarPort: New pairing experience", "On" if new_setup_on else "Off", + FeatureRow(STARPORT_NEW_SETUP_KEY, "New pairing experience", "On" if new_setup_on else "Off", b"1" if new_setup_on else b"0", ("Off", "On"), available=parked, reason=STARPORT_NEW_SETUP_DESCRIPTION if parked else held, default_value="On")] status = self._starport_status() if status is not None: enabled, hevc = bool(status.get("dedicated_wifi_interface")), bool(status.get("allow_hevc")) - rows.append(FeatureRow(STARPORT_WIFI_KEY, "StarPort: Stay on Wi-Fi", "On" if enabled else "Off", b"1" if enabled else b"0", + rows.append(FeatureRow(STARPORT_WIFI_KEY, "Stay on Wi-Fi", "On" if enabled else "Off", b"1" if enabled else b"0", ("Off", "On"), available=parked, reason=STARPORT_WIFI_DESCRIPTION if parked else held, default_value="On")) - rows.append(FeatureRow(STARPORT_HEVC_KEY, "StarPort: Allow H.265 video", "On" if hevc else "Off", b"1" if hevc else b"0", + rows.append(FeatureRow(STARPORT_HEVC_KEY, "Allow H.265 video", "On" if hevc else "Off", b"1" if hevc else b"0", ("Off", "On"), available=parked, reason=STARPORT_HEVC_DESCRIPTION if parked else held, default_value="Off")) return tuple(rows) diff --git a/openpilot/starpilot/galaxy/tests/test_offroad_configuration_pages.py b/openpilot/starpilot/galaxy/tests/test_offroad_configuration_pages.py index ae1d399af0..ca748938c6 100644 --- a/openpilot/starpilot/galaxy/tests/test_offroad_configuration_pages.py +++ b/openpilot/starpilot/galaxy/tests/test_offroad_configuration_pages.py @@ -58,7 +58,7 @@ class TestOffroadConfigurationPages(unittest.TestCase): expected = saved[name] if name == 'developer': # gated by Park, not by the vehicle - expected, current = ([row for row in rows if row[0] != 'StarPort: New pairing experience'] for rows in (expected, current)) + expected, current = ([row for row in rows if row[0] != 'New pairing experience'] for rows in (expected, current)) self.assertEqual([row[0] for row in expected], ['Use VOACC']) self.assertEqual([row[1] for row in expected], [False]) self.assertEqual([row[1] for row in current], [True]) diff --git a/openpilot/starpilot/galaxy/tests/test_settings.mjs b/openpilot/starpilot/galaxy/tests/test_settings.mjs index c76112702c..889073a827 100644 --- a/openpilot/starpilot/galaxy/tests/test_settings.mjs +++ b/openpilot/starpilot/galaxy/tests/test_settings.mjs @@ -160,6 +160,17 @@ const filtered = SettingsPage.computed.visibleRows.call({ state: { query: "lane" ] } } }) assert.deepEqual(filtered.map(({ index }) => index), [1]) // Filter keeps the original owner row index. +const developerRows = [{ label: "Use VOACC", value: "Off", reason: "" }, { label: "StarPort", value: "", reason: "", heading: true }, + { label: "Stay on Wi-Fi", value: "On", reason: "" }, { label: "Allow H.265 video", value: "Off", reason: "" }] +const cardsFor = (query) => { + const view = { state: { query, data: { rows: developerRows } }, initialPage: "developer", activeSection: {} } + view.visibleRows = SettingsPage.computed.visibleRows.call(view) + return SettingsPage.computed.rowCards.call(view).map(({ title, entries }) => [title, entries.map(({ index }) => index)]) +} +assert.deepEqual(cardsFor(""), [["", [0]], ["StarPort", [2, 3]]], "a heading row starts its own card") +assert.deepEqual(cardsFor("h.265"), [["", []], ["StarPort", [3]]], "search keeps a row in its card when the heading is filtered out") +assert.deepEqual(cardsFor("voacc"), [["", [0]]], "an emptied card is not shown") + const conditional = fixture() conditional.feed.start() await conditional.reply(0, { ...lane, page: "hub", rows: [{ label: "Conditional driving modes", page: "conditional", diff --git a/openpilot/starpilot/galaxy/web/js/settings.js b/openpilot/starpilot/galaxy/web/js/settings.js index 1758a4189d..3c0577c9e7 100644 --- a/openpilot/starpilot/galaxy/web/js/settings.js +++ b/openpilot/starpilot/galaxy/web/js/settings.js @@ -304,6 +304,14 @@ export const SettingsPage = { }).filter(({ row }) => !needle || `${row.label} ${row.value} ${row.reason}`.toLocaleLowerCase().includes(needle)) }, + // A heading row starts its own card; the rows after it belong to that card even when search hides the heading. + rowCards() { + const titles = [] + const owner = (this.state.data?.rows || []).map((row) => (row.heading ? titles.push(row.label) : titles.length)) + const cards = [{ title: "", entries: [] }, ...titles.map((title) => ({ title, entries: [] }))] + for (const entry of this.visibleRows) if (!entry.row.heading) cards[owner[entry.index] || 0].entries.push(entry) + return cards.filter((card, index) => !index || card.entries.length) + }, }, watch: { "state.pending"() { this.flushSoundChoices() }, @@ -449,15 +457,16 @@ export const SettingsPage = {