Merge branch 'areas-meshguide-sync'

This commit is contained in:
dborup
2026-07-27 08:16:55 +02:00
2 changed files with 18 additions and 2 deletions
+6 -2
View File
@@ -311,8 +311,12 @@ window.ObserverDetailNaiveBanner = {
data: {
labels: cached.metrics.map(function(m) { return new Date(m.timestamp).toLocaleString(); }),
datasets: [
{ label: 'SNR (dB)', data: cached.metrics.map(function(m) { return m.snr; }), borderColor: 'var(--accent)', yAxisID: 'y', tension: 0.2 },
{ label: 'Heard (s ago)', data: cached.metrics.map(function(m) { return m.heardSecsAgo; }), borderColor: 'var(--status-yellow)', yAxisID: 'y1', tension: 0.2 },
// Canvas can't resolve CSS var() as a strokeStyle -- Chart.js
// silently falls back to black for both lines if given one
// (bug: both lines rendered black). CHART_COLORS is this page's
// established literal-hex palette (see the 4 main charts below).
{ label: 'SNR (dB)', data: cached.metrics.map(function(m) { return m.snr; }), borderColor: CHART_COLORS[0], backgroundColor: CHART_COLORS[0] + '20', yAxisID: 'y', tension: 0.2 },
{ label: 'Heard (s ago)', data: cached.metrics.map(function(m) { return m.heardSecsAgo; }), borderColor: CHART_COLORS[6], backgroundColor: CHART_COLORS[6] + '20', yAxisID: 'y1', tension: 0.2 },
],
},
options: {
+12
View File
@@ -305,6 +305,18 @@ test('clicking a cached sparkline opens a modal with a dual-axis SNR/heard-secs-
assert.strictEqual(lastChartConfig.data.datasets[0].yAxisID, 'y');
assert.strictEqual(lastChartConfig.data.datasets[1].yAxisID, 'y1');
assert.ok(lastChartConfig.options.scales.y1.title.text.toLowerCase().includes('heard'), 'expected the second axis labeled for heard_secs_ago');
// Regression: canvas can't resolve CSS var() as a strokeStyle, so a raw
// 'var(--x)' string silently renders as Chart.js's default black --
// both lines looked identical/black in production before this was caught.
// Line colors must be resolved literal values (this page's CHART_COLORS
// palette), and the two datasets must be visually distinct.
const c0 = lastChartConfig.data.datasets[0].borderColor;
const c1 = lastChartConfig.data.datasets[1].borderColor;
assert.ok(!/^var\(/.test(c0), `dataset[0].borderColor must not be a CSS var() reference, got ${c0}`);
assert.ok(!/^var\(/.test(c1), `dataset[1].borderColor must not be a CSS var() reference, got ${c1}`);
assert.ok(/^#[0-9a-f]{6}$/i.test(c0), `dataset[0].borderColor must be a resolved hex color, got ${c0}`);
assert.ok(/^#[0-9a-f]{6}$/i.test(c1), `dataset[1].borderColor must be a resolved hex color, got ${c1}`);
assert.notStrictEqual(c0, c1, 'SNR and Heard(s ago) lines must be visually distinct colors');
});
test('openNeighborSnrModal is a no-op for a pubkey with no cached data', () => {