From 8daabf71f984db1d5112917d5ec4aca153915772 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Fri, 30 Oct 2026 12:02:00 -0500 Subject: [PATCH] Keep live plots refresh cadence and layout steady --- openpilot/starpilot/galaxy/tests/test_plots.mjs | 13 +++++++++++++ openpilot/starpilot/galaxy/web/css/galaxy.css | 2 ++ openpilot/starpilot/galaxy/web/js/plots.js | 4 ++-- prebuilt.json | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/openpilot/starpilot/galaxy/tests/test_plots.mjs b/openpilot/starpilot/galaxy/tests/test_plots.mjs index 772e40c5b7..7eb06c31d7 100644 --- a/openpilot/starpilot/galaxy/tests/test_plots.mjs +++ b/openpilot/starpilot/galaxy/tests/test_plots.mjs @@ -93,6 +93,19 @@ await live.reply(3, payload(3)) assert.equal(live.states.at(-1).status, 'idle') assert.equal(live.states.at(-1).history.length, 0) +const delayed = fixture() +delayed.feed.start() +delayed.advance(500) +await delayed.reply(0, payload(1)) +delayed.advance(250) +assert.equal(delayed.requests.length, 2, 'HTTP latency must not be added to the polling interval') +delayed.advance(500) +await delayed.reply(1, payload(2)) +assert.equal(delayed.states.at(-1).status, 'current') +assert.ok(!delayed.states.some(state => state.status === 'stale'), 'healthy delayed responses must not flicker stale') +delayed.feed.stop() +assert.match(PlotsPage.template, /class="gx-plots__status" role="status"/) + const stale = fixture() stale.feed.start() await stale.reply(0, payload(1)) diff --git a/openpilot/starpilot/galaxy/web/css/galaxy.css b/openpilot/starpilot/galaxy/web/css/galaxy.css index f6e3c3e1ff..e11a4fd8c0 100644 --- a/openpilot/starpilot/galaxy/web/css/galaxy.css +++ b/openpilot/starpilot/galaxy/web/css/galaxy.css @@ -741,6 +741,8 @@ ul { list-style: none; margin: 0; padding: 0; } .gx-card-grid .gx-card { margin-bottom: 0; } .gx-plots__toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: .75rem; margin: 1rem 0; } +.gx-plots__status { flex: 0 0 100%; min-height: 2.8em; display: flex; align-items: center; } +.gx-plots__hint { min-height: 2.8em; } .gx-plots__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 28rem), 1fr)); gap: 1rem; } .gx-plots__panel { min-width: 0; --card-inset: clamp(.85rem, 2vw, 1.25rem); padding: var(--card-inset); } .gx-plots__panel svg { display: block; width: 100%; height: auto; min-height: 8rem; background: rgba(127,127,127,.06); border-radius: .6rem; } diff --git a/openpilot/starpilot/galaxy/web/js/plots.js b/openpilot/starpilot/galaxy/web/js/plots.js index a1db9b583d..62a3f38d1a 100644 --- a/openpilot/starpilot/galaxy/web/js/plots.js +++ b/openpilot/starpilot/galaxy/web/js/plots.js @@ -164,7 +164,7 @@ export class PlotsFeed { if (generation === this.generation) { if (this.deadline !== null) this.cancel(this.deadline); this.deadline = null this.request = null - if (this.active && !this.paused) this.timer = this.later(() => { this.timer = null; this.load() }, POLL_MS) + if (this.active && !this.paused) this.timer = this.later(() => { this.timer = null; this.load() }, Math.max(0, POLL_MS - (this.now() - start))) } } } @@ -228,7 +228,7 @@ export const PlotsPage = {