mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-05-25 20:45:17 +00:00
fix: add favorites filter to live map
Fixes Kpa-clawbot/meshcore-analyzer#106
This commit is contained in:
+1
-1
@@ -88,7 +88,7 @@
|
||||
<script src="nodes.js?v=1774064852" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="traces.js?v=1774048777" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="analytics.js?v=1774083840" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="live.js?v=1774083841" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="live.js?v=1774256400" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="observers.js?v=1774018095" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="observer-detail.js?v=1774028201" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="node-analytics.js?v=1774042199" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
let soundEnabled = false;
|
||||
let showGhostHops = localStorage.getItem('live-ghost-hops') !== 'false';
|
||||
let realisticPropagation = localStorage.getItem('live-realistic-propagation') === 'true';
|
||||
let showOnlyFavorites = localStorage.getItem('live-favorites-only') === 'true';
|
||||
const propagationBuffer = new Map(); // hash -> {timer, packets[]}
|
||||
let _onResize = null;
|
||||
let _navCleanup = null;
|
||||
@@ -630,6 +631,8 @@
|
||||
<span id="ghostDesc" class="sr-only">Show interpolated ghost markers for unknown hops</span>
|
||||
<label><input type="checkbox" id="liveRealisticToggle" aria-describedby="realisticDesc"> Realistic</label>
|
||||
<span id="realisticDesc" class="sr-only">Buffer packets by hash and animate all paths simultaneously</span>
|
||||
<label><input type="checkbox" id="liveFavoritesToggle" aria-describedby="favDesc"> ⭐ Favorites</label>
|
||||
<span id="favDesc" class="sr-only">Show only favorited and claimed nodes</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="live-overlay live-feed" id="liveFeed">
|
||||
@@ -775,6 +778,14 @@
|
||||
localStorage.setItem('live-realistic-propagation', realisticPropagation);
|
||||
});
|
||||
|
||||
const favoritesToggle = document.getElementById('liveFavoritesToggle');
|
||||
favoritesToggle.checked = showOnlyFavorites;
|
||||
favoritesToggle.addEventListener('change', (e) => {
|
||||
showOnlyFavorites = e.target.checked;
|
||||
localStorage.setItem('live-favorites-only', showOnlyFavorites);
|
||||
applyFavoritesFilter();
|
||||
});
|
||||
|
||||
// Feed show/hide
|
||||
const feedEl = document.getElementById('liveFeed');
|
||||
// Keyboard support for feed items (event delegation)
|
||||
@@ -1181,6 +1192,37 @@
|
||||
if (heatLayer) { map.removeLayer(heatLayer); heatLayer = null; }
|
||||
}
|
||||
|
||||
function getLiveFavorites() {
|
||||
try { return new Set(JSON.parse(localStorage.getItem('meshcore-favorites') || '[]')); } catch { return new Set(); }
|
||||
}
|
||||
function getLiveMyNodes() {
|
||||
try { return new Set(JSON.parse(localStorage.getItem('meshcore-my-nodes') || '[]')); } catch { return new Set(); }
|
||||
}
|
||||
function isNodeFavorited(pubkey) {
|
||||
const favs = getLiveFavorites();
|
||||
const mine = getLiveMyNodes();
|
||||
return favs.has(pubkey) || mine.has(pubkey);
|
||||
}
|
||||
function applyFavoritesFilter() {
|
||||
Object.keys(nodeMarkers).forEach(key => {
|
||||
const marker = nodeMarkers[key];
|
||||
if (!marker) return;
|
||||
const visible = !showOnlyFavorites || isNodeFavorited(key);
|
||||
if (visible) {
|
||||
if (!nodesLayer.hasLayer(marker)) { marker.addTo(nodesLayer); if (marker._glowMarker) marker._glowMarker.addTo(nodesLayer); }
|
||||
} else {
|
||||
if (nodesLayer.hasLayer(marker)) { nodesLayer.removeLayer(marker); if (marker._glowMarker) nodesLayer.removeLayer(marker._glowMarker); }
|
||||
}
|
||||
});
|
||||
const _el2 = document.getElementById('liveNodeCount');
|
||||
if (_el2) {
|
||||
const count = showOnlyFavorites
|
||||
? Object.keys(nodeMarkers).filter(k => isNodeFavorited(k)).length
|
||||
: Object.keys(nodeMarkers).length;
|
||||
_el2.textContent = count;
|
||||
}
|
||||
}
|
||||
|
||||
function addNodeMarker(n) {
|
||||
if (nodeMarkers[n.public_key]) return nodeMarkers[n.public_key];
|
||||
const color = ROLE_COLORS[n.role] || ROLE_COLORS.unknown;
|
||||
@@ -1208,6 +1250,10 @@
|
||||
marker._baseColor = color;
|
||||
marker._baseSize = size;
|
||||
nodeMarkers[n.public_key] = marker;
|
||||
if (showOnlyFavorites && !isNodeFavorited(n.public_key)) {
|
||||
nodesLayer.removeLayer(marker);
|
||||
nodesLayer.removeLayer(glow);
|
||||
}
|
||||
return marker;
|
||||
}
|
||||
|
||||
@@ -1269,6 +1315,13 @@
|
||||
playSound(typeName);
|
||||
addFeedItem(icon, typeName, payload, hops, color, pkt);
|
||||
|
||||
// Favorites filter: skip animation if no involved nodes are favorited
|
||||
if (showOnlyFavorites) {
|
||||
const involvedKeys = hops.map(h => h.id || h.public_key).filter(Boolean);
|
||||
if (payload.pubKey) involvedKeys.push(payload.pubKey);
|
||||
if (!involvedKeys.some(k => isNodeFavorited(k))) return;
|
||||
}
|
||||
|
||||
// If ADVERT, ensure node appears on map
|
||||
if (typeName === 'ADVERT' && payload.pubKey) {
|
||||
const key = payload.pubKey;
|
||||
|
||||
Reference in New Issue
Block a user