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} |