fix: My Nodes filter uses server-side findPacketsForNode for all packet types

Client was matching field names that only exist on ADVERTs. Now sends
pubkeys to server, which uses findPacketsForNode() (byNode index +
text search) to find ALL packet types referencing those nodes.
This commit is contained in:
you
2026-03-20 09:30:41 +00:00
parent e31e4aa356
commit 9ef5c1a809
3 changed files with 31 additions and 16 deletions
+1 -1
View File
@@ -81,7 +81,7 @@
<script src="vendor/qrcode.js"></script>
<script src="app.js?v=1773993532"></script>
<script src="home.js?v=1773977027"></script>
<script src="packets.js?v=1773998477"></script>
<script src="packets.js?v=1773999041"></script>
<script src="map.js?v=1773998477" onerror="console.error('Failed to load:', this.src)"></script>
<script src="channels.js?v=1773977027" onerror="console.error('Failed to load:', this.src)"></script>
<script src="nodes.js?v=1773977027" onerror="console.error('Failed to load:', this.src)"></script>
+10 -14
View File
@@ -587,25 +587,21 @@
const groupBtn = document.getElementById('fGroup');
if (groupBtn) groupBtn.classList.toggle('active', groupByHash);
// Filter to claimed/favorited nodes if toggle is on
// Filter to claimed/favorited nodes if toggle is on — use server-side multi-node lookup
let displayPackets = packets;
if (filters.myNodes) {
const myNodes = JSON.parse(localStorage.getItem('meshcore-my-nodes') || '[]');
const myKeys = new Set(myNodes.map(n => n.pubkey));
const myKeys = myNodes.map(n => n.pubkey).filter(Boolean);
const favs = getFavorites();
const allKeys = new Set([...myKeys, ...favs]);
displayPackets = packets.filter(p => {
const allKeys = [...new Set([...myKeys, ...favs])];
if (allKeys.length > 0) {
try {
const d = JSON.parse(p.decoded_json || '{}');
const pathHops = JSON.parse(p.path_json || '[]');
return (d.pubKey && allKeys.has(d.pubKey)) ||
(d.srcPubKey && allKeys.has(d.srcPubKey)) ||
(d.destPubKey && allKeys.has(d.destPubKey)) ||
(d.srcHash && allKeys.has(d.srcHash)) ||
(d.destHash && allKeys.has(d.destHash)) ||
pathHops.some(h => allKeys.has(h));
} catch { return false; }
});
const myData = await api('/packets?nodes=' + allKeys.join(',') + '&limit=500');
displayPackets = myData.packets || [];
} catch { displayPackets = []; }
} else {
displayPackets = [];
}
}
if (!displayPackets.length) {
+20 -1
View File
@@ -671,9 +671,28 @@ app.get('/api/stats', (req, res) => {
});
app.get('/api/packets', (req, res) => {
const { limit = 50, offset = 0, type, route, region, observer, hash, since, until, groupByHash, node } = req.query;
const { limit = 50, offset = 0, type, route, region, observer, hash, since, until, groupByHash, node, nodes } = req.query;
const order = req.query.order === 'asc' ? 'ASC' : 'DESC';
// Multi-node filter: comma-separated pubkeys
if (nodes) {
const pubkeys = nodes.split(',').map(s => s.trim()).filter(Boolean);
const allPackets = new Map();
for (const pk of pubkeys) {
const { packets: found } = pktStore.findPacketsForNode(pk);
for (const p of found) allPackets.set(p.id, p);
}
let results = [...allPackets.values()].sort((a, b) => order === 'DESC' ? b.timestamp.localeCompare(a.timestamp) : a.timestamp.localeCompare(b.timestamp));
// Apply additional filters
if (type !== undefined) results = results.filter(p => String(p.payload_type) === String(type));
if (region) results = results.filter(p => (p.observer_id || '').includes(region) || (p.decoded_json || '').includes(region));
if (since) results = results.filter(p => p.timestamp >= since);
if (until) results = results.filter(p => p.timestamp <= until);
const total = results.length;
const paged = results.slice(Number(offset), Number(offset) + Number(limit));
return res.json({ packets: paged, total, limit: Number(limit), offset: Number(offset) });
}
if (groupByHash === 'true') {
return res.json(pktStore.queryGrouped({ limit, offset, type, route, region, observer, hash, since, until, node }));
}