feat: Implement iOS support and unify Compose Multiplatform infrastructure#4876
Merged
jamesarich merged 19 commits intomainfrom Mar 21, 2026
Merged
feat: Implement iOS support and unify Compose Multiplatform infrastructure#4876jamesarich merged 19 commits intomainfrom
jamesarich merged 19 commits intomainfrom
Conversation
…cture * Migrate platform-specific string formatting and `Dispatchers.IO` to common utilities (`formatString` and `ioDispatcher`). * Refactor Compose UI previews to use custom multiplatform-compatible annotations. * Add iOS build targets (`iosArm64`, `iosSimulatorArm64`) across core and feature modules. * Implement iOS-specific persistence using Okio and Room. * Add platform no-op stubs and CI compilation validation for iOS targets. * Update documentation roadmap to reflect iOS and JetBrains Compose migration progress.
…e Multiplatform * Centralized polymorphic NavKey serialization in NavigationConfig for Navigation 3 saved state. * Relocated desktop-specific screens to feature module jvmMain source sets to thin out the desktop module. * Migrated Message, Contacts, and MessageListPaged screens into commonMain for full cross-platform UI reuse. * Replaced PredictiveBackHandler with Compose Multiplatform NavigationBackHandler. * Replaced legacy tooling preview wildcards with explicit, multiplatform-compatible imports.
…ultiplatform UI * Reflected that desktop completely relies on feature modules via commonMain exported graphs. * Removed references to desktop-specific configuration screens which are now fully shared.
* Migrated NodeListScreen entirely to commonMain via platform-agnostic toast resources. * Moved AdaptiveNodeListScreen to commonMain to deduplicate JetBrains adaptive pane scaffolds across JVM and Android. * Standardized right-pane NodeDetailScreen via an expect/actual definition to isolate complex Android-specific location and compass permissions away from the common implementation. * Removed the duplicate DesktopAdaptiveNodeListScreen implementation in the desktop module.
* Removed Android-specific dependencies (LocalContext, toUri) in favor of shared multiplatform equivalents (CommonUri.parse, rememberShowToastResource). * Created a generic callback for NFC settings enabling feature modules to be platform agnostic. * Deleted the duplicate DesktopNetworkConfigScreen implementation entirely.
…igScreen * Added `@Suppress` to the NetworkConfigScreen function since it was moved from androidMain to commonMain, causing it to fail strict detekt length thresholds.
* Cleaned up obsolete baseline signatures and resolved legacy entries from previously extracted KMP views and viewmodels.
Contributor
There was a problem hiding this comment.
Pull request overview
Enables compile-only iOS target support across the KMP modules and further unifies the Compose Multiplatform + Navigation 3 infrastructure so Android/Desktop share more common code paths.
Changes:
- Add iOS targets (iosArm64, iosSimulatorArm64) and CI smoke compilation for iOS Simulator Arm64.
- Introduce multiplatform utility abstractions/stubs (e.g.,
ioDispatcher,formatString, URI/toast/NFC helpers) to keep commonMain compiling on iOS. - Refactor feature navigation/screens to use
expect/actualentry points and shared graphs, reducing desktop-specific wiring.
Reviewed changes
Copilot reviewed 147 out of 149 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| gradle/libs.versions.toml | Adds NavigationEvent + Compose tooling preview dependencies in version catalog |
| fix_dispatchers.py | Adds a helper script to replace Dispatchers.IO usages with ioDispatcher |
| feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsMainScreen.kt | Desktop actual implementations for Settings entry screens |
| feature/settings/src/iosMain/kotlin/org/meshtastic/feature/settings/debugging/NoopStubs.kt | iOS no-op stub for log export |
| feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/component/PacketResponseStateDialog.kt | Uses formatString for KMP-safe formatting |
| feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/component/LoadingOverlay.kt | Uses formatString for KMP-safe formatting |
| feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModel.kt | Switches to ioDispatcher for background work |
| feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/radio/component/NetworkConfigItemList.kt | Removes Android-only URI/NFC helpers; introduces CommonUri & callback injection |
| feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt | Moves shared entry wiring toward expect/actual screens |
| feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsMainScreen.kt | Android actual implementations for Settings entry + config screens |
| feature/settings/detekt-baseline.xml | Updates baseline (removes some suppressed issues) |
| feature/node/src/jvmMain/kotlin/org/meshtastic/feature/node/navigation/TracerouteMapScreens.kt | Desktop placeholder actual for traceroute map |
| feature/node/src/jvmMain/kotlin/org/meshtastic/feature/node/metrics/PositionLogScreens.kt | Desktop placeholder actual for position log |
| feature/node/src/jvmMain/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreens.kt | Desktop actual for node detail screen using shared content |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/PositionLogScreens.kt | Introduces expect for position log screen |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/PositionLogComponents.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt | Uses formatString during export formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/EnvironmentCharts.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/detail/NodeManagementActions.kt | Switches to ioDispatcher |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreens.kt | Adds expect for NodeDetailScreen |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/detail/CommonNodeRequestActions.kt | Switches to ioDispatcher |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/NodeItem.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/NodeDetailsSection.kt | Uses formatString for KMP-safe formatting |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/CompassBottomSheet.kt | Replaces Math.toRadians with PI math for KMP-friendliness; uses formatString |
| feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/compass/CompassViewModel.kt | Uses formatString |
| feature/node/src/androidMain/kotlin/org/meshtastic/feature/node/navigation/TracerouteMapScreens.kt | Android actual traceroute map screen wrapper for MetricsViewModel |
| feature/node/src/androidMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt | Adds expect traceroute map API + default args for desktop assembly |
| feature/node/src/androidMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt | Migrates back handling to NavigationEvent-based handler and adds injected navigation callback |
| feature/node/src/androidMain/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt | Marks PositionLogScreen as actual |
| feature/node/src/androidMain/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt | Replaces Android context toast with multiplatform toast helper |
| feature/node/src/androidMain/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt | Marks NodeDetailScreen as actual and aligns signature with expect |
| feature/messaging/src/jvmMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsEntryContent.kt | Desktop actual contacts entry wiring with custom detail pane |
| feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/ui/contact/ContactsViewModel.kt | Switches to ioDispatcher |
| feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/QuickChatViewModel.kt | Switches to ioDispatcher |
| feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/QuickChat.kt | Uses encodeToByteArray() for KMP-friendly byte sizing |
| feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/MessageViewModel.kt | Switches to ioDispatcher |
| feature/messaging/src/androidTest/kotlin/org/meshtastic/feature/messaging/component/MessageItemTest.kt | Updates preview parameter provider import |
| feature/messaging/src/androidMain/kotlin/org/meshtastic/feature/messaging/ui/contact/Contacts.kt | Removes Android-only URI conversion, uses MeshtasticUri; swaps toast impl |
| feature/messaging/src/androidMain/kotlin/org/meshtastic/feature/messaging/ui/contact/AdaptiveContactsScreen.kt | Migrates predictive back handling to NavigationEvent; allows custom detail pane |
| feature/messaging/src/androidMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt | Moves Contacts entry content to expect/actual; provides default scroll events |
| feature/messaging/src/androidMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsEntryContent.kt | Android actual ContactsEntryContent wiring |
| feature/messaging/src/androidMain/kotlin/org/meshtastic/feature/messaging/Message.kt | Uses multiplatform clipboard entry factory and encodeToByteArray() |
| feature/messaging/build.gradle.kts | Pulls paging-compose + navigationevent into commonMain; simplifies androidMain deps |
| feature/map/src/jvmMain/kotlin/org/meshtastic/feature/map/navigation/MapMainScreen.kt | Desktop placeholder actual map main screen |
| feature/map/src/commonMain/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt | Switches to ioDispatcher |
| feature/map/src/androidMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt | Introduces expect MapMainScreen entry point and uses it |
| feature/map/src/androidMain/kotlin/org/meshtastic/feature/map/navigation/MapMainScreen.kt | Android actual wiring to MapScreen/SharedMapViewModel |
| feature/map/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| feature/intro/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| feature/firmware/src/jvmMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareScreen.kt | Desktop actual firmware screen |
| feature/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareScreen.kt | Android actual firmware screen |
| feature/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt | Uses FirmwareScreen via expect/actual; exposes expect declaration |
| feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ScannerViewModel.kt | Uses ioDispatcher for flowOn |
| feature/connections/src/androidMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt | Uses shared ScannerViewModel instead of Android-specific VM |
| feature/connections/detekt-baseline.xml | Cleans/empties detekt baseline |
| feature/connections/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| docs/roadmap.md | Updates roadmap items to include iOS CI gate and shared settings status |
| docs/kmp-status.md | Updates KMP status wording to reflect fully shared graphs |
| docs/decisions/navigation3-parity-2026-03.md | Updates source anchors to reflect shared graph registration |
| docs/agent-playbooks/task-playbooks.md | Updates Navigation 3 wiring playbook for shared graphs + expect/actual |
| docs/agent-playbooks/di-navigation3-anti-patterns-playbook.md | Updates anchors for shared saved-state config and shared graph pattern |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/settings/DesktopSettingsScreen.kt | Moves desktop settings UI into feature package namespace |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/settings/DesktopSecurityConfigScreen.kt | Moves desktop settings UI into feature package namespace |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/settings/DesktopPositionConfigScreen.kt | Moves desktop settings UI into feature package namespace |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/settings/DesktopNetworkConfigScreen.kt | Removes desktop-specific network config screen (now shared) |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/settings/DesktopExternalNotificationConfigScreen.kt | Moves desktop settings UI into feature package namespace |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/settings/DesktopDeviceConfigScreen.kt | Moves desktop settings UI into feature package namespace |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/nodes/DesktopAdaptiveNodeListScreen.kt | Removes desktop-specific node list screen (now shared graphs + wrappers) |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/messaging/DesktopMessageContent.kt | Removes desktop-specific message content (now shared MessageScreen) |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/messaging/DesktopAdaptiveContactsScreen.kt | Removes desktop-specific contacts screen (now shared AdaptiveContactsScreen) |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/firmware/DesktopFirmwareScreen.kt | Moves desktop firmware UI into feature package namespace |
| desktop/src/main/kotlin/org/meshtastic/desktop/ui/DesktopMainScreen.kt | Removes desktop-local saved state config (now shared in core:navigation) |
| desktop/src/main/kotlin/org/meshtastic/desktop/navigation/DesktopSettingsNavigation.kt | Removes desktop-specific settings graph wiring (now shared settingsGraph) |
| desktop/src/main/kotlin/org/meshtastic/desktop/navigation/DesktopNodeNavigation.kt | Removes desktop-specific node graph wiring (now shared nodesGraph) |
| desktop/src/main/kotlin/org/meshtastic/desktop/navigation/DesktopNavigation.kt | Assembles desktop graph from feature-provided shared graphs |
| desktop/src/main/kotlin/org/meshtastic/desktop/navigation/DesktopMessagingNavigation.kt | Removes desktop-specific messaging graph wiring (now shared contactsGraph) |
| desktop/src/main/kotlin/org/meshtastic/desktop/Main.kt | Uses shared MeshtasticNavSavedStateConfig |
| core/ui/src/iosMain/kotlin/org/meshtastic/core/ui/util/NoopStubs.kt | Adds iOS stubs for clipboard, NFC, toast, maps, URL, brightness |
| core/ui/src/iosMain/kotlin/org/meshtastic/core/ui/theme/NoopStubs.kt | Adds iOS stub for dynamic color scheme |
| core/ui/src/iosMain/kotlin/org/meshtastic/core/ui/component/NoopStubs.kt | Adds iOS stubs for time ticking and enum helpers |
| core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/qr/ScannedQrCodeDialog.kt | Updates preview annotations to Compose tooling preview light/dark |
| core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/SignalInfo.kt | Uses formatString for KMP-safe formatting |
| core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/ScrollToTopEvent.kt | Adds rememberScrollToTopEvents helper |
| core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MaterialBatteryInfo.kt | Uses formatString for KMP-safe formatting |
| core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/LoraSignalIndicator.kt | Uses formatString for KMP-safe formatting |
| core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt | Uses encodeToByteArray() for KMP-friendly byte sizing |
| core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/DropDownPreference.kt | Adds JVM annotation import to support bridging (context within file) |
| core/ui/build.gradle.kts | Adjusts tooling preview dependency exposure and jvmAndroid-only tooling |
| core/testing/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| core/service/src/commonMain/kotlin/org/meshtastic/core/service/SharedRadioInterfaceService.kt | Uses atomic+Mutex for listener initialization synchronization |
| core/service/build.gradle.kts | Adds atomicfu dependency |
| core/resources/src/commonMain/kotlin/org/meshtastic/core/resources/GetString.kt | Uses formatString for KMP-safe formatting |
| core/resources/build.gradle.kts | Adds dependency on core:common to support formatString |
| core/repository/src/iosMain/kotlin/org/meshtastic/core/repository/Location.kt | Adds iOS no-op Location stub |
| core/repository/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| core/proto/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| core/prefs/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| core/nfc/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| core/network/src/commonMain/kotlin/org/meshtastic/core/network/radio/MockInterface.kt | Removes Integer.toHexString usage for KMP friendliness |
| core/network/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt | Adds shared Navigation 3 saved-state serializer config |
| core/navigation/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| core/model/src/iosMain/kotlin/org/meshtastic/core/model/util/NoopStubs.kt | Adds iOS stubs for platform-specific model utilities |
| core/model/src/commonMain/kotlin/org/meshtastic/core/model/util/SharedContact.kt | Uses e::class.simpleName for KMP |
| core/model/src/commonMain/kotlin/org/meshtastic/core/model/util/DistanceExtensions.kt | Uses formatString and refactors formatting logic |
| core/model/src/commonMain/kotlin/org/meshtastic/core/model/Node.kt | Uses formatString for KMP-safe formatting |
| core/model/src/commonMain/kotlin/org/meshtastic/core/model/DataPacket.kt | Uses formatString for KMP-safe formatting |
| core/model/src/commonMain/kotlin/org/meshtastic/core/model/Channel.kt | Uses copyOf() instead of clone() for KMP friendliness |
| core/domain/build.gradle.kts | Removes explicit jvm() target (now standardized elsewhere) |
| core/di/src/commonMain/kotlin/org/meshtastic/core/di/di/CoreDiModule.kt | Provides CoroutineDispatchers.io using ioDispatcher |
| core/di/build.gradle.kts | Adds dependency on core:common for ioDispatcher |
| core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/di/CoreDatastoreModule.kt | Uses ioDispatcher for DataStore scope |
| core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/UiPreferencesDataSource.kt | Uses ioDispatcher for backing scope |
| core/database/src/iosMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt | Reworks iOS DataStore creation using Okio storage |
| core/database/src/commonMain/kotlin/org/meshtastic/core/database/MeshtasticDatabase.kt | Sets Room query dispatcher via ioDispatcher; updates migration annotations |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/TracerouteHandlerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/PacketHandlerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/NodeManagerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/NeighborInfoHandlerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/MqttManagerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/MeshMessageProcessorImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/MeshDataHandlerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/MeshConnectionManagerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/MeshConfigHandlerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/MeshConfigFlowManagerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/MeshActionHandlerImpl.kt | Uses ioDispatcher for internal scope |
| core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/CommandSenderImpl.kt | Uses ioDispatcher for internal scope |
| core/common/src/jvmAndroidMain/kotlin/org/meshtastic/core/common/util/Formatter.kt | JVM/Android implementation of formatString |
| core/common/src/jvmAndroidMain/kotlin/org/meshtastic/core/common/util/Dispatchers.kt | JVM/Android ioDispatcher maps to Dispatchers.IO |
| core/common/src/iosMain/kotlin/org/meshtastic/core/common/util/NoopStubs.kt | Adds iOS stubs for common utilities to allow compilation |
| core/common/src/iosMain/kotlin/org/meshtastic/core/common/util/Formatter.kt | iOS stub implementation of formatString |
| core/common/src/iosMain/kotlin/org/meshtastic/core/common/util/Dispatchers.kt | iOS ioDispatcher maps to Dispatchers.Default |
| core/common/src/commonMain/kotlin/org/meshtastic/core/common/util/HomoglyphCharacterStringTransformer.kt | Simplifies map substitution logic |
| core/common/src/commonMain/kotlin/org/meshtastic/core/common/util/Formatter.kt | Adds expect fun formatString |
| core/common/src/commonMain/kotlin/org/meshtastic/core/common/util/Dispatchers.kt | Adds expect val ioDispatcher |
| core/ble/src/iosMain/kotlin/org/meshtastic/core/ble/NoopStubs.kt | Adds iOS BLE stubs for compilation |
| build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/KotlinAndroid.kt | Adds iOS KMP targets and shared opt-ins/compiler flags |
| app/src/main/kotlin/org/meshtastic/app/ui/Main.kt | Uses shared Navigation 3 saved-state config |
| app/detekt-baseline.xml | Cleans/empties detekt baseline |
| .jdk | Adds local JDK path configuration file |
| .gitignore | Updates ignored entries (appears to adjust firebase debug log ignore) |
| .github/workflows/reusable-check.yml | Expands KMP smoke compile to include iOS simulator target |
Comments suppressed due to low confidence (5)
.jdk:1
- This file hard-codes a developer-specific absolute path. Committing it will break other environments and can cause tooling churn in PRs. Consider removing
.jdkfrom the repo and adding it to.gitignore, or replacing it with a team-agnostic approach (e.g., documenting required JDK version and relying on toolchains).
core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/ScrollToTopEvent.kt:1 - A default
MutableSharedFlow()has no buffer;emit()will suspend if there are no collectors, which can deadlock UI coroutines depending on how events are produced. Consider configuring buffering (e.g.,MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)) and/or returning aSharedFlowplus a separate emitter API to avoid exposing mutable flow internals.
core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/ScrollToTopEvent.kt:1 - A default
MutableSharedFlow()has no buffer;emit()will suspend if there are no collectors, which can deadlock UI coroutines depending on how events are produced. Consider configuring buffering (e.g.,MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)) and/or returning aSharedFlowplus a separate emitter API to avoid exposing mutable flow internals.
fix_dispatchers.py:1 - This looks like a one-off migration script that rewrites source files in-place. Consider moving it under a clearly designated tooling/scripts directory (and documenting usage), or removing it from the repo once the migration is complete to avoid shipping ad-hoc code alongside production sources.
fix_dispatchers.py:1 - This looks like a one-off migration script that rewrites source files in-place. Consider moving it under a clearly designated tooling/scripts directory (and documenting usage), or removing it from the repo once the migration is complete to avoid shipping ad-hoc code alongside production sources.
core/common/src/iosMain/kotlin/org/meshtastic/core/common/util/Formatter.kt
Outdated
Show resolved
Hide resolved
core/database/src/iosMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt
Outdated
Show resolved
Hide resolved
build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/KotlinAndroid.kt
Outdated
Show resolved
Hide resolved
* Update iOS `formatString` stub to explicitly throw an UnsupportedOperationException rather than silently returning the unformatted pattern string. * Ensure the iOS DataStore stubs securely return `emptyPreferences()` rather than immediately crashing during app initialization. * Refactor `KotlinAndroid.kt` convention plugin to configure Kotlin compilerOptions lazily rather than eagerly resolving the task provider.
…updates * Updated GEMINI.md, AGENTS.md, and GitHub Copilot instructions to reflect iOS targets, thin Desktop shell architecture, and deduplicated UI. * Updated desktop/README.md to detail unified Navigation 3 configuration, shared graphs, and the reduction of the desktop target to a shell module. * Updated agent playbooks to explicitly forbid custom predictive back handlers in favor of Compose Multiplatform's NavigationBackHandler. * Cleansed leftover markdown formatting artifacts from previous playbook modifications. * Updated the Navigation 3 Parity Decision document to 'Implemented' and summarized the unification results.
* Moved formatMuteRemainingTime to commonMain to resolve undefined references in KMP UI. * Fixed unresolved layout fillMaxSize import in Desktop MapMainScreen placeholder. * Re-added explicit import to resolve duration issues in AndroidDateTimeUtils. * Fixed unresolved ContactsViewModel references in Desktop navigation stubs.
* Completely replaced custom wrapper invocations with native Compose Multiplatform resource formatting capabilities, utilizing the new APIs added in recent Compose releases. * Removed explicit formatting wrappers from , drastically simplifying synchronous string lookups. * Migrated localized resource loading in and to run inside coroutines via instead of performing blocking IO on the main execution thread.
…utines * Updated core AI/developer guides (AGENTS.md, GEMINI.md, copilot-instructions.md) to explicitly mandate the usage of `getStringSuspend` inside ViewModels and Coroutine scopes. * Updated `common-practices.md` to point to the newly relocated `NodeListScreen.kt` example in `commonMain`.
…lementation - Migrate to `LocalBarcodeScannerProvider` and `LocalNfcScannerProvider` in network settings. - Refactor `NetworkConfigScreen` to simplify UI logic, improve IP address formatting, and consolidate IPv4 configuration. - Update desktop `NodeDetailScreen` to use `uiState` collection and a unified action handler. - Add firmware feature dependency to the desktop module. - Clean up unused imports and qualified names across node and settings features.
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 156 out of 158 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (5)
.jdk:1
- Committing a
.jdkfile with an absolute developer-local path will break portability for other contributors/CI environments and can leak user/workstation details. This should be removed from version control and added to.gitignore(or replaced by a repo-relative/tooling-agnostic JDK configuration if the project wants to standardize local JDK setup).
core/service/src/commonMain/kotlin/org/meshtastic/core/service/SharedRadioInterfaceService.kt:1 - There’s a race window where multiple calls can pass the initial
listenersInitialized.valuecheck and each enqueue a coroutine, even though only one will win the mutex. Consider atomically preventing multiple launches (e.g.,if (!listenersInitialized.compareAndSet(false, true)) returnbefore launching), or otherwise ensure only one init coroutine is scheduled.
core/ui/build.gradle.kts:1 - Exposing preview tooling as an
apidependency makes it transitively available to downstream modules and can increase compile classpaths unnecessarily. Typically preview artifacts areimplementation(or even debug-only) because they’re only needed for preview annotations. Consider switchingapi(...)toimplementation(...)unless consumers truly need it on their public API surface.
core/ui/build.gradle.kts:1 - Exposing preview tooling as an
apidependency makes it transitively available to downstream modules and can increase compile classpaths unnecessarily. Typically preview artifacts areimplementation(or even debug-only) because they’re only needed for preview annotations. Consider switchingapi(...)toimplementation(...)unless consumers truly need it on their public API surface.
core/database/src/iosMain/kotlin/org/meshtastic/core/database/DatabaseBuilder.kt:1 - This iOS DataStore implementation silently discards persisted preferences (always reads empty, writes no-op). Even for 'compile-only' iOS support, this is a footgun because it can fail at runtime without obvious signals. Prefer failing fast with an explicit
UnsupportedOperationException(or log warnings) so any accidental runtime execution is immediately diagnosable.
…ading - Introduce `getAboutLibrariesJson()` as an expect/actual function to handle platform-specific library resource loading. - Add iOS navigation stubs for Map, Messaging, Firmware, and Settings screens. - Refine iOS no-op stub signatures in `core:ui` and `feature:settings` for better parameter clarity.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request expands Kotlin Multiplatform (KMP) support across the codebase, improves documentation for cross-platform development, and updates the build and CI process to ensure iOS compatibility. It also updates the BLE stack to use Kable, enhances shared testing and UI guidelines, and cleans up static analysis configuration.
Key changes include:
Kotlin Multiplatform (KMP) Expansion and Build Process:
iosArm64()andiosSimulatorArm64()targets to the standard KMP configuration inbuild-logic/convention, ensuring all relevant modules compile for iOS as well as JVM..github/workflows/reusable-check.ymlto include iOS Simulator Arm64 smoke compile steps for all KMP modules, not just JVM.Documentation Updates for Cross-Platform Development:
.github/copilot-instructions.md,AGENTS.md, andGEMINI.mdto reflect new KMP targets, BLE stack migration, feature module targets, and Compose Multiplatform best practices. This includes stricter guidance on string resources, QR code generation, and test libraries. [1] [2] [3] [4] [5]Bluetooth Low Energy (BLE) Stack Migration:
Navigation and UI Improvements:
MainScreencomposable inapp/src/main/kotlin/org/meshtastic/app/ui/Main.ktto useMeshtasticNavSavedStateConfigfor navigation back stack state, preparing for enhanced multiplatform navigation support. [1] [2]Static Analysis and Build Environment:
.jdkto a specific JDK path, standardizing the build environment.These changes collectively improve multiplatform support, developer experience, and code quality across the project.