Skip to content

Sync main with dev#16

Merged
MrAlders0n merged 58 commits intomainfrom
dev
Mar 20, 2026
Merged

Sync main with dev#16
MrAlders0n merged 58 commits intomainfrom
dev

Conversation

@MrAlders0n
Copy link
Copy Markdown
Contributor

  • Add offline mode prompt when zone check fails due to no internet
  • Added option to disable carpeater RSSI filter under settings
  • Multi-hop CARpeater packets now strip the CARpeater hop and report coverage from the underlying repeater with null SNR/RSSI, instead of being dropped entirely. Single-hop packets and discovery responses are still dropped. The -30 dBm failsafe is bypassed for packets matching your CARpeater prefix but stays active for everything else.
  • Added Code of Conduct & Security
  • Update links
  • Exclude .vscode/ from version control
  • Bug fixes:
  • ** Anonymous Mode — New privacy option in Settings that renames your device to "Anonymous" for all mesh pings. When enabled, other mesh users cannot see your companion name in wardrive broadcasts. Your device's public key is still used to authenticate your session with the MeshMapper API (geo-auth), but neither your sessions nor your pings are linked to it on the server. Toggling Anonymous Mode while connected automatically disconnects and reconnects with the new identity, switching to the Connection tab so you can see reconnection progress. On proper disconnect, the original device name is restored. Persisted across app restarts.**
  • Update repeater endpoint from /repeaters.json to /get_repeaters.php
  • ### New Features - Automatic map tile refresh after successful data upload, so new coverage appears on the map within the app near real-time - Deterministic 5-second upload timer for TX and discovery pings, replacing the old batch system that could take up to 20 seconds
  • Regional Flood Scoping: TX pings(Active Mode) are now scoped to your region's flood zone. Regional Admins set a scope in the admin panel, so only repeaters in your region forward wardriving pings. Discovery pings are unaffected. If no scope is assigned, pings flood globally as before.
  • New Features
  • ### Improvements - Admin-enforced settings now include reworded messaging with a brief explanation of why the constraint benefits the mesh
  • ## Bug Fixes
  • Debug logging is now enabled by default on all builds (not just dev builds), and the user's toggle preference is persisted across app restarts via Hive
  • The API returns "scopes":["#"] for zones with no regional scope. The code only checked for '' as the wildcard, so '#*' fell through to the scope-setting path.
  • Added dialog to upload logs window
  • ** Add Discovery Drop feature — failed discovery requests can now be reported to the API as failed pings (repeater_id: "None"), helping identify dead zones. Includes user toggle in Settings (default off), API-enforced override via disc_drop auth field, red markers on map/noise floor chart for failed discoveries when enabled.**
  • ** New Feature MeshCore firmware v1.14.0+ supports multi-byte path hashes (1, 2, or 3 bytes per hop), expanding repeater ID space from 256 to 65K or 16M unique IDs. The app now fully supports this protocol change.**
  • Add hopBytes support and update repeater display logic
  • Refactor settings screen theme and unit toggles to use SwitchListTile; improve UI text for clarity
  • Repeater markers now rotate with the map and stay upright
  • Prevent duplicate GPS stream subscriptions on restart (Prevent duplicate GPS stream subscriptions on restart #6)
  • Own and dispose app-level stream subscriptions (Own and dispose app-level stream subscriptions #7)
  • Fix mobile BLE scan stream completion and cleanup (Fix mobile BLE scan stream completion and cleanup #8)
  • Bump version to 1.2.0 and enhance authentication flow with staged public_key and contact_uri registration
  • - Hive corruption fallback for ping queue: When the api_queue Hive box fails to open (e.g. corruption), _safeWrite() was silently returning false and dropping all enqueued pings. A full wardrive session could complete with zero ping data uploaded, as all POSTs would be heartbeats only. Fixed by adding a _memoryQueue in-memory fallback: failed writes go to memory instead of being dropped, _uploadBatch drains both Hive and memory queues, queueSize reflects both, and all clear/disconnect/init paths also flush _memoryQueue.
  • Add heartbeat retry, local session expiry tracking, and offline queue preservation
  • Cancel stale auto-ping restore timers (Cancel stale auto-ping restore timers #10)
  • Recheck location permission after disclosure (Recheck location permission after disclosure #11)
  • - Discovery pings now extract repeater IDs using the region's hop byte count instead of always assuming 1 byte. In multi-byte regions, TX/RX logs showed full IDs like "4E7A" while discovery logs still showed the truncated "4E"
  • fixed overflow in disc request byte count fix
  • - Added option to keep the #wardriving channel after exiting a session (#149, @skye)
  • - Minimum ping distance is now configurable for TX and discovery pings. The default 25m floor stays the same, but users can increase it to reduce unnecessary pings in dense city driving or stop-and-go traffic. RX batch flushing distance is unaffected.
  • - GPS-related zone check errors (inaccurate/stale) no longer retry every 5 seconds or auto-switch to the error tab. The next zone check waits until the user moves 100m instead of hammering retries while stationary. The zone status bar now shows a GPS icon with "GPS Unavailable" in orange, and the full-screen error view displays a specific title and message with a manual "Retry Zone Check" button.
  • ** lib/screens/settings_screen.dart — Replaced the radio button dialog with a text field. Users type any number they want (minimum 25m enforced). The field shows "meters" as a suffix and "Minimum 25m" as helper text. Save button only accepts valid integers >= 25.**
  • - Hybrid mode now defaults to enabled for new users and existing users who haven't explicitly toggled it off. Saved preferences are preserved.
  • Implmented Trace Mode
  • - Fixed a regression where device firmware version was no longer being parsed correctly
  • - Redesigned the Connection tab for clarity. The previous layout was getting cluttered and hard to navigate. - Offline data session management is now always visible under Settings.
  • ### Bug Fixes - Fixed offline wardrive pings being lost when the app was killed by the OS, backgrounded, or disconnected mid-session - Offline pings now auto-save periodically, so at most ~60 seconds of data is lost in a worst-case app kill - Disconnecting while in offline mode now saves accumulated pings before cleanup - App backgrounding/suspension now triggers an immediate save of offline ping data
  • ** Bug 1 — Trace Mode fails after path byte mode switch: - lib/services/ping_service.dart:71: Changed final int _hopBytes to int _hopBytes and added a set hopBytes setter - lib/providers/app_state_provider.dart:1961: Added _pingService?.hopBytes = newHopBytes; in _applyLivePathHashMode() so PingService stays in sync when the user changes path mode at runtime**
  • ### Improvements - Auto-ping now shows "Skipped Xs" when a ping is skipped due to insufficient movement (25m minimum), replacing the generic countdown label across all UI layouts
  • ### New Features - Auto-stop after idle: auto-ping now automatically stops after 30 minutes of continuous skipped pings (no movement), saving battery and radio activity - New "Auto-Stop After Idle" toggle in Settings (default: ON), located under Min Ping Distance
  • fix trace bytes
  • Added Repeater Picker dropdown for traces
  • Final fixes for trace mode
  • Log tab redesign
  • Resigned log & settings screen
  • New Features - Live repeater snapshot: enable it in Settings to see the top 3 responded repeaters from your last ping, updating live as you wardrive
  • ### Bug Fixes - Connection screen now shows a "Server Unreachable" message with offline mode suggestion when auth fails due to network errors, instead of a generic error. - Fixed zone check flooding when driving with no network. Previously, every GPS update triggered an API call when the network was down. Position is now tracked even on failed calls, so retries are handled by the 5-second timer instead.
  • - Updated landscape controls to match the new portrait layout and added Trace mode support. - Updated the UI for the top heard repeaters display.
  • - Added text scale clamping for device accessibility settings. Previously the system text scale factor was applied unclamped across the entire app, which could break layouts at larger text sizes.
  • Fixing some font sizing and layouts
  • Fixed trace mode chip and trace icon
  • ### New Features - Persistent radio power overrides: custom TX power settings are now saved per device, similar to antenna selection. On connect, your previously set power override is automatically applied with a visual indicator showing it's been overridden. A "Reset to Auto" button in the power selector restores the auto-detected power for your device model.
  • ### New Features - Persistent radio power overrides: custom TX power settings are now saved per device, similar to antenna selection. On connect, your previously set power override is automatically applied with a visual indicator showing it's been overridden. A "Reset to Auto" button in the power selector restores the auto-detected power for your device model.

MrAlders0n and others added 30 commits February 17, 2026 13:14
When the zone status check fails with a network error, show a full-screen
UI with an "Enable Offline Mode" button (matching the maintenance mode
pattern) instead of the generic "Zone Check Failed" message. Also adds a
red "No Internet" indicator in the zone status bar. Non-network errors
retain the existing behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…verage from the underlying repeater with null SNR/RSSI, instead of being dropped entirely. Single-hop packets and discovery responses are still dropped. The -30 dBm failsafe is bypassed for packets matching your CARpeater prefix but stays active for everything else.
Editor-specific configs shouldn't be tracked in a public repo so
contributors can use their own setups.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- [#98](MeshMapper/MeshMapper_Project#98) - The heard repeaters panel now scrolls and dynamically expands to accommodate larger lists of heard repeaters
- [#95](MeshMapper/MeshMapper_Project#95) - Fixed the IATA popup panel being hidden behind the Android navigation bar
- Fixed a bug where a stale BLE device name was used instead of the current one
…vice to "Anonymous" for all mesh pings. When enabled, other mesh users cannot see your companion name in wardrive broadcasts. Your device's public key is still used to authenticate your session with the MeshMapper API (geo-auth), but neither your sessions nor

  your pings are linked to it on the server. Toggling Anonymous Mode while connected automatically disconnects and reconnects with the new identity, switching to the Connection tab so you can see reconnection progress. On proper disconnect, the original device name is restored. Persisted across app restarts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Automatic map tile refresh after successful data upload, so new coverage appears on the map within the app near real-time
- Deterministic 5-second upload timer for TX and discovery pings, replacing the old batch system that could take up to 20 seconds

### Bug Fixes
- Fixed tile refresh race condition that caused half-rendered tiles and ghost tiles at certain zoom levels
- Fixed Light (OSM) and Satellite (ArcGIS) tiles failing to load at low zoom on iOS retina displays

### Improvements
- Faster ping cycle with reduced listen window (7s to 5s) for TX echo, discovery response, and auto-ping cooldown
- Map zoom range adjusted to 3-17
- Updated repeater endpoint from /repeaters.json to /get_repeaters.php
- Immediate upload on disconnect with no wait period
…region's flood zone. Regional Admins set a scope in the admin panel, so only repeaters in your region forward wardriving pings. Discovery pings are unaffected. If no scope is assigned, pings flood globally as before.
    Regional admins can now enforce hybrid mode per-zone via the API; when enabled, hybrid mode is automatically activated and the toggle is locked on the Settings screen with a "Forced Enabled by Regional Admin" label
    Regional admins can set a minimum auto-ping interval per-zone; interval options below the minimum are greyed out in Settings with a "Disabled by Regional Admin" label
    If a user's saved interval falls below the admin-configured minimum, it is automatically bumped up on connect
- Admin-enforced settings now include reworded messaging with a brief explanation of why the constraint benefits the mesh
- Fixed RX carpeater detection checking the wrong hop position. On RX packets, the carpeater is co-located with the wardriver so it only appears as the last hop (delivery repeater), not the first. The check now correctly evaluates the last hop.
…uilds), and the user's toggle preference is persisted across app restarts via Hive
… code only checked for '*' as the wildcard, so '#*' fell through to the

  scope-setting path.
…ported to the API as failed pings (repeater_id: "None"), helping identify dead zones. Includes

  user toggle in Settings (default off), API-enforced override via disc_drop auth field, red markers on map/noise floor chart for failed discoveries when enabled.
MeshCore firmware v1.14.0+ supports multi-byte path hashes (1, 2, or 3 bytes per hop), expanding repeater ID space from 256 to 65K or 16M unique IDs. The app now fully supports this protocol change.
- Introduced hopBytes property in Repeater model to manage bytes per hop.
- Updated AppStateProvider to reflect changes in path hash mode.
- Enhanced connection_screen and settings_screen to accommodate hopBytes settings.
- Modified map_widget to display repeater markers based on hopBytes.
- Improved repeater_id_chip to show hex ID badges with dynamic sizing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clean fix, guarding startWatching() against stacked subscriptions. Placement at the top of the method is correct (before any early returns). Pattern matches existing subscription management elsewhere in the codebase.
Good catch. These three stream subscriptions were the last unowned listeners in AppStateProvider. The fix mirrors the existing pattern used for _adapterStateSubscription, _logRxDataSubscription, _noiseFloorSubscription, and _batterySubscription. Clean and consistent.
Fixes a real issue: the scan stream had no termination path, which could leave callers hanging. The three cleanup paths (natural stop, manual stop, finally) cover all cases well. The identical() check on _scanController is a nice detail for rapid re-scan scenarios. 

Minor note: the unawaited watcher on isScanning could theoretically fire before scan results arrive if isScanning briefly emits false during startup, but the !controller.isClosed guards prevent any actual breakage.
…ive box fails to open (e.g. corruption), `_safeWrite()` was silently returning false and dropping all enqueued pings. A full wardrive session could complete with zero ping data uploaded, as all POSTs would be heartbeats only. Fixed by adding a `_memoryQueue` in-memory fallback: failed writes go to memory instead of being dropped, `_uploadBatch` drains both Hive and memory queues, `queueSize` reflects both, and all clear/disconnect/init paths also flush `_memoryQueue`.
… preservation

- Heartbeat retries on network failure with exponential backoff (5 attempts, 30s-120s)
- Local session deadline timer fires at expires_at, triggers session error if backend is unreachable
- On session expiry, queued wardrive data is saved as an offline session instead of discarded
LGTM. Right fix, matches the pattern used by _reconnectTimer and _reconnectTimeoutTimer. The generation counter is slightly defensive given Dart's single-threaded model but adds no complexity so no complaints.
Clean separation of disclosure (show once) from permission (always recheck), plus proper permanently-denied handling
…s. The default 25m floor stays the same, but users can increase it to reduce unnecessary pings in dense city driving or stop-and-go traffic. RX batch flushing distance is unaffected.
…ery 5 seconds or auto-switch to the error tab. The next zone check waits until the user moves 100m instead of hammering retries while stationary. The zone status bar now shows a GPS icon with "GPS Unavailable" in orange, and the full-screen error view displays a specific title and message with a manual "Retry Zone Check" button.
…with a text field. Users type any number they want (minimum 25m enforced). The field shows

  "meters" as a suffix and "Minimum 25m" as helper text. Save button only accepts valid integers >= 25.
…s who haven't explicitly toggled it off. Saved preferences are preserved.
…getting cluttered and hard to navigate.

- Offline data session management is now always visible under Settings.
- Fixed offline wardrive pings being lost when the app was killed by the OS, backgrounded, or disconnected mid-session
- Offline pings now auto-save periodically, so at most ~60 seconds of data is lost in a worst-case app kill
- Disconnecting while in offline mode now saves accumulated pings before cleanup
- App backgrounding/suspension now triggers an immediate save of offline ping data
  - lib/services/ping_service.dart:71: Changed final int _hopBytes to int
  _hopBytes and added a set hopBytes setter
  - lib/providers/app_state_provider.dart:1961: Added _pingService?.hopBytes =
  newHopBytes; in _applyLivePathHashMode() so PingService stays in sync when the
   user changes path mode at runtime

  Bug 2 — "No log files available" when only active log exists:
  - lib/widgets/upload_logs_dialog.dart:67: Changed
  DebugFileLogger.listUploadableLogFiles() to
  widget.appState.prepareDebugLogsForUpload() — this rotates the active log
  first (same pattern as BugReportSheet), so the rotated file appears in the
  list
- Auto-ping now shows "Skipped Xs" when a ping is skipped due to insufficient movement (25m minimum), replacing the generic countdown label across all UI layouts
- Auto-stop after idle: auto-ping now automatically stops after 30 minutes of continuous skipped pings (no movement), saving battery and radio activity
- New "Auto-Stop After Idle" toggle in Settings (default: ON), located under Min Ping Distance
- Live repeater snapshot: enable it in Settings to see the top 3 responded repeaters from your last ping, updating live as you wardrive

**Improvements**
- Redesigned the Log tab
- Redesigned the Settings tab
- Connection screen now shows a "Server Unreachable" message with offline mode suggestion when auth fails due to network errors, instead of a generic error.
- Fixed zone check flooding when driving with no network. Previously, every GPS update triggered an API call when the network was down. Position is now tracked even on failed calls, so retries are handled by the 5-second timer instead.

### Improvements
- Online/offline toggle redesigned to look more clearly like a button.
…ed Trace mode support.

- Updated the UI for the top heard repeaters display.
…usly the system text scale factor was applied unclamped across the entire app, which could break layouts at larger text sizes.
- Persistent radio power overrides: custom TX power settings are now saved per device, similar to antenna selection. On connect, your previously set power override is automatically applied with a visual indicator showing it's been overridden. A "Reset to Auto" button in the power selector restores the auto-detected power for your device model.

### Improvements
- Redesigned the Top Heard overlay. Now shows the repeaters that heard your most recent ping sorted by SNR, with color-coded indicators per ping type (green for TX, purple for Discovery, cyan for Trace, blue for RX). Top 3 slots show the best results from your latest ping and fully replace on each new ping. A separate RX slot shows the strongest passively overheard repeater within a rolling 5-second window. Overlay clears on auto-ping stop, mode switch, disconnect, or log clear.
- Persistent radio power overrides: custom TX power settings are now saved per device, similar to antenna selection. On connect, your previously set power override is automatically applied with a visual indicator showing it's been overridden. A "Reset to Auto" button in the power selector restores the auto-detected power for your device model.

### Improvements
- Redesigned the Top Heard overlay. Now shows the repeaters that heard your most recent ping sorted by SNR, with color-coded indicators per ping type (green for TX, purple for Discovery, cyan for Trace, blue for RX). Top 3 slots show the best results from your latest ping and fully replace on each new ping. RX slot now shows the strongest passively overheard repeater within a rolling window that matches your auto-ping interval (15s, 30s, or 60s) instead of a hardcoded 5 seconds. Overlay clears on auto-ping stop, mode switch, disconnect, or log clear.
@MrAlders0n MrAlders0n merged commit 9d819b8 into main Mar 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants