mirror of
https://github.com/pablorevilla-meshtastic/meshview.git
synced 2026-07-03 00:11:41 +02:00
New charts added to stats as we have access not to nodes via API
This commit is contained in:
@@ -6,20 +6,6 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Removed .packet-fade-in animation CSS */
|
||||
/*
|
||||
.packet-fade-in {
|
||||
animation: fadeIn 0.5s ease forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#pause-button {
|
||||
white-space: nowrap;
|
||||
padding: 2px 8px;
|
||||
@@ -58,8 +44,12 @@ let lastTime = null;
|
||||
let portnum = "{{ portnum if portnum is not none else '' }}";
|
||||
let updatesPaused = false;
|
||||
|
||||
// Use firehose_interval from config (seconds), default to 3s if not set
|
||||
const firehoseInterval = {{ site_config["site"]["firehose_interal"] | default(3) }};
|
||||
if (firehoseInterval < 0) firehoseInterval = 0;
|
||||
|
||||
function fetchUpdates() {
|
||||
if (updatesPaused) return;
|
||||
if (updatesPaused || firehoseInterval === 0) return;
|
||||
|
||||
const url = new URL("/firehose/updates", window.location.origin);
|
||||
if (lastTime) url.searchParams.set("last_time", lastTime);
|
||||
@@ -74,7 +64,6 @@ function fetchUpdates() {
|
||||
|
||||
for (const html of data.packets.reverse()) {
|
||||
list.insertAdjacentHTML("afterbegin", html);
|
||||
// No animation here anymore
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -86,7 +75,6 @@ function fetchUpdates() {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const pauseBtn = document.getElementById("pause-button");
|
||||
|
||||
// Assuming you have a portnum selector somewhere (not shown in your snippet)
|
||||
const portnumSelector = document.querySelector('select[name="portnum"]');
|
||||
if (portnumSelector) {
|
||||
portnumSelector.addEventListener("change", (e) => {
|
||||
@@ -102,9 +90,11 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
pauseBtn.textContent = updatesPaused ? "Resume" : "Pause";
|
||||
});
|
||||
|
||||
// Start fetching updates
|
||||
// Start fetching updates with configurable interval
|
||||
fetchUpdates();
|
||||
setInterval(fetchUpdates, 1000);
|
||||
if (firehoseInterval > 0) {
|
||||
setInterval(fetchUpdates, firehoseInterval * 1000);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
+16
-32
@@ -46,11 +46,9 @@
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
||||
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
|
||||
crossorigin=""></script>
|
||||
|
||||
<!-- Leaflet PolylineDecorator for arrowheads -->
|
||||
<script src="https://unpkg.com/leaflet-polylinedecorator@1.6.0/dist/leaflet.polylinedecorator.js"
|
||||
<script src="https://unpkg.com/leaflet-polylinedecorator@1.6.0/dist/leaflet.polylinedecorator.js"
|
||||
integrity="sha384-FhPn/2P/fJGhQLeNWDn9B/2Gml2bPOrKJwFqJXgR3xOPYxWg5mYQ5XZdhUSugZT0"
|
||||
crossorigin=""></script>
|
||||
crossorigin></script>
|
||||
|
||||
<script>
|
||||
// ---- Map Setup ----
|
||||
@@ -199,13 +197,8 @@
|
||||
let checkbox = document.getElementById(`filter-${category.replace(/\s+/g,'-').toLowerCase()}`);
|
||||
let shouldShow = checkbox.checked && (!showRoutersOnly || node.isRouter);
|
||||
let marker = markerById[node.id];
|
||||
if (shouldShow) map.addLayer(marker);
|
||||
else {
|
||||
map.removeLayer(marker);
|
||||
if (marker.tooltip) {
|
||||
map.removeLayer(marker.tooltip);
|
||||
marker.tooltip = null;
|
||||
}
|
||||
if (marker) {
|
||||
marker.setStyle({ fillOpacity: shouldShow ? 1 : 0 });
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -219,7 +212,6 @@
|
||||
var edgesData = null;
|
||||
let selectedNodeId = null;
|
||||
|
||||
// Preload edges on page load
|
||||
fetch('/api/edges')
|
||||
.then(res => res.json())
|
||||
.then(data => { edgesData = data.edges; })
|
||||
@@ -229,34 +221,26 @@
|
||||
if (selectedNodeId != node.id) {
|
||||
selectedNodeId = node.id;
|
||||
edgeLayer.clearLayers();
|
||||
console.log(`Clicked node: ${node.long_name}`);
|
||||
if (!edgesData) {
|
||||
console.log("Edges not loaded yet");
|
||||
return;
|
||||
}
|
||||
if (!edgesData) return;
|
||||
|
||||
if (!map.hasLayer(edgeLayer)) edgeLayer.addTo(map);
|
||||
|
||||
edgesData.forEach(edge => {
|
||||
if (edge.from !== node.id && edge.to !== node.id) return;
|
||||
|
||||
const fromNode = nodeMap.get(edge.from);
|
||||
const toNode = nodeMap.get(edge.to);
|
||||
if (!fromNode || !toNode) return;
|
||||
if (isInvalidCoord(fromNode) || isInvalidCoord(toNode)) return;
|
||||
|
||||
const lineColor = edge.type === "neighbor" ? "darkred" : "black"; //different than the node category colors
|
||||
const lineColor = edge.type === "neighbor" ? "darkred" : "black";
|
||||
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();
|
||||
).addTo(edgeLayer).bringToFront();
|
||||
|
||||
// Add arrowhead
|
||||
if (edge.type === "traceroute") {
|
||||
L.polylineDecorator(polyline, {
|
||||
patterns: [
|
||||
@@ -264,13 +248,10 @@
|
||||
]
|
||||
}).addTo(edgeLayer);
|
||||
}
|
||||
|
||||
console.log(`Edge type: To: ${toNode.long_name} (${toNode.lat},${toNode.long})`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Clear edges only if the click was not on a marker
|
||||
map.on('click', function(e) {
|
||||
if (!e.originalEvent.target.classList.contains('leaflet-interactive')) {
|
||||
edgeLayer.clearLayers();
|
||||
@@ -278,8 +259,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// ---- Blinking Nodes ----
|
||||
var lastFetchTime = null;
|
||||
const activeBlinks = new Map();
|
||||
@@ -296,7 +275,6 @@
|
||||
|
||||
function blinkNode(marker, longName, portnum) {
|
||||
if (!map.hasLayer(marker)) return;
|
||||
|
||||
if (activeBlinks.has(marker)) {
|
||||
clearInterval(activeBlinks.get(marker));
|
||||
marker.setStyle({ fillColor: marker.originalColor });
|
||||
@@ -352,10 +330,13 @@
|
||||
|
||||
// ---- Polling Control ----
|
||||
let packetInterval = null;
|
||||
const mapInterval = {{ site_config["site"]["map_interval"] | default(3) }}; // seconds
|
||||
|
||||
function startPacketFetcher() {
|
||||
if (mapInterval <= 0) return; // Don't fetch if interval is 0
|
||||
if (!packetInterval) {
|
||||
fetchLatestPacket();
|
||||
packetInterval = setInterval(fetchNewPackets, 1000);
|
||||
packetInterval = setInterval(fetchNewPackets, mapInterval * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +353,10 @@
|
||||
});
|
||||
|
||||
// Init
|
||||
fetchLatestPacket();
|
||||
startPacketFetcher();
|
||||
if (mapInterval > 0) {
|
||||
fetchLatestPacket();
|
||||
startPacketFetcher();
|
||||
}
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
+8
-2
@@ -178,10 +178,16 @@ env.filters["node_id_to_hex"] = node_id_to_hex
|
||||
env.filters["format_timestamp"] = format_timestamp
|
||||
|
||||
routes = web.RouteTableDef()
|
||||
# Make the Map the home page
|
||||
@routes.get("/")
|
||||
async def index(request):
|
||||
raise web.HTTPFound(location="/map")
|
||||
"""
|
||||
Redirect root URL '/' to the page specified in CONFIG['site']['starting'].
|
||||
Defaults to '/map' if not set.
|
||||
"""
|
||||
# Get the starting page from config
|
||||
starting_url = CONFIG["site"].get("starting", "/map") # default to /map if not set
|
||||
raise web.HTTPFound(location=starting_url)
|
||||
|
||||
|
||||
|
||||
def generate_response(request, body, raw_node_id="", node=None):
|
||||
|
||||
Reference in New Issue
Block a user