From c8e629571b0305eb998bbf9f4a8a7e24c6c7485e Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Tue, 10 Nov 2026 13:05:09 -0600 Subject: [PATCH] Show every recorded model on the Galaxy dashboard --- openpilot/starpilot/galaxy/tests/test_home.mjs | 13 +++++++++++++ openpilot/starpilot/galaxy/web/js/home.js | 7 ++++--- prebuilt.json | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/openpilot/starpilot/galaxy/tests/test_home.mjs b/openpilot/starpilot/galaxy/tests/test_home.mjs index d73969cfb5..d45095e386 100644 --- a/openpilot/starpilot/galaxy/tests/test_home.mjs +++ b/openpilot/starpilot/galaxy/tests/test_home.mjs @@ -114,6 +114,19 @@ const imperial = driveSummary({ status: "ready", data: { ...drives, isMetric: fa assert.equal(imperial.last.distance, "7.5 mi") assert.equal(imperial.week.days[6].distance, "7.5 mi") assert.equal(imperial.records[0].display, "7.5 mi") +const modelHistory = ["ResFit", "Train Track", "Mountain Dew v3", "Light Speed 2", "Polaris Vega", + ...Array.from({ length: 12 }, (_, index) => `Recorded model ${index + 6}`)] + .map((name, index) => ({ name, distanceMeters: (17 - index) * 1000, durationSeconds: 60, drives: 1 })) +const allModels = driveSummary({ status: "ready", data: { ...drives, models: modelHistory } }) +assert.deepEqual(allModels.models.map(model => model.name), modelHistory.map(model => model.name), + "Recorded Models must include the full history, including lower-mileage recent models") +assert.equal(new Set(allModels.models.map(model => model.color)).size, modelHistory.length) +assert.ok(allModels.models.every(model => model.color && model.distance && model.drives === 1)) +assert.ok(allModels.models.every(model => allModels.modelStyle.includes(model.color))) +assert.doesNotMatch(allModels.modelStyle, /undefined|NaN/) +assert.ok(Math.abs(Number(/([\d.]+)%\)$/.exec(allModels.modelStyle)[1]) - 100) < 1e-9) +assert.equal(driveSummary({ status: "ready", data: { ...drives, + models: modelHistory.map(model => ({ ...model, distanceMeters: 0 })) } }).modelStyle, "") const previousTZ = process.env.TZ process.env.TZ = "America/Chicago" const midnightDrive = { ...route, startTime: Date.parse("2026-09-27T04:30:00Z") / 1000, diff --git a/openpilot/starpilot/galaxy/web/js/home.js b/openpilot/starpilot/galaxy/web/js/home.js index 5bb5199027..626c4bef2e 100644 --- a/openpilot/starpilot/galaxy/web/js/home.js +++ b/openpilot/starpilot/galaxy/web/js/home.js @@ -55,13 +55,14 @@ export function driveSummary(feed) { const last = data.lastDrive const analysisStatus = () => ({ analysisLabel: "Incomplete recording" }) const maximum = Math.max(1, ...data.week.days.map((day) => day.distanceMeters ?? 0)) - const models = data.models.slice(0, 3) + const models = data.models const modelTotal = models.reduce((sum, model) => sum + (model.distanceMeters ?? 0), 0) const colors = ["#5ec8c8", "#8b6cc5", "#d4a060"] + const modelColor = (index) => colors[index] || `hsl(${(index * 137.508) % 360} 55% 65%)` let offset = 0 const stops = models.map((model, index) => { const next = offset + (modelTotal > 0 ? (model.distanceMeters ?? 0) / modelTotal * 100 : 0) - const stop = `${colors[index]} ${offset}% ${next}%` + const stop = `${modelColor(index)} ${offset}% ${next}%` offset = next return stop }) @@ -86,7 +87,7 @@ export function driveSummary(feed) { duration: duration(drive.durationSeconds), engaged: percent(drive.engagedPercent), aol: percent(drive.aolPercent), model: shown(drive.model) })), records: data.records.map((record) => ({ id: record.id, label: record.label, display: recordDisplay(record, isMetric) })), models: models.map((model, index) => ({ name: model.name, distance: distance(model.distanceMeters, isMetric), - drives: model.drives, color: colors[index] })), + drives: model.drives, color: modelColor(index) })), modelStyle: modelTotal > 0 ? `background:conic-gradient(${stops.join(",")})` : "", } } diff --git a/prebuilt.json b/prebuilt.json index c91094aef0..8a9733b63d 100644 --- a/prebuilt.json +++ b/prebuilt.json @@ -1 +1 @@ -{"protected_inventory_sha256": "821c86f828fe4016bf78135cffa8bfb6970b6cc9fca6112ac6e2768d298961b7", "schema_version": 1} +{"protected_inventory_sha256": "00fe0f0ecfd0de587cb68916e7a338cf475d957297206a078d5b6f59590328f9", "schema_version": 1}