diff --git a/meshview/templates/map.html b/meshview/templates/map.html
index c821dcb..1263ff7 100644
--- a/meshview/templates/map.html
+++ b/meshview/templates/map.html
@@ -79,29 +79,22 @@
{% endfor %}
];
- // ---- Helpers ----
- const portMap = {
- 1: "Text", 67: "Telemetry", 3: "Position",
- 70: "Traceroute", 4: "Node Info", 71: "Neighbour Info", 73: "Map Report"
- };
+ const portMap = {1: "Text", 67: "Telemetry", 3: "Position", 70: "Traceroute", 4: "Node Info", 71: "Neighbour Info", 73: "Map Report"};
function timeAgo(date) {
- var now = Date.now();
- var diff = now - new Date(date);
- var seconds = Math.floor(diff / 1000);
- var minutes = Math.floor(seconds / 60);
- var hours = Math.floor(minutes / 60);
- var days = Math.floor(hours / 24);
+ const now = Date.now();
+ const diff = now - new Date(date);
+ const seconds = Math.floor(diff / 1000);
+ const minutes = Math.floor(seconds / 60);
+ const hours = Math.floor(minutes / 60);
+ const days = Math.floor(hours / 24);
if (days > 0) return days + "d";
if (hours > 0) return hours + "h";
if (minutes > 0) return minutes + "m";
return seconds + "s";
}
- const palette = [
- "#e6194b","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe",
- "#008080","#e6beff","#9a6324","#fffac8","#800000","#aaffc3","#808000","#ffd8b1","#000075","#808080"
- ];
+ const palette = ["#e6194b","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe","#008080","#e6beff","#9a6324","#fffac8","#800000","#aaffc3","#808000","#ffd8b1","#000075","#808080"];
const colorMap = new Map();
let nextColorIndex = 0;
@@ -118,15 +111,8 @@
function isInvalidCoord(node) {
if (!node) return true;
- let { lat, long } = node;
- lat = Math.round(lat);
- long = Math.round(long);
- return (
- lat === null || long === null ||
- lat === undefined || long === undefined ||
- lat === 0 || long === 0 ||
- Number.isNaN(lat) || Number.isNaN(long)
- );
+ let {lat, long} = node;
+ return !lat || !long || lat === 0 || long === 0 || Number.isNaN(lat) || Number.isNaN(long);
}
// ---- Marker Plotting ----
@@ -139,14 +125,7 @@
channels.add(category);
let color = hashToColor(category);
- let markerOptions = {
- radius: node.isRouter ? 9 : 7,
- color: "white",
- fillColor: color,
- fillOpacity: 1,
- weight: 0.7
- };
-
+ let markerOptions = { radius: node.isRouter ? 9 : 7, color: "white", fillColor: color, fillOpacity: 1, weight: 0.7 };
let popupContent = `${node.long_name} (${node.short_name})
Channel: ${node.channel}
Model: ${node.hw_model}
@@ -172,7 +151,6 @@
}
});
- // Fit map bounds
var bayAreaBounds = [
[{{ site_config["site"]["map_top_left_lat"] }}, {{ site_config["site"]["map_top_left_lon"] }}],
[{{ site_config["site"]["map_bottom_right_lat"] }}, {{ site_config["site"]["map_bottom_right_lon"] }}]
@@ -197,32 +175,24 @@
let checkbox = document.getElementById(`filter-${category.replace(/\s+/g,'-').toLowerCase()}`);
let shouldShow = checkbox.checked && (!showRoutersOnly || node.isRouter);
let marker = markerById[node.id];
- if (marker) {
- marker.setStyle({ fillOpacity: shouldShow ? 1 : 0 });
- }
+ if (marker) marker.setStyle({ fillOpacity: shouldShow ? 1 : 0 });
});
}
- document.querySelectorAll(".filter-checkbox").forEach(input => {
- input.addEventListener("change", updateMarkers);
- });
+ document.querySelectorAll(".filter-checkbox").forEach(input => input.addEventListener("change", updateMarkers));
// ---- Edges ----
var edgeLayer = L.layerGroup().addTo(map);
var edgesData = null;
let selectedNodeId = null;
- fetch('/api/edges')
- .then(res => res.json())
- .then(data => { edgesData = data.edges; })
- .catch(err => console.error(err));
+ fetch('/api/edges').then(res => res.json()).then(data => { edgesData = data.edges; }).catch(err => console.error(err));
function onNodeClick(node) {
if (selectedNodeId != node.id) {
selectedNodeId = node.id;
edgeLayer.clearLayers();
if (!edgesData) return;
-
if (!map.hasLayer(edgeLayer)) edgeLayer.addTo(map);
edgesData.forEach(edge => {
@@ -236,16 +206,11 @@
const dash = edge.type === "traceroute" ? "5,5" : null;
const weight = edge.type === "neighbor" ? 3 : 2;
- const polyline = L.polyline(
- [[fromNode.lat, fromNode.long], [toNode.lat, toNode.long]],
- { color: lineColor, weight, opacity: 1, dashArray: dash }
- ).addTo(edgeLayer).bringToFront();
+ const polyline = L.polyline([[fromNode.lat, fromNode.long],[toNode.lat, toNode.long]], { color: lineColor, weight, opacity: 1, dashArray: dash }).addTo(edgeLayer).bringToFront();
if (edge.type === "traceroute") {
L.polylineDecorator(polyline, {
- patterns: [
- { offset: '100%', repeat: 0, symbol: L.Symbol.arrowHead({ pixelSize: 5, polygon: false, pathOptions: { stroke: true, color: lineColor } }) }
- ]
+ patterns: [{ offset: '100%', repeat: 0, symbol: L.Symbol.arrowHead({ pixelSize: 5, polygon: false, pathOptions: { stroke: true, color: lineColor } }) }]
}).addTo(edgeLayer);
}
});
@@ -260,99 +225,106 @@
});
// ---- Blinking Nodes ----
- var lastFetchTime = null;
- const activeBlinks = new Map();
+ var activeBlinks = new Map();
+
+ function blinkNode(marker, longName, portnum) {
+ if (!map.hasLayer(marker)) return;
+ if (activeBlinks.has(marker)) {
+ clearInterval(activeBlinks.get(marker));
+ marker.setStyle({ fillColor: marker.originalColor });
+ if (marker.tooltip) map.removeLayer(marker.tooltip);
+ }
+
+ let blinkCount = 0;
+ let portName = portMap[portnum] || `Port ${portnum}`;
+ let tooltip = L.tooltip({
+ permanent: true,
+ direction: 'top',
+ offset: [0, -marker.options.radius - 5],
+ className: 'blinking-tooltip'
+ }).setContent(`${longName} (${portName})`).setLatLng(marker.getLatLng());
+ tooltip.addTo(map);
+ marker.tooltip = tooltip;
+
+ let interval = setInterval(() => {
+ if (map.hasLayer(marker)) {
+ // Alternate color
+ marker.setStyle({ fillColor: blinkCount % 2 === 0 ? 'yellow' : marker.originalColor });
+ // Bring marker to top
+ marker.bringToFront();
+ }
+ blinkCount++;
+ if (blinkCount > 7) {
+ clearInterval(interval);
+ marker.setStyle({ fillColor: marker.originalColor });
+ map.removeLayer(tooltip);
+ activeBlinks.delete(marker);
+ }
+ }, 500);
+
+ activeBlinks.set(marker, interval);
+ }
+
+
+ // ---- Packet Fetching ----
+ let lastImportTime = null;
function fetchLatestPacket() {
fetch(`/api/packets?limit=1`)
.then(res => res.json())
.then(data => {
- if (data.packets && data.packets.length > 0) lastFetchTime = data.packets[0].import_time;
- else lastFetchTime = new Date().toISOString();
+ if (data.packets && data.packets.length > 0) {
+ lastImportTime = data.packets[0].import_time;
+ console.log("Initial lastImportTime:", lastImportTime);
+ } else {
+ lastImportTime = new Date().toISOString();
+ console.log("No packets, setting lastImportTime to now:", lastImportTime);
+ }
})
.catch(err => console.error("Error fetching latest packet:", err));
}
- function blinkNode(marker, longName, portnum) {
- if (!map.hasLayer(marker)) return;
- if (activeBlinks.has(marker)) {
- clearInterval(activeBlinks.get(marker));
- marker.setStyle({ fillColor: marker.originalColor });
- if (marker.tooltip) map.removeLayer(marker.tooltip);
- }
+ function fetchNewPackets() {
+ if (!lastImportTime) return;
+ fetch(`/api/packets?since=${lastImportTime}`)
+ .then(res => res.json())
+ .then(data => {
+ console.log("===== New Fetch =====");
+ if (!data.packets || data.packets.length === 0) {
+ console.log("No new packets");
+ return;
+ }
- let blinkCount = 0;
- let portName = portMap[portnum] || `Port ${portnum}`;
- let tooltip = L.tooltip({
- permanent: true,
- direction: 'top',
- offset: [0, -marker.options.radius - 5],
- className: 'blinking-tooltip'
- }).setContent(`${longName} (${portName})`).setLatLng(marker.getLatLng());
- tooltip.addTo(map);
- marker.tooltip = tooltip;
+ let latestSeen = lastImportTime;
- let interval = setInterval(() => {
- if (map.hasLayer(marker)) {
- marker.setStyle({ fillColor: blinkCount % 2 === 0 ? 'yellow' : marker.originalColor });
- marker.bringToFront();
- }
- blinkCount++;
- if (blinkCount > 7) {
- clearInterval(interval);
- marker.setStyle({ fillColor: marker.originalColor });
- map.removeLayer(tooltip);
- activeBlinks.delete(marker);
- }
- }, 500);
+ data.packets.forEach(packet => {
+ console.log(`Packet ID: ${packet.id}, From Node: ${packet.from_node_id}, Port: ${packet.portnum}, Time: ${packet.import_time}`);
+ if (packet.import_time && (!latestSeen || packet.import_time > latestSeen)) latestSeen = packet.import_time;
- activeBlinks.set(marker, interval);
+ let marker = markerById[packet.from_node_id];
+ if (marker) {
+ let nodeData = nodeMap.get(packet.from_node_id);
+ if (nodeData) blinkNode(marker, nodeData.long_name, packet.portnum);
+ }
+ });
+
+ if (latestSeen) lastImportTime = latestSeen;
+ console.log("Updated lastImportTime:", lastImportTime);
+ console.log("===== End Fetch =====");
+ })
+ .catch(err => console.error("Fetch error:", err));
}
-function fetchNewPackets() {
- if (!lastFetchTime) return;
- fetch(`/api/packets?since=${lastFetchTime}`)
- .then(res => res.json())
- .then(data => {
- console.log("===== New Fetch =====");
- if (!data.packets || data.packets.length === 0) {
- console.log("No new packets");
- return;
- }
-
- data.packets.forEach(packet => {
- console.log(
- `Packet ID: ${packet.id}, From Node: ${packet.from_node_id}, Port: ${packet.portnum}`
- );
-
- let marker = markerById[packet.from_node_id];
- if (marker) {
- let nodeData = nodeMap.get(packet.from_node_id);
- if (nodeData) blinkNode(marker, nodeData.long_name, packet.portnum);
- }
- });
-
- let latestPacket = data.packets[0];
- if (latestPacket && latestPacket.import_time) {
- lastFetchTime = latestPacket.import_time;
- }
-
-
- console.log("===== End Fetch =====");
- })
- .catch(err => console.error("Fetch error:", err));
-}
-
-
- // ---- Polling Control code ----
+ // ---- Polling Control ----
let packetInterval = null;
- const mapInterval = {{ site_config["site"]["map_interval"] | default(3) }}; // seconds
+ const mapInterval = {{ site_config["site"]["map_interval"] | default(3) }};
function startPacketFetcher() {
- if (mapInterval <= 0) return; // Don't fetch if interval is 0
+ if (mapInterval <= 0) return;
if (!packetInterval) {
fetchLatestPacket();
packetInterval = setInterval(fetchNewPackets, mapInterval * 1000);
+ console.log("Packet fetcher started, interval:", mapInterval, "seconds");
}
}
@@ -360,6 +332,7 @@ function fetchNewPackets() {
if (packetInterval) {
clearInterval(packetInterval);
packetInterval = null;
+ console.log("Packet fetcher stopped");
}
}
@@ -368,11 +341,8 @@ function fetchNewPackets() {
else startPacketFetcher();
});
- // Init
- if (mapInterval > 0) {
- fetchLatestPacket();
- startPacketFetcher();
- }
-
+ // ---- Initialize ----
+ if (mapInterval > 0) startPacketFetcher();
+
{% endblock %}