diff --git a/CHANGELOG.md b/CHANGELOG.md index a02883c..34bf832 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [0.6.13] - 2026-02-18 + +### Added +- **Version in Navbar** aller Seiten sichtbar (via `app.js initPage()` + `/api/stats`). +- **Karte Alter-Transparenz**: Nodes < 24h voll sichtbar (0.9), 24–48h halb transparent (0.45), + 48–72h stark transparent (0.2), älter als 72h werden nicht mehr angezeigt. + Legende um Alter-Sektion erweitert. + +### Changed +- **Statistiken Rolling Window**: Anfragen-Zähler und Kanal-Breakdown nutzen jetzt + rollendes 24h-Fenster (jetzt minus 24h) statt Mitternacht-Reset. + ## [0.6.12] - 2026-02-18 ### Fixed diff --git a/config.yaml b/config.yaml index 6a5d6b0..137b882 100644 --- a/config.yaml +++ b/config.yaml @@ -1,4 +1,4 @@ -version: "0.6.12" +version: "0.6.13" bot: name: "MeshDD-Bot" diff --git a/meshbot/database.py b/meshbot/database.py index 61a9bf0..1714982 100644 --- a/meshbot/database.py +++ b/meshbot/database.py @@ -1,7 +1,6 @@ import aiosqlite import time import logging -from datetime import datetime logger = logging.getLogger(__name__) @@ -208,14 +207,13 @@ class Database: "SELECT COUNT(*) FROM nodes WHERE last_seen >= ?", (day_ago,) ) as c: stats["nodes_24h"] = (await c.fetchone())[0] - today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp() async with self.db.execute( - "SELECT COUNT(*) FROM commands WHERE timestamp >= ?", (today_start,) + "SELECT COUNT(*) FROM commands WHERE timestamp >= ?", (day_ago,) ) as c: stats["total_commands"] = (await c.fetchone())[0] async with self.db.execute( "SELECT channel, COUNT(*) as cnt FROM commands WHERE timestamp >= ? GROUP BY channel ORDER BY cnt DESC", - (today_start,), + (day_ago,), ) as cursor: stats["channel_breakdown"] = {row[0]: row[1] async for row in cursor} return stats diff --git a/static/admin.html b/static/admin.html index 87302d2..b176cb5 100644 --- a/static/admin.html +++ b/static/admin.html @@ -16,6 +16,7 @@ MeshDD-Bot +
diff --git a/static/js/app.js b/static/js/app.js index b36e8b1..004ae7a 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -102,4 +102,10 @@ function initPage({ onAuth = null } = {}) { _setupSidebarToggle(); if (onAuth) onAuth(user); }); + const vl = document.getElementById('versionLabel'); + if (vl) { + fetch('/api/stats') + .then(r => r.ok ? r.json() : null) + .then(d => { if (d?.version) vl.textContent = `v${d.version}`; }); + } } diff --git a/static/js/map.js b/static/js/map.js index 1066e99..148fa17 100644 --- a/static/js/map.js +++ b/static/js/map.js @@ -28,7 +28,7 @@ function createIcon(color) { return L.divIcon({ className: '', html: ` - + `, iconSize: [24, 24], iconAnchor: [12, 12], @@ -37,6 +37,16 @@ function createIcon(color) { }); } +// Returns opacity based on node age: full <24h, half 24-48h, faint 48-72h, null >72h (hide) +function getAgeOpacity(lastSeen) { + if (!lastSeen) return 0.9; + const age = Date.now() / 1000 - lastSeen; + if (age < 86400) return 0.9; + if (age < 172800) return 0.45; + if (age < 259200) return 0.2; + return null; +} + function nodeTooltip(node) { const name = node.long_name || node.short_name || node.node_id; const hops = node.hop_count != null ? node.hop_count : '?'; @@ -61,15 +71,28 @@ function updateMarker(node) { if (!node.lat || !node.lon) return; const id = node.node_id; + const opacity = getAgeOpacity(node.last_seen); + + // Node older than 72h: remove from map + if (opacity === null) { + if (markers[id]) { + map.removeLayer(markers[id]); + delete markers[id]; + delete nodeData[id]; + } + return; + } + nodeData[id] = node; const icon = createIcon(getHopColor(node.hop_count)); if (markers[id]) { markers[id].setLatLng([node.lat, node.lon]); markers[id].setIcon(icon); + markers[id].setOpacity(opacity); markers[id].setTooltipContent(nodeTooltip(node)); } else { - markers[id] = L.marker([node.lat, node.lon], { icon }) + markers[id] = L.marker([node.lat, node.lon], { icon, opacity }) .addTo(map) .bindTooltip(nodeTooltip(node), { direction: 'right', className: 'node-tooltip-wrap' }); } @@ -134,6 +157,10 @@ legend.onAdd = function () { const color = hop != null ? (hopColors[hop] || hopColorDefault) : hopColorDefault; div.innerHTML += `
${label}
`; }); + div.innerHTML += `
Alter +
< 24h
+
24–48h
+
48–72h
`; return div; }; diff --git a/static/map.html b/static/map.html index df7c9c4..c8c9a27 100644 --- a/static/map.html +++ b/static/map.html @@ -17,6 +17,7 @@ MeshDD-Bot +
diff --git a/static/packets.html b/static/packets.html index 6853e62..5d5c151 100644 --- a/static/packets.html +++ b/static/packets.html @@ -16,6 +16,7 @@ MeshDD-Bot +
diff --git a/static/scheduler.html b/static/scheduler.html index 15c8349..00ea962 100644 --- a/static/scheduler.html +++ b/static/scheduler.html @@ -16,6 +16,7 @@ MeshDD-Bot +
diff --git a/static/settings.html b/static/settings.html index fae1692..c88fb59 100644 --- a/static/settings.html +++ b/static/settings.html @@ -16,6 +16,7 @@ MeshDD-Bot +