Enhance documentation and features

- Updated supported languages to include Hungarian, Japanese, and Korean.
- Added new on-device message translation feature with detailed usage instructions.
- Introduced emoji reactions in chat with user interface and functionality details.
- Implemented linkification for automatic detection of URLs and meshcore URIs in messages.
- Added GPX export functionality for contacts with GPS coordinates.
- Enabled pinch-to-zoom for chat text scaling.
- Documented background service for Android to maintain BLE connection in the background.
- Revised BLE protocol documentation to reflect changes in connection state machine and command codes.
- Updated channels documentation to clarify message display and interaction options.
- Enhanced chat and messaging documentation with new translation button and message metadata.
- Clarified contact actions in contacts documentation.
- Adjusted map and location documentation for improved node name visibility and filter options.
- Revised navigation documentation to streamline disconnection process.
- Improved notification documentation to specify batch notification behavior.
- Updated repeater management documentation to reflect new features and settings.
- Enhanced scanner and connection documentation for device filtering and connection timeout.
- Expanded settings documentation to include new translation options.
- Removed jni plugin references from generated plugin files for Linux and Windows.
This commit is contained in:
zjs81
2026-05-09 17:19:58 -07:00
parent b472ea8c70
commit c229b0369e
14 changed files with 431 additions and 136 deletions
+76 -2
View File
@@ -25,8 +25,8 @@ A bottom sheet with a search field and a grid of GIF thumbnails.
### How to Access
App Settings → Appearance → Language
### Supported Languages (15)
English, French, Spanish, German, Polish, Slovenian, Portuguese, Italian, Chinese, Swedish, Dutch, Slovak, Bulgarian, Russian, Ukrainian
### Supported Languages (18)
English, French, Spanish, German, Polish, Slovenian, Portuguese, Italian, Chinese, Swedish, Dutch, Slovak, Bulgarian, Russian, Ukrainian, Hungarian, Japanese, Korean
### How It Works
- All UI strings go through Flutter's ARB localization system
@@ -185,3 +185,77 @@ An ML-based service that predicts expected delivery timeouts:
- Blends per-contact statistics with ML predictions
- Falls back to `3000 + 3000 × pathLength` ms when insufficient data
- Observations are persisted to storage via a 2-second debounced timer (observations within 2s of app termination may be lost)
---
## On-Device Message Translation
### What It Is
An optional on-device translation service powered by an embedded LLM (llamadart, running GGUF models). Translation runs entirely on-device — no data leaves the app.
### How to Access
Tap the translate button on any received message. On first use, the GGUF model file is downloaded and cached locally.
### How It Works
- Model files are managed by `TranslationFileStore`; download progress is shown in-place
- Translation runs via `TranslationService` using the llamadart CPU backend (arm64 and x64 on Android)
- Translated text is shown in `TranslatedMessageContent` as an inline overlay on the original message bubble
- Each translation is cached; re-tapping shows the cached result without re-running inference
---
## Emoji Reactions
### How to Access
Long-press a message bubble in any direct or channel chat, then select a reaction emoji.
### What the User Sees
An emoji picker inline with common reactions. Selected reactions appear below the message bubble with a count.
### How It Works
- Implemented via `emoji_picker.dart` and `reaction_helper.dart`
- Reactions are transmitted as a special message type visible to all participants with MeshCore Open
---
## Linkification
### What It Does
URLs and `meshcore://` URIs in received messages are automatically detected and rendered as tappable links.
### How It Works
- Powered by the `flutter_linkify` package via `link_handler.dart`
- Tapping a URL opens the system browser; tapping a `meshcore://` URI imports the contact
---
## GPX Export
### How to Access
Settings → Export section (three options: Export Repeaters, Export Contacts, Export All).
### What It Does
Exports contacts with GPS coordinates to a `.gpx` file via the OS share sheet. Not available on web.
---
## Pinch-to-Zoom Chat Text
### What It Does
Users can pinch to scale all chat text up or down within a session.
### How It Works
- Implemented via `ChatTextScaleService` and `ChatZoomWrapper`
- Scale range: 0.8× to 1.8×
- The chosen scale persists across the session via the service
---
## Background Service (Android)
### What It Does
On Android, a foreground service (`background_service.dart`) keeps the BLE connection and message handling alive when the app is in the background. On other platforms this is a no-op.
### User Impact
- A persistent notification appears while the service is running
- Messages are received and retry logic continues even when the app is not in the foreground
+4 -3
View File
@@ -33,7 +33,6 @@ RX (device → host): [0x3E][len_lo][len_hi][payload...]
- Length: 2-byte little-endian, payload only
- Max payload: 172 bytes
- TCP: `tcpNoDelay: true` (Nagle disabled), writes serialized to prevent interleaving
- USB: 10ms post-write delay between frames
## Connection State Machine
@@ -53,9 +52,11 @@ enum MeshCoreConnectionState {
- `MeshCore-`
- `Whisper-`
- `WisCore-`
- `Seeed`
- `Lilygo`
- `HT-`
- `LowMesh_MC_`
2. **Connect** with 15-second timeout
2. **Connect** with 15-second timeout (6 seconds on Linux)
3. **Request MTU** 185 bytes (non-web only)
4. **Discover services** and locate NUS
5. **Enable TX notifications** (up to 3 attempts on native)
@@ -79,7 +80,7 @@ On unexpected disconnection, auto-reconnect with exponential backoff:
| Max path size | 64 bytes | Maximum path data |
| Max name size | 32 bytes | Maximum node name |
| Max text payload | 160 bytes | Firmware `MAX_TEXT_LEN` |
| App protocol version | 3 | Sent in device query |
| App protocol version | 4 | Sent in device query |
| Contact frame size | 148 bytes | Fixed-size contact record |
## Command Codes (App → Device)
+3 -12
View File
@@ -28,7 +28,6 @@ QuickSwitchBar tab 1 (middle) from any main screen.
- **Scrollable list of channel cards**, each showing:
- Type icon with color coding (purple badge overlay for community channels)
- Channel name (or "Channel N" if unnamed)
- Subtitle: "Public channel", "Hashtag channel", "Private channel", or "Community channel - {name}"
- Unread badge (if messages are unread)
- Drag handle (when manual sort is active)
- **"+" FAB** to add a new channel
@@ -70,9 +69,9 @@ Tap a channel card to open the channel chat screen.
### App Bar
- Type icon (public/private/hashtag)
- Type icon: globe for public channels, tag (#) for all other channel types
- Channel name
- Subtitle: "{type} - {N} unread"
- Subtitle: "{Public|Private} {N} unread" (e.g., "Public • 3 unread")
### Message Display
@@ -113,17 +112,9 @@ Tap a channel card to open the channel chat screen.
| Path | Desktop only | Opens message path view |
| Add Reaction | Incoming messages only | Opens emoji picker (cannot react to your own messages) |
| Copy | All messages | Copies text to clipboard |
| Mark as Unread | Incoming messages only | Marks this message and all subsequent incoming messages as unread |
| Delete | All messages | Removes locally (not from mesh) |
### Message Path Viewing
Tap a message bubble to open the Channel Message Path Screen, which shows:
- Each hop in the path as a visual chain
- Known contacts identified by name at each hop
- Observed vs. declared hop counts
- Alternative path variants (if received via multiple paths)
- Map view buttons for geographic path visualization
## Communities
Communities are a layer above channels that provide a private namespace.
+5 -3
View File
@@ -37,6 +37,7 @@ From the Contacts screen, tap any Chat-type contact to open the ChatScreen.
### Input Bar
- **GIF button** (left): Opens GIF picker bottom sheet
- **Translation button** (optional, between GIF and text field): Shown only when translation is enabled in App Settings. Tap to configure outgoing-message translation language and on/off toggle.
- **Text field** (center): Auto-capitalization, enforces UTF-8 byte limit in real-time
- **Send button** (right): Submits the message
- On desktop: Enter/Numpad Enter also submits
@@ -66,8 +67,8 @@ Outgoing messages display a status indicator:
When enabled in App Settings, additional metadata appears inside each bubble:
- Timestamp (HH:MM)
- Retry count (e.g., "Retry 2 of 4")
- Status icon
- Retry count (e.g., "Retry 2 of 4") — only shown for outgoing messages where at least one retry has occurred
- Status icon (outgoing only)
- Round-trip time in seconds (if delivered)
## Message Length Limits
@@ -86,7 +87,7 @@ When a direct message is sent:
1. The app computes an expected ACK hash: `SHA256([timestamp][attempt][text][selfPubKey])[0:4]` — matching the firmware's hash calculation. If SMAZ compression is enabled, the compressed text (not the original) is hashed
2. On device acknowledgment (`RESP_CODE_SENT`), the message transitions to "sent" and a timeout timer starts
3. **Timeout duration**: Preferably from the ML timeout prediction service; otherwise `3000 + 3000 × path_length` milliseconds (15000ms for flood)
3. **Timeout duration**: Preferably from the ML timeout prediction service; otherwise calculated from LoRa airtime physics: `500 + (airtime × 6 + 250) × (pathLength + 1)` ms for direct paths, `500 + 16 × airtime` ms for flood (airtime is estimated from the radio's current spreading factor, bandwidth, and coding rate)
4. On timeout, the message is retried with **exponential backoff**: `1000 × 2^retryCount` ms (1s, 2s, 4s, 8s, 16s...)
5. **Max retries**: Configurable (default 5, range 210)
6. After max retries, the message is marked "failed" — but a **30-second grace window** remains during which a late ACK can still resolve the message to "delivered"
@@ -115,6 +116,7 @@ Add emoji reactions to incoming messages (not your own):
| Add reaction | Incoming messages only | Opens emoji picker |
| View path | Mobile: tap bubble directly; Desktop: long-press/right-click menu | Shows message routing path |
| Copy | All messages | Copies text to clipboard |
| Mark as Unread | Incoming messages only | Marks this message and all subsequent incoming messages as unread |
| Delete | All messages | Removes locally (not from mesh) |
| Retry | Failed outgoing messages | Re-sends the message |
| Open chat with sender | Room server chats | Opens 1:1 chat with the message sender |
+2 -1
View File
@@ -73,7 +73,8 @@ Groups are stored per radio identity (scoped by public key).
| Action | Availability | Description |
|---|---|---|
| Path Trace / Ping | Repeaters, Rooms (always); Chat if `pathLength > 0` | Opens PathTraceMapScreen. Label shows "Ping" when no path bytes are known, "Path Trace" otherwise |
| Ping | Repeaters (always) | Opens PathTraceMapScreen targeting the repeater |
| Path Trace | Rooms (always); Chat/Sensor if `pathLength > 0` | Opens PathTraceMapScreen. For rooms, label shows "Ping" when no path bytes are known, "Path Trace" when path bytes are available |
| Manage Repeater | Repeaters only | Login dialog → RepeaterHubScreen |
| Room Login | Rooms only | Login dialog → ChatScreen |
| Room Management | Rooms only | Login dialog → RepeaterHubScreen (management mode) |
+3 -3
View File
@@ -25,7 +25,7 @@ All contacts with known GPS coordinates are plotted:
| Room | Purple | Meeting room |
| Sensor | Orange | Sensors |
Node name labels appear automatically at zoom level 12 and above.
Node name labels appear automatically at zoom level 14 and above.
### Shared Map Pins (Flag Icons)
Location pins shared in chat messages are displayed as flags:
@@ -88,10 +88,10 @@ Shows a bottom sheet with:
- **Set as my location**: Updates your device's advertised location
### Filter Dialog (FAB)
Toggle visibility of: chat nodes, repeaters, other nodes, guessed locations, discovery contacts.
Toggle visibility of: chat nodes, repeaters, other nodes, guessed locations, discovery contacts, overlapping markers (stacked markers at similar coordinates), and shared map pins (flag markers).
Additional filters:
- **Key prefix filter**: Show only contacts whose public key starts with a given prefix
- **Last-seen time slider**: From 1 hour to "all time"
- **Last-seen time slider**: Exponential scale from near-zero to 6 months, with "all time" at the top end
### Legend Card (Top-Right)
Shows node count and pin count. Tappable to expand a legend of all marker types.
+3 -18
View File
@@ -22,31 +22,16 @@ The QuickSwitchBar is a Material 3 `NavigationBar` with a frosted-glass visual t
Tapping a tab replaces the current screen with a subtle fade + slight horizontal nudge transition (220ms forward, 200ms reverse). The back button is suppressed on all three main screens — navigation between them is flat, not stacked. All icons use outline variants (`people_outline`, `tag`, `map_outlined`) following Material 3 conventions.
## Device Screen
## Disconnection
The Device Screen is a transitional hub that shows after connection. In practice, the app navigates directly to Contacts after connecting, but the Device Screen is reachable via the QuickSwitchBar.
### What the User Sees
**App Bar**:
- Left: Battery indicator chip (tappable — toggles between percentage and voltage display). Icon changes based on level: `battery_unknown` when data unavailable, `battery_alert` (orange) at 15% or below, `battery_full` otherwise
- Left-aligned title (`centerTitle: false`): Two-line layout — small grey "MeshCore" label above the device name in bold
- Right: Disconnect button (`bluetooth_disabled` crossed-out icon) and Settings button (tune icon)
**Body**:
- **Connection Card**: Device avatar, device name, device ID, "Connected" chip, and battery chip
- **Quick Switch** section: The QuickSwitchBar widget for navigating to Contacts/Channels/Map
### Disconnection
- The disconnect button shows a confirmation dialog before disconnecting
- The disconnect button (available in the Settings screen and other main screens) shows a confirmation dialog before disconnecting
- If the device disconnects unexpectedly, the app automatically navigates back to the Scanner screen (fires after the current frame completes via a post-frame callback)
- This auto-navigation behavior (`DisconnectNavigationMixin`) is shared across all main screens
## Theme and Locale
- **Theme mode** is user-configurable in App Settings (System / Light / Dark) — not locked to system
- **Language** can be overridden to one of 15 supported languages, or follow the system locale
- **Language** can be overridden to one of 18 supported languages, or follow the system locale
- On web, if a non-Chromium browser is detected, the app shows a `ChromeRequiredScreen` instead of the Scanner (Web Bluetooth requires Chromium)
## Full Navigation Graph
+1 -1
View File
@@ -73,7 +73,7 @@ There is no per-contact muting.
The notification system prevents notification storms:
- **Minimum interval**: 3 seconds between individual notifications
- **Batch window**: If multiple notifications arrive within 5 seconds, they are combined into a single summary notification on a fourth Android channel (`batch_summary`): "MeshCore Activity2 messages, 1 channel message, 3 new nodes". Note: batch summaries are Android-only; on Apple platforms individual notifications are shown
- **Batch window**: If multiple notifications arrive within 5 seconds, they are combined into a single summary notification on a fourth Android channel (`batch_summary`). The title is "MeshCore Activity" and the body lists the grouped counts (e.g., "2 messages, 1 channel message, 3 new nodes"). Batch summaries are Android-only; queued notifications that overflow the batch window are silently dropped on other platforms
## Notification Clearing
+74 -41
View File
@@ -17,8 +17,8 @@ From the Contacts screen:
- Password field with show/hide toggle
- "Save password" checkbox (persists for future logins). If a saved password exists, it is pre-filled and the checkbox is pre-checked, making login one-tap
- Routing mode selector and "Manage Paths" link are available directly in the dialog (configure routing before login)
- Auto-retries up to 5 times on timeout, showing progress ("Attempt 2 of 5"). A wrong password stops immediately after the first attempt — only timeouts trigger retries
- After 5 failed attempts, further login attempts are blocked
- Auto-retries up to 5 times on timeout, showing progress ("Attempt 2 of 5"). A wrong password (explicit failure response) stops immediately — only timeouts trigger retries
- If auto-clock-sync is enabled for this repeater (configured in Repeater Settings), a `clock sync` command is sent automatically on successful login
---
@@ -28,15 +28,17 @@ The central management screen showing:
- **Header card**: Repeater name, short public key, path label, GPS coordinates (if known)
- **Battery chemistry selector**: NMC / LiFePO4 / LiPo (saved per repeater)
- **Management tool cards** (full-width cards with chevron arrows, not a grid). Title dynamically shows "Repeater Management" or "Room Management" based on contact type:
- **Management tool cards** (full-width cards with chevron arrows, not a grid). Title dynamically shows "Repeater Management" or "Room Management" (admin) or "Repeater Guest" / "Room Guest" (guest) based on contact type and login result:
| Card | Destination |
|---|---|
| Status | Repeater Status Screen |
| Telemetry | Telemetry Screen |
| CLI | Repeater CLI Screen |
| Neighbors | Neighbors Screen |
| Settings | Repeater Settings Screen |
| Card | Destination | Visibility |
|---|---|---|
| Status | Repeater Status Screen | All users |
| Telemetry | Telemetry Screen | All users |
| CLI | Repeater CLI Screen | Admin only |
| Neighbors | Neighbors Screen | All users |
| Settings | Repeater Settings Screen | Admin only |
The battery chemistry selector and CLI/Settings cards are hidden from guest users.
---
@@ -47,26 +49,28 @@ The central management screen showing:
Three information cards:
**System Information**:
- Battery percentage
- Uptime
- Queue length
- Error flags
- Battery percentage and voltage (e.g. "85% / 3.95V"), using the battery chemistry set in the hub screen
- Clock at login time
- Uptime (days/hours/minutes/seconds)
- Queue length
- Debug flags (error event count)
**Radio Statistics**:
- Last RSSI and SNR
- Noise floor
- TX and RX airtime
- TX airtime and RX airtime
**Packet Statistics**:
- Packets sent, received, and duplicates
- Broken down by flood vs. direct
- Packets sent and received, each broken down by flood vs. direct
- Duplicates, broken down by flood vs. direct
- Channel utilization (% of uptime used by TX + RX)
### Key Interactions
- Auto-queries the repeater on open; shows a loading spinner until data arrives
- On timeout: red snackbar error. On success: data appears with a green snackbar confirmation
- Pull-to-refresh or refresh button to re-query
- On timeout: red snackbar error. On success: data appears in-place (no extra snackbar)
- Pull-to-refresh or refresh button in the app bar to re-query
- Routing mode popup and path management dialog in app bar (these controls appear on **all** management sub-screens, not just Status)
- Accepts both binary `RESP_CODE_STATUS_RESPONSE` frames and legacy JSON text responses
---
@@ -76,7 +80,7 @@ A terminal-style interface for sending commands directly to the repeater.
### What the User Sees
- **Quick-command bar** (horizontal scroll): Shortcut buttons for common commands (get name, get radio, get tx, neighbors, ver, advert, clock)
- **Quick-command bar** (horizontal scroll): Shortcut buttons for 9 common commands (advert, get name, get radio, get tx, discover.neighbors, neighbors, ver, clock, clock sync)
- **Command history list**: Sent commands in primary color, responses in secondary color
- **Input bar**: Up/down history arrows, monospace text field with `> ` prefix, send button
@@ -92,9 +96,13 @@ A terminal-style interface for sending commands directly to the repeater.
### Available CLI Commands
**General**: `advert`, `reboot`, `clock`, `password`, `ver`, `clear stats`
The in-app help reference (help icon) documents all known commands. Categories:
**Settings**: `set name`, `set af`, `set tx`, `set repeat`, `set allow.read.only`, `set flood.max`, `set int.thresh`, `set agc.reset.interval`, `set multi.acks`, `set advert.interval`, `set flood.advert.interval`, `set guest.password`, `set lat`, `set lon`, `set radio`, `set rxdelay`, `set txdelay`, `set direct.txdelay`, `set bridge.*`, `set adc.multiplier`, `tempradio`, `setperm`
**General**: `advert`, `advert.zerohop`, `reboot`, `clock`, `clock sync`, `password`, `ver`, `clear stats`, `erase`, `poweroff`, `shutdown`, `clkreboot`, `start ota`, `time`, `board`, `discover.neighbors`, `powersaving`, `stats-packets`, `stats-radio`, `stats-core`
**Get**: `get name`, `get role`, `get public.key`, `get prv.key`, `get repeat`, `get tx`, `get freq`, `get radio`, `get radio.rxgain`, `get af`, `get dutycycle`, `get int.thresh`, `get agc.reset.interval`, `get multi.acks`, `get allow.read.only`, `get advert.interval`, `get flood.advert.interval`, `get guest.password`, `get lat`, `get lon`, `get rxdelay`, `get txdelay`, `get direct.txdelay`, `get flood.max`, `get owner.info`, `get path.hash.mode`, `get loop.detect`, `get acl`, `get bridge.*`, `get adc.multiplier`, `get bootloader.ver`
**Set**: `set name`, `set af`, `set tx`, `set repeat`, `set allow.read.only`, `set flood.max`, `set int.thresh`, `set agc.reset.interval`, `set multi.acks`, `set advert.interval`, `set flood.advert.interval`, `set guest.password`, `set lat`, `set lon`, `set freq`, `set radio`, `set rxdelay`, `set txdelay`, `set direct.txdelay`, `set radio.rxgain`, `set dutycycle`, `set loop.detect`, `set path.hash.mode`, `set owner.info`, `set prv.key`, `set bridge.*`, `set adc.multiplier`, `tempradio`, `setperm`
**Bridge**: `get bridge.type`
@@ -102,9 +110,11 @@ A terminal-style interface for sending commands directly to the repeater.
**Neighbors**: `neighbors`, `neighbor.remove`
**Region Management**: `region`, `region load/get/put/remove/allowf/denyf/home/save`
**Power Management**: `get pwrmgt.support`, `get pwrmgt.source`, `get pwrmgt.bootreason`, `get pwrmgt.bootmv`
**GPS**: `gps`, `gps on/off/sync/setloc/advert`
**Sensors**: `sensor get {key}`
**Region Management**: `region`, `region load`, `region get`, `region put`, `region remove`, `region allowf`, `region denyf`, `region home`, `region save`, `region default`, `region list allowed`, `region list denied`
---
@@ -147,40 +157,63 @@ A card titled "Repeater's Neighbors - N" listing each neighbor as:
### What the User Sees
Five configuration cards:
Nine configuration cards, each with its own per-field refresh button(s):
**1. Basic Settings**
- Name field
- Admin password field
- Guest password field
- Admin password field (write-only; always sent when non-empty)
- Guest password field (write-only; always sent when non-empty)
**2. Radio Settings**
- Frequency (MHz)
- TX Power (dBm)
- TX Power (dBm) — has its own independent refresh button
- Bandwidth dropdown (kHz)
- Spreading Factor (SF5SF12)
- Coding Rate (4/54/8)
- RX Gain boost toggle
**3. Location Settings**
- Latitude and longitude fields
- Latitude and longitude fields, each with an independent refresh button
**4. Features**
- Packet forwarding toggle
- Guest access toggle
- Packet forwarding toggle (`set repeat`)
- Guest access toggle (`set allow.read.only`)
- Multi-ACKs toggle (`set multi.acks`)
- Auto clock sync after login toggle (local app setting only, not sent to repeater)
**5. Advertisement Settings**
**5. Network Health**
- Loop detection dropdown (off / minimal / moderate / strict; `set loop.detect`)
- Duty cycle slider (1100%; `set dutycycle`)
**6. Advertisement Settings**
- Local advert interval slider (60240 minutes) with enable/disable toggle
- Flood advert interval slider (3168 hours) with enable/disable toggle
- Flood max hops slider (064; `set flood.max`)
**6. Danger Zone** (red-styled card)
- Reboot repeater
- Erase filesystem (serial-only warning)
**7. Owner Info**
- Multi-line text field for operator contact info (`set owner.info`); newlines sent as `|`
**8. Actions** (one-tap, no save needed)
- Send Advertisement (`advert`)
- Send Zero-Hop Advertisement (`advert.zerohop`)
- Clock Sync (`clock sync`)
**9. Advanced** (collapsed by default)
- Path hash mode dropdown (02; `set path.hash.mode`)
- TX delay field (`set txdelay`)
- Direct TX delay field (`set direct.txdelay`)
- Interference threshold field (`set int.thresh`)
- AGC reset interval slider (0240s in multiples of 4; `set agc.reset.interval`)
**Danger Zone** (red-styled card)
- Reboot repeater (sends `reboot` with confirmation dialog)
- Erase filesystem (serial-only; shows informational snackbar only — no command is sent over the air)
### Key Interactions
- **Settings are NOT auto-fetched on open**. Only name and location are pre-filled from locally cached contact data. You must tap each section's refresh button to fetch live values from the repeater
- TX Power has its own separate refresh button, independent from the main Radio Settings refresh
- Save button appears when changes are detected
- Settings are sent sequentially with 200ms delays between commands (fire-and-forget, no per-command acknowledgment wait)
- Validation prevents invalid values (e.g., frequency range, LoRa parameter compatibility)
- **Settings are NOT auto-fetched on open**. Name is pre-filled from cached contact data. Each section has its own refresh button to fetch live values from the repeater
- TX Power, RX Gain, latitude, longitude, and advanced fields each have independent inline refresh buttons
- Save button in app bar appears when any change is detected; failed commands keep those fields dirty for retry
- Settings are sent sequentially with 200ms delays between commands; firmware responses are checked and partial failures are reported in a snackbar
- Some changes (e.g. radio frequency) require a reboot; the firmware response triggers an orange "reboot needed" snackbar
- Advertisement interval sliders reset to defaults when re-enabled (local: 60 min, flood: 3 hours)
- **Erase Filesystem** does NOT send any command over the air — tapping it only shows a snackbar explaining the operation requires physical serial access. It is effectively non-functional when connected wirelessly
- **Erase Filesystem** does NOT send any command over the air — tapping it only shows a snackbar explaining the operation requires physical serial access
+2 -2
View File
@@ -51,7 +51,7 @@ Note: The weak (-80 to -90 dBm) and poor (< -90 dBm) tiers share the same icon s
### How Scanning Works
- Filters for devices with names starting with `MeshCore-` or `Whisper-`
- Filters for devices with names starting with one of the known prefixes: `MeshCore-`, `Whisper-`, `WisCore-`, `Seeed`, `Lilygo`, `HT-`, `LowMesh_MC_`
- Uses low-latency scan mode on Android
- Scans for 10 seconds then auto-stops
- On iOS/macOS, waits for BLE adapter initialization before starting
@@ -61,7 +61,7 @@ Note: The weak (-80 to -90 dBm) and poor (< -90 dBm) tiers share the same icon s
Tap a device tile or its Connect button:
1. The connector stops scanning and transitions to "connecting"
2. Connects to the device with a 15-second timeout
2. Connects to the device with a 15-second timeout (6 seconds on Linux)
3. Requests MTU 185 bytes for optimal throughput
4. Discovers BLE services and locates the Nordic UART Service
5. Subscribes to TX notifications for receiving data
+12 -2
View File
@@ -46,7 +46,7 @@ A dedicated sub-screen for app-level preferences (nothing here is sent to the de
### Appearance
- **Theme**: System / Light / Dark
- **Language**: System default or one of 15 languages (English, French, Spanish, German, Polish, Slovenian, Portuguese, Italian, Chinese, Swedish, Dutch, Slovak, Bulgarian, Russian, Ukrainian)
- **Language**: System default or one of 18 languages (English, French, Spanish, German, Polish, Slovenian, Portuguese, Italian, Chinese, Swedish, Dutch, Slovak, Bulgarian, Russian, Ukrainian, Hungarian, Japanese, Korean)
- **Enable Message Tracing**: Shows path trace overlays and extra metadata on messages
### Notifications
@@ -57,6 +57,7 @@ A dedicated sub-screen for app-level preferences (nothing here is sent to the de
### Messaging
- **Clear Path on Max Retry**: Erases the stored routing path after all retries fail
- **Jump to Oldest Unread**: When opening a chat, scrolls to the oldest unread message instead of the newest
- **Auto Route Rotation**: Enables weighted routing algorithm. When enabled, expands to show five slider sub-settings (hidden when off):
- Max Route Weight (110, default 5, integer steps)
- Initial Route Weight (0.55.0, default 3.0)
@@ -67,6 +68,15 @@ A dedicated sub-screen for app-level preferences (nothing here is sent to the de
### Battery
- **Battery Chemistry**: NMC / LiFePO4 / LiPo (per device, used to calibrate percentage from voltage)
### Translation
Not shown on web. Controls on-device message translation powered by a locally-downloaded ML model:
- **Enable Translation**: Translates incoming messages into the selected target language
- **Translate Composer**: Translates outgoing messages from the target language back before sending
- **Target Language**: Language to translate into (searchable list; defaults to the app language)
- **Downloaded Model**: Dropdown to select among already-downloaded translation models
- **Preset Model**: Download a curated preset model with one tap
- **Custom Model URL**: Enter a URL to download a custom GGUF-format model; shows download progress and a cancel button
### Map Display
- **Show Repeaters**: Toggle repeater markers on map
- **Show Chat Nodes**: Toggle chat node markers
@@ -91,7 +101,7 @@ These settings are sent directly to the connected device firmware.
### Radio Settings
Opens a dialog pre-populated with the device's current radio settings. Contains:
- **Preset dropdown**: 19 regional presets — selecting a preset immediately fills all fields below. Full list: Australia, Australia (Narrow), Australia SA/WA/QLD, Czech Republic, EU 433MHz, EU/UK (Long Range), EU/UK (Medium Range), EU/UK (Narrow), New Zealand, New Zealand (Narrow), Portugal 433, Portugal 869, Switzerland, USA Arizona, USA/Canada, Vietnam, Off-Grid 433, Off-Grid 869, Off-Grid 918
- **Preset dropdown**: 19 regional presets — selecting a preset immediately fills all fields below. Full list: Australia, Australia (Narrow), Australia SA, WA, QLD, Czech Republic, EU 433MHz, EU/UK (Long Range), EU/UK (Medium Range), EU/UK (Narrow), New Zealand, New Zealand (Narrow), Portugal 433, Portugal 869, Switzerland, USA Arizona, USA/Canada, Vietnam, Off-Grid 433, Off-Grid 869, Off-Grid 918
- **Frequency** (MHz): Free text, validated 3002500 MHz
- **Bandwidth**: Dropdown (7.8 / 10.4 / 15.6 / 20.8 / 31.25 / 41.7 / 62.5 / 125 / 250 / 500 kHz)
- **Spreading Factor**: SF5SF12