mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-03-27 10:11:48 -04:00
9.8 KiB
9.8 KiB
Roadmap
Last updated: 2026-03-17
Forward-looking priorities for the Meshtastic KMP multi-target effort. For current state, see kmp-status.md. For the full gap analysis, see decisions/architecture-review-2026-03.md.
Architecture Health (Immediate)
These items address structural gaps identified in the March 2026 architecture review. They are prerequisites for safe multi-target expansion.
| Item | Impact | Effort | Status |
|---|---|---|---|
Purge java.util.Locale from commonMain (3 files) |
High | Low | ✅ |
Replace ConcurrentHashMap in commonMain (3 files) |
High | Low | ✅ |
Create core:testing shared test fixtures |
Medium | Low | ✅ |
Add feature module commonTest (settings, node, messaging) |
Medium | Medium | ✅ |
Desktop Koin checkModules() integration test |
Medium | Low | ✅ |
| Auto-wire Desktop ViewModels via K2 Compiler (eliminate manual wiring) | Medium | Low | ✅ |
| here | Migrate to JetBrains Compose Multiplatform dependencies | High | Low |
Active Work
Desktop Feature Completion (Phase 4)
Objective: Complete desktop wiring for all features and ensure full integration.
Current State (March 2026):
- ✅ Settings: ~35 screens with real configuration, including theme/about parity and desktop language picker support
- ✅ Nodes: Adaptive list-detail with node management
- ✅ Messaging: Adaptive contacts with message view + send
- ✅ Connections: Dynamic discovery of platform-supported transports (TCP, Serial/USB, BLE)
- ❌ Map: Placeholder only, needs MapLibre or alternative
- ⚠️ Firmware: Placeholder wired into nav graph; native DFU not applicable to desktop
- ⚠️ Intro: Onboarding flow (may not apply to desktop)
Implementation Steps:
- Tier 1: Core Wiring (Essential)
- Complete Map integration (MapLibre or equivalent)
- Verify all features accessible via navigation
- Test navigation flows end-to-end
- Tier 2: Polish (High Priority)
- Additional desktop-specific settings polish
- ✅ MenuBar integration and Keyboard shortcuts
- Window management
- State persistence
- Tier 3: Advanced (Nice-to-have)
- Performance optimization
- Advanced map features
- Theme customization
- Multi-window support
| Transport | Platform | Status |
|---|---|---|
| TCP | Desktop (JVM) | ✅ Done — shared StreamFrameCodec + TcpTransport in core:network |
| Serial/USB | Desktop (JVM) | ✅ Done — jSerialComm |
| MQTT | All (KMP) | ✅ Completed — KMQTT in commonMain |
| BLE | Android | ✅ Done — Kable |
| BLE | Desktop | ✅ Done — Kable (JVM) |
| BLE | iOS | ❌ Future — Kable/CoreBluetooth |
Desktop Feature Gaps
| Feature | Status |
|---|---|
| Settings | ✅ ~35 real screens (7 desktop-specific) + desktop locale picker with in-place recomposition |
| Node list | ✅ Adaptive list-detail with real NodeDetailContent |
| Messaging | ✅ Adaptive contacts with real message view + send |
| Connections | ✅ Unified shared UI with dynamic transport detection |
| Metrics logs | ✅ TracerouteLog, NeighborInfoLog, HostMetricsLog |
| Map | ❌ Needs MapLibre or equivalent |
| Charts | ✅ Vico KMP charts wired in commonMain (Device, Environment, Signal, Power, Pax) |
| Debug Panel | ✅ Real screen (mesh log viewer via shared DebugViewModel) |
| Notifications | ✅ Desktop native notifications with system tray icon support |
| MenuBar | ✅ Done — Native application menu bar with File/View menus |
| About | ✅ Shared commonMain screen (AboutLibraries KMP produceLibraries + per-platform JSON) |
| Packaging | ✅ Done — Native distribution pipeline in CI (DMG, MSI, DEB) |
Near-Term Priorities (30 days)
core:testingmodule — ✅ Done (established shared fakes for cross-modulecommonTest)- Feature
commonTestbootstrap — ✅ Done (131 shared tests across all 7 features covering integration and error handling) - Radio transport abstraction — ✅ Done: Defined
RadioTransportinterface incore:repository/commonMainand replacedIRadioInterface; Next: continue extracting remaining platform transports fromapp/repository/radio/into core modules feature:connectionsmodule — ✅ Done: Extracted connections UI into KMP feature module with dynamic transport availability detection- Navigation 3 parity baseline — ✅ Done: shared
TopLevelDestinationincore:navigation; both shells use same enum; parity tests incore:navigation/commonTestanddesktop/test - iOS CI gate — add
iosArm64()/iosSimulatorArm64()to convention plugins and CI (compile-only, no implementations) - Build-logic consolidation — ✅ Done: Created
meshtastic.kmp.featureconvention plugin (modelled after NiA'sAndroidFeatureImplConventionPlugin). Composeskmp.library+kmp.library.compose+koinand wires common Compose/Lifecycle/Koin/androidMain deps. All 7 feature modules migrated; ~100 duplicated dep lines eliminated.
Medium-Term Priorities (60 days)
- App module thinning — Extracted ChannelViewModel, NodeMapViewModel, NodeContextMenu, EmptyDetailPlaceholder to shared modules.
- ✅ Done: Extracted remaining 5 ViewModels:
SettingsViewModel,RadioConfigViewModel,DebugViewModel,MetricsViewModel,UIViewModelto shared KMP modules. - ✅ Done: Extracted service, worker, and radio files from
apptocore:service/androidMainandcore:network/androidMain. - Next: Extract remaining Android-specific files (e.g., Navigation files, App Widgets, message queues, and root Activity logic) out of
:appto establish a truly thin app module.
- ✅ Done: Extracted remaining 5 ViewModels:
- ✅ Done: Serial/USB transport — direct radio connection on Desktop via jSerialComm
- MQTT transport — cloud relay operation (KMP, benefits all targets) ✅
- Evaluate KMP-native testing tools — Evaluate
MokkeryorMockativeto replacemockkincommonMainofcore:testingfor iOS readiness. IntegrateTurbinefor sharedFlowtesting. - Desktop ViewModel auto-wiring — ✅ Done: ensured Koin K2 Compiler Plugin generates ViewModel modules for JVM target; eliminated manual wiring in
DesktopKoinModule - KMP charting — ✅ Done: Vico charts migrated to
feature:node/commonMainusing KMP artifacts; desktop wires them directly - Navigation contract extraction — ✅ Done: shared
TopLevelDestinationenum incore:navigation; icon mapping incore:ui; parity tests in place. Both shells derive from the same source of truth. - Dependency stabilization — track stable releases for CMP, Koin, Lifecycle, Nav3
Longer-Term (90+ days)
- iOS proof target — declare
iosArm64()/iosSimulatorArm64()in KMP modules; BLE via Kable/CoreBluetooth - Platform-Native UI Interop —
- iOS Maps & Camera: Implement
MapLibreorMKMapViewvia Compose Multiplatform'sUIKitView. LeverageAVCaptureSessionwrapped inUIKitViewto fulfill theLocalBarcodeScannerProvidercontract. - Desktop Maps: Implement maps via
SwingPanelwrapper, utilizing experimental interop blending (compose.interop.blending=true) to ensure tooltips and Compose overlays render correctly on top of the native JComponent. - Web (wasmJs) Integrations: Leverage
HtmlViewto embed raw DOM elements (e.g.,<video>,<iframe>, or canvas-based maps) directly into the Compose UI tree while binding the root app viaCanvasBasedWindow.
- iOS Maps & Camera: Implement
core:apicontract split — separate transport-neutral service contracts from Android AIDL packaging- Native packaging — ✅ Done: DMG, MSI, DEB distributions for Desktop via release pipeline
- Module maturity dashboard — living inventory of per-module KMP readiness
- Shared UI vs Shared Logic split — If the iOS target utilizes native SwiftUI instead of Compose Multiplatform, evaluate splitting feature modules into pure
sharedLogic(business rules, ViewModels) andsharedUI(Compose Multiplatform) to prevent dragging Compose dependencies into pure native iOS apps.
Design Principles
- Solve in
commonMainfirst. If it doesn't need platform APIs, it belongs incommonMain. - Interfaces in
commonMain, implementations per-target. The repository pattern is established — extend it. Prefer dependency injection (Koin) with interfaces overexpect/actualdeclarations whenever possible to keep architecture decoupled and highly testable. - UI Interop Strategies. When a Compose Multiplatform equivalent doesn't exist (e.g., Maps, Camera), use standard interop APIs rather than extracting the entire screen to native code. Use
AndroidViewfor Android,UIKitViewfor iOS,SwingPanelfor JVM/Desktop, andHtmlViewfor Web (wasmJs). Always wrap these in a sharedcommonMaininterface contract (likeLocalBarcodeScannerProvider). - Stubs are a valid first implementation. Every target starts with no-op stubs, then graduates to real implementations.
- Feature modules stay target-agnostic in
commonMain. Platform UI goes in platform source sets. Keep the UI layer dumb and rely on shared ViewModels (Unidirectional Data Flow) to drive state. - Transport is a pluggable adapter. BLE, serial, TCP, MQTT all implement
RadioInterfaceService. - CI validates every target. If a module declares
jvm(), CI compiles it. No exceptions. Run tests on appropriate host runners (macOS for iOS, Linux for JVM/Android) to catch platform regressions. - Test in
commonTestfirst. ViewModel and business logic tests belong incommonTestso every target runs them. Use sharedcore:testingutilities to minimize duplication. - Zero Platform Leaks. Never import
java.*orandroid.*insidecommonMain. Use KMP-native alternatives likekotlinx-datetimeandOkio.