From f3caf42be4c2353de2ff864985dceec77f3ffd7f Mon Sep 17 00:00:00 2001 From: Kpa-clawbot Date: Fri, 3 Apr 2026 21:09:02 -0700 Subject: [PATCH] feat: show transport badge in live packet feed (#551) ## Summary Show the transport badge ("T") in the live packet feed, matching the packets table (#337). ## Changes - Add `transportBadge(pkt.route_type)` to all 4 feed rendering paths in `live.js`: - Grouped feed items (initial history load) - `addFeedItemDOM()` (VCR replay) - Dedup new feed items (live WebSocket updates) - Node detail panel recent packets list - Uses existing `transportBadge()` from `app.js` and `.badge-transport` CSS from `style.css` ## Testing - 2 new source-level assertions in `test-live.js` verifying `transportBadge()` calls exist - All existing tests pass (67 passed in test-live.js, no new failures) Fixes #338 Co-authored-by: you --- public/live.js | 8 ++++---- test-live.js | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/public/live.js b/public/live.js index 378c387f..4cc6b763 100644 --- a/public/live.js +++ b/public/live.js @@ -1343,7 +1343,7 @@ html += `

Recent Packets

` + recent.slice(0, 10).map(p => `
- ${escapeHtml(p.payload_type || '?')}${p.observation_count > 1 ? ' 👁 ' + p.observation_count + '' : ''} + ${escapeHtml(p.payload_type || '?')}${transportBadge(p.route_type)}${p.observation_count > 1 ? ' 👁 ' + p.observation_count + '' : ''} ${formatLiveTimestampHtml(p.timestamp)}
`).join('') + '
'; @@ -1548,7 +1548,7 @@ item.innerHTML = ` ${icon} ${typeName} - ${hopStr}${obsBadge} + ${transportBadge(pkt.route_type)}${hopStr}${obsBadge} ${escapeHtml(preview)} ${formatLiveTimestampHtml(group.latestTs || Date.now())} `; @@ -2490,7 +2490,7 @@ item.innerHTML = ` ${icon} ${typeName} - ${hopStr}${obsBadge} + ${transportBadge(pkt.route_type)}${hopStr}${obsBadge} ${escapeHtml(preview)} ${formatLiveTimestampHtml(pkt._ts || Date.now())} `; @@ -2558,7 +2558,7 @@ item.innerHTML = ` ${icon} ${typeName} - ${hopStr}${obsBadge} + ${transportBadge(pkt.route_type)}${hopStr}${obsBadge} ${escapeHtml(preview)} ${formatLiveTimestampHtml(pkt._ts || Date.now())} `; diff --git a/test-live.js b/test-live.js index 98d9325e..d3edaa92 100644 --- a/test-live.js +++ b/test-live.js @@ -881,6 +881,17 @@ console.log('\n=== live.js: source-level safety checks ==='); assert.ok(src.includes('const existingIds = new Set(VCR.buffer.map(b => b.pkt.id)'), 'vcrRewind should dedup by packet ID'); }); + + test('feed items include transport badge', () => { + const count = (src.match(/transportBadge\(pkt\.route_type\)/g) || []).length; + assert.ok(count >= 3, + `feed rendering should call transportBadge(pkt.route_type) in at least 3 places (found ${count})`); + }); + + test('node detail recent packets include transport badge', () => { + assert.ok(src.includes('transportBadge(p.route_type)'), + 'node detail recent packets should call transportBadge(p.route_type)'); + }); } // ===== SUMMARY =====