App navigation
App Flow
Section titled “App Flow”The app follows this general flow:
Launch → Scanner Screen → [Connect via BLE/USB/TCP] → Contacts ScreenAfter connecting, the three main screens (Contacts, Channels, Map) are accessible via a persistent bottom navigation bar called the QuickSwitchBar.
Quick Switch Bar
Section titled “Quick Switch Bar”The QuickSwitchBar is a Material 3 NavigationBar with a frosted-glass visual treatment (blur backdrop, transparent theme, rounded corners). It appears at the bottom of all three main screens.
| Index | Icon | Label | Screen |
|---|---|---|---|
| 0 | People | Contacts | ContactsScreen |
| 1 | Tag | Channels | ChannelsScreen |
| 2 | Map | Map | MapScreen |
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
Section titled “Device Screen”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
Section titled “What the User Sees”App Bar:
- Left: Battery indicator chip (tappable — toggles between percentage and voltage display). Icon changes based on level:
battery_unknownwhen data unavailable,battery_alert(orange) at 15% or below,battery_fullotherwise - Left-aligned title (
centerTitle: false): Two-line layout — small grey “MeshCore” label above the device name in bold - Right: Disconnect button (
bluetooth_disabledcrossed-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
Section titled “Disconnection”- The disconnect button 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
Section titled “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
- On web, if a non-Chromium browser is detected, the app shows a
ChromeRequiredScreeninstead of the Scanner (Web Bluetooth requires Chromium)
Full Navigation Graph
Section titled “Full Navigation Graph”ScannerScreen (root, always on stack) ├─ [BLE connect] → push → ContactsScreen ├─ [TCP FAB] → push → TcpScreen │ └─ [TCP connected] → pushReplacement → ContactsScreen └─ [USB FAB] → push → UsbScreen └─ [USB connected] → pushReplacement → ContactsScreen
ContactsScreen (selected=0) ├─ [quick-switch 1] → pushReplacement → ChannelsScreen ├─ [quick-switch 2] → pushReplacement → MapScreen ├─ [tap contact] → push → ChatScreen ├─ [overflow > Settings] → push → SettingsScreen └─ [overflow > Discovered] → push → DiscoveryScreen
ChannelsScreen (selected=1) ├─ [quick-switch 0] → pushReplacement → ContactsScreen ├─ [quick-switch 2] → pushReplacement → MapScreen ├─ [tap channel] → push → ChannelChatScreen └─ [overflow > Settings] → push → SettingsScreen
MapScreen (selected=2) ├─ [quick-switch 0] → pushReplacement → ContactsScreen ├─ [quick-switch 1] → pushReplacement → ChannelsScreen ├─ [radar button] → push → PathTraceMapScreen ├─ [terrain button] → push → LineOfSightMapScreen └─ [long-press] → share marker / set location
Settings (push from any main screen) └─ [App Settings] → push → AppSettingsScreen └─ [Offline Map Cache] → push → MapCacheScreenAny disconnection from any screen triggers popUntil(route.isFirst), returning to the Scanner.