Commit Graph

1615 Commits

Author SHA1 Message Date
James Smith 47ab080ca8 feat: retire data-animations from index.html, login.html, and base_dashboard.html 2026-05-19 22:25:38 +01:00
James Smith 5aba99f998 feat: add Display Mode step to first-run setup modal 2026-05-19 22:23:58 +01:00
James Smith cc9ca6375d feat: replace animations toggle with display mode selector in settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 22:22:05 +01:00
James Smith b1e238b398 feat: add tier toggle button to nav; migrate data-animations restore to data-ui-tier 2026-05-19 22:20:31 +01:00
James Smith 369da480d7 feat: add lean/enhanced component overrides; retire data-animations component CSS 2026-05-19 22:18:48 +01:00
James Smith b6f37ea64b feat: add lean/enhanced layout overrides; retire data-animations CSS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 22:16:50 +01:00
James Smith 5d0162628a feat: add lean/enhanced body background overrides 2026-05-19 22:14:25 +01:00
James Smith b57ea83f82 feat: add lean and enhanced CSS variable override blocks 2026-05-19 21:55:01 +01:00
James Smith 11c95ff5d1 chore: remove project-local CLAUDE.md 2026-05-19 11:53:44 +01:00
James Smith f2712c9d2e debug(meshcore): enable BLE debug mode and disconnect before connect
- Enable debug=True on MeshCore.create_ble() to surface verbose logs
- Disconnect any existing BlueZ connection before bleak connects to
  avoid conflicts from prior bluetoothctl/pairing sessions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:15:24 +01:00
Smittix 50a486c39e Merge pull request #229 from smittix/fix/meshcore-connect-error-reporting
fix(meshcore): surface backend error messages and extend polling window
2026-05-13 21:00:55 +01:00
James Smith cfa5333845 fix(meshcore): surface backend error messages and extend polling window
- Store last status message on MeshcoreClient so error details survive
  beyond the SSE event (which isn't active during connecting state)
- Status endpoint now returns message field so the frontend can show
  the real reason (e.g. 'Connection failed after retries: ...')
- Extend JS polling from 30s to 90s to outlast the backend's 65s
  retry sequence (5+15+45s delays) before declaring timeout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:59:33 +01:00
Smittix 152fd4753d Merge pull request #228 from smittix/fix/meshcore-ble-scan-gevent
fix(meshcore): run BLE scan in dedicated thread to avoid gevent conflict
2026-05-13 20:53:02 +01:00
James Smith 43dd957d36 fix(meshcore): run BLE scan in dedicated thread to avoid gevent conflict
asyncio.run() called from a gevent-patched Flask thread fails under
gunicorn+gevent. Run the one-shot scan in a ThreadPoolExecutor thread
with its own event loop, matching how AsyncWorker handles it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:52:44 +01:00
Smittix bbd7ead8fd Merge pull request #227 from smittix/fix/meshcore-ble-scan-500
fix(meshcore): fix BLE scan 500 and allow scan before connect
2026-05-13 20:50:06 +01:00
James Smith bd8df72093 fix(meshcore): revert wrong scan_ble_sync route call, fix scan without worker
- Revert route to scan_ble() — scan_ble_sync() lives on AsyncWorker,
  not MeshcoreClient; the 500 was caused by our previous fix
- MeshcoreClient.scan_ble() now runs a one-shot asyncio scan when no
  worker is active, so Scan works before Connect is pressed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:49:44 +01:00
Smittix 836e66846a Merge pull request #226 from smittix/fix/meshcore-ble-scan-method
fix(meshcore): call scan_ble_sync() in BLE scan route
2026-05-13 20:47:38 +01:00
James Smith 345654216e fix(meshcore): call scan_ble_sync() not scan_ble() in ble/scan route
Route was calling a non-existent method, causing a 500 on every scan.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:47:07 +01:00
Smittix 10841b9aa1 Merge pull request #225 from smittix/fix/meshcore-ble-scan
fix(meshcore): BLE scan feedback and cancel while connecting
2026-05-13 20:43:02 +01:00
James Smith 1f573ee6ed fix(meshcore): BLE scan feedback and cancel-during-connecting
- Scan button shows 'Scanning...' and disables during fetch; shows
  'No devices found' or 'Scan failed' on empty/error result; auto-
  selects device if only one is returned
- Disconnect button now enabled during 'connecting' state so users
  can cancel a stuck connection and retry with a different device

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:42:25 +01:00
Smittix 4658be799a Merge pull request #224 from smittix/fix/meshcore-connect-timeout
fix(meshcore): show error when connection times out
2026-05-13 20:39:30 +01:00
James Smith 5af970efc0 fix(meshcore): show error state when connection times out
After 30s of polling with no response, update UI to 'Connection timed
out' instead of silently leaving the dot stuck on Connecting...

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:39:16 +01:00
Smittix 1eb3762f32 Merge pull request #223 from smittix/fix/meshcore-ux-feedback
fix(meshcore): layout height, connection polling, and modal visibility
2026-05-13 17:33:05 +01:00
James Smith 40c000d60d fix(meshcore): fix layout height, connection polling, and modal visibility
- Add base flex properties to #meshcoreVisuals so it fills full panel
  height when meshtastic.css hasn't been lazily loaded yet
- Poll /meshcore/status every 2s after Connect click so the UI
  transitions out of "Connecting..." when the backend is ready
- Fix Add Contact and Traceroute modals to use .show class pattern
  (signal-details-modal uses opacity/visibility transitions, not display)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 16:59:59 +01:00
Smittix dede08b66a Merge pull request #221 from smittix/fix/meshcore-fill-height
fix(meshcore): fill panel height by removing intermediate wrapper div
2026-05-13 13:02:02 +01:00
James Smith 6232e650a7 fix(meshcore): make strip and body direct children of visuals container
Remove the intermediate #meshcoreMode wrapper div that was breaking the
flex height chain. Strip and body are now direct children of
#meshcoreVisuals (matching the Meshtastic pattern), so flex: 1 propagates
correctly and the content fills the full panel height.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 12:16:02 +01:00
Smittix 0df0b1f88e Merge pull request #220 from smittix/fix/meshcore-sidebar-hidden-css
fix(meshcore): add mesh-sidebar-hidden rules to meshcore.css
2026-05-13 12:06:36 +01:00
James Smith a63939b0f0 fix(meshcore): add mesh-sidebar-hidden rules to meshcore.css
The sidebar-hiding CSS lives only in meshtastic.css, which is lazily
loaded and may not be present when switching directly to Meshcore mode.
Duplicating the three rules into meshcore.css ensures the generic
sidebar is correctly hidden and the output panel fills the screen
regardless of load order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 11:32:14 +01:00
Smittix 5dce49daaa Merge pull request #219 from smittix/fix/meshcore-strip-layout-and-map-tiles
fix(meshcore): restyle to strip layout, fix map tiles
2026-05-13 10:54:35 +01:00
James Smith 4f717bb454 fix(meshcore): restyle to strip layout, fix map tiles
Replaced inner-sidebar layout (which collided with the generic app
sidebar) with a Meshtastic-style top connection strip + body row.
Contacts/nodes panel sits left of the tabbed content area, matching
the established pattern. Map now uses Settings.createTileLayer() with
a dark CartoDB fallback instead of plain OSM light tiles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 10:23:31 +01:00
Smittix 5f6aca54eb Merge pull request #218 from smittix/fix/meshcore-visuals-layout
fix(meshcore): move UI into visuals container, fix layout
2026-05-13 10:15:56 +01:00
James Smith b6786822e8 fix(meshcore): move UI into visuals container, fix layout
meshcoreMode partial was inside the generic .sidebar which gets hidden
when meshcore mode is active. Moved the include into meshcoreVisuals
(inside the output panel) — matching the same pattern as Meshtastic.
Also overrides mesh-visuals-container's column/padding defaults so the
meshcore sidebar+main row layout renders correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 10:15:14 +01:00
Smittix 9cee687af5 Merge pull request #217 from smittix/fix/meshcore-active-display
fix(meshcore): show mode panel when active
2026-05-13 10:11:10 +01:00
James Smith a392b30cd9 fix(meshcore): show mode panel when active
meshcore.css was missing the .active display rule, so the meshcoreMode
div (display:none inline) was never made visible when the mode was
selected, leaving only the generic sidebar visible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 10:10:25 +01:00
Smittix b2aa27da97 Merge pull request #216 from smittix/fix/meshcore-nav-and-card-styling
fix(meshcore): add to nav and fix welcome card styling
2026-05-13 10:06:40 +01:00
James Smith c554cbcacf fix(meshcore): add to nav and fix welcome card styling
Meshcore was missing from both the desktop Wireless dropdown and mobile
nav. The welcome card also used non-standard div/emoji markup instead of
the SVG icon pattern used by every other mode, causing wrong font and
colour rendering.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 10:02:45 +01:00
James Smith bd6a5f132e fix(drone): use Settings tile layer for theme-aware map
Replace hardcoded OSM tiles with Settings.createTileLayer() + registerMap()
so the drone map respects the user's map theme preference and switches
automatically with light/dark theme changes. Falls back to CartoDB dark_all
if Settings is unavailable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 09:58:04 +01:00
James Smith 8caeb4b961 fix(drone): fix main panel height collapse in flex output container
Replace height:100% with flex:1+min-height:0 on .drone-visuals-container
so it fills the flex-column .output-panel correctly (height:100% collapses
inside a scroll container). Add min-height:400px to .drone-main-map so
Leaflet has pixel dimensions to render into.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 09:45:00 +01:00
James Smith 2537c6d140 fix(drone): conform to established SPA patterns throughout
- Device population: move refreshDroneDevices() inline to index.html
  (same pattern as refreshTscmDevices) and call it from switchMode
  alongside DroneMode.init(); remove _refreshDevices/populateSelect
  from drone.js which was never guaranteed to run before lazy-load
  completed, causing selects to stay on "Loading…" permanently

- IIFE pattern: change from named IIFE + window.DroneMode assignment
  to var DroneMode = (function(){...return{...}})() matching OOK/
  SpyStations convention

- Init guard: add _initialized flag (OOK state.initialized pattern);
  re-entry after destroy() re-registers map/SSE cleanly without
  duplicating click listeners on every mode switch

- Lifecycle: destroy() resets _initialized = false so map and SSE
  are correctly rebuilt on re-entry

- Stop phase: add isDroneRunning tracking variable in index.html;
  _setRunningUI() syncs it; switchMode stop phase now POSTs
  /drone/stop when leaving drone mode while active, matching TSCM

- /drone/devices: add monitor_capable field to WiFi interfaces,
  add running_as_root and warnings array to response (mirrors
  /tscm/devices shape); add os import; show privilege warning div
  in drone.html when not running as root

- drone.html: remove for= attribute from SDR label (plain <label>
  inside .form-group matches TSCM convention); add droneDeviceWarnings
  div for privilege warnings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 09:33:38 +01:00
James Smith 9fd60b6839 feat(drone): replace freeform inputs with populated device selects
Add /drone/devices endpoint that enumerates available WiFi interfaces
(via iw/iwconfig) and RTL-SDR devices (via SDRFactory.detect_devices),
matching the pattern used by TSCM.

Sidebar WiFi interface and RTL-SDR inputs are now <select> elements
populated on init() from /drone/devices, consistent with how other
modes expose hardware selection. HackRF checkbox remains as a toggle
since it's a binary capability rather than an enumerated device list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 09:25:21 +01:00
James Smith ba3ee1575e feat(drone): add main visuals panel with map and contact list
- Sidebar inputs now use form-group/label pattern matching other modes
- Move map and contact list out of sidebar into a dedicated droneVisuals
  main panel (same pattern as tscm, spystations, etc.)
- droneVisuals: stats header (contacts / non-compliant / high-risk),
  left contact card panel, and full-height Leaflet map on the right
- Wire droneVisuals into switchMode display toggle and modesWithVisuals
  so the shared signal-feed output is hidden when drone mode is active
- Add invalidateMap() to force Leaflet to recalculate after the
  container becomes visible
- Stats now update both sidebar counts and main panel values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 09:16:54 +01:00
James Smith 09142420ab fix(drone): show sidebar panel and expose SDR config options
Remove inline style="display: none;" that was preventing the droneMode
panel from becoming visible when the active class was toggled — inline
styles override CSS class rules without !important. Add RTL-SDR device
index and HackRF toggle inputs that the backend already accepted but
were never surfaced in the UI; wire them through to the /drone/start
POST body.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 09:07:42 +01:00
James Smith 8dd30ea847 feat(meshcore): wire Meshcore into index.html (14 insertion points) 2026-05-11 15:47:27 +01:00
James Smith fca950bf98 feat(meshcore): add frontend JS module (IIFE, SSE, map, telemetry, traceroute) 2026-05-11 14:58:45 +01:00
James Smith 93b93fe3d6 feat(meshcore): add HTML partial (sidebar, tabs, modals)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 12:58:29 +01:00
James Smith e3a1f8430c feat(meshcore): add CSS for Meshcore mode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 12:56:58 +01:00
James Smith 4927c7d1a4 feat(meshcore): register blueprint and add meshcore dependency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 12:55:37 +01:00
James Smith a9e52bc52e test(meshcore): assert error message propagated in on_error test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 12:54:30 +01:00
James Smith a6b86dc79f test(meshcore): fix BLE docker test and add library boundary isolation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 12:51:45 +01:00
James Smith 62a3fe95ea test(meshcore): add integration tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 12:49:05 +01:00