Commit Graph

61 Commits

Author SHA1 Message Date
you cbec6b3108 Move hop resolution to client side
Create public/hop-resolver.js that mirrors the server's disambiguateHops()
algorithm (prefix index, forward/backward pass, distance sanity check).

Replace all /api/resolve-hops fetch calls in packets.js with local
HopResolver.resolve() calls. The resolver lazily fetches and caches the
full nodes list via /api/nodes on first use.

The server endpoint is kept as fallback but no longer called by the UI,
eliminating 40+ HTTP requests per session.
2026-03-21 20:39:28 +00:00
you ace705ef8e fix: use dropdown for region filter on packets page
Pills look out of place in the dense toolbar. Added { dropdown: true }
option to RegionFilter.init() to force dropdown mode regardless of
region count.
2026-03-21 08:22:12 +00:00
you debc873b26 fix: BYOP button accessibility compliance
- Add aria-label and aria-haspopup='dialog' to BYOP trigger button
- Add aria-label to close button and textarea
- Add role='status' and aria-live='polite' to result container
- Add role='alert' to error messages for screen reader announcement
- Fix textarea focus style: visible outline instead of outline:none
- Update cache busters
2026-03-21 08:06:37 +00:00
you 39f5b40322 packets: replace single-select region dropdown with shared RegionFilter component
- Fixes empty region dropdown (was populated before async regionMap loaded)
- Now uses multi-select RegionFilter component consistent with other pages
- Loads regions from /api/observers with proper async handling
- Supports multi-region filtering
2026-03-21 08:00:44 +00:00
you 8ad2348a16 fix: simplify channel key scheme + add CHAN packet detail renderer
- Remove composite key scheme (ch_/unk_ prefixes) that broke URL routing
  due to # in channel names. Use plain numeric channelHash as key instead.
- All packets with same hash byte go in one bucket; name is set from
  first successful decryption.
- Add packet detail renderer for decoded CHAN type showing channel name,
  sender, and sender timestamp.
- Update cache buster for packets.js.
2026-03-21 06:11:01 +00:00
you ac44f7fc2a feat: paths through node section on repeater detail page 2026-03-21 02:22:59 +00:00
you 75a1b8fc98 fix: anchor hop disambiguation from sender origin, not just observer
resolve-hops now accepts originLat/originLon params. Forward pass
starts from sender position so first ambiguous hop resolves to the
nearest node to the sender, not the observer.
2026-03-21 02:19:20 +00:00
you 221d83da44 feat: replay sends all observations, uses realistic propagation on live map 2026-03-21 01:49:31 +00:00
you ac389f7af6 feat: show packet propagation time in detail pane (spread across observers) 2026-03-21 01:32:00 +00:00
you 85c356448e fix: switch all user-facing URLs to hash-based for stability across restarts
After dedup migration, packet IDs from the legacy 'packets' table differ
from transmission IDs in the 'transmissions' table. URLs using numeric IDs
became invalid after restart when _loadNormalized() assigned different IDs.

Changes:
- All packet URLs now use 16-char hex hashes instead of numeric IDs
  (#/packets/HASH instead of #/packet/ID)
- selectPacket() accepts hash parameter, uses hash-based URLs
- Copy Link generates hash-based URLs
- Search results link to hash-based URLs
- /api/packets/:id endpoint accepts both numeric IDs and 16-char hashes
- insert() now calls insertTransmission() to get stable transmission IDs
- Added db.getTransmission() for direct transmission table lookup
- Removed redundant byTransmission map (identical to byHash)
- All byTransmission references replaced with byHash
2026-03-21 00:18:11 +00:00
you d621a9f34a Make ADVERT node names clickable links to node detail page 2026-03-21 00:09:30 +00:00
you 8c2d5d770f fix: Advertised Hash Size field shows byte offset 1 (path byte), not payload offset 2026-03-21 00:03:55 +00:00
you e7f2613d1e packets: show Advertised Hash Size prominently in ADVERT field table 2026-03-20 23:43:40 +00:00
you 84bf7fb545 packets: show hash_size in detail meta + fix blank hash_size in field table 2026-03-20 23:32:43 +00:00
you f1aa6caf93 fix: packet expand shows observations, heard-by uses correct field name
- pktToggleGroup fetches ?expand=observations and maps them as children
- Live page heard-by uses o.packetCount (was o.count → undefined)
2026-03-20 22:02:54 +00:00
you a882aae681 M5: Frontend updates for dedup — observation_count badges, totalTransmissions
- packets.js: Show observation_count badge (👁 N) on grouped rows
- nodes.js: Use totalTransmissions (fallback totalPackets), show observation badges on recent packets
- home.js: Use totalTransmissions for network stats
- node-analytics.js: Use totalTransmissions for throughput display
- analytics.js: Use totalTransmissions for overview stats and node rankings
- live.js: Use totalTransmissions in node detail, show observation badges in feed and recent packets
- style.css: Add .badge-obs style for observation count badges
- index.html: Bump cache busters on all changed JS/CSS files

All changes have backward compat fallbacks to totalPackets.
2026-03-20 21:31:10 +00:00
you f0db317051 fix: observer locations case-insensitive match, regions from API not hardcoded
- Observer ID is uppercase, node pubkey is lowercase — added COLLATE NOCASE
- New /api/config/regions endpoint merges config regions + observed IATAs
- map.js and packets.js fetch regions from API instead of hardcoded maps
2026-03-20 16:10:16 +00:00
you 8ef65def7d fix: make renderTableRows async (await broke packets page entirely) 2026-03-20 09:33:08 +00:00
you 9ef5c1a809 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.
2026-03-20 09:30:41 +00:00
you db884f12eb fix: 4 bugs - spark bars inline style, My Nodes filter field names, duplicate pin button, map dark mode
1. Spark bars: inline style override on td (max-width:none, min-width:80px)
2. My Nodes filter: pubkey→pubKey, to/from→srcPubKey/destPubKey/srcHash/destHash
3. Pin button: guard against duplicates in init, remove in destroy
4. Map page: CartoDB dark/light tiles with MutationObserver theme swap
2026-03-20 09:21:17 +00:00
you 039d1fc28f fix: resolve observer names from observers table in packets view
observer_name on packets is often NULL; now cross-references
the loaded observers list to display friendly names
2026-03-20 07:51:26 +00:00
you bee124e6d2 fix: shrink donut chart, show observer name in dropdown 2026-03-20 07:44:20 +00:00
you fceff15e2f feat: update URL bar when selecting a packet for easy sharing 2026-03-20 06:49:20 +00:00
you 395abc2585 feat: standalone packet detail page at #/packet/ID
- New route #/packet/123 shows full packet detail on its own page
- Back link to packets list
- Copy Link button now generates #/packet/ID URLs
- Reuses existing renderDetail() for consistent display
2026-03-20 06:44:18 +00:00
you e82e4fe05f fix: copy link URL format — use #/packets/id/N not query param 2026-03-20 06:42:12 +00:00
you 6cf9793706 feat: copy link button in packet detail pane 2026-03-20 06:41:36 +00:00
you cd678d492d perf: grouped mode also updates client-side from WS — zero API fetches
Existing groups get count/observer_count incremented, latest timestamp
updated, longest path kept. New hashes get a new group prepended.
Expanded children updated inline. No more /api/packets re-fetch on
any incoming packet in either mode.
2026-03-20 04:15:04 +00:00
you 4c6172bc6e perf: WS packets prepend client-side instead of re-fetching entire list
Non-grouped mode: new packets from WebSocket are filtered client-side
and prepended to the table, no API call. Grouped mode still re-fetches
(group counts change). Server broadcast now includes full packet row.
Eliminates repeated /api/packets fetches on every incoming packet.
2026-03-20 04:12:07 +00:00
you de658bfb0d perf: configurable cache TTLs via config.json — server + client fetch from /api/config/cache
All cache TTLs now read from config.json cacheTTL section (seconds).
Client fetches config on load via GET /api/config/cache.
config.example.json updated with defaults.
Edit config.json, restart server — no code changes needed to tweak TTLs.
2026-03-20 03:23:58 +00:00
you 720d019a28 perf: align cache TTLs with real data rates — analytics 30min-1hr, nodes 5min, chat 10-15s, stats 10s, server debounce 30s 2026-03-20 03:20:33 +00:00
you e98e04553a feat: add frontend API response caching with TTL, in-flight dedup, and WebSocket invalidation
- Replace api() with caching version supporting TTL and request deduplication
- Add appropriate TTLs to all api() call sites across all frontend JS files:
  - /stats: 5s TTL (was called 962 times in 3 min)
  - /nodes/:pubkey: 15s, /health: 30s, /observers: 30s
  - /channels: 15s, messages: 10s
  - /analytics/*: 60s, /bulk-health: 60s, /network-status: 60s
  - /nodes?*: 10s
- Skip caching for real-time endpoints (/packets, /resolve-hops, /perf)
- Invalidate /stats, /nodes, /channels caches on WebSocket messages
- Deduplicate in-flight requests (same path returns same promise)
- Add cache hit rate to window.apiPerf() console debugging
- Update all cache busters in index.html
2026-03-20 02:03:25 +00:00
you 36598a3623 mobile: hide hash column by default 2026-03-20 01:15:49 +00:00
you 0dc2dd3f25 mobile packets: bottom sheet detail, collapsed filters, smaller table, fewer columns
- Mobile (≤640px) default columns: time, hash, type, details (hide region, observer, path, rpt, size)
- Detail panel hidden on mobile; tapping row opens slide-up bottom sheet (70vh max, close button, drag handle)
- Filter bar collapses to single 'Filters' toggle button on mobile
- Table font 11px, tighter padding, no min-width forcing horizontal scroll
- Panel-right completely hidden on mobile (no split layout)
2026-03-20 01:14:32 +00:00
you ca21dc5608 feat: packets view — ★ My Nodes toggle filters to only claimed/favorited node packets 2026-03-19 23:09:44 +00:00
you 472090aeb5 Remove duplicate escapeHtml and debounce functions, keep globals in app.js
closes #28
2026-03-19 21:32:39 +00:00
you 71969785bf fix: packets accessibility — remove stopPropagation, add aria-live, add touch resize
closes #67
closes #68
closes #69
2026-03-19 21:11:15 +00:00
you 9e4308a1d0 fix: Excel-like column resize — drag steals from neighbor, percentages persist, panel drag reflows proportionally 2026-03-19 21:04:15 +00:00
you b0f6ccf12e fix: explicitly set left panel + table width during drag for live column reflow 2026-03-19 21:01:01 +00:00
you b36790445b fix: force table reflow during detail pane drag resize 2026-03-19 20:59:50 +00:00
you 1c25a2bc5b fix: packets — BYOP mobile, column toggle, max-width, race condition, destroy cleanup (closes #70, #71, #72, #73, #74) 2026-03-19 19:39:29 +00:00
you 5255f7091e fix: analytics — async race, guards, legend CSS, dedup API, responsive layout (closes #75, #76, #77, #78, #79, #80, #81) 2026-03-19 19:38:58 +00:00
you 1f3b8756af fix: ARIA tab pattern, form labels, focus management (closes #10, #13, #14) 2026-03-19 19:00:43 +00:00
you 3372870674 fix: packets mobile columns, BYOP dialog a11y, filter combobox ARIA (closes #18, #65, #66) 2026-03-19 18:58:32 +00:00
you 72743fd9ee fix: WS debounce helper, clean up remaining window globals (closes #7, #8) 2026-03-19 16:51:34 +00:00
you 080d4bc3c1 fix: home.js listener stacking, packets.js filter bar rebuild (closes #4, #6) 2026-03-19 16:46:41 +00:00
you b4d0d6a056 fix: make table rows keyboard-accessible with delegated event listeners (fixes #9)
- Replace inline onclick on <tr> elements with data-action/data-value attributes
- Add tabindex="0" and role="row" to all clickable rows
- Add delegated click and keydown (Enter/Space) listeners on containers
- Remove window._pktSelect, _pktToggleGroup, _pktSelectHash, _nodeSelect globals
- Convert to local functions referenced by delegated handlers

Affected files: packets.js, nodes.js, analytics.js
(channels.js and observers.js had no interactive <tr> elements)
2026-03-19 15:50:18 +00:00
you 5205cf04fe fix: escape decoded.text and decoded.name in innerHTML to prevent XSS (fixes #5)
- nodes.js: escape decoded.text and decoded.name in advertisement list rendering
- packets.js: escape decoded.text in summary display and decoded.name in fieldRow
2026-03-19 15:46:04 +00:00
you 02b8034a4c Fix observer location for hop disambiguation
- ADVERT is payload_type 4 not 1
- Frontend sends observer_id (not just observer_name) since some
  observers have null name
- Observer position derived from geographic center of nodes it
  commonly receives ADVERTs from
- Last hop in path disambiguated by proximity to observer position
2026-03-19 08:26:37 +00:00
you 81520e4660 Fix hop disambiguation: last hop prefers observer proximity
- Observer name resolved to lat/lon for geographic context
- Last hop in path sorted by distance to observer (not center)
  since it's the node that delivered the packet to the observer
- Packets page now passes observer_name to /api/resolve-hops
- Fixes CroatR1 being picked over Test Repeater for hop 8A
2026-03-19 08:18:26 +00:00
you ec87455b79 Pass server-disambiguated full pubkeys to map route view
Was fetching /api/resolve-hops (with geographic disambiguation) then
throwing away the result and still passing raw 1-byte prefixes. Now
passes full pubkeys so the map doesn't re-disambiguate differently.
2026-03-19 08:15:39 +00:00