From 0eed8f80010aa190423cb3cdcd4599e2ac55a7b8 Mon Sep 17 00:00:00 2001 From: Pablo Revilla Date: Fri, 21 Nov 2025 15:41:25 -0800 Subject: [PATCH] Finishing up all the pages for the 3.0 release. Now all pages are functional. --- meshview/templates/firehose.html | 66 ++++++++++++++++++++------------ meshview/templates/new_node.html | 34 +++++++++++++++- 2 files changed, 74 insertions(+), 26 deletions(-) diff --git a/meshview/templates/firehose.html b/meshview/templates/firehose.html index b6e2b22..946bd69 100644 --- a/meshview/templates/firehose.html +++ b/meshview/templates/firehose.html @@ -30,6 +30,7 @@ } .packet-table tr:nth-of-type(odd) { background-color: #272b2f; } .packet-table tr:nth-of-type(even) { background-color: #212529; } + .port-tag { display: inline-block; padding: 1px 6px; @@ -68,6 +69,17 @@ font-weight: bold; } .toggle-btn:hover { color: #fff; } + +/* Link next to port tag */ +.inline-link { + margin-left: 6px; + font-weight: bold; + text-decoration: none; + color: #9fd4ff; +} +.inline-link:hover { + color: #c7e6ff; +} {% endblock %} {% block body %} @@ -85,7 +97,6 @@ From To Port - Links @@ -106,7 +117,6 @@ function applyTranslations(translations, root=document) { }); } -// --- Load translations for firehose section --- async function loadTranslations() { try { const cfg = await window._siteConfigPromise; @@ -155,14 +165,13 @@ const PORT_COLORS = { 78: "#795548" }; -// --- Load node names --- +// Load node names async function loadNodes() { const res = await fetch("/api/nodes"); if (!res.ok) return; const data = await res.json(); for (const n of data.nodes || []) { - const name = n.long_name || n.short_name || n.id || n.node_id; - nodeMap[n.node_id] = name; + nodeMap[n.node_id] = n.long_name || n.short_name || n.id || n.node_id; } nodeMap[4294967295] = "All"; } @@ -172,12 +181,18 @@ function nodeName(id) { return nodeMap[id] || id; } -function portLabel(portnum, payload) { +function portLabel(portnum, payload, linksHtml) { const name = PORT_MAP[portnum] || "Unknown"; const color = PORT_COLORS[portnum] || "#6c757d"; const safePayload = payload ? payload.replace(/"/g, """) : ""; - return `${name} - (${portnum})`; + + return ` + + ${name} + + (${portnum}) + ${linksHtml || ""} + `; } function formatLocalTime(importTimeUs) { @@ -191,7 +206,6 @@ async function configureFirehose() { const cfg = await window._siteConfigPromise; const intervalSec = cfg?.site?.firehose_interval; if (intervalSec && !isNaN(intervalSec)) updateInterval = parseInt(intervalSec) * 1000; - console.log("Firehose update interval:", updateInterval, "ms"); } catch (err) { console.warn("Failed to read firehose interval:", err); } @@ -213,33 +227,36 @@ async function fetchUpdates() { const list = document.getElementById("packet_list"); for (const pkt of packets.reverse()) { - const fromNodeId = pkt.from_node_id; - const toNodeId = pkt.to_node_id; + const from = pkt.from_node_id === 4294967295 + ? `All` + : `${nodeMap[pkt.from_node_id] || pkt.from_node_id}`; - let from = fromNodeId === 4294967295 ? `All` : - `${nodeMap[fromNodeId] || fromNodeId}`; + const to = pkt.to_node_id === 1 + ? `direct to MQTT` + : pkt.to_node_id === 4294967295 + ? `All` + : `${nodeMap[pkt.to_node_id] || pkt.to_node_id}`; - let to = toNodeId === 1 ? `direct to MQTT` : - toNodeId === 4294967295 ? `All` : - `${nodeMap[toNodeId] || toNodeId}`; + // Inline link next to port tag + let inlineLinks = ""; - let links = ""; if (pkt.portnum === 3 && pkt.payload) { const latMatch = pkt.payload.match(/latitude_i:\s*(-?\d+)/); const lonMatch = pkt.payload.match(/longitude_i:\s*(-?\d+)/); + if (latMatch && lonMatch) { const lat = parseInt(latMatch[1]) / 1e7; const lon = parseInt(lonMatch[1]) / 1e7; - links += `Map`; + inlineLinks += ` 📍`; } } if (pkt.portnum === 70) { let traceId = pkt.id; - const idMatch = pkt.payload.match(/ID:\s*(\d+)/i); - if (idMatch) traceId = idMatch[1]; - if (links) links += " | "; - links += `Graph`; + const match = pkt.payload.match(/ID:\s*(\d+)/i); + if (match) traceId = match[1]; + + inlineLinks += ` `; } const safePayload = (pkt.payload || "").replace(//g, ">"); @@ -251,11 +268,10 @@ async function fetchUpdates() { ${pkt.id} ${from} ${to} - ${portLabel(pkt.portnum, pkt.payload)} - ${links} + ${portLabel(pkt.portnum, pkt.payload, inlineLinks)} - ${safePayload} + ${safePayload} `; list.insertAdjacentHTML("afterbegin", html); } diff --git a/meshview/templates/new_node.html b/meshview/templates/new_node.html index 4a6efd8..a122ab8 100644 --- a/meshview/templates/new_node.html +++ b/meshview/templates/new_node.html @@ -130,6 +130,17 @@ background:#1b1e22; border-radius:8px; width:90%; height:85%; padding:10px; } + +/* Link next to port tag */ +.inline-link { + margin-left: 6px; + font-weight: bold; + text-decoration: none; + color: #9fd4ff; +} +.inline-link:hover { + color: #c7e6ff; +} {% endblock %} {% block body %} @@ -537,13 +548,34 @@ async function loadPackets(){ drawNeighbors(pkt.from_node_id, nids); } + let inlineLinks = ""; + + if (pkt.portnum === 3 && pkt.payload) { + const latMatch = pkt.payload.match(/latitude_i:\s*(-?\d+)/); + const lonMatch = pkt.payload.match(/longitude_i:\s*(-?\d+)/); + + if (latMatch && lonMatch) { + const lat = parseFloat(latMatch[1]) / 1e7; + const lon = parseFloat(lonMatch[1]) / 1e7; + inlineLinks += ` 📍`; + } + } + + if (pkt.portnum === 70) { + let traceId = pkt.id; + const match = pkt.payload?.match(/ID:\s*(\d+)/i); + if (match) traceId = match[1]; + inlineLinks += ` `; + } + + list.insertAdjacentHTML("afterbegin", ` ${localTime} ${pkt.id} ${fromCell} ${toCell} - ${portLabel(pkt.portnum)} + ${portLabel(pkt.portnum)}${inlineLinks} ${safePayload}