mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor(metrics/map): DRY up charts, decompose MapView monoliths, add test coverage (#5049)
This commit is contained in:
parent
56332f4d77
commit
520fa717a9
71 changed files with 3464 additions and 2169 deletions
|
|
@ -26,7 +26,9 @@ Examples in current code:
|
|||
- Platform/flavor UI implementations should be injected via `CompositionLocal` from app.
|
||||
|
||||
Examples:
|
||||
- Contract: `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/MapViewProvider.kt`
|
||||
- Contract (main map): `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/MapViewProvider.kt`
|
||||
- Contract (node tracks): `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/LocalNodeTrackMapProvider.kt`
|
||||
- Contract (traceroute): `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/LocalTracerouteMapProvider.kt`
|
||||
- Provider wiring: `app/src/main/kotlin/org/meshtastic/app/MainActivity.kt`
|
||||
|
||||
## 4) DI and module activation checks
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ Key files for discovering established patterns:
|
|||
| Shared ViewModel | `feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/MessageViewModel.kt` |
|
||||
| `CompositionLocal` platform injection | `app/src/main/kotlin/org/meshtastic/app/MainActivity.kt` |
|
||||
| Platform abstraction contract | `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/MapViewProvider.kt` |
|
||||
| Node track map provider contract | `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/LocalNodeTrackMapProvider.kt` |
|
||||
| Traceroute map provider contract | `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/LocalTracerouteMapProvider.kt` |
|
||||
| Shared strings resource | `core/resources/src/commonMain/composeResources/values/strings.xml` |
|
||||
| Okio shared I/O | `core/domain/src/commonMain/kotlin/org/meshtastic/core/domain/usecase/settings/ImportProfileUseCase.kt` |
|
||||
| `stateInWhileSubscribed` | `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/viewmodel/ViewModelExtensions.kt` |
|
||||
|
|
@ -82,7 +84,9 @@ Reference examples:
|
|||
4. Keep adapter types narrow and stable (interfaces, DTO-like params).
|
||||
|
||||
Reference examples:
|
||||
- Contract: `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/MapViewProvider.kt`
|
||||
- Contract (main map): `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/MapViewProvider.kt`
|
||||
- Contract (node tracks): `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/LocalNodeTrackMapProvider.kt`
|
||||
- Contract (traceroute): `core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/util/LocalTracerouteMapProvider.kt`
|
||||
- Provider wiring: `app/src/main/kotlin/org/meshtastic/app/MainActivity.kt`
|
||||
- Consumer side: `feature/map/src/androidMain/kotlin/org/meshtastic/feature/map/MapScreen.kt`
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ The codebase is **~98% structurally KMP** — 18/20 core modules and 8/8 feature
|
|||
|
||||
Of the five structural gaps originally identified, four are resolved and one remains in progress:
|
||||
|
||||
1. **`app` is a God module** — originally 90 files / ~11K LOC of transport, service, UI, and ViewModel code that should live in core/feature modules. *(✅ Resolved — app module reduced to 6 files: `MainActivity`, `MeshUtilApplication`, Nav shell, and DI config)*
|
||||
1. **`app` is a God module** — originally 90 files / ~11K LOC of transport, service, UI, and ViewModel code that should live in core/feature modules. *(✅ Resolved — app module reduced to 8 files: `MainActivity`, `MeshUtilApplication`, Nav shell, DI config, and shared map UI components)*
|
||||
2. ~~**Radio transport layer is app-locked**~~ — ✅ Resolved: `RadioTransport` interface in `core:repository/commonMain`; shared `StreamFrameCodec` + `TcpTransport` in `core:network`.
|
||||
3. ~~**`java.*` APIs leak into `commonMain`**~~ — ✅ Resolved: `Locale`, `ConcurrentHashMap`, `ReentrantLock` purged.
|
||||
4. ~~**Zero feature-level `commonTest`**~~ — ✅ Resolved: 193 shared tests across all 8 features; `core:testing` module established.
|
||||
|
|
@ -24,7 +24,7 @@ Of the five structural gaps originally identified, four are resolved and one rem
|
|||
| `core/*/commonMain` | 337 | 32,700 | Shared business/data logic |
|
||||
| `feature/*/commonMain` | 146 | 19,700 | Shared feature UI + ViewModels |
|
||||
| `feature/*/androidMain` | 62 | 14,700 | Platform UI (charts, previews, permissions) |
|
||||
| `app/src/main` | 6 | ~300 | Android app shell (target achieved) |
|
||||
| `app/src/main` | 8 | ~450 | Android app shell + shared map UI components |
|
||||
| `desktop/src` | 26 | 4,800 | Desktop app shell |
|
||||
| `core/*/androidMain` | 49 | 3,500 | Platform implementations |
|
||||
| `core/*/jvmMain` | 11 | ~500 | JVM actuals |
|
||||
|
|
@ -38,7 +38,7 @@ Of the five structural gaps originally identified, four are resolved and one rem
|
|||
|
||||
### A1. `app` module is a God module
|
||||
|
||||
The `app` module should be a thin shell (~20 files): `MainActivity`, DI assembly, nav host. Originally it held **90 files / ~11K LOC**, now completely reduced to a **6-file shell**:
|
||||
The `app` module should be a thin shell (~20 files): `MainActivity`, DI assembly, nav host, and shared flavor-agnostic UI. Originally it held **90 files / ~11K LOC**, now reduced to an **8-file shell** (6 original + 2 shared map UI components: `MapButton`, `MapControlsOverlay`):
|
||||
|
||||
| Area | Files | LOC | Where it should live |
|
||||
|---|---:|---:|---|
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# KMP Migration Status
|
||||
|
||||
> Last updated: 2026-03-31
|
||||
> Last updated: 2026-04-10
|
||||
|
||||
Single source of truth for Kotlin Multiplatform migration progress. For the forward-looking roadmap, see [`roadmap.md`](./roadmap.md). For completed decision records, see [`decisions/`](./decisions/).
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ Modules that share JVM-specific code between Android and desktop now standardize
|
|||
| `feature:messaging` | ✅ | ✅ Adaptive contacts + messages; fully shared `contactsGraph`, `MessageScreen`, `ContactsScreen`, and `MessageListPaged` |
|
||||
| `feature:connections` | ✅ | ✅ Shared `ConnectionsScreen` with dynamic transport detection |
|
||||
| `feature:intro` | — | — | Screens remain in `androidMain`; shared ViewModel only |
|
||||
| `feature:map` | — | Placeholder; shared `NodeMapViewModel` and `BaseMapViewModel` only |
|
||||
| `feature:map` | — | Placeholder; shared `NodeMapViewModel`, `BaseMapViewModel`, and `TracerouteNodeSelection`. Map rendering decomposed into 3 `CompositionLocal` provider contracts (`MapViewProvider`, `NodeTrackMapProvider`, `TracerouteMapProvider`) with per-flavor implementations in `:app` |
|
||||
| `feature:firmware` | ✅ | ✅ Fully KMP: Unified OTA, native Secure DFU, USB/UF2, FirmwareRetriever |
|
||||
| `feature:wifi-provision` | ✅ | ✅ KMP WiFi provisioning via BLE (Nymea protocol); shared UI and ViewModel |
|
||||
| `feature:widget` | ❌ | — | Android-only (Glance appwidgets). Intentional. |
|
||||
|
|
@ -144,6 +144,8 @@ Extracted to shared `commonMain` (no longer app-only):
|
|||
- `ChannelViewModel` → `feature:settings/commonMain`
|
||||
- `NodeMapViewModel` → `feature:map/commonMain` (Shared logic for node-specific maps)
|
||||
- `BaseMapViewModel` → `feature:map/commonMain` (Core contract for all maps)
|
||||
- `TracerouteOverlay` → `core:model/commonMain` (Pure data class for traceroute route segments; extracted from `feature:map` for cross-module reuse)
|
||||
- `GeoConstants` → `core:model/commonMain` (Centralized `DEG_D`, `HEADING_DEG`, `EARTH_RADIUS_METERS` constants; eliminates 7 duplicate private constants)
|
||||
|
||||
Extracted to core KMP modules:
|
||||
- Android Services, WorkManager Workers, and BroadcastReceivers → `core:service/androidMain`
|
||||
|
|
@ -151,7 +153,7 @@ Extracted to core KMP modules:
|
|||
- TCP radio connections, BLE radio connections (`BleRadioInterface`), and mDNS/NSD Service Discovery → `core:network/commonMain` (with Android `NsdManager` and Desktop `JmDNS` implementations)
|
||||
|
||||
Remaining to be extracted from `:app` or unified in `commonMain`:
|
||||
- `MapViewModel` (Unify Google/F-Droid flavors into a single `commonMain` class consuming a `MapConfigProvider` interface)
|
||||
- `MapViewModel` (Unify Google/F-Droid flavors into a single `commonMain` class consuming a `MapConfigProvider` interface. `MapViewProvider` interface simplified — track rendering and traceroute rendering extracted to dedicated provider contracts)
|
||||
|
||||
## Prerelease Dependencies
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Roadmap
|
||||
|
||||
> Last updated: 2026-03-31
|
||||
> Last updated: 2026-04-10
|
||||
|
||||
Forward-looking priorities for the Meshtastic KMP multi-target effort. For current state, see [`kmp-status.md`](./kmp-status.md). For the full gap analysis, see [`decisions/architecture-review-2026-03.md`](./decisions/architecture-review-2026-03.md).
|
||||
|
||||
|
|
@ -81,10 +81,10 @@ These items address structural gaps identified in the March 2026 architecture re
|
|||
|
||||
1. **Evaluate KMP-native testing tools** — ✅ **Done:** Fully evaluated and integrated `Mokkery`, `Turbine`, and `Kotest` across the KMP modules. `mockk` has been successfully replaced, enabling property-based and Flow testing in `commonTest` for iOS readiness.
|
||||
2. **Desktop Map Integration** — Address the major Desktop feature gap by implementing a raster map view using [**MapComposeMP**](https://github.com/p-lr/MapComposeMP).
|
||||
- Implement a `MapComposeProvider` for Desktop.
|
||||
- Implement Desktop providers for the 3 decomposed map contracts: `MapViewProvider` (main map), `NodeTrackMapProvider` (per-node track overlay for `PositionLogScreen`), and `TracerouteMapProvider` (traceroute visualization).
|
||||
- Implement a **Web Mercator Projection** helper in `feature:map/commonMain` to translate GPS coordinates to the 2D image plane.
|
||||
- Leverage the existing `BaseMapViewModel` contract.
|
||||
3. **Unify `MapViewModel`** — Collapse the remaining Google and F-Droid specific `MapViewModel` classes in the `:app` module into a single `commonMain` implementation by isolating platform-specific settings (styles, tile sources) behind a repository interface.
|
||||
- Leverage the existing `BaseMapViewModel` contract and `TracerouteNodeSelection` logic in `commonMain`.
|
||||
3. **Unify `MapViewModel`** — Collapse the remaining Google and F-Droid specific `MapViewModel` classes in the `:app` module into a single `commonMain` implementation by isolating platform-specific settings (styles, tile sources) behind a repository interface. The `MapViewProvider` interface has been simplified (track/traceroute rendering extracted to dedicated providers), reducing the surface area of this unification.
|
||||
4. **iOS CI gate** — ✅ **Done:** added `iosArm64()`/`iosSimulatorArm64()` to convention plugins and CI. `commonMain` successfully compiles on iOS.
|
||||
|
||||
## Medium-Term Priorities (60 days)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue