mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
7.3 KiB
7.3 KiB
Task Playbooks
Use these as practical recipes. Keep edits minimal and aligned with existing module boundaries.
For architecture rules and coding standards, see AGENTS.md.
Code Anchor Quick Reference
Key files for discovering established patterns:
| Pattern | Reference File |
|---|---|
| App DI wiring | app/src/main/kotlin/org/meshtastic/app/di/AppKoinModule.kt |
| App startup / Koin bootstrap | app/src/main/kotlin/org/meshtastic/app/MeshUtilApplication.kt |
| 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 |
| 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 |
Playbook A: Add or update a user-visible string
- Add/update key in
core/resources/src/commonMain/composeResources/values/strings.xml. - Import generated resource symbol in UI code (
org.meshtastic.core.resources.<key>). - Use
stringResource(Res.string.<key>)in Compose. - If the string appears in a shared dialog, prefer
core:uidialog components. - Verify no hardcoded user-facing strings were introduced.
Reference examples:
feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/list/NodeListScreen.ktcore/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/AlertDialogs.kt
Playbook B: Add shared ViewModel logic in a feature module
- Implement or extend base ViewModel logic in
feature/<name>/src/commonMain/.... - Keep shared class free of Android framework dependencies.
- Keep Android framework dependencies out of shared logic; if the module already uses Koin annotations in
commonMain, keep patterns consistent and ensure app root inclusion. - Update navigation entry points in
feature/*/src/androidMain/kotlin/org/meshtastic/feature/*/navigation/...to resolve ViewModels withkoinViewModel().
Reference examples:
- Shared base:
feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/MessageViewModel.kt - Shared base UI ViewModel:
core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/viewmodel/UIViewModel.kt - Navigation usage:
feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt - Desktop navigation usage:
desktop/src/main/kotlin/org/meshtastic/desktop/navigation/DesktopNavigation.kt
Playbook C: Add a new dependency or service binding
- Check
gradle/libs.versions.tomlfor existing library and version alias. - Add new dependency to version catalog first (if truly new).
- Wire implementation in the owning module (
core:*,feature:*, orapp) following existing architecture. - Register bindings/modules in app Koin graph where needed.
- For Android system integration (WorkManager, service bootstrapping), wire via
MeshUtilApplicationand app-layer modules.
Reference examples:
- App startup and Koin bootstrap:
app/src/main/kotlin/org/meshtastic/app/MeshUtilApplication.kt - App module scan:
app/src/main/kotlin/org/meshtastic/app/MainKoinModule.kt
Playbook D: Add or modify navigation flow
- Define/extend route keys in
core:navigation. - Implement feature entry/content using Navigation 3 types (
NavKey,NavBackStack,EntryProviderScope). - Add graph entries under the relevant feature module's
navigationpackage (e.g.,feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation). - If the entry content depends on platform-specific UI (e.g. Activity context or specific desktop wrappers), use
expect/actualdeclarations for the content composables. - Use backstack mutation (
add,removeLastOrNull) instead of introducing controller-coupled APIs. - Verify deep-link behavior if route is externally reachable.
Reference examples:
- Shared graph wiring:
feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt - Android specific content:
feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsMainScreen.kt - Desktop specific content:
feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsMainScreen.kt - Feature intro graph pattern:
feature/intro/src/androidMain/kotlin/org/meshtastic/feature/intro/IntroNavGraph.kt - Desktop nav shell:
desktop/src/main/kotlin/org/meshtastic/desktop/ui/DesktopMainScreen.kt - Desktop nav graph assembly:
desktop/src/main/kotlin/org/meshtastic/desktop/navigation/DesktopNavigation.kt
Playbook E: Add flavor/platform-specific UI implementation
- Keep shared contracts in
core:uior feature shared code. - Inject flavor/platform implementation via
CompositionLocalfromapp. - Avoid direct dependency from shared modules to Google Maps/osmdroid/other Android SDK-only APIs.
- 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 - Provider wiring:
app/src/main/kotlin/org/meshtastic/app/MainActivity.kt - Consumer side:
feature/map/src/androidMain/kotlin/org/meshtastic/feature/map/MapScreen.kt
Playbook F: Onboard a new platform target
- Create a platform application module (e.g.,
desktop/,ios/). - Copy
desktop/src/main/kotlin/org/meshtastic/desktop/stub/NoopStubs.ktas the starting stub set. All repository interfaces have no-op implementations there. - Create a
<Platform>KoinModulethat mirrorsdesktop/src/main/kotlin/org/meshtastic/desktop/di/DesktopKoinModule.kt— use stubs for unimplemented interfaces, real implementations where available. - Add
kotlinx-coroutines-swing(JVM/Desktop) or the equivalent platform coroutines dispatcher module. Without it,Dispatchers.Mainis unavailable and any code usinglifecycle.coroutineScopewill crash at runtime. - Progressively replace stubs with real implementations (e.g., serial transport for desktop, CoreBluetooth for iOS).
- Add
<platform>()target to feature modules as needed (allcore:*modules already declarejvm()). - Update CI JVM smoke compile step in
.github/workflows/reusable-check.ymlto include new modules. - If
commonMaincode fails to compile for the new target, it's a KMP migration debt — fix the shared code, not the target.
Reference examples:
- Desktop stubs:
desktop/src/main/kotlin/org/meshtastic/desktop/stub/NoopStubs.kt - Desktop DI:
desktop/src/main/kotlin/org/meshtastic/desktop/di/DesktopKoinModule.kt - Desktop Navigation 3 shell:
desktop/src/main/kotlin/org/meshtastic/desktop/ui/DesktopMainScreen.kt - Desktop nav graph entries:
desktop/src/main/kotlin/org/meshtastic/desktop/navigation/DesktopNavigation.kt - Desktop shared feature wiring:
feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt - Desktop-specific screen:
feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/DesktopSettingsScreen.kt - Roadmap:
docs/roadmap.md